Add player's nextwaypoint to the player struct

Network synchronised(?) nextwaypoint in player struct
Make the waypointheap actually a heap and not allocate memory for every individual waypoint.
No need to store id in the waypoint struct, since it can be gotten from the waypointheap now.
This commit is contained in:
Sryder 2019-06-16 17:58:28 +01:00
parent 530214aa87
commit 49a8b0ac38
6 changed files with 111 additions and 76 deletions

View file

@ -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.

View file

@ -8392,10 +8392,6 @@ static const char *const KARTSTUFF_LIST[] = {
"POSITION",
"OLDPOSITION",
"POSITIONDELAY",
"PREVCHECK",
"NEXTCHECK",
"WAYPOINT",
"STARPOSTWP",
"STARPOSTFLIP",
"RESPAWN",
"DROPDASH",

View file

@ -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;

View file

@ -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);
}

View file

@ -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()

View file

@ -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);
}
}
}
}
}