diff --git a/src/k_kart.c b/src/k_kart.c index f01f0d0b2..51763384a 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -4767,6 +4767,8 @@ void K_KartUpdatePosition(player_t *player) fixed_t pmo, imo; mobj_t *mo; + return; + if (player->spectator || !player->mo) return; diff --git a/src/k_waypoint.c b/src/k_waypoint.c index a34215f42..0491c23a0 100644 --- a/src/k_waypoint.c +++ b/src/k_waypoint.c @@ -1,101 +1,129 @@ #include "k_waypoint.h" #include "doomdef.h" +#include "p_local.h" #include "p_mobj.h" #include "p_tick.h" #include "z_zone.h" +static waypoint_t **waypointheap = NULL; static waypoint_t *firstwaypoint = NULL; -static UINT32 numwaypoints = 0; +static size_t numwaypoints = 0; +static size_t numwaypointmobjs = 0; /*-------------------------------------------------- - waypoint_t *K_SearchWaypoints(waypoint_t *waypoint, mobj_t * const mobj, boolean * const visitedarray) + waypoint_t *K_SearchWaypoints(waypoint_t *waypoint, mobj_t * const mobj, boolean * const visitedarray) - Searches through the waypoint list for a waypoint that has an mobj, just does a simple flood search for the - waypoint that uses this mobj, no pathfinding + Searches through the waypoint list for a waypoint that has an mobj, just does a simple flood search for the + waypoint that uses this mobj, no pathfinding - Input Arguments:- - waypoint - The waypoint that is currently being checked, goes through nextWaypoints after this one - mobj - the mobj that we are searching for, cannot be changed to a different pointer - visitedarray - An array of booleans that let us know if a waypoint has already been checked, marked to true when - one is, so we don't repeat going down a path. Cannot be changed to a different pointer + Input Arguments:- + waypoint - The waypoint that is currently being checked, goes through nextwaypoints after this one + mobj - the mobj that we are searching for, cannot be changed to a different pointer + visitedarray - An array of booleans that let us know if a waypoint has already been checked, marked to true when + one is, so we don't repeat going down a path. Cannot be changed to a different pointer Return:- - The waypoint that uses that mobj, NULL if it wasn't found, NULL if it isn't an MT_WAYPOINT + The waypoint that uses that mobj, NULL if it wasn't found, NULL if it isn't an MT_WAYPOINT --------------------------------------------------*/ static waypoint_t *K_SearchWaypoints(waypoint_t *waypoint, mobj_t * const mobj, boolean * const visitedarray) { - UINT32 i; - waypoint_t *foundwaypoint; + waypoint_t *foundwaypoint = NULL; + // Error conditions + if (mobj == NULL || P_MobjWasRemoved(mobj)) + { + CONS_Debug(DBG_GAMELOGIC, "NULL mobj in K_SearchWaypoints.\n"); + return NULL; + } if (mobj->type != MT_WAYPOINT) { + CONS_Debug(DBG_GAMELOGIC, "Non MT_WAYPOINT mobj in K_SearchWaypoints. Type=%d.\n", mobj->type); + return NULL; + } + if (visitedarray == NULL) + { + CONS_Debug(DBG_GAMELOGIC, "NULL visitedarray in K_SearchWaypoints.\n"); return NULL; } searchwaypointstart: - // If we've already visited this waypoint, we've already checked the next waypoint, and going further is useless - if (visitedarray[waypoint->id] == true) + if (waypoint == NULL) { + CONS_Debug(DBG_GAMELOGIC, "NULL waypoint in K_SearchWaypoints.\n"); return NULL; } - // Mark this waypoint as being visited - visitedarray[waypoint->id] = true; - - if (waypoint->mobj == mobj) + // If we've already visited this waypoint, we've already checked the next waypoints, and continuing is useless + if (visitedarray[waypoint->id] != true) { - return waypoint; - } + // Mark this waypoint as being visited + visitedarray[waypoint->id] = true; - // If this waypoint only has one next waypoint, set the waypoint to be the only next one and jump back to the start - // this is to avoid going too deep into the stack where we can - if (waypoint->numnextwaypoints == 1) - { - waypoint = waypoint->nextwaypoints[0]; - goto searchwaypointstart; - } - - // This waypoint has no next waypoint, so just stop searching - if (waypoint->numnextwaypoints == 0) - { - return NULL; - } - - // For each next waypoint, Search through it's path continuation until we hopefully find the one we're looking for - for (i = 0; i < waypoint->numnextwaypoints; i++) - { - foundwaypoint = K_SearchWaypoints(waypoint->nextwaypoints[i], mobj, visitedarray); - - if (foundwaypoint != NULL) + if (waypoint->mobj == mobj) { - return foundwaypoint; + foundwaypoint = waypoint; + } + else + { + // If this waypoint only has one next waypoint, set the waypoint to be the next one and jump back + // to the start, this is to avoid going too deep into the stack where we can + // Yes this is a horrible horrible goto, but the alternative is a do while loop with an extra variable, + // which is slightly more confusing. This is probably the fastest and least confusing option that keeps + // this functionality + if (waypoint->numnextwaypoints == 1 && waypoint->nextwaypoints[0] != NULL) + { + waypoint = waypoint->nextwaypoints[0]; + goto searchwaypointstart; + } + else if (waypoint->numnextwaypoints != 0) + { + UINT32 i; + // For each next waypoint, Search through it's path continuation until we hopefully find the one we're + // looking for + for (i = 0; i < waypoint->numnextwaypoints; i++) + { + if (waypoint->nextwaypoints[i] != NULL) + { + foundwaypoint = K_SearchWaypoints(waypoint->nextwaypoints[i], mobj, visitedarray); + + if (foundwaypoint != NULL) + { + break; + } + } + } + } } } - // Matching waypoint was not found down this path - return NULL; + return foundwaypoint; } /*-------------------------------------------------- - waypoint_t *K_SearchWaypointsForMobj(mobj_t * const mobj) + waypoint_t *K_SearchWaypointGraphForMobj(mobj_t * const mobj) - Searches through the waypoint list for a waypoint that has an mobj - - Input Arguments:- - mobj - The mobj that we are searching for, cannot be changed to a different pointer - - Return:- - The waypoint that uses that mobj, NULL if it wasn't found, NULL if it isn't an MT_WAYPOINT + See header file for description. --------------------------------------------------*/ -waypoint_t *K_SearchWaypointsForMobj(mobj_t * const mobj) +waypoint_t *K_SearchWaypointGraphForMobj(mobj_t * const mobj) { - boolean *visitedarray; - waypoint_t *foundwaypoint; + boolean *visitedarray = NULL; + waypoint_t *foundwaypoint = NULL; - // If the mobj it's looking for isn't even a waypoint, then reject it + // Error conditions + if (mobj == NULL || P_MobjWasRemoved(mobj)) + { + CONS_Debug(DBG_GAMELOGIC, "NULL mobj in K_SearchWaypointsForMobj.\n"); + return NULL; + } if (mobj->type != MT_WAYPOINT) { + CONS_Debug(DBG_GAMELOGIC, "Non MT_WAYPOINT mobj in K_SearchWaypointsForMobj. Type=%d.\n", mobj->type); + return NULL; + } + if (firstwaypoint == NULL) + { + CONS_Debug(DBG_GAMELOGIC, "K_SearchWaypointsForMobj called when no first waypoint.\n"); return NULL; } @@ -106,23 +134,77 @@ waypoint_t *K_SearchWaypointsForMobj(mobj_t * const mobj) } /*-------------------------------------------------- - static void K_AddPrevToWaypoint(waypoint_t *waypoint, waypoint_t *prevwaypoint) + waypoint_t *K_SearchWaypointHeapForMobj(mobj_t * const mobj) - Adds another waypoint to a waypoint's previous waypoint list, this needs to be done like this because there is no - way to identify previous waypoints from just IDs, so we need to reallocate the memory for every previous waypoint + See header file for description. +--------------------------------------------------*/ +waypoint_t *K_SearchWaypointHeapForMobj(mobj_t * const mobj) +{ + UINT32 i = 0; + waypoint_t *foundwaypoint = NULL; - Input Arguments:- - waypoint - The waypoint which is having its previous waypoint list added to - prevwaypoint - The waypoint which is being added to the previous waypoint list + // Error conditions + if (mobj == NULL || P_MobjWasRemoved(mobj)) + { + CONS_Debug(DBG_GAMELOGIC, "NULL mobj in K_SearchWaypointsForMobj.\n"); + return NULL; + } + if (mobj->type != MT_WAYPOINT) + { + CONS_Debug(DBG_GAMELOGIC, "Non MT_WAYPOINT mobj in K_SearchWaypointsForMobj. Type=%d.\n", mobj->type); + return NULL; + } + if (waypointheap == NULL) + { + CONS_Debug(DBG_GAMELOGIC, "K_SearchWaypointsForMobj called when no waypointheap.\n"); + return NULL; + } - Return:- - Pointer to waypoint_t for the rest of the waypoint data to be placed into + // Simply search through the waypointheap for the waypoint with the mobj! Much simpler when no pathfinding needed. + // search up to numwaypoints and NOT numwaypointmobjs as numwaypoints is the real number of waypoints setup in + // the heap while numwaypointmobjs ends up being the capacity + for (i = 0; i < numwaypoints; i++) + { + if (waypointheap[i]->mobj == mobj) + { + foundwaypoint = waypointheap[i]; + break; + } + } + + return foundwaypoint; +} + +/*-------------------------------------------------- + static void K_AddPrevToWaypoint(waypoint_t *waypoint, waypoint_t *prevwaypoint) + + Adds another waypoint to a waypoint's previous waypoint list, this needs to be done like this because there is no + way to identify previous waypoints from just IDs, so we need to reallocate the memory for every previous waypoint + + Input Arguments:- + waypoint - The waypoint which is having its previous waypoint list added to + prevwaypoint - The waypoint which is being added to the previous waypoint list + + Return:- + Pointer to waypoint_t for the rest of the waypoint data to be placed into --------------------------------------------------*/ static void K_AddPrevToWaypoint(waypoint_t *waypoint, waypoint_t *prevwaypoint) { + // Error conditions + if (waypoint == NULL) + { + CONS_Debug(DBG_SETUP, "NULL waypoint in K_AddPrevToWaypoint.\n"); + return; + } + if (prevwaypoint == NULL) + { + CONS_Debug(DBG_SETUP, "NULL prevwaypoint in K_AddPrevToWaypoint.\n"); + return; + } + waypoint->numprevwaypoints++; - waypoint->prevwaypoints = Z_Realloc(waypoint->prevwaypoints, waypoint->numprevwaypoints * sizeof(waypoint_t *), - PU_LEVEL, NULL); + waypoint->prevwaypoints = + Z_Realloc(waypoint->prevwaypoints, waypoint->numprevwaypoints * sizeof(waypoint_t *), PU_LEVEL, NULL); if (!waypoint->prevwaypoints) { @@ -133,136 +215,327 @@ static void K_AddPrevToWaypoint(waypoint_t *waypoint, waypoint_t *prevwaypoint) } /*-------------------------------------------------- - static waypoint_t *K_NewWaypoint(mobj_t *mobj) + static waypoint_t *K_NewWaypoint(mobj_t *mobj) - Creates memory for a new waypoint + Creates memory for a new waypoint - Input Arguments:- - mobj - The map object that this waypoint is represented by + Input Arguments:- + mobj - The map object that this waypoint is represented by - Return:- - Pointer to waypoint_t for the rest of the waypoint data to be placed into + Return:- + Pointer to waypoint_t for the rest of the waypoint data to be placed into --------------------------------------------------*/ static waypoint_t *K_NewWaypoint(mobj_t *mobj) { - waypoint_t *waypoint = Z_Calloc(sizeof(waypoint_t), PU_LEVEL, NULL); + waypoint_t *waypoint; + + // Error conditions + if (mobj == NULL || P_MobjWasRemoved(mobj)) + { + CONS_Debug(DBG_SETUP, "NULL mobj in K_NewWaypoint.\n"); + return NULL; + } + if (waypointheap == NULL) + { + CONS_Debug(DBG_SETUP, "NULL waypointheap in K_NewWaypoint.\n"); + return NULL; + } + + // Each made waypoint is placed directly into the waypoint heap to be able to search it during creation + waypointheap[numwaypoints] = Z_Calloc(sizeof(waypoint_t), PU_LEVEL, NULL); + waypoint = waypointheap[numwaypoints]; + // numwaypoints is incremented later when waypoint->id is set if (!waypoint) { I_Error("K_NewWaypoint: Failed to allocate memory for waypoint."); } + P_SetTarget(&waypoint->mobj, mobj); waypoint->id = numwaypoints++; + return waypoint; } /*-------------------------------------------------- - static waypoint_t *K_SetupWaypoint(mobj_t *mobj) + static waypoint_t *K_MakeWaypoint(mobj_t *mobj) - Either gets an already made waypoint, or sets up a new waypoint for an mobj, including next and previous waypoints + Make a new waypoint from a map object. Setups up most of the data for it, and allocates most memory + Remaining creation is handled in K_SetupWaypoint - Input Arguments:- - mobj - The map object that this waypoint is represented by + Input Arguments:- + mobj - The map object that this waypoint is represented by - Return:- - Pointer to the setup waypoint, NULL if one was not setup + Return:- + Pointer to the setup waypoint, NULL if one was not setup +--------------------------------------------------*/ +static waypoint_t *K_MakeWaypoint(mobj_t *mobj) +{ + waypoint_t *madewaypoint = NULL; + mobj_t *otherwaypointmobj = NULL; + + // Error conditions + if (mobj == NULL || P_MobjWasRemoved(mobj)) + { + CONS_Debug(DBG_SETUP, "NULL mobj in K_MakeWaypoint.\n"); + return NULL; + } + if (waypointcap == NULL) + { + CONS_Debug(DBG_SETUP, "K_MakeWaypoint called with NULL waypointcap."); + return false; + } + + madewaypoint = K_NewWaypoint(mobj); + + // Go through the other waypoint mobjs in the map to find out how many waypoints are after this one + for (otherwaypointmobj = waypointcap; otherwaypointmobj != NULL; otherwaypointmobj = otherwaypointmobj->tracer) + { + // threshold = next waypoint id, movecount = my id + if (mobj->threshold == otherwaypointmobj->movecount) + { + madewaypoint->numnextwaypoints++; + } + } + + // No next waypoints + if (madewaypoint->numnextwaypoints != 0) + { + // Allocate memory to hold enough pointers to all of the next waypoints + madewaypoint->nextwaypoints = Z_Calloc(madewaypoint->numnextwaypoints * sizeof(waypoint_t *), PU_LEVEL, NULL); + if (madewaypoint->nextwaypoints == NULL) + { + I_Error("K_MakeWaypoint: Out of Memory"); + } + } + + return madewaypoint; +} + +/*-------------------------------------------------- + static waypoint_t *K_SetupWaypoint(mobj_t *mobj) + + Either gets an already made waypoint, or sets up a new waypoint for an mobj, + including next and previous waypoints + + Input Arguments:- + mobj - The map object that this waypoint is represented by + + Return:- + Pointer to the setup waypoint, NULL if one was not setup --------------------------------------------------*/ static waypoint_t *K_SetupWaypoint(mobj_t *mobj) { - UINT32 nextwaypointindex = 0; waypoint_t *thiswaypoint = NULL; - mobj_t *otherwpmobj = NULL; - // If this mobj is not an MT_WAYPOINT, don't create waypoints from it + // Error conditions + if (mobj == NULL || P_MobjWasRemoved(mobj)) + { + CONS_Debug(DBG_SETUP, "NULL mobj in K_SetupWaypoint.\n"); + return NULL; + } if (mobj->type != MT_WAYPOINT) { - CONS_Debug(DBG_GAMELOGIC, "WARNING: Non MT_WAYPOINT mobj in K_SetupWaypoint."); + CONS_Debug(DBG_SETUP, "Non MT_WAYPOINT mobj in K_SetupWaypoint. Type=%d.\n", mobj->type); return NULL; } + if (waypointcap == NULL) + { + CONS_Debug(DBG_SETUP, "K_SetupWaypoint called with NULL waypointcap."); + return false; + } // If we have waypoints already created, search through them first to see if this mobj is already added. if (firstwaypoint != NULL) { - thiswaypoint = K_SearchWaypointsForMobj(mobj); + thiswaypoint = K_SearchWaypointHeapForMobj(mobj); } - // return the waypoint if we already made it - if (thiswaypoint != NULL) + // The waypoint hasn't already been made, so make it + if (thiswaypoint == NULL) { - return thiswaypoint; - } + mobj_t *otherwaypointmobj = NULL; + UINT32 nextwaypointindex = 0; - // If we haven't already made the waypoint, make it now. - thiswaypoint = K_NewWaypoint(mobj); + thiswaypoint = K_MakeWaypoint(mobj); - // Temporarily set the first waypoint to be the first waypoint we setup, this is so that we can search through them - // as they're made and added to the linked list - if (firstwaypoint != NULL) - { - firstwaypoint = thiswaypoint; - } - - // Go through the other waypoint mobjs in the map to find out how many waypoints are after this one - for (otherwpmobj = waypointcap; otherwpmobj != NULL; otherwpmobj = otherwpmobj->tracer) - { - if (mobj->threshold == otherwpmobj->threshold) + // Temporarily set the first waypoint to be the first waypoint we setup, this is so that we can search + // through them as they're made and added to the linked list + if (firstwaypoint == NULL) { - thiswaypoint->numnextwaypoints++; + firstwaypoint = thiswaypoint; + } + + if (thiswaypoint->numnextwaypoints > 0) + { + // Go through the waypoint mobjs to setup the next waypoints and make this waypoint know they're its next + // I kept this out of K_MakeWaypoint so the stack isn't gone down as deep + for (otherwaypointmobj = waypointcap; otherwaypointmobj != NULL; otherwaypointmobj = otherwaypointmobj->tracer) + { + // threshold = next waypoint id, movecount = my id + if (mobj->threshold == otherwaypointmobj->movecount) + { + thiswaypoint->nextwaypoints[nextwaypointindex] = K_SetupWaypoint(otherwaypointmobj); + K_AddPrevToWaypoint(thiswaypoint->nextwaypoints[nextwaypointindex], thiswaypoint); + nextwaypointindex++; + } + if (nextwaypointindex >= thiswaypoint->numnextwaypoints) + { + break; + } + } } } - // No next waypoints - if (thiswaypoint->numnextwaypoints == 0) - { - return NULL; - } - - // Allocate memory to hold enough pointers to all of the next waypoints - thiswaypoint->nextwaypoints = Z_Malloc(thiswaypoint->numnextwaypoints * sizeof(waypoint_t *), PU_LEVEL, NULL); - if (!thiswaypoint->numnextwaypoints) - { - I_Error("K_SetupWaypoint: Out of Memory"); - } - - // Go through the waypoint mobjs again to setup the next waypoints and make this waypoint know they're the next one - for (otherwpmobj = waypointcap; otherwpmobj != NULL; otherwpmobj = otherwpmobj->tracer) - { - if (mobj->threshold == otherwpmobj->movecount) - { - thiswaypoint->nextwaypoints[nextwaypointindex] = K_SetupWaypoint(otherwpmobj); - K_AddPrevToWaypoint(thiswaypoint->nextwaypoints[nextwaypointindex], thiswaypoint); - nextwaypointindex++; - } - if (nextwaypointindex >= thiswaypoint->numnextwaypoints) - { - break; - } - } - - // Should always be returning a valid waypoint here return thiswaypoint; } /*-------------------------------------------------- - boolean K_SetupWaypointList() + static boolean K_AllocateWaypointHeap() - Sets up the waypoint list for Kart race maps, does not return a status to say whether creation was fully - successful, but we're able to print out warnings if something is wrong. + Allocates the waypoint heap enough space for the number of waypoint mobjs on the map + + Return:- + True if the allocation was successful, false if it wasn't. Will I_Error if out of memory still. --------------------------------------------------*/ -void K_SetupWaypointList() +boolean K_AllocateWaypointHeap() { - if (!waypointcap) + mobj_t *waypointmobj = NULL; + boolean allocationsuccessful = false; + + // Error conditions + if (waypointheap != NULL) { - CONS_Debug(DBG_GAMELOGIC, "WARNING: K_SetupWaypointList called with no waypointcap."); + CONS_Debug(DBG_SETUP, "K_AllocateWaypointHeap called when waypointheap is already allocated."); + return false; + } + if (waypointcap == NULL) + { + CONS_Debug(DBG_SETUP, "K_AllocateWaypointHeap called with NULL waypointcap."); + return false; + } + + // This should be an allocation for the first time. Reset the number of mobjs back to 0 if it's not already + numwaypointmobjs = 0; + + // Find how many waypoint mobjs there are in the map, this is the maximum number of waypoints there CAN be + for (waypointmobj = waypointcap; waypointmobj != NULL; waypointmobj = waypointmobj->tracer) + { + if (waypointmobj->type != MT_WAYPOINT) + { + CONS_Debug(DBG_SETUP, + "Non MT_WAYPOINT mobj in waypointcap in K_AllocateWaypointHeap. Type=%d\n.", waypointmobj->type); + continue; + } + + numwaypointmobjs++; + } + + if (numwaypointmobjs > 0) + { + // Allocate space in the heap for every mobj, it's possible some mobjs aren't linked up and not all of the heap + // allocated will be used, but it's a fairly reasonable assumption that this isn't going to be awful if true + waypointheap = Z_Calloc(numwaypointmobjs * sizeof(waypoint_t **), PU_LEVEL, NULL); + + if (waypointheap == NULL) + { + // We could theoretically CONS_Debug here and continue without using waypoints, but I feel that will require + // error checks that will end up spamming the console when we think waypoints SHOULD be working. + // Safer to just exit if out of memory and not end up constantly trying to use the waypoints in this case + I_Error("K_AllocateWaypointHeap: Out of memory."); + } + allocationsuccessful = true; } else { - // The waypoint in the waypointcap is going to be considered our first waypoint - K_SetupWaypoint(waypointcap); + CONS_Debug(DBG_SETUP, "No waypoint mobjs in waypointcap."); + } - if (!firstwaypoint) + return allocationsuccessful; +} + +/*-------------------------------------------------- + void K_FreeWaypoints() + + For safety, this will free the waypointheap and all the waypoints allocated if they aren't already before they + are setup. If the PU_LEVEL tag is cleared, make sure to call K_ClearWaypoints or this will try to free already + freed memory! +--------------------------------------------------*/ +void K_FreeWaypoints() +{ + if (waypointheap != NULL) + { + // Free each waypoint if it's not already + INT32 i; + for (i = 0; i < numwaypoints; i++) { - CONS_Debug(DBG_GAMELOGIC, "WARNING: K_SetupWaypointList made no waypoints."); + if (waypointheap[i] != NULL) + { + Z_Free(waypointheap[i]); + } + else + { + CONS_Debug(DBG_SETUP, "NULL waypoint %d attempted to be freed.", i); + } + } + + // Free the waypointheap + Z_Free(waypointheap); + } + + K_ClearWaypoints(); +} + +/*-------------------------------------------------- + boolean K_SetupWaypointList() + + See header file for description. +--------------------------------------------------*/ +boolean K_SetupWaypointList() +{ + boolean setupsuccessful = false; + + K_FreeWaypoints(); + + if (!waypointcap) + { + CONS_Debug(DBG_SETUP, "K_SetupWaypointList called with no waypointcap.\n"); + } + else + { + if (K_AllocateWaypointHeap() == true) + { + // The waypoint in the waypointcap is going to be considered our first waypoint + K_SetupWaypoint(waypointcap); + + if (!firstwaypoint) + { + CONS_Debug(DBG_SETUP, "K_SetupWaypointList made no waypoints.\n"); + } + else + { + CONS_Debug(DBG_SETUP, "Successfully setup %zu waypoints.\n", numwaypoints); + if (numwaypoints < numwaypointmobjs) + { + CONS_Printf("Not all waypoints in the map are connected! %zu waypoints setup but %zu mobjs.", + numwaypoints, numwaypointmobjs); + } + setupsuccessful = true; + } } } -} \ No newline at end of file + + return setupsuccessful; +} + +/*-------------------------------------------------- + void K_ClearWaypoints() + + See header file for description. +--------------------------------------------------*/ +void K_ClearWaypoints() +{ + waypointheap = NULL; + numwaypoints = 0; + numwaypointmobjs = 0; +} diff --git a/src/k_waypoint.h b/src/k_waypoint.h index 41b13b631..9184ce103 100644 --- a/src/k_waypoint.h +++ b/src/k_waypoint.h @@ -18,9 +18,63 @@ typedef struct waypoint_s // AVAILABLE FOR LUA -waypoint_t *K_SearchWaypointsForMobj(mobj_t * const mobj); + + +/*-------------------------------------------------- + waypoint_t *K_SearchWaypointGraphForMobj(mobj_t * const mobj) + + Searches through the waypoint graph for a waypoint that has an mobj, if a waypoint can be found through here it + does mean that the waypoint graph can be traversed to find it + + Input Arguments:- + mobj - The mobj that we are searching for, cannot be changed to a different pointer + + Return:- + The waypoint that uses that mobj, NULL if it wasn't found, NULL if it isn't an MT_WAYPOINT +--------------------------------------------------*/ + +waypoint_t *K_SearchWaypointGraphForMobj(mobj_t * const mobj); + +/*-------------------------------------------------- + waypoint_t *K_SearchWaypointHeapForMobj(mobj_t * const mobj) + + Searches through the waypoint heap for a waypoint that has an mobj, this does not necessarily mean the waypoint + can be reached from another waypoint + + Input Arguments:- + mobj - The mobj that we are searching for, cannot be changed to a different pointer + + Return:- + The waypoint that uses that mobj, NULL if it wasn't found, NULL if it isn't an MT_WAYPOINT +--------------------------------------------------*/ + +waypoint_t *K_SearchWaypointHeapForMobj(mobj_t * const mobj); // NOT AVAILABLE FOR LUA -void K_SetupWaypointList(void); + + +/*-------------------------------------------------- + boolean K_SetupWaypointList() + + Sets up the waypoint list for Kart race maps, prints out warnings if something is wrong. + + Return:- + true if waypoint setup was seemingly successful, false if no waypoints were setup + A true return value does not necessarily mean that the waypoints on the map are completely correct +--------------------------------------------------*/ + +boolean K_SetupWaypointList(void); + + +/*-------------------------------------------------- + void K_ClearWaypoints() + + Clears waypointheap, firstwaypoint, numwaypoints, and numwaypointmobjs + WARNING: This does *not* Free waypointheap or any waypoints! They are stored in PU_LEVEL so they are freed once + the level is completed! This is called just before K_SetupWaypointList in P_SetupLevel as they are freed then. + A separate method is called in K_SetupWaypointList that will free everything specifically if they aren't already +--------------------------------------------------*/ + +void K_ClearWaypoints(void); #endif \ No newline at end of file diff --git a/src/p_mobj.c b/src/p_mobj.c index f2ce9c824..a0ad0d716 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -11816,11 +11816,11 @@ ML_NOCLIMB : Direction not controllable mobj->movecount = mthing->angle; if (mthing->options & MTF_AMBUSH) { - mobj->reactiontime = 1; + mobj->reactiontime = 0; // Can't respawn at if Ambush is off } else { - mobj->reactiontime = 0; + mobj->reactiontime = 1; } // Sryder 2018-12-7: Grabbed this from the old MT_BOSS3WAYPOINT section so they'll be in the waypointcap instead diff --git a/src/p_setup.c b/src/p_setup.c index 49b22184e..3cc4b874b 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -80,6 +80,7 @@ // SRB2Kart #include "k_kart.h" +#include "k_waypoint.h" // // Map MD5, calculated on level load. @@ -3058,6 +3059,17 @@ boolean P_SetupLevel(boolean skipprecip) globalweather = mapheaderinfo[gamemap-1]->weather; + // The waypoint data that's in PU_LEVEL needs to be reset back to 0/NULL now since PU_LEVEL was cleared + K_ClearWaypoints(); + // Load the waypoints please! + if (G_RaceGametype()) + { + if (K_SetupWaypointList() == false) + { + CONS_Printf("Waypoints were not able to be setup! Player positions will not work correctly."); + } + } + #ifdef HWRENDER // not win32 only 19990829 by Kin if (rendermode != render_soft && rendermode != render_none) { @@ -3435,7 +3447,7 @@ boolean P_AddWadFile(const char *wadfilename) // R_AddSkins(wadnum); // faB: wadfile index in wadfiles[] - // + // // edit music defs // S_LoadMusicDefs(wadnum);