From 6ce0c9f78ec92f3f579c727f9f4e3e03ef7e0fec Mon Sep 17 00:00:00 2001
From: Christoph Oelckers <c.oelckers@zdoom.fake>
Date: Wed, 10 Feb 2016 00:17:00 +0100
Subject: [PATCH] - split up PClass::Derive and its child functions because
 part of them is also needed when initializing an inherited native class with
 the properties of its parent - but calling the base version in PClass is not
 possible. - moved a few AActor properties out of the EXE so that I could
 easily test if it works.

---
 src/d_player.h                 |  2 +-
 src/dobjtype.cpp               |  1 +
 src/dobjtype.h                 |  5 +++--
 src/g_shared/a_pickups.cpp     | 12 ++++++------
 src/g_shared/a_pickups.h       | 11 +++++------
 src/g_shared/a_puzzleitems.cpp |  4 ++--
 src/g_shared/a_weapons.cpp     |  4 ++--
 src/info.cpp                   |  8 +-------
 src/info.h                     |  2 +-
 src/p_user.cpp                 |  4 ++--
 src/thingdef/thingdef.cpp      |  1 +
 wadsrc/static/actors/actor.txt |  4 ++++
 12 files changed, 29 insertions(+), 29 deletions(-)

diff --git a/src/d_player.h b/src/d_player.h
index 9a4e60d0f..60acb25d2 100644
--- a/src/d_player.h
+++ b/src/d_player.h
@@ -73,9 +73,9 @@ class PClassPlayerPawn : public PClassActor
 {
 	DECLARE_CLASS(PClassPlayerPawn, PClassActor);
 protected:
-	virtual void Derive(PClass *newclass);
 public:
 	PClassPlayerPawn();
+	virtual void DeriveData(PClass *newclass);
 	void EnumColorSets(TArray<int> *out);
 	FPlayerColorSet *GetColorSet(int setnum) { return ColorSets.CheckKey(setnum); }
 	void SetPainFlash(FName type, PalEntry color);
diff --git a/src/dobjtype.cpp b/src/dobjtype.cpp
index f16bd588d..1762079fb 100644
--- a/src/dobjtype.cpp
+++ b/src/dobjtype.cpp
@@ -2347,6 +2347,7 @@ PClass *PClass::CreateDerivedClass(FName name, unsigned int size)
 	type->Size = size;
 	type->bRuntimeClass = true;
 	Derive(type);
+	DeriveData(type);
 	if (!notnew)
 	{
 		type->InsertIntoHash();
diff --git a/src/dobjtype.h b/src/dobjtype.h
index 8e0331f2f..9ba327658 100644
--- a/src/dobjtype.h
+++ b/src/dobjtype.h
@@ -610,13 +610,14 @@ class PClass : public PStruct
 	DECLARE_CLASS(PClass, PStruct);
 	HAS_OBJECT_POINTERS;
 protected:
-	virtual void Derive(PClass *newclass);
 	// We unravel _WITH_META here just as we did for PType.
 	enum { MetaClassNum = CLASSREG_PClassClass };
+	virtual void Derive(PClass *newclass);
 public:
 	typedef PClassClass MetaClass;
 	MetaClass *GetClass() const;
 
+	virtual void DeriveData(PClass *newclass) {}
 	static void StaticInit();
 	static void StaticShutdown();
 	static void StaticBootstrap();
@@ -677,9 +678,9 @@ class PClassType : public PClass
 {
 	DECLARE_CLASS(PClassType, PClass);
 protected:
-	virtual void Derive(PClass *newclass);
 public:
 	PClassType();
+	virtual void Derive(PClass *newclass);
 
 	PClass *TypeTableType;	// The type to use for hashing into the type table
 };
diff --git a/src/g_shared/a_pickups.cpp b/src/g_shared/a_pickups.cpp
index f192f650f..c19564f78 100644
--- a/src/g_shared/a_pickups.cpp
+++ b/src/g_shared/a_pickups.cpp
@@ -30,10 +30,10 @@ PClassInventory::PClassInventory()
 	AltHUDIcon.SetNull();
 }
 
-void PClassInventory::Derive(PClass *newclass)
+void PClassInventory::DeriveData(PClass *newclass)
 {
 	assert(newclass->IsKindOf(RUNTIME_CLASS(PClassInventory)));
-	Super::Derive(newclass);
+	Super::DeriveData(newclass);
 	PClassInventory *newc = static_cast<PClassInventory *>(newclass);
 
 	newc->PickupMessage = PickupMessage;
@@ -60,10 +60,10 @@ PClassAmmo::PClassAmmo()
 	DropAmount = 0;
 }
 
-void PClassAmmo::Derive(PClass *newclass)
+void PClassAmmo::DeriveData(PClass *newclass)
 {
 	assert(newclass->IsKindOf(RUNTIME_CLASS(PClassAmmo)));
-	Super::Derive(newclass);
+	Super::DeriveData(newclass);
 	PClassAmmo *newc = static_cast<PClassAmmo *>(newclass);
 
 	newc->DropAmount = DropAmount;
@@ -1684,10 +1684,10 @@ PClassHealth::PClassHealth()
 //
 //===========================================================================
 
-void PClassHealth::Derive(PClass *newclass)
+void PClassHealth::DeriveData(PClass *newclass)
 {
 	assert(newclass->IsKindOf(RUNTIME_CLASS(PClassHealth)));
-	Super::Derive(newclass);
+	Super::DeriveData(newclass);
 	PClassHealth *newc = static_cast<PClassHealth *>(newclass);
 	
 	newc->LowHealth = LowHealth;
diff --git a/src/g_shared/a_pickups.h b/src/g_shared/a_pickups.h
index 9c9c1e48c..a927f1919 100644
--- a/src/g_shared/a_pickups.h
+++ b/src/g_shared/a_pickups.h
@@ -135,10 +135,9 @@ enum
 class PClassInventory : public PClassActor
 {
 	DECLARE_CLASS(PClassInventory, PClassActor)
-protected:
-	virtual void Derive(PClass *newclass);
 public:
 	PClassInventory();
+	virtual void DeriveData(PClass *newclass);
 	virtual void ReplaceClassRef(PClass *oldclass, PClass *newclass);
 
 	FString PickupMessage;
@@ -242,7 +241,7 @@ class PClassAmmo : public PClassInventory
 {
 	DECLARE_CLASS(PClassAmmo, PClassInventory)
 protected:
-	virtual void Derive(PClass *newclass);
+	virtual void DeriveData(PClass *newclass);
 public:
 	PClassAmmo();
 
@@ -267,7 +266,7 @@ class PClassWeapon : public PClassInventory
 {
 	DECLARE_CLASS(PClassWeapon, PClassInventory);
 protected:
-	virtual void Derive(PClass *newclass);
+	virtual void DeriveData(PClass *newclass);
 public:
 	PClassWeapon();
 	virtual void ReplaceClassRef(PClass *oldclass, PClass *newclass);
@@ -403,9 +402,9 @@ class PClassHealth : public PClassInventory
 {
 	DECLARE_CLASS(PClassHealth, PClassInventory)
 protected:
-	virtual void Derive(PClass *newclass);
 public:
 	PClassHealth();
+	virtual void DeriveData(PClass *newclass);
 
 	FString LowHealthMessage;
 	int LowHealth;
@@ -520,8 +519,8 @@ class PClassPuzzleItem : public PClassInventory
 {
 	DECLARE_CLASS(PClassPuzzleItem, PClassInventory);
 protected:
-	virtual void Derive(PClass *newclass);
 public:
+	virtual void DeriveData(PClass *newclass);
 	FString PuzzFailMessage;
 };
 
diff --git a/src/g_shared/a_puzzleitems.cpp b/src/g_shared/a_puzzleitems.cpp
index 0d60ab829..837ac3463 100644
--- a/src/g_shared/a_puzzleitems.cpp
+++ b/src/g_shared/a_puzzleitems.cpp
@@ -11,9 +11,9 @@
 
 IMPLEMENT_CLASS(PClassPuzzleItem)
 
-void PClassPuzzleItem::Derive(PClass *newclass)
+void PClassPuzzleItem::DeriveData(PClass *newclass)
 {
-	Super::Derive(newclass);
+	Super::DeriveData(newclass);
 	assert(newclass->IsKindOf(RUNTIME_CLASS(PClassPuzzleItem)));
 	static_cast<PClassPuzzleItem *>(newclass)->PuzzFailMessage = PuzzFailMessage;
 }
diff --git a/src/g_shared/a_weapons.cpp b/src/g_shared/a_weapons.cpp
index e7242ad3f..09ab0ffd8 100644
--- a/src/g_shared/a_weapons.cpp
+++ b/src/g_shared/a_weapons.cpp
@@ -44,10 +44,10 @@ PClassWeapon::PClassWeapon()
 	SlotPriority = FIXED_MAX;
 }
 
-void PClassWeapon::Derive(PClass *newclass)
+void PClassWeapon::DeriveData(PClass *newclass)
 {
 	assert(newclass->IsKindOf(RUNTIME_CLASS(PClassWeapon)));
-	Super::Derive(newclass);
+	Super::DeriveData(newclass);
 	PClassWeapon *newc = static_cast<PClassWeapon *>(newclass);
 
 	newc->SlotNumber = SlotNumber;
diff --git a/src/info.cpp b/src/info.cpp
index 1ca53470c..c2aff93d4 100644
--- a/src/info.cpp
+++ b/src/info.cpp
@@ -201,16 +201,11 @@ PClassActor::PClassActor()
 	FastSpeed = FIXED_MIN;
 	RDFactor = FRACUNIT;
 	CameraHeight = FIXED_MIN;
-	BloodType = NAME_Blood;
-	BloodType2 = NAME_BloodSplatter;
-	BloodType3 = NAME_AxeBlood;
 
 	DropItems = NULL;
 
 	DontHurtShooter = false;
-	ExplosionDamage = 128;
 	ExplosionRadius = -1;
-	MissileHeight = 32*FRACUNIT;
 	MeleeDamage = 0;
 
 	// Record this in the master list.
@@ -250,10 +245,9 @@ PClassActor::~PClassActor()
 //
 //==========================================================================
 
-void PClassActor::Derive(PClass *newclass)
+void PClassActor::DeriveData(PClass *newclass)
 {
 	assert(newclass->IsKindOf(RUNTIME_CLASS(PClassActor)));
-	Super::Derive(newclass);
 	PClassActor *newa = static_cast<PClassActor *>(newclass);
 
 	newa->Obituary = Obituary;
diff --git a/src/info.h b/src/info.h
index 52ccca305..9014a2f55 100644
--- a/src/info.h
+++ b/src/info.h
@@ -192,10 +192,10 @@ class PClassActor : public PClass
 	DECLARE_CLASS(PClassActor, PClass);
 	HAS_OBJECT_POINTERS;
 protected:
-	virtual void Derive(PClass *newclass);
 public:
 	static void StaticInit ();
 	static void StaticSetActorNums ();
+	virtual void DeriveData(PClass *newclass);
 
 	PClassActor();
 	~PClassActor();
diff --git a/src/p_user.cpp b/src/p_user.cpp
index e23ccff7b..59098e83a 100644
--- a/src/p_user.cpp
+++ b/src/p_user.cpp
@@ -515,10 +515,10 @@ PClassPlayerPawn::PClassPlayerPawn()
 	ColorRangeEnd = 0;
 }
 
-void PClassPlayerPawn::Derive(PClass *newclass)
+void PClassPlayerPawn::DeriveData(PClass *newclass)
 {
 	assert(newclass->IsKindOf(RUNTIME_CLASS(PClassPlayerPawn)));
-	Super::Derive(newclass);
+	Super::DeriveData(newclass);
 	PClassPlayerPawn *newp = static_cast<PClassPlayerPawn *>(newclass);
 	size_t i;
 
diff --git a/src/thingdef/thingdef.cpp b/src/thingdef/thingdef.cpp
index 30d94c6a3..99d46baca 100644
--- a/src/thingdef/thingdef.cpp
+++ b/src/thingdef/thingdef.cpp
@@ -137,6 +137,7 @@ PClassActor *CreateNewActor(const FScriptPosition &sc, FName typeName, FName par
 			goto create;
 		}
 		ti->InitializeNativeDefaults();
+		ti->ParentClass->DeriveData(ti);
 	}
 	else
 	{
diff --git a/wadsrc/static/actors/actor.txt b/wadsrc/static/actors/actor.txt
index 8677cfb82..8a79dd170 100644
--- a/wadsrc/static/actors/actor.txt
+++ b/wadsrc/static/actors/actor.txt
@@ -32,6 +32,10 @@ ACTOR Actor native //: Thinker
 	RipLevelMin 0
 	RipLevelMax 0
 	DefThreshold 100
+	BloodType "Blood", "BloodSplatter", "AxeBlood"
+	ExplosionDamage 128
+	MissileHeight 32
+	
 
 	// Functions
 	native bool CheckClass(class<Actor> checkclass, int ptr_select = AAPTR_DEFAULT, bool match_superclass = false);