diff --git a/docs/rh-log.txt b/docs/rh-log.txt index 5adc22e0fb..b0ec5eab99 100644 --- a/docs/rh-log.txt +++ b/docs/rh-log.txt @@ -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++. diff --git a/src/dthinker.cpp b/src/dthinker.cpp index e1e6896a0f..fa6bfe0596 100644 --- a/src/dthinker.cpp +++ b/src/dthinker.cpp @@ -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(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 (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; diff --git a/src/dthinker.h b/src/dthinker.h index ae8989adc6..f7905c5b8d 100644 --- a/src/dthinker.h +++ b/src/dthinker.h @@ -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 diff --git a/src/g_shared/a_pickups.cpp b/src/g_shared/a_pickups.cpp index 9618c0950b..a7660bdfb8 100644 --- a/src/g_shared/a_pickups.cpp +++ b/src/g_shared/a_pickups.cpp @@ -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(item)->Pred, item->Succ); + item->Amount, item->MaxAmount); } }