diff --git a/src/d_netcmd.c b/src/d_netcmd.c index a015b8e73..8b5e9063a 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -372,6 +372,8 @@ consvar_t cv_kartdebugamount = {"kartdebugamount", "1", CV_NETVAR|CV_CHEAT|CV_NO consvar_t cv_kartdebugshrink = {"kartdebugshrink", "Off", CV_NETVAR|CV_CHEAT|CV_NOSHOWHELP, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_kartdebugdistribution = {"kartdebugdistribution", "Off", CV_NETVAR|CV_CHEAT|CV_NOSHOWHELP, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_kartdebughuddrop = {"kartdebughuddrop", "Off", CV_NETVAR|CV_CHEAT|CV_NOSHOWHELP, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +static CV_PossibleValue_t kartdebugwaypoint_cons_t[] = {{0, "Off"}, {1, "Forwards"}, {2, "Backwards"}, {0, NULL}}; +consvar_t cv_kartdebugwaypoints = {"kartdebugwaypoints", "Off", CV_NETVAR|CV_CHEAT|CV_NOSHOWHELP, kartdebugwaypoint_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_kartdebugcheckpoint = {"kartdebugcheckpoint", "Off", CV_NOSHOWHELP, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_kartdebugnodes = {"kartdebugnodes", "Off", CV_NOSHOWHELP, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; diff --git a/src/d_netcmd.h b/src/d_netcmd.h index 2269996fb..f78ba3097 100644 --- a/src/d_netcmd.h +++ b/src/d_netcmd.h @@ -126,6 +126,7 @@ extern consvar_t cv_karteliminatelast; extern consvar_t cv_votetime; extern consvar_t cv_kartdebugitem, cv_kartdebugamount, cv_kartdebugshrink, cv_kartdebugdistribution, cv_kartdebughuddrop; +extern consvar_t cv_kartdebugwaypoints; extern consvar_t cv_kartdebugcheckpoint, cv_kartdebugnodes; extern consvar_t cv_itemfinder; diff --git a/src/info.c b/src/info.c index b0eaa85b5..f111fa950 100644 --- a/src/info.c +++ b/src/info.c @@ -16029,7 +16029,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = { // MT_WAYPOINT 2001, // doomednum - S_NULL, // spawnstate + S_INVISIBLE, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound diff --git a/src/k_kart.c b/src/k_kart.c index 51763384a..1167b22a6 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -440,6 +440,7 @@ void K_RegisterKartStuff(void) CV_RegisterVar(&cv_kartdebugshrink); CV_RegisterVar(&cv_kartdebugdistribution); CV_RegisterVar(&cv_kartdebughuddrop); + CV_RegisterVar(&cv_kartdebugwaypoints); CV_RegisterVar(&cv_kartdebugcheckpoint); CV_RegisterVar(&cv_kartdebugnodes); diff --git a/src/k_waypoint.c b/src/k_waypoint.c index 0491c23a0..7bfb1bcb3 100644 --- a/src/k_waypoint.c +++ b/src/k_waypoint.c @@ -1,6 +1,7 @@ #include "k_waypoint.h" #include "doomdef.h" +#include "d_netcmd.h" #include "p_local.h" #include "p_mobj.h" #include "p_tick.h" @@ -11,6 +12,146 @@ static waypoint_t *firstwaypoint = NULL; static size_t numwaypoints = 0; static size_t numwaypointmobjs = 0; +#define SPARKLES_PER_CONNECTION 16 + +/*-------------------------------------------------- + void K_DebugWaypointsSpawnLine(waypoint_t * const waypoint1, waypoint_t * const waypoint2) + + Draw a debugging line between 2 waypoints + + Input Arguments:- + waypoint1 - A waypoint to draw the line between + waypoint2 - The other waypoint to draw the line between +--------------------------------------------------*/ +static void K_DebugWaypointsSpawnLine(waypoint_t * const waypoint1, waypoint_t * const waypoint2) +{ + mobj_t *waypointmobj1, *waypointmobj2; + mobj_t *spawnedmobj; + fixed_t stepx, stepy, stepz; + fixed_t x, y, z; + INT32 n; + + // Error conditions + if (waypoint1 == NULL || waypoint2 == NULL) + { + CONS_Debug(DBG_GAMELOGIC, "NULL waypoint in K_DebugWaypointsSpawnLine.\n"); + return; + } + if (waypoint1->mobj == NULL || waypoint2->mobj == NULL) + { + CONS_Debug(DBG_GAMELOGIC, "NULL mobj on waypoint in K_DebugWaypointsSpawnLine.\n"); + return; + } + if (cv_kartdebugwaypoints.value == 0) + { + CONS_Debug(DBG_GAMELOGIC, "In K_DebugWaypointsSpawnLine when kartdebugwaypoints is off.\n"); + return; + } + + waypointmobj1 = waypoint1->mobj; + waypointmobj2 = waypoint2->mobj; + + n = SPARKLES_PER_CONNECTION; + + // Draw the sparkles + stepx = (waypointmobj2->x - waypointmobj1->x) / n; + stepy = (waypointmobj2->y - waypointmobj1->y) / n; + stepz = (waypointmobj2->z - waypointmobj1->z) / n; + x = waypointmobj1->x; + y = waypointmobj1->y; + z = waypointmobj1->z; + do + { + spawnedmobj = P_SpawnMobj(x, y, z, MT_SPARK); + P_SetMobjState(spawnedmobj, S_SPRK1 + ((leveltime + n) % 16)); + spawnedmobj->state->nextstate = S_NULL; + spawnedmobj->state->tics = 1; + x += stepx; + y += stepy; + z += stepz; + } while (n--); +} + +#undef DEBUG_SPARKLE_DISTANCE + +/*-------------------------------------------------- + void K_DebugWaypointsVisualise() + + See header file for description. +--------------------------------------------------*/ +void K_DebugWaypointsVisualise(void) +{ + mobj_t *waypointmobj; + mobj_t *debugmobj; + waypoint_t *waypoint; + waypoint_t *otherwaypoint; + UINT32 i; + + if (waypointcap == NULL) + { + // No point putting a debug message here when it could easily happen when turning on the cvar in battle + return; + } + if (cv_kartdebugwaypoints.value == 0) + { + // Going to nip this in the bud and say no drawing all this without the cvar, it's not particularly optimised + return; + } + + // Hunt through the waypointcap so we can show all waypoint mobjs and not just ones that were able to be graphed + for (waypointmobj = waypointcap; waypointmobj != NULL; waypointmobj = waypointmobj->tracer) + { + waypoint = K_SearchWaypointHeapForMobj(waypointmobj); + + debugmobj = P_SpawnMobj(waypointmobj->x, waypointmobj->y, waypointmobj->z, MT_SPARK); + P_SetMobjState(debugmobj, S_THOK); + + // There's a waypoint setup for this mobj! So draw that it's a valid waypoint and draw lines to its connections + if (waypoint != NULL) + { + if (waypoint->numnextwaypoints == 0 || waypoint->numprevwaypoints == 0) + { + debugmobj->color = SKINCOLOR_ORANGE; + } + else + { + debugmobj->color = SKINCOLOR_BLUE; + } + + // Valid waypoint, so draw lines of SPARKLES to its next or previous waypoints + if (cv_kartdebugwaypoints.value == 1) + { + for (i = 0; i < waypoint->numnextwaypoints; i++) + { + if (waypoint->nextwaypoints[i] != NULL) + { + otherwaypoint = waypoint->nextwaypoints[i]; + K_DebugWaypointsSpawnLine(waypoint, otherwaypoint); + } + } + } + else if (cv_kartdebugwaypoints.value == 2) + { + for (i = 0; i < waypoint->numprevwaypoints; i++) + { + if (waypoint->prevwaypoints[i] != NULL) + { + otherwaypoint = waypoint->prevwaypoints[i]; + K_DebugWaypointsSpawnLine(waypoint, otherwaypoint); + } + } + } + } + else + { + debugmobj->color = SKINCOLOR_RED; + } + debugmobj->state->tics = 1; + debugmobj->state->nextstate = S_NULL; + } +} + + /*-------------------------------------------------- waypoint_t *K_SearchWaypoints(waypoint_t *waypoint, mobj_t * const mobj, boolean * const visitedarray) @@ -282,7 +423,7 @@ static waypoint_t *K_MakeWaypoint(mobj_t *mobj) } if (waypointcap == NULL) { - CONS_Debug(DBG_SETUP, "K_MakeWaypoint called with NULL waypointcap."); + CONS_Debug(DBG_SETUP, "K_MakeWaypoint called with NULL waypointcap.\n"); return false; } @@ -341,7 +482,7 @@ static waypoint_t *K_SetupWaypoint(mobj_t *mobj) } if (waypointcap == NULL) { - CONS_Debug(DBG_SETUP, "K_SetupWaypoint called with NULL waypointcap."); + CONS_Debug(DBG_SETUP, "K_SetupWaypoint called with NULL waypointcap.\n"); return false; } @@ -391,14 +532,14 @@ static waypoint_t *K_SetupWaypoint(mobj_t *mobj) } /*-------------------------------------------------- - static boolean K_AllocateWaypointHeap() + static boolean K_AllocateWaypointHeap(void) 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. --------------------------------------------------*/ -boolean K_AllocateWaypointHeap() +static boolean K_AllocateWaypointHeap(void) { mobj_t *waypointmobj = NULL; boolean allocationsuccessful = false; @@ -406,12 +547,12 @@ boolean K_AllocateWaypointHeap() // Error conditions if (waypointheap != NULL) { - CONS_Debug(DBG_SETUP, "K_AllocateWaypointHeap called when waypointheap is already allocated."); + CONS_Debug(DBG_SETUP, "K_AllocateWaypointHeap called when waypointheap is already allocated.\n"); return false; } if (waypointcap == NULL) { - CONS_Debug(DBG_SETUP, "K_AllocateWaypointHeap called with NULL waypointcap."); + CONS_Debug(DBG_SETUP, "K_AllocateWaypointHeap called with NULL waypointcap.\n"); return false; } @@ -448,25 +589,25 @@ boolean K_AllocateWaypointHeap() } else { - CONS_Debug(DBG_SETUP, "No waypoint mobjs in waypointcap."); + CONS_Debug(DBG_SETUP, "No waypoint mobjs in waypointcap.\n"); } return allocationsuccessful; } /*-------------------------------------------------- - void K_FreeWaypoints() + void K_FreeWaypoints(void) 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() +static void K_FreeWaypoints(void) { if (waypointheap != NULL) { // Free each waypoint if it's not already - INT32 i; + UINT32 i; for (i = 0; i < numwaypoints; i++) { if (waypointheap[i] != NULL) @@ -475,7 +616,7 @@ void K_FreeWaypoints() } else { - CONS_Debug(DBG_SETUP, "NULL waypoint %d attempted to be freed.", i); + CONS_Debug(DBG_SETUP, "NULL waypoint %d attempted to be freed.\n", i); } } @@ -487,11 +628,11 @@ void K_FreeWaypoints() } /*-------------------------------------------------- - boolean K_SetupWaypointList() + boolean K_SetupWaypointList(void) See header file for description. --------------------------------------------------*/ -boolean K_SetupWaypointList() +boolean K_SetupWaypointList(void) { boolean setupsuccessful = false; @@ -517,7 +658,7 @@ boolean K_SetupWaypointList() 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.", + CONS_Printf("Not all waypoints in the map are connected! %zu waypoints setup but %zu mobjs.\n", numwaypoints, numwaypointmobjs); } setupsuccessful = true; @@ -529,11 +670,11 @@ boolean K_SetupWaypointList() } /*-------------------------------------------------- - void K_ClearWaypoints() + void K_ClearWaypoints(void) See header file for description. --------------------------------------------------*/ -void K_ClearWaypoints() +void K_ClearWaypoints(void) { waypointheap = NULL; numwaypoints = 0; diff --git a/src/k_waypoint.h b/src/k_waypoint.h index 9184ce103..21cf43b5e 100644 --- a/src/k_waypoint.h +++ b/src/k_waypoint.h @@ -7,13 +7,13 @@ typedef struct waypoint_s { mobj_t *mobj; - UINT32 id; + size_t id; struct waypoint_s **nextwaypoints; struct waypoint_s **prevwaypoints; fixed_t *nextwaypointdistances; fixed_t *prevwaypointdistances; - UINT32 numnextwaypoints; - UINT32 numprevwaypoints; + size_t numnextwaypoints; + size_t numprevwaypoints; } waypoint_t; @@ -54,7 +54,16 @@ waypoint_t *K_SearchWaypointHeapForMobj(mobj_t * const mobj); /*-------------------------------------------------- - boolean K_SetupWaypointList() + void K_DebugWaypointsVisualise() + + Creates mobjs in order to visualise waypoints for debugging. +--------------------------------------------------*/ + +void K_DebugWaypointsVisualise(void); + + +/*-------------------------------------------------- + boolean K_SetupWaypointList(void) Sets up the waypoint list for Kart race maps, prints out warnings if something is wrong. @@ -67,7 +76,7 @@ boolean K_SetupWaypointList(void); /*-------------------------------------------------- - void K_ClearWaypoints() + void K_ClearWaypoints(void) 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 diff --git a/src/p_tick.c b/src/p_tick.c index b46b248bb..8509a7621 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -22,6 +22,7 @@ #include "lua_script.h" #include "lua_hook.h" #include "k_kart.h" +#include "k_waypoint.h" // Object place #include "m_cheat.h" @@ -714,6 +715,11 @@ void P_Ticker(boolean run) && --mapreset <= 1 && server) // Remember: server uses it for mapchange, but EVERYONE ticks down for the animation D_MapChange(gamemap, gametype, encoremode, true, 0, false, false); + + if (cv_kartdebugwaypoints.value != 0) + { + K_DebugWaypointsVisualise(); + } } // Always move the camera.