Browse Source

Tidy up checks for missile collision with objects/tiles

This was repeated in multiple places with essentially identical logic. Can expose the existing missiles.cpp function to capture the use in scrollrt.cpp
pull/3859/head
ephphatha 4 years ago committed by Anders Jenbo
parent
commit
279fbe32b3
  1. 48
      Source/missiles.cpp
  2. 5
      Source/missiles.h
  3. 1
      Source/objects.h
  4. 9
      Source/scrollrt.cpp

48
Source/missiles.cpp

@ -547,40 +547,21 @@ void CheckMissileCol(Missile &missile, int mindam, int maxdam, bool shift, Point
}
}
}
if (dObject[mx][my] != 0) {
Object &object = Objects[abs(dObject[mx][my]) - 1];
if (!object._oMissFlag) {
if (object.IsBreakable()) {
BreakObject(-1, object);
}
if (!nodel)
missile._mirange = 0;
missile._miHitFlag = false;
if (IsMissileBlockedByTile({ mx, my })) {
Object *object = ObjectAtPosition({ mx, my });
if (object != nullptr && object->IsBreakable()) {
BreakObject(-1, *object);
}
}
if (nMissileTable[dPiece[mx][my]]) {
if (!nodel)
missile._mirange = 0;
missile._miHitFlag = false;
}
if (missile._mirange == 0 && MissilesData[missile._mitype].miSFX != -1)
PlaySfxLoc(MissilesData[missile._mitype].miSFX, missile.position.tile);
}
/**
* @brief Could the missile collide with solid objects? (like walls or closed doors)
*/
bool CouldMissileCollideWithSolidObject(Point tile)
{
int oid = dObject[tile.x][tile.y];
if (oid != 0) {
oid = abs(oid) - 1;
if (!Objects[oid]._oMissFlag)
return true;
}
return nMissileTable[dPiece[tile.x][tile.y]];
}
void MoveMissileAndCheckMissileCol(Missile &missile, int mindam, int maxdam, bool ignoreStart, bool ifCollidesDontMoveToHitTile)
{
Point prevTile = missile.position.tile;
@ -633,7 +614,7 @@ void MoveMissileAndCheckMissileCol(Missile &missile, int mindam, int maxdam, boo
if (missile._mirange != 0)
continue;
if ((missile._miHitFlag && MissilesData[missile._mitype].MovementDistribution == MissileMovementDistrubution::Blockable) || CouldMissileCollideWithSolidObject(tile)) {
if ((missile._miHitFlag && MissilesData[missile._mitype].MovementDistribution == MissileMovementDistrubution::Blockable) || IsMissileBlockedByTile(tile)) {
missile.position.traveled = traveled;
if (ifCollidesDontMoveToHitTile && missile._mirange == 0) {
missile.position.traveled -= incVelocity;
@ -839,6 +820,21 @@ void SpawnLightning(Missile &missile, int dam)
} // namespace
bool IsMissileBlockedByTile(Point tile)
{
if (!InDungeonBounds(tile)) {
return true;
}
if (nMissileTable[dPiece[tile.x][tile.y]]) {
return true;
}
Object *object = ObjectAtPosition(tile);
// _oMissFlag is true if the object allows missiles to pass through so we need to invert the check here...
return object != nullptr && !object->_oMissFlag;
}
void GetDamageAmt(int i, int *mind, int *maxd)
{
assert(MyPlayerId >= 0 && MyPlayerId < MAX_PLRS);

5
Source/missiles.h

@ -168,6 +168,11 @@ void DeleteMissile(int i);
bool MonsterTrapHit(int m, int mindam, int maxdam, int dist, missile_id t, bool shift);
bool PlayerMHit(int pnum, Monster *monster, int dist, int mind, int maxd, missile_id mtype, bool shift, int earflag, bool *blocked);
/**
* @brief Could the missile collide with solid objects? (like walls or closed doors)
*/
bool IsMissileBlockedByTile(Point position);
/**
* @brief Sets the missile sprite to the given sheet frame
* @param missile this object

1
Source/objects.h

@ -33,6 +33,7 @@ struct Object {
bool _oDelFlag;
int8_t _oBreak;
bool _oSolidFlag;
/** True if the object allows missiles to pass through, false if it collides with missiles */
bool _oMissFlag;
uint8_t _oSelFlag;
bool _oPreFlag;

9
Source/scrollrt.cpp

@ -106,13 +106,8 @@ bool CouldMissileCollide(Point tile, bool checkPlayerAndMonster)
if (dPlayer[tile.x][tile.y] > 0)
return true;
}
int oid = dObject[tile.x][tile.y];
if (oid != 0) {
oid = abs(oid) - 1;
if (!Objects[oid]._oMissFlag)
return true;
}
return nMissileTable[dPiece[tile.x][tile.y]];
return IsMissileBlockedByTile(tile);
}
void UpdateMissileRendererData(Missile &m)

Loading…
Cancel
Save