From 87d7b3601a000d9e59901d70f37ff6ee644f9619 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sun, 6 Jul 2008 03:52:53 +0000 Subject: [PATCH] - Added a check to G_DoSaveGame() to prevent saving when you're not actually in a level. - Fixed: Serialized player data must always be loaded, even if it's simply to be discarded, so that anything serialized after the players will load from the correct position in the file when revisiting a hub map. SVN r1069 (trunk) --- docs/rh-log.txt | 9 ++++- src/g_game.cpp | 7 ++++ src/g_level.cpp | 5 +-- src/p_saveg.cpp | 92 ++++++++++++++++++++++++++----------------------- src/p_saveg.h | 2 +- 5 files changed, 66 insertions(+), 49 deletions(-) diff --git a/docs/rh-log.txt b/docs/rh-log.txt index 5a3351cf2e..02252b94da 100644 --- a/docs/rh-log.txt +++ b/docs/rh-log.txt @@ -1,3 +1,10 @@ +July 5, 2008 +- Added a check to G_DoSaveGame() to prevent saving when you're not actually + in a level. +- Fixed: Serialized player data must always be loaded, even if it's simply to + be discarded, so that anything serialized after the players will load from + the correct position in the file when revisiting a hub map. + July 5, 2008 (Changes by Graf Zahl) - Changed: AInventory::Tick now only calls the super method if the item is not owned. Having owned inventory items interact with the world is not supposed @@ -16,7 +23,7 @@ July 5, 2008 (Changes by Graf Zahl) July 4, 2008 - Fixed: Screenwipes now pause sounds, since there can be sounds playing - during it. + during them. - UI sounds are now omitted from savegames. - Fixed: Menu sounds had been restricted to one at a time again. - Moved the P_SerializeSounds() call to the end of G_SerializeLevel() so that diff --git a/src/g_game.cpp b/src/g_game.cpp index 938a289918..dab6b5f4c0 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -1989,6 +1989,13 @@ static void PutSavePic (FILE *file, int width, int height) void G_DoSaveGame (bool okForQuicksave, FString filename, const char *description) { + // Do not even try, if we're not in a level. (Can happen after + // a demo finishes playback.) + if (lines == NULL || sectors == NULL) + { + return; + } + if (demoplayback) { filename = G_BuildSaveName ("demosave.zds", -1); diff --git a/src/g_level.cpp b/src/g_level.cpp index 657faff5ca..7befda5035 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -2860,10 +2860,7 @@ void G_SerializeLevel (FArchive &arc, bool hubLoad) FCanvasTextureInfo::Serialize (arc); AM_SerializeMarkers(arc); - if (!hubLoad) - { - P_SerializePlayers (arc); - } + P_SerializePlayers (arc, hubLoad); P_SerializeSounds (arc); } diff --git a/src/p_saveg.cpp b/src/p_saveg.cpp index 682d6963f9..596b1367ea 100644 --- a/src/p_saveg.cpp +++ b/src/p_saveg.cpp @@ -48,14 +48,14 @@ #include "r_interpolate.h" static void CopyPlayer (player_t *dst, player_t *src, const char *name); -static void ReadOnePlayer (FArchive &arc); -static void ReadMultiplePlayers (FArchive &arc, int numPlayers, int numPlayersNow); +static void ReadOnePlayer (FArchive &arc, bool skipload); +static void ReadMultiplePlayers (FArchive &arc, int numPlayers, int numPlayersNow, bool skipload); static void SpawnExtraPlayers (); // // P_ArchivePlayers // -void P_SerializePlayers (FArchive &arc) +void P_SerializePlayers (FArchive &arc, bool skipload) { BYTE numPlayers, numPlayersNow; int i; @@ -92,20 +92,20 @@ void P_SerializePlayers (FArchive &arc) // first player present, no matter what their name. if (numPlayers == 1) { - ReadOnePlayer (arc); + ReadOnePlayer (arc, skipload); } else { - ReadMultiplePlayers (arc, numPlayers, numPlayersNow); + ReadMultiplePlayers (arc, numPlayers, numPlayersNow, skipload); } - if (numPlayersNow > numPlayers) + if (!skipload && numPlayersNow > numPlayers) { SpawnExtraPlayers (); } } } -static void ReadOnePlayer (FArchive &arc) +static void ReadOnePlayer (FArchive &arc, bool skipload) { int i; char *name = NULL; @@ -122,7 +122,10 @@ static void ReadOnePlayer (FArchive &arc) didIt = true; player_t playerTemp; playerTemp.Serialize (arc); - CopyPlayer (&players[i], &playerTemp, name); + if (!skipload) + { + CopyPlayer (&players[i], &playerTemp, name); + } } else { @@ -137,7 +140,7 @@ static void ReadOnePlayer (FArchive &arc) delete[] name; } -static void ReadMultiplePlayers (FArchive &arc, int numPlayers, int numPlayersNow) +static void ReadMultiplePlayers (FArchive &arc, int numPlayers, int numPlayersNow, bool skipload) { // For two or more players, read each player into a temporary array. int i, j; @@ -158,36 +161,19 @@ static void ReadMultiplePlayers (FArchive &arc, int numPlayers, int numPlayersNo playerUsed[i] = playeringame[i] ? 0 : 2; } - // Now try to match players from the savegame with players present - // based on their names. If two players in the savegame have the - // same name, then they are assigned to players in the current game - // on a first-come, first-served basis. - for (i = 0; i < numPlayers; ++i) + if (!skipload) { - for (j = 0; j < MAXPLAYERS; ++j) - { - if (playerUsed[j] == 0 && stricmp(players[j].userinfo.netname, nametemp[i]) == 0) - { // Found a match, so copy our temp player to the real player - Printf ("Found player %d (%s) at %d\n", i, nametemp[i], j); - CopyPlayer (&players[j], &playertemp[i], nametemp[i]); - playerUsed[j] = 1; - tempPlayerUsed[i] = 1; - break; - } - } - } - - // Any players that didn't have matching names are assigned to existing - // players on a first-come, first-served basis. - for (i = 0; i < numPlayers; ++i) - { - if (tempPlayerUsed[i] == 0) + // Now try to match players from the savegame with players present + // based on their names. If two players in the savegame have the + // same name, then they are assigned to players in the current game + // on a first-come, first-served basis. + for (i = 0; i < numPlayers; ++i) { for (j = 0; j < MAXPLAYERS; ++j) { - if (playerUsed[j] == 0) - { - Printf ("Assigned player %d (%s) to %d (%s)\n", i, nametemp[i], j, players[j].userinfo.netname); + if (playerUsed[j] == 0 && stricmp(players[j].userinfo.netname, nametemp[i]) == 0) + { // Found a match, so copy our temp player to the real player + Printf ("Found player %d (%s) at %d\n", i, nametemp[i], j); CopyPlayer (&players[j], &playertemp[i], nametemp[i]); playerUsed[j] = 1; tempPlayerUsed[i] = 1; @@ -195,17 +181,37 @@ static void ReadMultiplePlayers (FArchive &arc, int numPlayers, int numPlayersNo } } } - } - // Make sure any extra players don't have actors spawned yet. - for (j = 0; j < MAXPLAYERS; ++j) - { - if (playerUsed[j] == 0) + // Any players that didn't have matching names are assigned to existing + // players on a first-come, first-served basis. + for (i = 0; i < numPlayers; ++i) { - if (players[j].mo != NULL) + if (tempPlayerUsed[i] == 0) { - players[j].mo->Destroy(); - players[j].mo = NULL; + for (j = 0; j < MAXPLAYERS; ++j) + { + if (playerUsed[j] == 0) + { + Printf ("Assigned player %d (%s) to %d (%s)\n", i, nametemp[i], j, players[j].userinfo.netname); + CopyPlayer (&players[j], &playertemp[i], nametemp[i]); + playerUsed[j] = 1; + tempPlayerUsed[i] = 1; + break; + } + } + } + } + + // Make sure any extra players don't have actors spawned yet. + for (j = 0; j < MAXPLAYERS; ++j) + { + if (playerUsed[j] == 0) + { + if (players[j].mo != NULL) + { + players[j].mo->Destroy(); + players[j].mo = NULL; + } } } } diff --git a/src/p_saveg.h b/src/p_saveg.h index edb73e67ee..09f5f28e21 100644 --- a/src/p_saveg.h +++ b/src/p_saveg.h @@ -39,7 +39,7 @@ // Persistent storage/archiving. // These are the load / save game routines. // Also see farchive.(h|cpp) -void P_SerializePlayers (FArchive &arc); +void P_SerializePlayers (FArchive &arc, bool fakeload); void P_SerializeWorld (FArchive &arc); void P_SerializeThinkers (FArchive &arc, bool); void P_SerializePolyobjs (FArchive &arc);