From 48430d9b1a648508f068b7714b68e6cb32a8bfba Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 25 Aug 2016 21:15:53 +0200 Subject: [PATCH 1/2] - don't assume that deserializing an actor will result in a valid pointer. This addresses a very strange crash I encounteded while travelling in a hub, and ended up with a NULL pointer after the 'Serialize' call which means that some code cleared the variable that is currently being deserialized. I was completely unable to find out what caused this because there is so much recursion going on in the deserializer. All actions on the deserialized actor are now being done with a local copy of that variable so that altering the actual one won't have any adverse effects. --- src/farchive.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/farchive.cpp b/src/farchive.cpp index 6697fd5b7..317abe702 100644 --- a/src/farchive.cpp +++ b/src/farchive.cpp @@ -1194,6 +1194,7 @@ FArchive &FArchive::ReadObject (DObject* &obj, PClass *wanttype) const PClass *type; BYTE playerNum; DWORD index; + DObject *newobj; operator<< (objHead); @@ -1255,11 +1256,11 @@ FArchive &FArchive::ReadObject (DObject* &obj, PClass *wanttype) case NEW_CLS_OBJ: type = ReadClass (wanttype); // Printf ("New class: %s (%u)\n", type->Name, m_File->Tell()); - obj = type->CreateNew (); + newobj = obj = type->CreateNew (); MapObject (obj); - obj->SerializeUserVars (*this); - obj->Serialize (*this); - obj->CheckIfSerialized (); + newobj->SerializeUserVars (*this); + newobj->Serialize (*this); + newobj->CheckIfSerialized (); break; case NEW_PLYR_OBJ: From 9ca6764556aa07e94d5928ae7a8ad7d0b5aaed82 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 25 Aug 2016 21:41:17 +0200 Subject: [PATCH 2/2] Revert "- removed STAT_INVENTORY." This reverts commit 5ff0abe5681a519f05c1339c6d01e3e970178a81. - use STAT_INVENTORY only for held items. Seems this was causing some strange issues with hubs, but for items placed in the world it still cannot be allowed to have them in a different statnum. --- src/g_level.cpp | 2 +- src/g_shared/a_pickups.cpp | 2 ++ src/statnums.h | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/g_level.cpp b/src/g_level.cpp index 349d8f5a6..e47cbb4a5 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -1280,7 +1280,7 @@ void G_FinishTravel () for (inv = pawn->Inventory; inv != NULL; inv = inv->Inventory) { - inv->ChangeStatNum (STAT_DEFAULT); + inv->ChangeStatNum (STAT_INVENTORY); inv->LinkToWorld (); inv->Travelled (); } diff --git a/src/g_shared/a_pickups.cpp b/src/g_shared/a_pickups.cpp index e41a91d2f..c72366201 100644 --- a/src/g_shared/a_pickups.cpp +++ b/src/g_shared/a_pickups.cpp @@ -821,6 +821,7 @@ void AInventory::BecomeItem () } RemoveFromHash (); flags &= ~MF_SPECIAL; + ChangeStatNum(STAT_INVENTORY); SetState (FindState("Held")); } @@ -847,6 +848,7 @@ void AInventory::BecomePickup () } flags = (GetDefault()->flags | MF_DROPPED) & ~MF_COUNTITEM; renderflags &= ~RF_INVISIBLE; + ChangeStatNum(STAT_DEFAULT); SetState (SpawnState); } diff --git a/src/statnums.h b/src/statnums.h index 45bb53e65..7f691e232 100644 --- a/src/statnums.h +++ b/src/statnums.h @@ -53,7 +53,7 @@ enum STAT_BOSSTARGET, // A boss brain target STAT_LIGHTNING, // The lightning thinker STAT_DECALTHINKER, // An object that thinks for a decal - UNUSED_STAT_INVENTORY, // An inventory item (value kept for savegame compatibility.) + STAT_INVENTORY, // An inventory item STAT_LIGHT, // A sector light effect STAT_LIGHTTRANSFER, // A sector light transfer. These must be ticked after the light effects!!! STAT_EARTHQUAKE, // Earthquake actors