From 9201a27b996ba41698bb5e129efa6f0b8873b232 Mon Sep 17 00:00:00 2001 From: ephphatha Date: Thu, 28 Oct 2021 16:37:08 +1100 Subject: [PATCH] Separate search and spawn logic for town portal --- Source/missiles.cpp | 60 +++++++++++++++++++++++++-------------------- 1 file changed, 34 insertions(+), 26 deletions(-) diff --git a/Source/missiles.cpp b/Source/missiles.cpp index 7e70e91c5..4cecdf2b0 100644 --- a/Source/missiles.cpp +++ b/Source/missiles.cpp @@ -2071,32 +2071,40 @@ void AddWeapexp(Missile &missile, Point dst, Direction /*midir*/) void AddTown(Missile &missile, Point dst, Direction /*midir*/) { - Point target = dst; - if (currlevel != 0) { - missile._miDelFlag = true; - for (int i = 0; i < 6; i++) { - int k = CrawlNum[i]; - int ck = k + 2; - for (auto j = static_cast(CrawlTable[k]); j > 0; j--, ck += 2) { - target = dst + Displacement { CrawlTable[ck - 1], CrawlTable[ck] }; - if (!InDungeonBounds(target)) - continue; + if (currlevel == 0) { + missile.position.tile = dst; + missile.position.start = dst; + } else { + std::optional targetPosition = FindClosestValidPosition( + [](Point target) { + if (!InDungeonBounds(target)) { + return false; + } + if (dObject[target.x][target.y] != 0) { + return false; + } + if (dPlayer[target.x][target.y] != 0) { + return false; + } + if (TileContainsMissile(target)) { + return false; + } + + int dp = dPiece[target.x][target.y]; + if (nSolidTable[dp] || nMissileTable[dp]) { + return false; + } + return !CheckIfTrig(target); + }, + dst, 0, 5); - int dp = dPiece[target.x][target.y]; - if (!TileContainsMissile(target) && !nSolidTable[dp] && !nMissileTable[dp] && dObject[target.x][target.y] == 0 && dPlayer[target.x][target.y] == 0) { - if (!CheckIfTrig(target)) { - missile.position.tile = target; - missile.position.start = target; - missile._miDelFlag = false; - i = 6; - break; - } - } - } + if (targetPosition) { + missile.position.tile = *targetPosition; + missile.position.start = *targetPosition; + missile._miDelFlag = false; + } else { + missile._miDelFlag = true; } - } else { - missile.position.tile = target; - missile.position.start = target; } missile._mirange = 100; @@ -2110,9 +2118,9 @@ void AddTown(Missile &missile, Point dst, Direction /*midir*/) PutMissile(missile); if (missile._misource == MyPlayerId && !missile._miDelFlag && currlevel != 0) { if (!setlevel) { - NetSendCmdLocParam3(true, CMD_ACTIVATEPORTAL, target, currlevel, leveltype, 0); + NetSendCmdLocParam3(true, CMD_ACTIVATEPORTAL, missile.position.tile, currlevel, leveltype, 0); } else { - NetSendCmdLocParam3(true, CMD_ACTIVATEPORTAL, target, setlvlnum, leveltype, 1); + NetSendCmdLocParam3(true, CMD_ACTIVATEPORTAL, missile.position.tile, setlvlnum, leveltype, 1); } } }