mirror of
https://gitlab.com/drummyfish/anarch.git
synced 2024-11-24 01:42:19 -05:00
Fix shot collisions
This commit is contained in:
parent
9b6803936f
commit
75476da4af
@ -41,6 +41,13 @@
|
|||||||
*/
|
*/
|
||||||
#define SFG_MELEE_RANGE 1600
|
#define SFG_MELEE_RANGE 1600
|
||||||
|
|
||||||
|
/**
|
||||||
|
When a projectile is shot, it'll be offset by this distance (in RCL_Units)
|
||||||
|
from the shooter.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define SFG_PROJECTILE_SPAWN_OFFSET 256
|
||||||
|
|
||||||
/**
|
/**
|
||||||
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,
|
||||||
180 degrees to both sides).
|
180 degrees to both sides).
|
||||||
|
82
main.c
82
main.c
@ -1637,7 +1637,7 @@ void SFG_monsterPerformAI(SFG_MonsterRecord *monster)
|
|||||||
) + RCL_UNITS_PER_SQUARE / 2,
|
) + RCL_UNITS_PER_SQUARE / 2,
|
||||||
dir,
|
dir,
|
||||||
0,
|
0,
|
||||||
SFG_ELEMENT_COLLISION_DISTANCE
|
SFG_PROJECTILE_SPAWN_OFFSET
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1842,6 +1842,35 @@ static inline uint8_t SFG_elementCollides(
|
|||||||
<= SFG_ELEMENT_COLLISION_DISTANCE;
|
<= SFG_ELEMENT_COLLISION_DISTANCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Checks collision of a projectile with level element at given position.
|
||||||
|
*/
|
||||||
|
uint8_t SFG_projectileCollides(SFG_ProjectileRecord *projectile,
|
||||||
|
RCL_Unit x, RCL_Unit y, RCL_Unit z)
|
||||||
|
{
|
||||||
|
if (!SFG_elementCollides(x,y,z,
|
||||||
|
projectile->position[0],projectile->position[1],projectile->position[2]))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if ((projectile->type == SFG_PROJECTILE_EXPLOSION) ||
|
||||||
|
(projectile->type == SFG_PROJECTILE_DUST))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* For directional projectiles we only register a collision if its direction
|
||||||
|
is "towards" the element so that the shooter doesn't get shot by his own
|
||||||
|
projectile. */
|
||||||
|
|
||||||
|
RCL_Vector2D projDir, toElement;
|
||||||
|
|
||||||
|
projDir.x = projectile->direction[0];
|
||||||
|
projDir.y = projectile->direction[1];
|
||||||
|
|
||||||
|
toElement.x = x - projectile->position[0];
|
||||||
|
toElement.y = y - projectile->position[1];
|
||||||
|
|
||||||
|
return RCL_vectorsAngleCos(projDir,toElement) >= 0;
|
||||||
|
}
|
||||||
|
|
||||||
SFG_getLevelElementSprite(
|
SFG_getLevelElementSprite(
|
||||||
uint8_t elementType, uint8_t *spriteIndex, uint8_t *spriteSize)
|
uint8_t elementType, uint8_t *spriteIndex, uint8_t *spriteSize)
|
||||||
{
|
{
|
||||||
@ -1984,7 +2013,7 @@ void SFG_gameStep()
|
|||||||
(SFG_player.camera.shear *
|
(SFG_player.camera.shear *
|
||||||
SFG_GET_PROJECTILE_SPEED_UPS(projectile)) /
|
SFG_GET_PROJECTILE_SPEED_UPS(projectile)) /
|
||||||
SFG_CAMERA_MAX_SHEAR_PIXELS,
|
SFG_CAMERA_MAX_SHEAR_PIXELS,
|
||||||
SFG_ELEMENT_COLLISION_DISTANCE + RCL_CAMERA_COLL_RADIUS
|
SFG_PROJECTILE_SPAWN_OFFSET
|
||||||
);
|
);
|
||||||
|
|
||||||
direction += angleAdd;
|
direction += angleAdd;
|
||||||
@ -2432,12 +2461,12 @@ void SFG_gameStep()
|
|||||||
|
|
||||||
uint8_t eliminate = 0;
|
uint8_t eliminate = 0;
|
||||||
|
|
||||||
for (uint8_t j = 0; j < 3; ++j) // projectile outside map?
|
for (uint8_t j = 0; j < 3; ++j)
|
||||||
{
|
{
|
||||||
pos[j] = p->position[j];
|
pos[j] = p->position[j];
|
||||||
pos[j] += p->direction[j];
|
pos[j] += p->direction[j];
|
||||||
|
|
||||||
if (
|
if ( // projectile outside map?
|
||||||
(pos[j] < 0) ||
|
(pos[j] < 0) ||
|
||||||
(pos[j] >= (SFG_MAP_SIZE * RCL_UNITS_PER_SQUARE)))
|
(pos[j] >= (SFG_MAP_SIZE * RCL_UNITS_PER_SQUARE)))
|
||||||
{
|
{
|
||||||
@ -2450,31 +2479,28 @@ void SFG_gameStep()
|
|||||||
{
|
{
|
||||||
eliminate = 1;
|
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]
|
|
||||||
))
|
|
||||||
{
|
|
||||||
eliminate = 1;
|
|
||||||
|
|
||||||
SFG_playerChangeHealth(-1 * SFG_getDamageValue(attackType));
|
|
||||||
}
|
|
||||||
else if (
|
else if (
|
||||||
(p->type != SFG_PROJECTILE_EXPLOSION) &&
|
(p->type != SFG_PROJECTILE_EXPLOSION) &&
|
||||||
(p->type != SFG_PROJECTILE_DUST))
|
(p->type != SFG_PROJECTILE_DUST))
|
||||||
{
|
{
|
||||||
|
if (SFG_projectileCollides( // collides with player?
|
||||||
|
p,
|
||||||
|
SFG_player.camera.position.x,
|
||||||
|
SFG_player.camera.position.y,
|
||||||
|
SFG_player.camera.height))
|
||||||
|
{
|
||||||
|
eliminate = 1;
|
||||||
|
SFG_playerChangeHealth(-1 * SFG_getDamageValue(attackType));
|
||||||
|
}
|
||||||
|
|
||||||
// check collision with the map
|
// check collision with the map
|
||||||
|
|
||||||
if (
|
if (!eliminate &&
|
||||||
(SFG_floorHeightAt(pos[0] / RCL_UNITS_PER_SQUARE,pos[1] /
|
((SFG_floorHeightAt(pos[0] / RCL_UNITS_PER_SQUARE,pos[1] /
|
||||||
RCL_UNITS_PER_SQUARE) >= pos[2])
|
RCL_UNITS_PER_SQUARE) >= pos[2])
|
||||||
||
|
||
|
||||||
(SFG_ceilingHeightAt(pos[0] / RCL_UNITS_PER_SQUARE,pos[1] /
|
(SFG_ceilingHeightAt(pos[0] / RCL_UNITS_PER_SQUARE,pos[1] /
|
||||||
RCL_UNITS_PER_SQUARE) <= pos[2])
|
RCL_UNITS_PER_SQUARE) <= pos[2]))
|
||||||
)
|
)
|
||||||
eliminate = 1;
|
eliminate = 1;
|
||||||
|
|
||||||
@ -2487,18 +2513,13 @@ void SFG_gameStep()
|
|||||||
|
|
||||||
if (SFG_MR_STATE(*m) != SFG_MONSTER_STATE_INACTIVE)
|
if (SFG_MR_STATE(*m) != SFG_MONSTER_STATE_INACTIVE)
|
||||||
{
|
{
|
||||||
if (
|
if (SFG_projectileCollides(p,
|
||||||
SFG_elementCollides(
|
|
||||||
p->position[0],
|
|
||||||
p->position[1],
|
|
||||||
p->position[2],
|
|
||||||
SFG_MONSTER_COORD_TO_RCL_UNITS(m->coords[0]),
|
SFG_MONSTER_COORD_TO_RCL_UNITS(m->coords[0]),
|
||||||
SFG_MONSTER_COORD_TO_RCL_UNITS(m->coords[1]),
|
SFG_MONSTER_COORD_TO_RCL_UNITS(m->coords[1]),
|
||||||
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]))
|
||||||
)
|
))
|
||||||
)
|
|
||||||
{
|
{
|
||||||
eliminate = 1;
|
eliminate = 1;
|
||||||
SFG_monsterChangeHealth(m,-1 * SFG_getDamageValue(attackType));
|
SFG_monsterChangeHealth(m,-1 * SFG_getDamageValue(attackType));
|
||||||
@ -2518,10 +2539,7 @@ void SFG_gameStep()
|
|||||||
RCL_Unit y = SFG_ELEMENT_COORD_TO_RCL_UNITS(e->coords[1]);
|
RCL_Unit y = SFG_ELEMENT_COORD_TO_RCL_UNITS(e->coords[1]);
|
||||||
RCL_Unit z = SFG_floorHeightAt(e->coords[0],e->coords[1]);
|
RCL_Unit z = SFG_floorHeightAt(e->coords[0],e->coords[1]);
|
||||||
|
|
||||||
if (
|
if (SFG_projectileCollides(p,x,y,z))
|
||||||
SFG_elementCollides(p->position[0],p->position[1],p->position[2],
|
|
||||||
x,y,z)
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
if (
|
if (
|
||||||
(e->type == SFG_LEVEL_ELEMENT_BARREL) &&
|
(e->type == SFG_LEVEL_ELEMENT_BARREL) &&
|
||||||
@ -2545,6 +2563,8 @@ void SFG_gameStep()
|
|||||||
SFG_createExplosion(p->position[0],p->position[1],p->position[2]);
|
SFG_createExplosion(p->position[0],p->position[1],p->position[2]);
|
||||||
else if (p->type == SFG_PROJECTILE_BULLET)
|
else if (p->type == SFG_PROJECTILE_BULLET)
|
||||||
SFG_createDust(p->position[0],p->position[1],p->position[2]);
|
SFG_createDust(p->position[0],p->position[1],p->position[2]);
|
||||||
|
else if (p->type == SFG_PROJECTILE_PLASMA)
|
||||||
|
SFG_playSoundSafe(4,SFG_distantSoundVolume(pos[0],pos[1],pos[2]));
|
||||||
|
|
||||||
// remove the projectile
|
// remove the projectile
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user