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 #define SFG_EXPLOSION_DISTANCE 2048
/**
How much damage triggers a barrel explosion.
*/
#define SFG_BARREL_EXPLOSION_DAMAGE_THRESHOLD 11
/** /**
Maximum player health. Maximum player health.
*/ */
@ -110,7 +116,7 @@
/** /**
How much randomness (positive and negative) will be added to damage 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. 100% of the base value.
*/ */
#define SFG_DAMAGE_RANDOMNESS 64 #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_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_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_BULLETS, {7, 23}}, {SFG_LEVEL_ELEMENT_BULLETS, {8, 23}},
{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_NONE, {0, 0}}, {SFG_LEVEL_ELEMENT_NONE, {0, 0}}, {SFG_LEVEL_ELEMENT_BARREL, {9, 39}}, {SFG_LEVEL_ELEMENT_BARREL, {9, 40}},
{SFG_LEVEL_ELEMENT_NONE, {0, 0}}, {SFG_LEVEL_ELEMENT_NONE, {0, 0}}, {SFG_LEVEL_ELEMENT_BARREL, {9, 41}}, {SFG_LEVEL_ELEMENT_BARREL, {9, 42}},
{SFG_LEVEL_ELEMENT_NONE, {0, 0}}, {SFG_LEVEL_ELEMENT_NONE, {0, 0}}, {SFG_LEVEL_ELEMENT_BARREL, {9, 43}}, {SFG_LEVEL_ELEMENT_BARREL, {9, 44}},
{SFG_LEVEL_ELEMENT_NONE, {0, 0}}, {SFG_LEVEL_ELEMENT_NONE, {0, 0}}, {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}}, {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}},

106
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 value = SFG_attackDamageTable[attackType]; // has to be signed
int32_t maxAdd = (value * SFG_DAMAGE_RANDOMNESS) / 256; 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) if (value < 0)
value = 0; value = 0;
return value; return value;
} }
@ -1261,6 +1260,23 @@ void SFG_monsterChangeHealth(SFG_MonsterRecord *monster, int8_t healthAdd)
monster->health = health; 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) void SFG_createExplosion(RCL_Unit x, RCL_Unit y, RCL_Unit z)
{ {
SFG_ProjectileRecord explosion; SFG_ProjectileRecord explosion;
@ -1280,9 +1296,10 @@ void SFG_createExplosion(RCL_Unit x, RCL_Unit y, RCL_Unit z)
SFG_createProjectile(explosion); SFG_createProjectile(explosion);
uint8_t damage = SFG_getDamageValue(SFG_WEAPON_FIRE_TYPE_FIREBALL);
if (SFG_pushPlayerAway(x,y,SFG_EXPLOSION_DISTANCE)) if (SFG_pushPlayerAway(x,y,SFG_EXPLOSION_DISTANCE))
SFG_playerChangeHealth( SFG_playerChangeHealth(-1 * damage);
-1 * SFG_getDamageValue(SFG_WEAPON_FIRE_TYPE_FIREBALL));
for (uint16_t i = 0; i < SFG_currentLevel.monsterRecordCount; ++i) for (uint16_t i = 0; i < SFG_currentLevel.monsterRecordCount; ++i)
{ {
@ -1307,32 +1324,37 @@ void SFG_createExplosion(RCL_Unit x, RCL_Unit y, RCL_Unit z)
} }
} }
// explode other barrels // explode nearby barrels
for (uint16_t i = 0; i < SFG_currentLevel.itemRecordCount; ++i) 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;
SFG_LevelElement element = SFG_ITEM_RECORD_LEVEL_ELEMENT(item);
if (element.type != SFG_LEVEL_ELEMENT_BARREL)
continue;
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)
{ {
// TODO: explode SFG_ItemRecord item = SFG_currentLevel.itemRecords[i];
/* 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,elementX,elementY,elementHeight) <= SFG_EXPLOSION_DISTANCE)
{
SFG_explodeBarrel(i,elementX,elementY,elementHeight);
i--;
}
} }
}
} }
void SFG_createDust(RCL_Unit x, RCL_Unit y, RCL_Unit z) void SFG_createDust(RCL_Unit x, RCL_Unit y, RCL_Unit z)
@ -1998,11 +2020,7 @@ void SFG_gameStep()
// take, eliminate the item // take, eliminate the item
for (uint16_t j = i; j < SFG_currentLevel.itemRecordCount - 1; ++j) SFG_removeItem(i);
SFG_currentLevel.itemRecords[j] =
SFG_currentLevel.itemRecords[j + 1];
SFG_currentLevel.itemRecordCount--;
i--; i--;
} }
@ -2141,18 +2159,24 @@ void SFG_gameStep()
if (e != 0) 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 ( if (
SFG_elementCollides( SFG_elementCollides(p->position[0],p->position[1],p->position[2],
p->position[0], x,y,z,0,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)
) )
{ {
if (
(e->type == SFG_LEVEL_ELEMENT_BARREL) &&
(SFG_getDamageValue(attackType) >=
SFG_BARREL_EXPLOSION_DAMAGE_THRESHOLD)
)
{
SFG_explodeBarrel(j,x,y,z);
}
eliminate = 1; eliminate = 1;
break; break;
} }