Work on attacks

This commit is contained in:
Miloslav Číž 2020-01-02 17:22:00 +01:00
parent ecedf3ba44
commit 8b97f597a7
4 changed files with 78 additions and 25 deletions

BIN
assets/monster_dead.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 449 B

View File

@ -84,11 +84,6 @@
*/
#define SFG_EXPLOSION_DISTANCE 2048
/**
How much damage explosion causes in its range.
*/
#define SFG_EXPLOSION_DAMAGE 18
/**
Maximum player health.
*/
@ -104,6 +99,13 @@
*/
#define SFG_HEALTH_KIT_VALUE 20
/**
How much randomness (positive and negative) will be added to damage
(e.g. by weapons, explisions). This constant is is 0 to 255, 255 meaning
100% of the base value.
*/
#define SFG_DAMAGE_RANDOMNESS 64
/**
Angle in which multiple projectiles are spread, RCL_Units.
*/
@ -354,6 +356,8 @@ uint16_t SFG_monsterAttributeTable[SFG_MONSTERS_TOTAL] =
#define SFG_WEAPON_FIRE_TYPE_FIREBALL 2
#define SFG_WEAPON_FIRE_TYPE_PLASMA 3
#define SFG_WEAPON_FIRE_TYPES_TOTAL 4
/**
Table of weapon attributes, each as a byte in format:
@ -374,6 +378,14 @@ SFG_PROGRAM_MEMORY uint8_t SFG_weaponAttributeTable[SFG_WEAPONS_TOTAL] =
/* solution */ SFG_WEAPON_ATTRIBUTE(SFG_WEAPON_FIRE_TYPE_PLASMA,4,1000)
};
SFG_PROGRAM_MEMORY uint8_t SFG_attackDamageTable[SFG_WEAPON_FIRE_TYPES_TOTAL] =
{
/* melee */ 8,
/* bullet */ 10,
/* explostion (fireball) */ 13,
/* plasma */ 17
};
#define SFG_PROJECTILE_EXPLOSION 0
#define SFG_PROJECTILE_FIREBALL 1
#define SFG_PROJECTILE_PLASMA 2

78
main.c
View File

@ -317,6 +317,32 @@ uint8_t SFG_random()
return SFG_currentRandom;
}
/**
Returns a damage value for specific attack type (SFG_WEAPON_FIRE_TYPE_...),
with added randomness (so the values will differe). For explosion pass
SFG_WEAPON_FIRE_TYPE_FIREBALL.
*/
uint8_t SFG_getDamageValue(uint8_t attackType)
{
if (attackType >= SFG_WEAPON_FIRE_TYPES_TOTAL)
return 0;
int32_t value = SFG_attackDamageTable[attackType]; // has to be signed
printf("%d ",value);
int32_t maxAdd = (value * SFG_DAMAGE_RANDOMNESS) / 256;
value = value - (maxAdd / 2) + (SFG_random() * maxAdd / 256);
if (value < 0)
value = 0;
printf("%d\n",value);
return value;
}
static inline RCL_Unit
SFG_taxicabDistance(RCL_Unit x0, RCL_Unit y0, RCL_Unit x1, RCL_Unit y1)
{
@ -573,7 +599,6 @@ void SFG_pixelFunc(RCL_PixelInfo *pixel)
}
else
{
color = SFG_getTexel(
SFG_backgroundImages[0],
SFG_backgroundScaleMap[((pixel->position.x
@ -1235,7 +1260,8 @@ void SFG_createExplosion(RCL_Unit x, RCL_Unit y, RCL_Unit z)
SFG_createProjectile(explosion);
if (SFG_pushPlayerAway(x,y,SFG_EXPLOSION_DISTANCE))
SFG_playerChangeHealth(-1 * SFG_EXPLOSION_DAMAGE);
SFG_playerChangeHealth(
-1 * SFG_getDamageValue(SFG_WEAPON_FIRE_TYPE_FIREBALL));
for (uint8_t i = 0; i < SFG_currentLevel.monsterRecordCount; ++i)
{
@ -1249,7 +1275,8 @@ void SFG_createExplosion(RCL_Unit x, RCL_Unit y, RCL_Unit z)
SFG_EXPLOSION_DISTANCE)
)
{
SFG_monsterChangeHealth(monster,-1 * SFG_EXPLOSION_DAMAGE);
SFG_monsterChangeHealth(monster,
-1 * SFG_getDamageValue(SFG_WEAPON_FIRE_TYPE_FIREBALL));
}
}
}
@ -1276,7 +1303,6 @@ void SFG_createDust(RCL_Unit x, RCL_Unit y, RCL_Unit z)
void SFG_monsterPerformAI(SFG_MonsterRecord *monster)
{
return;
uint8_t state = SFG_MR_STATE(*monster);
uint8_t type = SFG_MR_TYPE(*monster);
uint8_t monsterNumber = SFG_MONSTER_TYPE_TO_INDEX(type);
@ -1935,11 +1961,18 @@ void SFG_gameStep()
{ // ^ has to be signed
SFG_ProjectileRecord *p = &(SFG_currentLevel.projectileRecords[i]);
uint8_t attackType = 255;
if (p->type == SFG_PROJECTILE_BULLET)
attackType = SFG_WEAPON_FIRE_TYPE_BULLET;
else if (p->type == SFG_PROJECTILE_PLASMA)
attackType = SFG_WEAPON_FIRE_TYPE_PLASMA;
RCL_Unit pos[3]; // we have to convert from uint16_t because under/overflows
uint8_t eliminate = 0;
for (uint8_t j = 0; j < 3; ++j)
for (uint8_t j = 0; j < 3; ++j) // projectile outside map?
{
pos[j] = p->position[j];
pos[j] += p->direction[j];
@ -1953,22 +1986,24 @@ void SFG_gameStep()
}
}
if (
(p->doubleFramesToLive == 0) ||
SFG_elementCollides(
SFG_player.camera.position.x,
SFG_player.camera.position.y,
SFG_player.camera.height,
p->position[0],
p->position[1],
p->position[2],
0,
0
)
)
if (p->doubleFramesToLive == 0) // no more time to live?
{
eliminate = 1;
}
else if (SFG_elementCollides( // hits player?
SFG_player.camera.position.x,
SFG_player.camera.position.y,
SFG_player.camera.height,
p->position[0],
p->position[1],
p->position[2],
0,
0))
{
eliminate = 1;
SFG_playerChangeHealth(-1 * SFG_getDamageValue(attackType));
}
else if (
(p->type != SFG_PROJECTILE_EXPLOSION) &&
(p->type != SFG_PROJECTILE_DUST))
@ -2002,6 +2037,7 @@ void SFG_gameStep()
)
{
eliminate = 1;
SFG_monsterChangeHealth(m,SFG_getDamageValue(attackType));
break;
}
}
@ -2026,8 +2062,6 @@ void SFG_gameStep()
0)
)
{
eliminate = 1;
break;
}
@ -2473,6 +2507,10 @@ void SFG_drawWeapon(int16_t bobOffset)
void SFG_draw()
{
#if SFG_BACKGROUND_BLUR != 0
SFG_backgroundBlurIndex = 0;
#endif
if (SFG_keyPressed(SFG_KEY_MAP))
{
SFG_drawMap();

View File

@ -26,6 +26,9 @@
#undef SFG_LOG
#define SFG_LOG(str) printf("game: %s\n",str);
#undef SFG_BACKGROUND_BLUR
#define SFG_BACKGROUND_BLUR 1
const uint8_t *sdlKeyboardState;
uint16_t screen[SFG_SCREEN_RESOLUTION_X * SFG_SCREEN_RESOLUTION_Y]; // RGB565 format