- added some comments about the special player treatment in hub travels because this is not really intuitive...

This commit is contained in:
Christoph Oelckers 2016-09-23 18:12:38 +02:00
parent 01d28e3eb2
commit b844ab137e
2 changed files with 13 additions and 4 deletions

View file

@ -209,7 +209,6 @@ enum EObjectFlags
OF_JustSpawned = 1 << 8, // Thinker was spawned this tic OF_JustSpawned = 1 << 8, // Thinker was spawned this tic
OF_SerialSuccess = 1 << 9, // For debugging Serialize() calls OF_SerialSuccess = 1 << 9, // For debugging Serialize() calls
OF_Sentinel = 1 << 10, // Object is serving as the sentinel in a ring list OF_Sentinel = 1 << 10, // Object is serving as the sentinel in a ring list
OF_LoadedPlayer = 1 << 11, // this gets flagged during deserialization so that the player checks in there can be simplified.
}; };
template<class T> class TObjPtr; template<class T> class TObjPtr;

View file

@ -818,7 +818,7 @@ void FSerializer::ReadObjects(bool hubtravel)
{ {
DThinker::bSerialOverride = true; DThinker::bSerialOverride = true;
r->mDObjects.Resize(ArraySize()); r->mDObjects.Resize(ArraySize());
// First create all the objects // First iteration: create all the objects but do nothing with them yet.
for (unsigned i = 0; i < r->mDObjects.Size(); i++) for (unsigned i = 0; i < r->mDObjects.Size(); i++)
{ {
if (BeginObject(nullptr)) if (BeginObject(nullptr))
@ -833,6 +833,7 @@ void FSerializer::ReadObjects(bool hubtravel)
Printf("Unknown object class '%d' in savegame", clsname.GetChars()); Printf("Unknown object class '%d' in savegame", clsname.GetChars());
founderrors = true; founderrors = true;
r->mDObjects[i] = RUNTIME_CLASS(AActor)->CreateNew(); // make sure we got at least a valid pointer for the duration of the loading process. r->mDObjects[i] = RUNTIME_CLASS(AActor)->CreateNew(); // make sure we got at least a valid pointer for the duration of the loading process.
r->mDObjects[i]->Destroy(); // but we do not want to keep this around, so destroy it right away.
} }
else else
{ {
@ -859,8 +860,7 @@ void FSerializer::ReadObjects(bool hubtravel)
int pindex = -1; int pindex = -1;
if (hubtravel) if (hubtravel)
{ {
// mark this as a hub travelling player. This needs to be taken care of later and be replaced with the real travelling player, // mark this as a hub travelling player. This needs to be substituted later, but that's better done when all objects have been loaded.
// but that's better done at the end of this loop so that inventory ownership is not getting messed up.
Serialize(*this, "playerindex", pindex, nullptr); Serialize(*this, "playerindex", pindex, nullptr);
if (hubtravel && pindex >= 0 && pindex < MAXPLAYERS) if (hubtravel && pindex >= 0 && pindex < MAXPLAYERS)
{ {
@ -885,6 +885,16 @@ void FSerializer::ReadObjects(bool hubtravel)
} }
EndArray(); EndArray();
// Special treatment for hub travel: We do not want the player pawn which exited the level when this snapshot was made
// but the one that got freshly created when the map was loaded in P_SetupLevel.
// The loop above marked all objects that represent a player, so now we go through them, and if a corresponding
// player had been spawned on map load it gets substituted here.
// The substitution does not take place inside the above loop to ensure that no changes to the loaded objects
// can occur afterward. At this point everything has been loaded and the substitution is a simple matter of
// calling DObject::StaticPointerSubstitution.
// If no corresponding player can be founded among the freshly spawned ones, the one from the snapshot is kept.
if (hubtravel) if (hubtravel)
{ {
for (int i = 0; i < MAXPLAYERS; i++) for (int i = 0; i < MAXPLAYERS; i++)