diff --git a/src/k_waypoint.c b/src/k_waypoint.c index f77e6d62f..a70e3a249 100644 --- a/src/k_waypoint.c +++ b/src/k_waypoint.c @@ -318,6 +318,16 @@ size_t K_GetWaypointHeapIndex(waypoint_t *waypoint) return waypointindex; } +/*-------------------------------------------------- + size_t K_GetNumWaypoints(void) + + See header file for description. +--------------------------------------------------*/ +size_t K_GetNumWaypoints(void) +{ + return numwaypoints; +} + /*-------------------------------------------------- waypoint_t *K_GetWaypointFromIndex(size_t waypointindex) @@ -1478,7 +1488,6 @@ static waypoint_t *K_MakeWaypoint(mobj_t *const mobj) I_Assert(waypointcap != NULL); // No waypoint mobjs in map load I_Assert(numwaypoints < numwaypointmobjs); // waypoint array reached max capacity - // numwaypoints is incremented later in K_SetupWaypoint madewaypoint = &waypointheap[numwaypoints]; numwaypoints++; diff --git a/src/k_waypoint.h b/src/k_waypoint.h index fb8d37f20..f1a678603 100644 --- a/src/k_waypoint.h +++ b/src/k_waypoint.h @@ -287,6 +287,16 @@ waypoint_t *K_SearchWaypointHeapForMobj(mobj_t * const mobj); --------------------------------------------------*/ size_t K_GetWaypointHeapIndex(waypoint_t *waypoint); +/*-------------------------------------------------- + size_t K_GetNumWaypoints(void) + + Returns the number of waypoints that are in the heap. + Intended for Net Archiving/Unarchiving + + Return:- + The number of waypoints in the heap +--------------------------------------------------*/ +size_t K_GetNumWaypoints(void); /*-------------------------------------------------- waypoint_t *K_GetWaypointFromIndex(size_t waypointindex) diff --git a/src/p_saveg.c b/src/p_saveg.c index ccae035ee..b65c0f17a 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -49,6 +49,7 @@ UINT8 *save_p; #define ARCHIVEBLOCK_POBJS 0x7F928546 #define ARCHIVEBLOCK_THINKERS 0x7F37037C #define ARCHIVEBLOCK_SPECIALS 0x7F228378 +#define ARCHIVEBLOCK_WAYPOINTS 0x7F46498F // Note: This cannot be bigger // than an UINT16 @@ -1908,6 +1909,49 @@ static void P_NetArchiveThinkers(void) WRITEUINT8(save_p, tc_end); } +static void P_NetArchiveWaypoints(void) +{ + waypoint_t *waypoint; + size_t i; + size_t numWaypoints = K_GetNumWaypoints(); + + WRITEUINT32(save_p, ARCHIVEBLOCK_WAYPOINTS); + WRITEUINT32(save_p, numWaypoints); + + for (i = 0U; i < numWaypoints; i++) { + waypoint = K_GetWaypointFromIndex(i); + + // The only thing we save for each waypoint is the mobj. + // Waypoints should NEVER be completely created or destroyed mid-race as a result of this + WRITEUINT32(save_p, waypoint->mobj->mobjnum); + } +} + +static void P_NetUnArchiveWaypoints(void) +{ + if (READUINT32(save_p) != ARCHIVEBLOCK_WAYPOINTS) + I_Error("Bad $$$.sav at archive block Waypoints!"); + else { + UINT32 numArchiveWaypoints = READUINT32(save_p); + size_t numSpawnedWaypoints = K_GetNumWaypoints(); + + if (numArchiveWaypoints != numSpawnedWaypoints) { + I_Error("Bad $$$.sav: More saved waypoints than created!"); + } else { + waypoint_t *waypoint; + UINT32 i; + UINT32 temp; + for (i = 0U; i < numArchiveWaypoints; i++) { + waypoint = K_GetWaypointFromIndex(i); + temp = READUINT32(save_p); + if (!P_SetTarget(&waypoint->mobj, P_FindNewPosition(temp))) { + CONS_Debug(DBG_GAMELOGIC, "waypoint mobj not found for %d\n", i); + } + } + } + } +} + // Now save the pointers, tracer and target, but at load time we must // relink to this; the savegame contains the old position in the pointer // field copyed in the info field temporarily, but finally we just search @@ -3526,6 +3570,7 @@ void P_SaveNetGame(void) #endif P_NetArchiveThinkers(); P_NetArchiveSpecials(); + P_NetArchiveWaypoints(); } #ifdef HAVE_BLUA LUA_Archive(); @@ -3570,6 +3615,7 @@ boolean P_LoadNetGame(void) #endif P_NetUnArchiveThinkers(); P_NetUnArchiveSpecials(); + P_NetUnArchiveWaypoints(); P_RelinkPointers(); P_FinishMobjs(); }