- 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)
This commit is contained in:
Randy Heit 2008-07-06 03:52:53 +00:00
parent 448b8955c5
commit 87d7b3601a
5 changed files with 66 additions and 49 deletions

View file

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

View file

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

View file

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

View file

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

View file

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