Explode barrels

This commit is contained in:
Miloslav Číž 2020-01-11 19:22:14 +01:00
parent b4cc671cd8
commit ec5703bcec
3 changed files with 77 additions and 47 deletions

View File

@ -93,6 +93,12 @@
*/
#define SFG_EXPLOSION_DISTANCE 2048
/**
How much damage triggers a barrel explosion.
*/
#define SFG_BARREL_EXPLOSION_DAMAGE_THRESHOLD 11
/**
Maximum player health.
*/
@ -110,7 +116,7 @@
/**
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
(e.g. by weapons, explosions, ...). This constant is is 0 to 255, 255 meaning
100% of the base value.
*/
#define SFG_DAMAGE_RANDOMNESS 64

View File

@ -269,11 +269,11 @@ SFG_PROGRAM_MEMORY SFG_Level SFG_level0 =
{SFG_LEVEL_ELEMENT_MONSTER_TURRET, {5, 24}}, {SFG_LEVEL_ELEMENT_NONE, {0, 0}},
{SFG_LEVEL_ELEMENT_MONSTER_EXPLODER, {22, 18}}, {SFG_LEVEL_ELEMENT_NONE, {0, 0}},
{SFG_LEVEL_ELEMENT_BULLETS, {7, 23}}, {SFG_LEVEL_ELEMENT_BULLETS, {8, 23}},
{SFG_LEVEL_ELEMENT_NONE, {0, 0}}, {SFG_LEVEL_ELEMENT_NONE, {0, 0}},
{SFG_LEVEL_ELEMENT_NONE, {0, 0}}, {SFG_LEVEL_ELEMENT_NONE, {0, 0}},
{SFG_LEVEL_ELEMENT_NONE, {0, 0}}, {SFG_LEVEL_ELEMENT_NONE, {0, 0}},
{SFG_LEVEL_ELEMENT_NONE, {0, 0}}, {SFG_LEVEL_ELEMENT_NONE, {0, 0}},
{SFG_LEVEL_ELEMENT_NONE, {0, 0}}, {SFG_LEVEL_ELEMENT_NONE, {0, 0}},
{SFG_LEVEL_ELEMENT_BARREL, {9, 37}}, {SFG_LEVEL_ELEMENT_BARREL, {9, 38}},
{SFG_LEVEL_ELEMENT_BARREL, {9, 39}}, {SFG_LEVEL_ELEMENT_BARREL, {9, 40}},
{SFG_LEVEL_ELEMENT_BARREL, {9, 41}}, {SFG_LEVEL_ELEMENT_BARREL, {9, 42}},
{SFG_LEVEL_ELEMENT_BARREL, {9, 43}}, {SFG_LEVEL_ELEMENT_BARREL, {9, 44}},
{SFG_LEVEL_ELEMENT_BARREL, {8, 45}}, {SFG_LEVEL_ELEMENT_BARREL, {9, 46}},
{SFG_LEVEL_ELEMENT_NONE, {0, 0}}, {SFG_LEVEL_ELEMENT_NONE, {0, 0}},
{SFG_LEVEL_ELEMENT_NONE, {0, 0}}, {SFG_LEVEL_ELEMENT_NONE, {0, 0}},
{SFG_LEVEL_ELEMENT_NONE, {0, 0}}, {SFG_LEVEL_ELEMENT_NONE, {0, 0}},

76
main.c
View File

@ -336,12 +336,11 @@ uint8_t SFG_getDamageValue(uint8_t attackType)
int32_t value = SFG_attackDamageTable[attackType]; // has to be signed
int32_t maxAdd = (value * SFG_DAMAGE_RANDOMNESS) / 256;
value = value - (maxAdd / 2) + (SFG_random() * maxAdd / 256);
value = value + (maxAdd / 2) - (SFG_random() * maxAdd / 256);
if (value < 0)
value = 0;
return value;
}
@ -1261,6 +1260,23 @@ void SFG_monsterChangeHealth(SFG_MonsterRecord *monster, int8_t healthAdd)
monster->health = health;
}
void SFG_removeItem(uint8_t index)
{
SFG_LOG("removing item");
for (uint16_t j = index; j < SFG_currentLevel.itemRecordCount - 1; ++j)
SFG_currentLevel.itemRecords[j] =
SFG_currentLevel.itemRecords[j + 1];
SFG_currentLevel.itemRecordCount--;
}
void SFG_explodeBarrel(uint8_t itemIndex, RCL_Unit x, RCL_Unit y, RCL_Unit z)
{
SFG_removeItem(itemIndex);
SFG_createExplosion(x,y,z);
}
void SFG_createExplosion(RCL_Unit x, RCL_Unit y, RCL_Unit z)
{
SFG_ProjectileRecord explosion;
@ -1280,9 +1296,10 @@ void SFG_createExplosion(RCL_Unit x, RCL_Unit y, RCL_Unit z)
SFG_createProjectile(explosion);
uint8_t damage = SFG_getDamageValue(SFG_WEAPON_FIRE_TYPE_FIREBALL);
if (SFG_pushPlayerAway(x,y,SFG_EXPLOSION_DISTANCE))
SFG_playerChangeHealth(
-1 * SFG_getDamageValue(SFG_WEAPON_FIRE_TYPE_FIREBALL));
SFG_playerChangeHealth(-1 * damage);
for (uint16_t i = 0; i < SFG_currentLevel.monsterRecordCount; ++i)
{
@ -1307,30 +1324,35 @@ void SFG_createExplosion(RCL_Unit x, RCL_Unit y, RCL_Unit z)
}
}
// explode other barrels
// explode nearby barrels
if (damage >= SFG_BARREL_EXPLOSION_DAMAGE_THRESHOLD)
for (uint16_t i = 0; i < SFG_currentLevel.itemRecordCount; ++i)
{
SFG_ItemRecord item = SFG_currentLevel.itemRecords[i];
if (!(item & SFG_ITEM_RECORD_ACTIVE_MASK))
continue;
/* We DON'T check just active barrels but all, otherwise it looks weird
that out of sight barrels in a line didn't explode.*/
SFG_LevelElement element = SFG_ITEM_RECORD_LEVEL_ELEMENT(item);
if (element.type != SFG_LEVEL_ELEMENT_BARREL)
continue;
RCL_Unit elementX =
element.coords[0] * RCL_UNITS_PER_SQUARE + RCL_UNITS_PER_SQUARE / 2;
RCL_Unit elementY =
element.coords[1] * RCL_UNITS_PER_SQUARE + RCL_UNITS_PER_SQUARE / 2;
RCL_Unit elementHeight =
SFG_floorHeightAt(element.coords[0],element.coords[1]);
if (SFG_taxicabDistance(
x,y,z,
element.coords[0] * RCL_UNITS_PER_SQUARE + RCL_UNITS_PER_SQUARE / 2,
element.coords[1] * RCL_UNITS_PER_SQUARE + RCL_UNITS_PER_SQUARE / 2,
elementHeight) <= SFG_EXPLOSION_DISTANCE)
x,y,z,elementX,elementY,elementHeight) <= SFG_EXPLOSION_DISTANCE)
{
// TODO: explode
SFG_explodeBarrel(i,elementX,elementY,elementHeight);
i--;
}
}
}
@ -1998,11 +2020,7 @@ void SFG_gameStep()
// take, eliminate the item
for (uint16_t j = i; j < SFG_currentLevel.itemRecordCount - 1; ++j)
SFG_currentLevel.itemRecords[j] =
SFG_currentLevel.itemRecords[j + 1];
SFG_currentLevel.itemRecordCount--;
SFG_removeItem(i);
i--;
}
@ -2141,18 +2159,24 @@ void SFG_gameStep()
if (e != 0)
{
RCL_Unit x = SFG_ELEMENT_COORD_TO_RCL_UNITS(e->coords[0]);
RCL_Unit y = SFG_ELEMENT_COORD_TO_RCL_UNITS(e->coords[1]);
RCL_Unit z = SFG_floorHeightAt(e->coords[0],e->coords[1]);
if (
SFG_elementCollides(
p->position[0],
p->position[1],
p->position[2],
SFG_ELEMENT_COORD_TO_RCL_UNITS(e->coords[0]),
SFG_ELEMENT_COORD_TO_RCL_UNITS(e->coords[1]),
SFG_floorHeightAt(e->coords[0],e->coords[1]),
0,
0)
SFG_elementCollides(p->position[0],p->position[1],p->position[2],
x,y,z,0,0)
)
{
if (
(e->type == SFG_LEVEL_ELEMENT_BARREL) &&
(SFG_getDamageValue(attackType) >=
SFG_BARREL_EXPLOSION_DAMAGE_THRESHOLD)
)
{
SFG_explodeBarrel(j,x,y,z);
}
eliminate = 1;
break;
}