Fix distance computations

This commit is contained in:
Miloslav Číž 2020-01-07 21:26:38 +01:00
parent 237afdb21e
commit cad12c2d93
2 changed files with 62 additions and 46 deletions

View File

@ -39,7 +39,7 @@
/** /**
Melee and close-up attack range, in RCL_Units. Melee and close-up attack range, in RCL_Units.
*/ */
#define SFG_MELEE_RANGE 1400 #define SFG_MELEE_RANGE 1600
/** /**
Player's melee hit range, in RCL_Units (RCL_UNITS_PER_SQUARE means full angle, Player's melee hit range, in RCL_Units (RCL_UNITS_PER_SQUARE means full angle,
@ -79,7 +79,7 @@
Distance at which level elements (sprites) collide, in RCL_Unit (1024 per Distance at which level elements (sprites) collide, in RCL_Unit (1024 per
square). square).
*/ */
#define SFG_ELEMENT_COLLISION_DISTANCE 800 #define SFG_ELEMENT_COLLISION_DISTANCE 2048
/** /**
Height, in RCL_Units, at which collisions happen with level elements Height, in RCL_Units, at which collisions happen with level elements

94
main.c
View File

@ -143,6 +143,10 @@ typedef uint8_t SFG_ItemRecord;
#define SFG_ITEM_RECORD_ACTIVE_MASK 0x80 #define SFG_ITEM_RECORD_ACTIVE_MASK 0x80
#define SFG_ITEM_RECORD_LEVEL_ELEMENT(itemRecord) \
(SFG_currentLevel.levelPointer->elements[itemRecord & \
~SFG_ITEM_RECORD_ACTIVE_MASK])
typedef struct typedef struct
{ {
uint8_t stateType; /**< Holds state (lower 4 bits) and type of monster uint8_t stateType; /**< Holds state (lower 4 bits) and type of monster
@ -341,10 +345,10 @@ uint8_t SFG_getDamageValue(uint8_t attackType)
return value; return value;
} }
static inline RCL_Unit RCL_Unit SFG_taxicabDistance(
SFG_taxicabDistance(RCL_Unit x0, RCL_Unit y0, RCL_Unit x1, RCL_Unit y1) RCL_Unit x0, RCL_Unit y0, RCL_Unit z0, RCL_Unit x1, RCL_Unit y1, RCL_Unit z1)
{ {
return RCL_absVal(x0 - x1) + RCL_absVal(y0 - y1); return (RCL_absVal(x0 - x1) + RCL_absVal(y0 - y1) + RCL_absVal(z0 - z1));
} }
static inline uint8_t SFG_RCLUnitToZBuffer(RCL_Unit x) static inline uint8_t SFG_RCLUnitToZBuffer(RCL_Unit x)
@ -1277,18 +1281,51 @@ void SFG_createExplosion(RCL_Unit x, RCL_Unit y, RCL_Unit z)
{ {
SFG_MonsterRecord *monster = &(SFG_currentLevel.monsterRecords[i]); SFG_MonsterRecord *monster = &(SFG_currentLevel.monsterRecords[i]);
if ( if (SFG_MR_STATE(*monster) == SFG_MONSTER_STATE_INACTIVE)
(SFG_MR_STATE(*monster) != SFG_MONSTER_STATE_INACTIVE) && continue;
(RCL_absVal(SFG_MONSTER_COORD_TO_RCL_UNITS(monster->coords[0]) - x) <=
SFG_EXPLOSION_DISTANCE) && RCL_Unit monsterHeight =
(RCL_absVal(SFG_MONSTER_COORD_TO_RCL_UNITS(monster->coords[1]) - y) <= SFG_floorHeightAt(
SFG_EXPLOSION_DISTANCE) SFG_MONSTER_COORD_TO_SQUARES(monster->coords[0]),
) SFG_MONSTER_COORD_TO_SQUARES(monster->coords[1]))
+ RCL_UNITS_PER_SQUARE / 2;
if (SFG_taxicabDistance(
SFG_MONSTER_COORD_TO_RCL_UNITS(monster->coords[0]),
SFG_MONSTER_COORD_TO_RCL_UNITS(monster->coords[1]),monsterHeight,
x,y,z) <= SFG_EXPLOSION_DISTANCE)
{ {
SFG_monsterChangeHealth(monster, SFG_monsterChangeHealth(monster,
-1 * SFG_getDamageValue(SFG_WEAPON_FIRE_TYPE_FIREBALL)); -1 * SFG_getDamageValue(SFG_WEAPON_FIRE_TYPE_FIREBALL));
} }
} }
// explode other barrels
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
}
}
} }
void SFG_createDust(RCL_Unit x, RCL_Unit y, RCL_Unit z) void SFG_createDust(RCL_Unit x, RCL_Unit y, RCL_Unit z)
@ -1311,14 +1348,6 @@ void SFG_createDust(RCL_Unit x, RCL_Unit y, RCL_Unit z)
SFG_createProjectile(dust); SFG_createProjectile(dust);
} }
uint8_t SFG_isInMeleeRange(RCL_Unit x0, RCL_Unit y0, RCL_Unit z0, RCL_Unit x1,
RCL_Unit y1, RCL_Unit z1)
{
return
(SFG_taxicabDistance(x0,y0,x1,y1) <= SFG_MELEE_RANGE) &&
(RCL_absVal(z0 - z1) <= SFG_MELEE_RANGE);
}
void SFG_getMonsterWorldPosition(SFG_MonsterRecord *monster, RCL_Unit *x, void SFG_getMonsterWorldPosition(SFG_MonsterRecord *monster, RCL_Unit *x,
RCL_Unit *y, RCL_Unit *z) RCL_Unit *y, RCL_Unit *z)
{ {
@ -1427,14 +1456,10 @@ void SFG_monsterPerformAI(SFG_MonsterRecord *monster)
SFG_getMonsterWorldPosition(monster,&pX,&pY,&pZ); SFG_getMonsterWorldPosition(monster,&pX,&pY,&pZ);
uint8_t isClose = // close to player? uint8_t isClose = // close to player?
SFG_isInMeleeRange( SFG_taxicabDistance(pX,pY,pZ,
pX,
pY,
pZ,
SFG_player.camera.position.x, SFG_player.camera.position.x,
SFG_player.camera.position.y, SFG_player.camera.position.y,
SFG_player.camera.height SFG_player.camera.height) <= SFG_MELEE_RANGE;
);
if (!isClose) if (!isClose)
{ {
@ -1612,15 +1637,8 @@ static inline uint8_t SFG_elementCollides(
) )
{ {
return return
( SFG_taxicabDistance(pointX,pointY,pointZ,elementX,elementY,elementHeight)
SFG_taxicabDistance(pointX,pointY,elementX,elementY) <= (SFG_ELEMENT_COLLISION_DISTANCE + widthMargin);
<= (SFG_ELEMENT_COLLISION_DISTANCE + widthMargin)
)
&&
(
(pointZ - heightMargin - elementHeight)
<= SFG_ELEMENT_COLLISION_HEIGHT
);
} }
/** /**
@ -1724,10 +1742,10 @@ void SFG_gameStep()
RCL_Unit pX, pY, pZ; RCL_Unit pX, pY, pZ;
SFG_getMonsterWorldPosition(m,&pX,&pY,&pZ); SFG_getMonsterWorldPosition(m,&pX,&pY,&pZ);
if (!SFG_isInMeleeRange(pX,pY,pZ, if (SFG_taxicabDistance(pX,pY,pZ,
SFG_player.camera.position.x, SFG_player.camera.position.x,
SFG_player.camera.position.y, SFG_player.camera.position.y,
SFG_player.camera.height)) SFG_player.camera.height) > SFG_MELEE_RANGE)
continue; continue;
RCL_Vector2D toMonster; RCL_Vector2D toMonster;
@ -1930,8 +1948,7 @@ void SFG_gameStep()
SFG_floorHeightAt( SFG_floorHeightAt(
SFG_MONSTER_COORD_TO_SQUARES(m->coords[0]), SFG_MONSTER_COORD_TO_SQUARES(m->coords[0]),
SFG_MONSTER_COORD_TO_SQUARES(m->coords[1])), SFG_MONSTER_COORD_TO_SQUARES(m->coords[1])),
RCL_CAMERA_COLL_RADIUS / 2, 0,0
RCL_CAMERA_COLL_HEIGHT_BELOW
) )
) )
{ {
@ -1964,8 +1981,7 @@ void SFG_gameStep()
ePos.x, ePos.x,
ePos.y, ePos.y,
SFG_floorHeightAt(e->coords[0],e->coords[1]), SFG_floorHeightAt(e->coords[0],e->coords[1]),
RCL_CAMERA_COLL_RADIUS / 2, 0,0
RCL_CAMERA_COLL_HEIGHT_BELOW
) )
) )
{ {