Use FindClosestValidPosition when placing Hork Spawn

This commit is contained in:
ephphatha 2021-10-28 14:34:03 +11:00 committed by Anders Jenbo
commit b5bda7dbeb
3 changed files with 38 additions and 23 deletions

View file

@ -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;
std::optional<Point> spawnPosition = FindClosestValidPosition(
[](Point target) {
return !IsTileOccupied(target);
},
missile.position.tile, 0, 1);
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;
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 {

View file

@ -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])
{
/**

View file

@ -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