From 776509e68aa696d4fba125c646c760f1ad8dc50d Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 7 Feb 2017 18:12:38 +0100 Subject: [PATCH] - let skip_super use the AActor assignment operator. The blanket memcpy it used was clobbering some data. - moved the Finalize method from PClassActor to AActor. Now that defaults get their vtbl pointer initialized this will actually work. --- src/actor.h | 1 + src/g_inventory/a_pickups.cpp | 4 ++-- src/g_inventory/a_pickups.h | 1 + src/g_inventory/a_weapons.cpp | 3 ++- src/g_inventory/a_weapons.h | 4 ++-- src/info.cpp | 8 ++++---- src/info.h | 1 - src/scripting/decorate/thingdef_parse.cpp | 2 +- src/scripting/thingdef_properties.cpp | 2 +- src/scripting/zscript/zcc_compile.cpp | 15 +-------------- 10 files changed, 15 insertions(+), 26 deletions(-) diff --git a/src/actor.h b/src/actor.h index 05b1aa076b..4016d447b4 100644 --- a/src/actor.h +++ b/src/actor.h @@ -596,6 +596,7 @@ public: AActor &operator= (const AActor &other); ~AActor (); + virtual void Finalize(FStateDefinitions &statedef); virtual void OnDestroy() override; virtual void Serialize(FSerializer &arc) override; virtual void PostSerialize() override; diff --git a/src/g_inventory/a_pickups.cpp b/src/g_inventory/a_pickups.cpp index fc35d2da4a..66f51e92ef 100644 --- a/src/g_inventory/a_pickups.cpp +++ b/src/g_inventory/a_pickups.cpp @@ -73,10 +73,10 @@ size_t PClassInventory::PointerSubstitution(DObject *oldclass, DObject *newclass return changed; } -void PClassInventory::Finalize(FStateDefinitions &statedef) +void AInventory::Finalize(FStateDefinitions &statedef) { Super::Finalize(statedef); - ((AActor*)Defaults)->flags |= MF_SPECIAL; + flags |= MF_SPECIAL; } IMPLEMENT_CLASS(AInventory, false, true) diff --git a/src/g_inventory/a_pickups.h b/src/g_inventory/a_pickups.h index 7ca317397a..be6280c0a7 100644 --- a/src/g_inventory/a_pickups.h +++ b/src/g_inventory/a_pickups.h @@ -72,6 +72,7 @@ class AInventory : public AActor HAS_OBJECT_POINTERS public: + virtual void Finalize(FStateDefinitions &statedef) override; virtual void Serialize(FSerializer &arc) override; virtual void MarkPrecacheSounds() const override; virtual void OnDestroy() override; diff --git a/src/g_inventory/a_weapons.cpp b/src/g_inventory/a_weapons.cpp index 24661dfd19..7c2a0fb815 100644 --- a/src/g_inventory/a_weapons.cpp +++ b/src/g_inventory/a_weapons.cpp @@ -155,13 +155,14 @@ void PClassWeapon::DeriveData(PClass *newclass) // //=========================================================================== -void PClassWeapon::Finalize(FStateDefinitions &statedef) +void AWeapon::Finalize(FStateDefinitions &statedef) { Super::Finalize(statedef); FState *ready = FindState(NAME_Ready); FState *select = FindState(NAME_Select); FState *deselect = FindState(NAME_Deselect); FState *fire = FindState(NAME_Fire); + auto TypeName = GetClass()->TypeName; // Consider any weapon without any valid state abstract and don't output a warning // This is for creating base classes for weapon groups that only set up some properties. diff --git a/src/g_inventory/a_weapons.h b/src/g_inventory/a_weapons.h index 21eaf9b890..b2eeaf9514 100644 --- a/src/g_inventory/a_weapons.h +++ b/src/g_inventory/a_weapons.h @@ -94,7 +94,6 @@ protected: virtual void DeriveData(PClass *newclass); public: PClassWeapon(); - void Finalize(FStateDefinitions &statedef); int SlotNumber; int SlotPriority; @@ -135,7 +134,8 @@ public: virtual void MarkPrecacheSounds() const; - virtual void Serialize(FSerializer &arc) override; + void Finalize(FStateDefinitions &statedef) override; + void Serialize(FSerializer &arc) override; void PostMorphWeapon(); diff --git a/src/info.cpp b/src/info.cpp index a424c890f7..c86486b5e0 100644 --- a/src/info.cpp +++ b/src/info.cpp @@ -429,20 +429,20 @@ void PClassActor::SetDropItems(DDropItem *drops) // //========================================================================== -void PClassActor::Finalize(FStateDefinitions &statedef) +void AActor::Finalize(FStateDefinitions &statedef) { - AActor *defaults = (AActor*)Defaults; + AActor *defaults = this; try { - statedef.FinishStates(this, defaults); + statedef.FinishStates(GetClass(), defaults); } catch (CRecoverableError &) { statedef.MakeStateDefines(NULL); throw; } - statedef.InstallStates(this, defaults); + statedef.InstallStates(GetClass(), defaults); statedef.MakeStateDefines(NULL); } diff --git a/src/info.h b/src/info.h index 4a6baa671f..3a20994f54 100644 --- a/src/info.h +++ b/src/info.h @@ -259,7 +259,6 @@ public: size_t PropagateMark(); bool SetReplacement(FName replaceName); void SetDropItems(DDropItem *drops); - virtual void Finalize(FStateDefinitions &statedef); FState *FindState(int numnames, FName *names, bool exact=false) const; FState *FindStateByString(const char *name, bool exact=false); diff --git a/src/scripting/decorate/thingdef_parse.cpp b/src/scripting/decorate/thingdef_parse.cpp index 505585937e..fc411186a6 100644 --- a/src/scripting/decorate/thingdef_parse.cpp +++ b/src/scripting/decorate/thingdef_parse.cpp @@ -1155,7 +1155,7 @@ static void ParseActor(FScanner &sc, PNamespace *ns) } try { - info->Finalize(bag.statedef); + GetDefaultByType(info)->Finalize(bag.statedef); } catch (CRecoverableError &err) { diff --git a/src/scripting/thingdef_properties.cpp b/src/scripting/thingdef_properties.cpp index 6823001475..4822a27b3e 100644 --- a/src/scripting/thingdef_properties.cpp +++ b/src/scripting/thingdef_properties.cpp @@ -560,7 +560,7 @@ DEFINE_PROPERTY(skip_super, 0, Actor) return; } - memcpy ((void *)defaults, (void *)GetDefault(), sizeof(AActor)); + *defaults = *GetDefault(); ResetBaggage (&bag, RUNTIME_CLASS(AActor)); } diff --git a/src/scripting/zscript/zcc_compile.cpp b/src/scripting/zscript/zcc_compile.cpp index 44428ab882..93f41746f2 100644 --- a/src/scripting/zscript/zcc_compile.cpp +++ b/src/scripting/zscript/zcc_compile.cpp @@ -2447,19 +2447,6 @@ void ZCCCompiler::CompileStates() continue; } - // Same here, hack in the DVMObject as they weren't in the list originally - // TODO: process them in a non hackish way obviously - if (c->Type()->bRuntimeClass == true && c->Type()->ParentClass->bRuntimeClass == false) - { - auto vmtype = static_cast(c->Type()->ParentClass); - if (vmtype->StateList == nullptr) - { - FStateDefinitions vmstates; - vmstates.MakeStateDefines(dyn_cast(vmtype->ParentClass)); - vmtype->Finalize(vmstates); - } - } - FString statename; // The state builder wants the label as one complete string, not separated into tokens. FStateDefinitions statedef; statedef.MakeStateDefines(dyn_cast(c->Type()->ParentClass)); @@ -2658,7 +2645,7 @@ void ZCCCompiler::CompileStates() } try { - static_cast(c->Type())->Finalize(statedef); + GetDefaultByType(c->Type())->Finalize(statedef); } catch (CRecoverableError &err) {