diff --git a/src/d_player.h b/src/d_player.h index cdc4fed30..1eb63770c 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -29,6 +29,9 @@ // as commands per game tick. #include "d_ticcmd.h" +// the player struct stores a waypoint for racing +#include "k_waypoint.h" + // Extra abilities/settings for skins (combinable stuff) typedef enum { @@ -429,6 +432,7 @@ typedef struct player_s INT16 lturn_max[MAXPREDICTTICS]; // What's the expected turn value for full-left for a number of frames back (to account for netgame latency)? INT16 rturn_max[MAXPREDICTTICS]; // Ditto but for full-right UINT32 distancetofinish; + waypoint_t *nextwaypoint; // Bit flags. // See pflags_t, above. diff --git a/src/dehacked.c b/src/dehacked.c index be45f3f0f..2162bcbf5 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -8392,10 +8392,6 @@ static const char *const KARTSTUFF_LIST[] = { "POSITION", "OLDPOSITION", "POSITIONDELAY", - "PREVCHECK", - "NEXTCHECK", - "WAYPOINT", - "STARPOSTWP", "STARPOSTFLIP", "RESPAWN", "DROPDASH", diff --git a/src/k_kart.c b/src/k_kart.c index f0bc7149b..07d44909b 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -5796,11 +5796,11 @@ static void K_UpdateDistanceFromFinishLine(player_t *player) { if ((player != NULL) && (player->mo != NULL)) { - waypoint_t *bestwaypoint = K_GetPlayerNextWaypoint(player); waypoint_t *finishline = K_GetFinishLineWaypoint(); + player->nextwaypoint = K_GetPlayerNextWaypoint(player); // bestwaypoint is now the waypoint that is in front of us - if ((bestwaypoint != NULL) && (finishline != NULL)) + if ((player->nextwaypoint != NULL) && (finishline != NULL)) { const boolean useshortcuts = false; const boolean huntbackwards = false; @@ -5808,7 +5808,7 @@ static void K_UpdateDistanceFromFinishLine(player_t *player) path_t pathtofinish = {}; pathfindsuccess = - K_PathfindToWaypoint(bestwaypoint, finishline, &pathtofinish, useshortcuts, huntbackwards); + K_PathfindToWaypoint(player->nextwaypoint, finishline, &pathtofinish, useshortcuts, huntbackwards); // Update the player's distance to the finish line if a path was found. // Using shortcuts won't find a path, so the distance won't be updated until the player gets back on track @@ -5817,8 +5817,10 @@ static void K_UpdateDistanceFromFinishLine(player_t *player) // Add euclidean distance to the next waypoint to the distancetofinish UINT32 adddist; fixed_t disttowaypoint = - P_AproxDistance(player->mo->x - bestwaypoint->mobj->x, player->mo->y - bestwaypoint->mobj->y); - disttowaypoint = P_AproxDistance(disttowaypoint, player->mo->z - bestwaypoint->mobj->z); + P_AproxDistance( + player->mo->x - player->nextwaypoint->mobj->x, + player->mo->y - player->nextwaypoint->mobj->y); + disttowaypoint = P_AproxDistance(disttowaypoint, player->mo->z - player->nextwaypoint->mobj->z); adddist = ((UINT32)disttowaypoint) >> FRACBITS; diff --git a/src/k_waypoint.c b/src/k_waypoint.c index 79017b4dd..570fa8a51 100644 --- a/src/k_waypoint.c +++ b/src/k_waypoint.c @@ -14,7 +14,7 @@ static const size_t OPENSET_BASE_SIZE = 16U; static const size_t CLOSEDSET_BASE_SIZE = 256U; static const size_t NODESARRAY_BASE_SIZE = 256U; -static waypoint_t **waypointheap = NULL; +static waypoint_t *waypointheap = NULL; static waypoint_t *firstwaypoint = NULL; static waypoint_t *finishline = NULL; @@ -160,6 +160,49 @@ INT32 K_GetWaypointID(waypoint_t *waypoint) return waypointid; } + +/*-------------------------------------------------- + size_t K_GetWaypointHeapIndex(waypoint_t *waypoint) + + See header file for description. +--------------------------------------------------*/ +size_t K_GetWaypointHeapIndex(waypoint_t *waypoint) +{ + size_t waypointindex = SIZE_MAX; + + if (waypoint == NULL) + { + CONS_Debug(DBG_GAMELOGIC, "NULL waypoint in K_GetWaypointID.\n"); + } + else + { + waypointindex = waypoint - waypointheap; + } + + return waypointindex; +} + +/*-------------------------------------------------- + waypoint_t *K_GetWaypointFromIndex(size_t waypointindex) + + See header file for description. +--------------------------------------------------*/ +waypoint_t *K_GetWaypointFromIndex(size_t waypointindex) +{ + waypoint_t *waypoint = NULL; + + if (waypointindex >= numwaypoints) + { + CONS_Debug(DBG_GAMELOGIC, "waypointindex higher than number of waypoints in K_GetWaypointFromIndex"); + } + else + { + waypoint = &waypointheap[waypointindex]; + } + + return waypoint; +} + /*-------------------------------------------------- void K_DebugWaypointsSpawnLine(waypoint_t *const waypoint1, waypoint_t *const waypoint2) @@ -940,11 +983,12 @@ searchwaypointstart: } else { + size_t waypointindex = K_GetWaypointHeapIndex(waypoint); // If we've already visited this waypoint, we've already checked the next waypoints, no point continuing - if (visitedarray[waypoint->id] != true) + if ((waypointindex != SIZE_MAX) && (visitedarray[waypointindex] != true)) { // Mark this waypoint as being visited - visitedarray[waypoint->id] = true; + visitedarray[waypointindex] = true; if (conditionalfunc(waypoint, condition) == true) { @@ -1105,9 +1149,9 @@ static waypoint_t *K_SearchWaypointHeap( // waypoints setup in the heap while numwaypointmobjs ends up being the capacity for (i = 0; i < numwaypoints; i++) { - if (conditionalfunc(waypointheap[i], condition) == true) + if (conditionalfunc(&waypointheap[i], condition) == true) { - foundwaypoint = waypointheap[i]; + foundwaypoint = &waypointheap[i]; break; } } @@ -1188,49 +1232,6 @@ static void K_AddPrevToWaypoint(waypoint_t *const waypoint, waypoint_t *const pr } } -/*-------------------------------------------------- - static waypoint_t *K_NewWaypoint(mobj_t *mobj) - - Creates memory for a new waypoint - - 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 ---------------------------------------------------*/ -static waypoint_t *K_NewWaypoint(mobj_t *const mobj) -{ - waypoint_t *waypoint = NULL; - - // Error conditions - if (mobj == NULL || P_MobjWasRemoved(mobj)) - { - CONS_Debug(DBG_SETUP, "NULL mobj in K_NewWaypoint.\n"); - } - else if (waypointheap == NULL) - { - CONS_Debug(DBG_SETUP, "NULL waypointheap in K_NewWaypoint.\n"); - } - else - { - // 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 == NULL) - { - I_Error("K_NewWaypoint: Failed to allocate memory for waypoint."); - } - - P_SetTarget(&waypoint->mobj, mobj); - waypoint->id = numwaypoints++; - } - - return waypoint; -} - /*-------------------------------------------------- static waypoint_t *K_MakeWaypoint(mobj_t *const mobj) @@ -1257,9 +1258,17 @@ static waypoint_t *K_MakeWaypoint(mobj_t *const mobj) { CONS_Debug(DBG_SETUP, "K_MakeWaypoint called with NULL waypointcap.\n"); } + else if (numwaypoints >= numwaypointmobjs) + { + CONS_Debug(DBG_SETUP, "K_MakeWaypoint called with max waypoint capacity reached.\n"); + } else { - madewaypoint = K_NewWaypoint(mobj); + // numwaypoints is incremented later in K_SetupWaypoint + madewaypoint = &waypointheap[numwaypoints]; + numwaypoints++; + + P_SetTarget(&madewaypoint->mobj, 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) @@ -1340,8 +1349,7 @@ static waypoint_t *K_SetupWaypoint(mobj_t *const mobj) if (thiswaypoint != NULL) { - // 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 + // Set the first waypoint if it isn't already if (firstwaypoint == NULL) { firstwaypoint = thiswaypoint; @@ -1447,7 +1455,7 @@ static boolean K_AllocateWaypointHeap(void) { // 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 - waypointheap = Z_Calloc(numwaypointmobjs * sizeof(waypoint_t **), PU_LEVEL, NULL); + waypointheap = Z_Calloc(numwaypointmobjs * sizeof(waypoint_t), PU_LEVEL, NULL); if (waypointheap == NULL) { @@ -1478,20 +1486,6 @@ static void K_FreeWaypoints(void) { if (waypointheap != NULL) { - // Free each waypoint if it's not already - UINT32 i; - for (i = 0; i < numwaypoints; i++) - { - if (waypointheap[i] != NULL) - { - Z_Free(waypointheap[i]); - } - else - { - CONS_Debug(DBG_SETUP, "NULL waypoint %d attempted to be freed.\n", i); - } - } - // Free the waypointheap Z_Free(waypointheap); } diff --git a/src/k_waypoint.h b/src/k_waypoint.h index 7e5dffc1a..35f21570a 100644 --- a/src/k_waypoint.h +++ b/src/k_waypoint.h @@ -8,7 +8,6 @@ typedef struct waypoint_s { mobj_t *mobj; - size_t id; struct waypoint_s **nextwaypoints; struct waypoint_s **prevwaypoints; UINT32 *nextwaypointdistances; @@ -200,9 +199,38 @@ waypoint_t *K_SearchWaypointGraphForMobj(mobj_t * const mobj); waypoint_t *K_SearchWaypointHeapForMobj(mobj_t * const mobj); + // NOT AVAILABLE FOR LUA +/*-------------------------------------------------- + size_t K_GetWaypointHeapIndex(waypoint_t *waypoint) + + Returns the waypoint's index in the waypoint heap. + + Input Arguments:- + waypoint - The waypoint to return the index of. + + Return:- + The waypoint heap index, SIZE_MAX if there's an issue with the waypoint. +--------------------------------------------------*/ +size_t K_GetWaypointHeapIndex(waypoint_t *waypoint); + + +/*-------------------------------------------------- + waypoint_t *K_GetWaypointFromIndex(size_t waypointindex) + + Returns the waypoint from an index to the heap. + + Input Arguments:- + waypointindex - The index of the waypoint to get + + Return:- + The waypoint from the heap index, NULL if the index if too high +--------------------------------------------------*/ +waypoint_t *K_GetWaypointFromIndex(size_t waypointindex); + + /*-------------------------------------------------- void K_DebugWaypointsVisualise() diff --git a/src/p_saveg.c b/src/p_saveg.c index d8f4351a4..1d7dbeef4 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -278,6 +278,7 @@ static void P_NetArchivePlayers(void) } WRITEUINT32(save_p, players[i].distancetofinish); + WRITEUINT32(save_p, K_GetWaypointHeapIndex(players[i].nextwaypoint)); } } @@ -448,6 +449,7 @@ static void P_NetUnArchivePlayers(void) } players[i].distancetofinish = READUINT32(save_p); + players[i].nextwaypoint = (waypoint_t *)(size_t)READUINT32(save_p); } } @@ -3062,6 +3064,15 @@ static void P_RelinkPointers(void) if (!P_SetTarget(&mobj->player->awayviewmobj, P_FindNewPosition(temp))) CONS_Debug(DBG_GAMELOGIC, "awayviewmobj not found on %d\n", mobj->type); } + if (mobj->player && mobj->player->nextwaypoint) + { + temp = (UINT32)(size_t)mobj->player->nextwaypoint; + mobj->player->nextwaypoint = K_GetWaypointFromIndex(temp); + if (mobj->player->nextwaypoint == NULL) + { + CONS_Debug(DBG_GAMELOGIC, "nextwaypoint not found on %d\n", mobj->type); + } + } } } }