mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2026-03-30 15:01:48 +00:00
Make waypoints setup on map load
Refactor some things to make slightly clearer code Change comments to use completely tabs Add extra error checks to methods for helpful debugging and safety Use a heap of waypoints during creation to be able to search for them to make links, to not freeze the game Add a way to clear waypoints so that the methods don't error after more than one map load Flip the ambush flag so that adding it will make the waypoint unable to be respawned at when the feature happens Temporarily disable K_UpdateKartPosition so that it doesn't crash on map load
This commit is contained in:
parent
a72630942d
commit
5fba15a58b
5 changed files with 487 additions and 146 deletions
|
|
@ -4767,6 +4767,8 @@ void K_KartUpdatePosition(player_t *player)
|
|||
fixed_t pmo, imo;
|
||||
mobj_t *mo;
|
||||
|
||||
return;
|
||||
|
||||
if (player->spectator || !player->mo)
|
||||
return;
|
||||
|
||||
|
|
|
|||
555
src/k_waypoint.c
555
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return setupsuccessful;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
void K_ClearWaypoints()
|
||||
|
||||
See header file for description.
|
||||
--------------------------------------------------*/
|
||||
void K_ClearWaypoints()
|
||||
{
|
||||
waypointheap = NULL;
|
||||
numwaypoints = 0;
|
||||
numwaypointmobjs = 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue