- Fixed: DThinker::SerializeAll() did not serialize any thinkers in the

FreshThinkers lists. These thinkers would still be saved in the savegame if
  there were other references to them, but they would not go in any thinker
  lists when loading the savegame. An easy way to exercise this bug is to
  give yourself something new with the console and then save the game right
  away without closing the console by using the "save" command. The item
  would be stored in the savegame thanks to its presence in the Inventory
  list, but it wouldn't be in a thinker list when the game was reloaded
  because it was still in the FreshThinkers list when the game was saved.


SVN r763 (trunk)
This commit is contained in:
Randy Heit 2008-02-22 01:45:32 +00:00
parent 0dccb97819
commit 60472c2b45
4 changed files with 44 additions and 22 deletions

View file

@ -1,4 +1,13 @@
February 21, 2008
- Fixed: DThinker::SerializeAll() did not serialize any thinkers in the
FreshThinkers lists. These thinkers would still be saved in the savegame if
there were other references to them, but they would not go in any thinker
lists when loading the savegame. An easy way to exercise this bug is to
give yourself something new with the console and then save the game right
away without closing the console by using the "save" command. The item
would be stored in the savegame thanks to its presence in the Inventory
list, but it wouldn't be in a thinker list when the game was reloaded
because it was still in the FreshThinkers list when the game was saved.
- Fixed: PO_Busy() did not check for a NULL return from GetPolyobj().
- Fixed two problems with printfs from the net controller stuff: one of them
is totally valid, and the other is GCC not being as nice as VC++.

View file

@ -52,9 +52,21 @@ List DThinker::Thinkers[MAX_STATNUM+1];
List DThinker::FreshThinkers[MAX_STATNUM+1];
bool DThinker::bSerialOverride = false;
void DThinker::SerializeAll (FArchive &arc, bool hubLoad)
void DThinker::SaveList(FArchive &arc, Node *node)
{
if (node->Succ != NULL)
{
do
{
DThinker *thinker = static_cast<DThinker *>(node);
arc << thinker;
node = node->Succ;
} while (node->Succ != NULL);
}
}
void DThinker::SerializeAll(FArchive &arc, bool hubLoad)
{
Node *node;
DThinker *thinker;
BYTE stat;
int statcount;
@ -67,29 +79,21 @@ void DThinker::SerializeAll (FArchive &arc, bool hubLoad)
// the thinker lists here instead of relying on the archiver to do it
// for us.
if (arc.IsStoring ())
if (arc.IsStoring())
{
for (statcount = i = 0; i <= MAX_STATNUM; i++)
{
if (!Thinkers[i].IsEmpty ())
{
statcount++;
}
statcount += (!Thinkers[i].IsEmpty() || !FreshThinkers[i].IsEmpty());
}
arc << statcount;
for (i = 0; i <= MAX_STATNUM; i++)
{
node = Thinkers[i].Head;
if (node->Succ != NULL)
if (!Thinkers[i].IsEmpty() || !FreshThinkers[i].IsEmpty())
{
stat = i;
arc << stat;
do
{
thinker = static_cast<DThinker *> (node);
arc << thinker;
node = node->Succ;
} while (node->Succ != NULL);
SaveList(arc, Thinkers[i].Head);
SaveList(arc, FreshThinkers[i].Head);
thinker = NULL;
arc << thinker; // Save a final NULL for this list
}
@ -98,9 +102,9 @@ void DThinker::SerializeAll (FArchive &arc, bool hubLoad)
else
{
if (hubLoad)
DestroyMostThinkers ();
DestroyMostThinkers();
else
DestroyAllThinkers ();
DestroyAllThinkers();
// Prevent the constructor from inserting thinkers into a list.
bSerialOverride = true;
@ -113,7 +117,16 @@ void DThinker::SerializeAll (FArchive &arc, bool hubLoad)
arc << stat << thinker;
while (thinker != NULL)
{
Thinkers[stat].AddTail (thinker);
// Thinkers with the OF_JustSpawned flag set go in the FreshThinkers
// list. Anything else goes in the regular Thinkers list.
if (thinker->ObjectFlags & OF_JustSpawned)
{
FreshThinkers[stat].AddTail(thinker);
}
else
{
Thinkers[stat].AddTail(thinker);
}
arc << thinker;
}
statcount--;
@ -122,7 +135,7 @@ void DThinker::SerializeAll (FArchive &arc, bool hubLoad)
catch (class CDoomError &)
{
bSerialOverride = false;
DestroyAllThinkers ();
DestroyAllThinkers();
throw;
}
bSerialOverride = false;

View file

@ -74,7 +74,7 @@ private:
static void DestroyThinkersInList (Node *first);
static void DestroyMostThinkersInList (List &list, int stat);
static int TickThinkers (List *list, List *dest); // Returns: # of thinkers ticked
static void SaveList(FArchive &arc, Node *node);
static List Thinkers[MAX_STATNUM+1]; // Current thinkers
static List FreshThinkers[MAX_STATNUM+1]; // Newly created thinkers

View file

@ -1257,9 +1257,9 @@ CCMD (printinv)
}
for (item = players[pnum].mo->Inventory; item != NULL; item = item->Inventory)
{
Printf ("%s #%u (%d/%d) <%p/%p>\n", item->GetClass()->TypeName.GetChars(),
Printf ("%s #%u (%d/%d)\n", item->GetClass()->TypeName.GetChars(),
item->InventoryID,
item->Amount, item->MaxAmount, static_cast<Node*>(item)->Pred, item->Succ);
item->Amount, item->MaxAmount);
}
}