- completely eliminated the horrible fudging that went on with players during hub travel. This means that DestroyMostThinkers and the player substitution mechanism in the object deserializer are gone now.

I wish I had realized this the last time it came up - it would have saved me a lot of trouble.
But as it turns out, the more recent travelling code makes all of this completely unnecessary, working perfectly fine with deleting the player pawns along with the rest of the thinkers before loading the stored ones from the savegame (and getting rid of those in G_FinishTravel.)
And with a sane savegame format that does not depend on side effects from how the thinker serializing handled linking into the lists the old code was even harmful, leaving voodoo dolls behind.
I had the exact same effect when I tried to reshuffle some things for reliably restoring portals, but did not make the connection to interference between two mutually incompatible player travelling mechanisms that just worked by sheer happenstance with the original order of things.
This commit is contained in:
Christoph Oelckers 2016-09-23 23:03:11 +02:00
commit 69291b9cf9
4 changed files with 1 additions and 114 deletions

View file

@ -332,24 +332,6 @@ void DThinker::DestroyAllThinkers ()
GC::FullGC();
}
// Destroy all thinkers except for player-controlled actors
// Players are simply removed from the list of thinkers and
// will be added back after serialization is complete.
void DThinker::DestroyMostThinkers ()
{
int i;
for (i = 0; i <= MAX_STATNUM; i++)
{
if (i != STAT_TRAVELLING)
{
DestroyMostThinkersInList (Thinkers[i], i);
DestroyMostThinkersInList (FreshThinkers[i], i);
}
}
GC::FullGC();
}
void DThinker::DestroyThinkersInList (FThinkerList &list)
{
if (list.Sentinel != NULL)
@ -364,39 +346,6 @@ void DThinker::DestroyThinkersInList (FThinkerList &list)
}
}
void DThinker::DestroyMostThinkersInList (FThinkerList &list, int stat)
{
if (stat != STAT_PLAYER)
{
DestroyThinkersInList (list);
}
else if (list.Sentinel != NULL)
{ // If it's a voodoo doll, destroy it. Otherwise, simply remove
// it from the list. G_FinishTravel() will find it later from
// a players[].mo link and destroy it then, after copying various
// information to a new player.
for (DThinker *probe = list.Sentinel->NextThinker; probe != list.Sentinel; probe = list.Sentinel->NextThinker)
{
if (!probe->IsKindOf(RUNTIME_CLASS(APlayerPawn)) || // <- should not happen
static_cast<AActor *>(probe)->player == NULL ||
static_cast<AActor *>(probe)->player->mo != probe)
{
probe->Destroy();
}
else
{
probe->Remove();
// Technically, this doesn't need to be in any list now, since
// it's only going to be found later and destroyed before ever
// needing to tick again, but by moving it to a separate list,
// I can keep my debug assertions that all thinkers are either
// euthanizing or in a list.
Thinkers[MAX_STATNUM+1].AddTail(probe);
}
}
}
}
void DThinker::RunThinkers ()
{
int i, count;