From 01b1a9d3a734385723a67aa536d527e39e222a1a Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Thu, 15 Sep 2022 21:44:45 -0400 Subject: [PATCH] Prevent poh-bees on no-respawn waypoints --- src/k_waypoint.c | 117 +++++++++++++++++++++++++++++++++++++++++++ src/k_waypoint.h | 30 +++++++++++ src/objects/shrink.c | 2 +- 3 files changed, 148 insertions(+), 1 deletion(-) diff --git a/src/k_waypoint.c b/src/k_waypoint.c index 0a8dfd0f0..2c9ebec9a 100644 --- a/src/k_waypoint.c +++ b/src/k_waypoint.c @@ -1101,6 +1101,40 @@ static boolean K_WaypointPathfindReachedGScore(void *data, void *setupData) return scoreReached; } +/*-------------------------------------------------- + static boolean K_WaypointPathfindReachedGScoreSpawnable(void *data, void *setupData) + + Returns if the current waypoint data reaches our end G score. + + Input Arguments:- + data - Should point to a pathfindnode_t to compare + setupData - Should point to the pathfindsetup_t to compare + + Return:- + True if the waypoint reached the G score, false otherwise. +--------------------------------------------------*/ +static boolean K_WaypointPathfindReachedGScoreSpawnable(void *data, void *setupData) +{ + boolean scoreReached = false; + boolean spawnable = false; + + if (data == NULL || setupData == NULL) + { + CONS_Debug(DBG_GAMELOGIC, "K_WaypointPathfindReachedGScoreSpawnable received NULL data.\n"); + } + else + { + pathfindnode_t *node = (pathfindnode_t *)data; + pathfindsetup_t *setup = (pathfindsetup_t *)setupData; + waypoint_t *wp = (waypoint_t *)node->nodedata; + + scoreReached = (node->gscore >= setup->endgscore); + spawnable = K_GetWaypointIsSpawnpoint(wp); + } + + return (scoreReached && spawnable); +} + /*-------------------------------------------------- boolean K_PathfindToWaypoint( waypoint_t *const sourcewaypoint, @@ -1266,6 +1300,89 @@ boolean K_PathfindThruCircuit( return pathfound; } +/*-------------------------------------------------- + boolean K_PathfindThruCircuitSpawnable( + waypoint_t *const sourcewaypoint, + const UINT32 traveldistance, + path_t *const returnpath, + const boolean useshortcuts, + const boolean huntbackwards) + + See header file for description. +--------------------------------------------------*/ +boolean K_PathfindThruCircuitSpawnable( + waypoint_t *const sourcewaypoint, + const UINT32 traveldistance, + path_t *const returnpath, + const boolean useshortcuts, + const boolean huntbackwards) +{ + boolean pathfound = false; + + if (sourcewaypoint == NULL) + { + CONS_Debug(DBG_GAMELOGIC, "NULL sourcewaypoint in K_PathfindThruCircuitSpawnable.\n"); + } + else if (finishline == NULL) + { + CONS_Debug(DBG_GAMELOGIC, "NULL finishline in K_PathfindThruCircuitSpawnable.\n"); + } + else if (((huntbackwards == false) && (sourcewaypoint->numnextwaypoints == 0)) + || ((huntbackwards == true) && (sourcewaypoint->numprevwaypoints == 0))) + { + CONS_Debug(DBG_GAMELOGIC, + "K_PathfindThruCircuitSpawnable: sourcewaypoint with ID %d has no next waypoint\n", + K_GetWaypointID(sourcewaypoint)); + } + else if (((huntbackwards == false) && (finishline->numprevwaypoints == 0)) + || ((huntbackwards == true) && (finishline->numnextwaypoints == 0))) + { + CONS_Debug(DBG_GAMELOGIC, + "K_PathfindThruCircuitSpawnable: finishline with ID %d has no previous waypoint\n", + K_GetWaypointID(finishline)); + } + else + { + pathfindsetup_t pathfindsetup = {0}; + getconnectednodesfunc nextnodesfunc = K_WaypointPathfindGetNext; + getnodeconnectioncostsfunc nodecostsfunc = K_WaypointPathfindGetNextCosts; + getnodeheuristicfunc heuristicfunc = K_WaypointPathfindGetHeuristic; + getnodetraversablefunc traversablefunc = K_WaypointPathfindTraversableNoShortcuts; + getpathfindfinishedfunc finishedfunc = K_WaypointPathfindReachedGScoreSpawnable; + + if (huntbackwards) + { + nextnodesfunc = K_WaypointPathfindGetPrev; + nodecostsfunc = K_WaypointPathfindGetPrevCosts; + } + + if (useshortcuts) + { + traversablefunc = K_WaypointPathfindTraversableAllEnabled; + } + + pathfindsetup.opensetcapacity = K_GetOpensetBaseSize(); + pathfindsetup.closedsetcapacity = K_GetClosedsetBaseSize(); + pathfindsetup.nodesarraycapacity = K_GetNodesArrayBaseSize(); + pathfindsetup.startnodedata = sourcewaypoint; + pathfindsetup.endnodedata = finishline; + pathfindsetup.endgscore = traveldistance; + pathfindsetup.getconnectednodes = nextnodesfunc; + pathfindsetup.getconnectioncosts = nodecostsfunc; + pathfindsetup.getheuristic = heuristicfunc; + pathfindsetup.gettraversable = traversablefunc; + pathfindsetup.getfinished = finishedfunc; + + pathfound = K_PathfindAStar(returnpath, &pathfindsetup); + + K_UpdateOpensetBaseSize(pathfindsetup.opensetcapacity); + K_UpdateClosedsetBaseSize(pathfindsetup.closedsetcapacity); + K_UpdateNodesArrayBaseSize(pathfindsetup.nodesarraycapacity); + } + + return pathfound; +} + /*-------------------------------------------------- waypoint_t *K_GetNextWaypointToDestination( waypoint_t *const sourcewaypoint, diff --git a/src/k_waypoint.h b/src/k_waypoint.h index a2201ff26..1cb659dbe 100644 --- a/src/k_waypoint.h +++ b/src/k_waypoint.h @@ -245,6 +245,36 @@ boolean K_PathfindThruCircuit( const boolean huntbackwards); +/*-------------------------------------------------- + boolean K_PathfindThruCircuitSpawnable( + waypoint_t *const sourcewaypoint, + const UINT32 traveldistance, + path_t *const returnpath, + const boolean useshortcuts, + const boolean huntbackwards) + + The same as K_PathfindThruCircuit, but continues until hitting a waypoint that + can be respawned at. + + Input Arguments:- + sourcewaypoint - The waypoint to start searching from + traveldistance - How far along the circuit it will try to pathfind. + returnpath - The path_t that will contain the final found path + useshortcuts - Whether to use waypoints that are marked as being shortcuts in the search + huntbackwards - Goes through the waypoints backwards if true + + Return:- + True if a circuit path could be constructed, false if it couldn't. +--------------------------------------------------*/ + +boolean K_PathfindThruCircuitSpawnable( + waypoint_t *const sourcewaypoint, + const UINT32 traveldistance, + path_t *const returnpath, + const boolean useshortcuts, + const boolean huntbackwards); + + /*-------------------------------------------------- waypoint_t *K_GetNextWaypointToDestination( waypoint_t *const sourcewaypoint, diff --git a/src/objects/shrink.c b/src/objects/shrink.c index a37c93ac3..0728385cf 100644 --- a/src/objects/shrink.c +++ b/src/objects/shrink.c @@ -564,7 +564,7 @@ static waypoint_t *GetPohbeeWaypoint(waypoint_t *anchor, const UINT32 traveldist path_t pathtofinish = {0}; waypoint_t *ret = NULL; - pathfindsuccess = K_PathfindThruCircuit( + pathfindsuccess = K_PathfindThruCircuitSpawnable( anchor, traveldist, &pathtofinish, useshortcuts, huntbackwards