Browse Source

Use FindClosestValidPosition when placing Hork Spawn

pull/3431/head
ephphatha 5 years ago committed by Anders Jenbo
parent
commit
b5bda7dbeb
  1. 34
      Source/missiles.cpp
  2. 22
      Source/path.cpp
  3. 5
      Source/path.h

34
Source/missiles.cpp

@ -3156,30 +3156,18 @@ void MI_HorkSpawn(Missile &missile)
CheckMissileCol(missile, 0, 0, false, missile.position.tile, false);
if (missile._mirange <= 0) {
missile._miDelFlag = true;
for (int i = 0; i < 2; i++) {
int k = CrawlNum[i];
int ck = k + 2;
for (auto j = static_cast<uint8_t>(CrawlTable[k]); j > 0; j--, ck += 2) {
Point target = missile.position.tile + Displacement { CrawlTable[ck - 1], CrawlTable[ck] };
if (!InDungeonBounds(target))
continue;
if (nSolidTable[dPiece[target.x][target.y]])
continue;
if (dMonster[target.x][target.y] != 0)
continue;
if (dPlayer[target.x][target.y] != 0)
continue;
if (dObject[target.x][target.y] != 0)
continue;
auto md = static_cast<Direction>(missile.var1);
int monsterId = AddMonster(target, md, 1, true);
if (monsterId != -1)
M_StartStand(Monsters[monsterId], md);
i = 6;
break;
std::optional<Point> spawnPosition = FindClosestValidPosition(
[](Point target) {
return !IsTileOccupied(target);
},
missile.position.tile, 0, 1);
if (spawnPosition) {
auto facing = static_cast<Direction>(missile.var1);
int monsterId = AddMonster(*spawnPosition, facing, 1, true);
if (monsterId != -1) {
M_StartStand(Monsters[monsterId], facing);
}
}
} else {

22
Source/path.cpp

@ -316,6 +316,28 @@ bool IsTileWalkable(Point position, bool ignoreDoors)
return !IsTileSolid(position);
}
bool IsTileOccupied(Point position)
{
if (!InDungeonBounds(position)) {
return true; // OOB positions are considered occupied.
}
if (IsTileSolid(position)) {
return true;
}
if (dMonster[position.x][position.y] != 0) {
return true;
}
if (dPlayer[position.x][position.y] != 0) {
return true;
}
if (dObject[position.x][position.y] != 0) {
return true;
}
return false;
}
int FindPath(const std::function<bool(Point)> &posOk, Point startPosition, Point destinationPosition, int8_t path[MAX_PATH_LENGTH])
{
/**

5
Source/path.h

@ -35,6 +35,11 @@ bool IsTileSolid(Point position);
*/
bool IsTileWalkable(Point position, bool ignoreDoors = false);
/**
* @brief Checks if the position contains an object, player, monster, or solid dungeon piece
*/
bool IsTileOccupied(Point position);
/**
* @brief Find the shortest path from startPosition to destinationPosition, using PosOk(Point) to check that each step is a valid position.
* Store the step directions (corresponds to an index in PathDirs) in path, which must have room for 24 steps

Loading…
Cancel
Save