Use FindClosestValidPosition when placing Hork Spawn
This commit is contained in:
parent
db8b8c245e
commit
b5bda7dbeb
3 changed files with 38 additions and 23 deletions
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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])
|
||||
{
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -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…
Add table
Add a link
Reference in a new issue