From 604b5ef673d88bcf51fa5dbf3f06904f3b0a52f3 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 25 Mar 2010 20:38:00 +0000 Subject: [PATCH] - Removed the old meta data system. All meta data is now stored in subclasses of PClass. This should simplify scripting, since it means that meta fields can be treated (mostly) the same as normal fields. SVN r2242 (scripting) --- src/actor.h | 53 ++------ src/d_dehacked.cpp | 22 ++-- src/d_net.cpp | 14 +-- src/d_netinfo.cpp | 14 +-- src/d_player.h | 50 ++++---- src/dobject.cpp | 128 ------------------- src/dobject.h | 65 ++-------- src/dobjtype.cpp | 97 ++++++++------ src/dobjtype.h | 3 +- src/g_doom/a_bossbrain.cpp | 12 +- src/g_doom/a_doomweaps.cpp | 8 +- src/g_doom/a_revenant.cpp | 2 +- src/g_heretic/a_dsparil.cpp | 6 +- src/g_heretic/a_hereticweaps.cpp | 24 ++-- src/g_heretic/a_wizard.cpp | 2 +- src/g_hexen/a_bats.cpp | 2 +- src/g_hexen/a_clericholy.cpp | 7 +- src/g_hexen/a_fighterhammer.cpp | 2 +- src/g_hexen/a_healingradius.cpp | 7 +- src/g_hexen/a_heresiarch.cpp | 6 +- src/g_hexen/a_iceguy.cpp | 2 +- src/g_hexen/a_korax.cpp | 7 +- src/g_hexen/a_magelightning.cpp | 13 +- src/g_hexen/a_summon.cpp | 2 +- src/g_raven/a_minotaur.cpp | 2 +- src/g_shared/a_action.cpp | 4 +- src/g_shared/a_artifacts.cpp | 6 +- src/g_shared/a_fastprojectile.cpp | 2 +- src/g_shared/a_morph.cpp | 16 ++- src/g_shared/a_morph.h | 2 +- src/g_shared/a_pickups.cpp | 78 ++++++++++-- src/g_shared/a_pickups.h | 113 +++++++++++------ src/g_shared/a_puzzleitems.cpp | 17 ++- src/g_shared/a_randomspawner.cpp | 14 +-- src/g_shared/a_weaponpiece.h | 2 +- src/g_shared/a_weapons.cpp | 107 +++++++++------- src/g_shared/sbarinfo_commands.cpp | 2 +- src/g_shared/shared_hud.cpp | 29 ++--- src/g_strife/a_crusader.cpp | 12 +- src/g_strife/a_inquisitor.cpp | 4 +- src/g_strife/a_sentinel.cpp | 2 +- src/g_strife/a_strifeweapons.cpp | 16 +-- src/info.cpp | 65 +++++++++- src/info.h | 31 +++++ src/m_cheat.cpp | 8 +- src/m_cheat.h | 5 +- src/m_menu.cpp | 13 +- src/p_acs.cpp | 4 +- src/p_enemy.cpp | 9 +- src/p_interaction.cpp | 43 +++---- src/p_local.h | 18 +-- src/p_map.cpp | 10 +- src/p_mobj.cpp | 117 +++++++++-------- src/p_user.cpp | 116 ++++++++++------- src/r_main.cpp | 2 +- src/r_things.cpp | 43 +++---- src/textures/textures.h | 4 +- src/thingdef/olddecorations.cpp | 12 +- src/thingdef/thingdef.cpp | 12 +- src/thingdef/thingdef.h | 11 +- src/thingdef/thingdef_codeptr.cpp | 26 ++-- src/thingdef/thingdef_properties.cpp | 181 ++++++++++++++++----------- 62 files changed, 903 insertions(+), 803 deletions(-) diff --git a/src/actor.h b/src/actor.h index c16080f79..1dcf22c9b 100644 --- a/src/actor.h +++ b/src/actor.h @@ -492,48 +492,17 @@ struct line_t; struct secplane_t; struct FStrifeDialogueNode; -enum -{ - AMETA_BASE = 0x12000, - - AMETA_Obituary, // string (player was killed by this actor) - AMETA_HitObituary, // string (player was killed by this actor in melee) - AMETA_DeathHeight, // fixed (height on normal death) - AMETA_BurnHeight, // fixed (height on burning death) - AMETA_StrifeName, // string (for named Strife objects) - AMETA_BloodColor, // colorized blood - AMETA_GibHealth, // negative health below which this monster dies an extreme death - AMETA_WoundHealth, // health needed to enter wound state - AMETA_PoisonDamage, // Amount of poison damage - AMETA_FastSpeed, // Speed in fast mode - AMETA_RDFactor, // Radius damage factor - AMETA_CameraHeight, // Height of camera when used as such - AMETA_HowlSound, // Sound being played when electrocuted or poisoned - AMETA_BloodType, // Blood replacement type - AMETA_BloodType2, // Bloodsplatter replacement type - AMETA_BloodType3, // AxeBlood replacement type -}; - -struct FDropItem -{ - FName Name; - int probability; - int amount; - FDropItem * Next; -}; - -class FDropItemPtrArray : public TArray +class DDropItem : public DObject { + DECLARE_CLASS(DDropItem, DObject) + HAS_OBJECT_POINTERS public: - ~FDropItemPtrArray(); + DDropItem *Next; + FName Name; + int Probability; + int Amount; }; -extern FDropItemPtrArray DropItemList; - -void FreeDropItemChain(FDropItem *chain); -int StoreDropItemChain(FDropItem *chain); - - // Map Object definition. class AActor : public DThinker @@ -556,7 +525,7 @@ public: return (AActor *)(RUNTIME_TYPE(this)->Defaults); } - FDropItem *GetDropItems(); + DDropItem *GetDropItems() const; // Return true if the monster should use a missile attack, false for melee bool SuggestMissileAttack (fixed_t dist); @@ -702,7 +671,11 @@ public: void Crash(); // Return starting health adjusted by skill level - int SpawnHealth(); + int SpawnHealth() const; + + int GetGibHealth() const; + + fixed_t GetCameraHeight() const; // Check for monsters that count as kill but excludes all friendlies. bool CountsAsKill() const diff --git a/src/d_dehacked.cpp b/src/d_dehacked.cpp index fd2d23514..5a9e10145 100644 --- a/src/d_dehacked.cpp +++ b/src/d_dehacked.cpp @@ -142,7 +142,7 @@ struct StyleName static TArray StyleNames; -static TArray AmmoNames; +static TArray AmmoNames; static TArray WeaponNames; // DeHackEd trickery to support MBF-style parameters @@ -1869,18 +1869,14 @@ static int PatchMisc (int dummy) player->health = deh.StartHealth; // Hm... I'm not sure that this is the right way to change this info... - unsigned int index = PClass::FindClass(NAME_DoomPlayer)->Meta.GetMetaInt (ACMETA_DropItems) - 1; - if (index >= 0 && index < DropItemList.Size()) + DDropItem *di = PClass::FindActor(NAME_DoomPlayer)->DropItems; + while (di != NULL) { - FDropItem * di = DropItemList[index]; - while (di != NULL) + if (di->Name == NAME_Clip) { - if (di->Name == NAME_Clip) - { - di->amount = deh.StartBullets; - } - di = di->Next; + di->Amount = deh.StartBullets; } + di = di->Next; } } @@ -2780,12 +2776,12 @@ static bool LoadDehSupp () } else { - PClass *cls = PClass::FindClass(sc.String); - if (cls == NULL || cls->ParentClass != RUNTIME_CLASS(AAmmo)) + PClassAmmo *cls = dyn_cast(PClass::FindClass(sc.String)); + if (cls == NULL) { sc.ScriptError("Unknown ammo type '%s'", sc.String); } - AmmoNames.Push(static_cast(cls)); + AmmoNames.Push(cls); } if (sc.CheckString("}")) break; sc.MustGetStringName(","); diff --git a/src/d_net.cpp b/src/d_net.cpp index 6c874f7b9..226baf9ba 100644 --- a/src/d_net.cpp +++ b/src/d_net.cpp @@ -2099,7 +2099,7 @@ void Net_DoCommand (int type, BYTE **stream, int player) case DEM_SUMMONFRIEND2: case DEM_SUMMONFOE2: { - const PClass *typeinfo; + PClassActor *typeinfo; int angle = 0; SWORD tid = 0; BYTE special = 0; @@ -2114,8 +2114,8 @@ void Net_DoCommand (int type, BYTE **stream, int player) for(i = 0; i < 5; i++) args[i] = ReadLong(stream); } - typeinfo = PClass::FindClass (s); - if (typeinfo != NULL && typeinfo->IsKindOf(RUNTIME_CLASS(PClassActor))) + typeinfo = PClass::FindActor(s); + if (typeinfo != NULL) { AActor *source = players[player].mo; if (source != NULL) @@ -2318,7 +2318,7 @@ void Net_DoCommand (int type, BYTE **stream, int player) case DEM_MORPHEX: { s = ReadString (stream); - const char *msg = cht_Morph (players + player, PClass::FindClass (s), false); + const char *msg = cht_Morph (players + player, dyn_cast(PClass::FindClass (s)), false); if (player == consoleplayer) { Printf ("%s\n", *msg != '\0' ? msg : "Morph failed."); @@ -2383,7 +2383,7 @@ void Net_DoCommand (int type, BYTE **stream, int player) } for(int i = 0; i < count; ++i) { - PClassActor *wpn = Net_ReadWeapon(stream); + PClassWeapon *wpn = Net_ReadWeapon(stream); players[player].weapons.AddSlot(slot, wpn, player == consoleplayer); } } @@ -2392,7 +2392,7 @@ void Net_DoCommand (int type, BYTE **stream, int player) case DEM_ADDSLOT: { int slot = ReadByte(stream); - PClassActor *wpn = Net_ReadWeapon(stream); + PClassWeapon *wpn = Net_ReadWeapon(stream); players[player].weapons.AddSlot(slot, wpn, player == consoleplayer); } break; @@ -2400,7 +2400,7 @@ void Net_DoCommand (int type, BYTE **stream, int player) case DEM_ADDSLOTDEFAULT: { int slot = ReadByte(stream); - PClassActor *wpn = Net_ReadWeapon(stream); + PClassWeapon *wpn = Net_ReadWeapon(stream); players[player].weapons.AddSlotDefault(slot, wpn, player == consoleplayer); } break; diff --git a/src/d_netinfo.cpp b/src/d_netinfo.cpp index e31354a6e..608408627 100644 --- a/src/d_netinfo.cpp +++ b/src/d_netinfo.cpp @@ -169,9 +169,9 @@ int D_PlayerClassToInt (const char *classname) { for (unsigned int i = 0; i < PlayerClasses.Size (); ++i) { - const PClass *type = PlayerClasses[i].Type; + PClassPlayerPawn *type = PlayerClasses[i].Type; - if (stricmp (type->Meta.GetMetaString (APMETA_DisplayName), classname) == 0) + if (type->DisplayName.IsNotEmpty() && stricmp(type->DisplayName, classname) == 0) { return i; } @@ -556,7 +556,7 @@ void D_WriteUserInfoStrings (int i, BYTE **stream, bool compact) { userinfo_t *info = &players[i].userinfo; - const PClass *type = PlayerClasses[info->PlayerClass].Type; + PClassPlayerPawn *type = PlayerClasses[info->PlayerClass].Type; if (!compact) { @@ -582,8 +582,7 @@ void D_WriteUserInfoStrings (int i, BYTE **stream, bool compact) info->neverswitch, (float)(info->MoveBob) / 65536.f, (float)(info->StillBob) / 65536.f, - info->PlayerClass == -1 ? "Random" : - D_EscapeUserInfo(type->Meta.GetMetaString (APMETA_DisplayName)).GetChars() + info->PlayerClass == -1 ? "Random" : D_EscapeUserInfo(type->DisplayName).GetChars() ); } else @@ -611,8 +610,7 @@ void D_WriteUserInfoStrings (int i, BYTE **stream, bool compact) info->neverswitch, (float)(info->MoveBob) / 65536.f, (float)(info->StillBob) / 65536.f, - info->PlayerClass == -1 ? "Random" : - D_EscapeUserInfo(type->Meta.GetMetaString (APMETA_DisplayName)).GetChars() + info->PlayerClass == -1 ? "Random" : D_EscapeUserInfo(type->DisplayName).GetChars() ); } } @@ -837,7 +835,7 @@ CCMD (playerinfo) Printf ("MoveBob: %g\n", ui->MoveBob/65536.f); Printf ("StillBob: %g\n", ui->StillBob/65536.f); Printf ("PlayerClass: %s (%d)\n", - ui->PlayerClass == -1 ? "Random" : PlayerClasses[ui->PlayerClass].Type->Meta.GetMetaString (APMETA_DisplayName), + ui->PlayerClass == -1 ? "Random" : PlayerClasses[ui->PlayerClass].Type->DisplayName.GetChars(), ui->PlayerClass); if (argv.argc() > 2) PrintMiscActorInfo(players[i].mo); } diff --git a/src/d_player.h b/src/d_player.h index 3c9ad954c..75f0fbfa1 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -44,38 +44,30 @@ //Added by MC: #include "b_bot.h" -enum -{ - APMETA_BASE = 0x95000, - - APMETA_DisplayName, // display name (used in menus etc.) - APMETA_SoundClass, // sound class - APMETA_Face, // doom status bar face (when used) - APMETA_ColorRange, // skin color range - APMETA_InvulMode, - APMETA_HealingRadius, - APMETA_Hexenarmor0, - APMETA_Hexenarmor1, - APMETA_Hexenarmor2, - APMETA_Hexenarmor3, - APMETA_Hexenarmor4, - APMETA_Slot0, - APMETA_Slot1, - APMETA_Slot2, - APMETA_Slot3, - APMETA_Slot4, - APMETA_Slot5, - APMETA_Slot6, - APMETA_Slot7, - APMETA_Slot8, - APMETA_Slot9, -}; - class player_t; +class PClassPlayerPawn : public PClassActor +{ + DECLARE_CLASS(PClassPlayerPawn, PClassActor); +protected: + virtual void Derive(PClass *newclass); +public: + PClassPlayerPawn(); + + FString DisplayName; // Display name (used in menus, etc.) + FString SoundClass; // Sound class + FString Face; // Doom status bar face (when used) + FString Slot[10]; + FName InvulMode; + FName HealingRadiusType; + fixed_t HexenArmor[5]; + BYTE ColorRangeStart; // Skin color range + BYTE ColorRangeEnd; +}; + class APlayerPawn : public AActor { - DECLARE_CLASS (APlayerPawn, AActor) + DECLARE_CLASS_WITH_META(APlayerPawn, AActor, PClassPlayerPawn) HAS_OBJECT_POINTERS public: virtual void Serialize (FArchive &arc); @@ -431,7 +423,7 @@ public: bool CheckSkin (int skin); - const PClass *Type; + PClassPlayerPawn *Type; DWORD Flags; TArray Skins; }; diff --git a/src/dobject.cpp b/src/dobject.cpp index f34a577bb..2f5fd0cac 100644 --- a/src/dobject.cpp +++ b/src/dobject.cpp @@ -60,134 +60,6 @@ ClassReg DObject::RegistrationInfo = }; _DECLARE_TI(DObject) -FMetaTable::~FMetaTable () -{ - FreeMeta (); -} - -FMetaTable::FMetaTable (const FMetaTable &other) -{ - Meta = NULL; - CopyMeta (&other); -} - -FMetaTable &FMetaTable::operator = (const FMetaTable &other) -{ - CopyMeta (&other); - return *this; -} - -void FMetaTable::FreeMeta () -{ - while (Meta != NULL) - { - FMetaData *meta = Meta; - - switch (meta->Type) - { - case META_String: - delete[] meta->Value.String; - break; - default: - break; - } - Meta = meta->Next; - delete meta; - } -} - -void FMetaTable::CopyMeta (const FMetaTable *other) -{ - const FMetaData *meta_src; - FMetaData **meta_dest; - - FreeMeta (); - - meta_src = other->Meta; - meta_dest = &Meta; - while (meta_src != NULL) - { - FMetaData *newmeta = new FMetaData (meta_src->Type, meta_src->ID); - switch (meta_src->Type) - { - case META_String: - newmeta->Value.String = copystring (meta_src->Value.String); - break; - default: - newmeta->Value = meta_src->Value; - break; - } - *meta_dest = newmeta; - meta_dest = &newmeta->Next; - meta_src = meta_src->Next; - } - *meta_dest = NULL; -} - -FMetaData *FMetaTable::FindMeta (EMetaType type, DWORD id) const -{ - FMetaData *meta = Meta; - - while (meta != NULL) - { - if (meta->ID == id && meta->Type == type) - { - return meta; - } - meta = meta->Next; - } - return NULL; -} - -FMetaData *FMetaTable::FindMetaDef (EMetaType type, DWORD id) -{ - FMetaData *meta = FindMeta (type, id); - if (meta == NULL) - { - meta = new FMetaData (type, id); - meta->Next = Meta; - meta->Value.String = NULL; - Meta = meta; - } - return meta; -} - -void FMetaTable::SetMetaInt (DWORD id, int parm) -{ - FMetaData *meta = FindMetaDef (META_Int, id); - meta->Value.Int = parm; -} - -int FMetaTable::GetMetaInt (DWORD id, int def) const -{ - FMetaData *meta = FindMeta (META_Int, id); - return meta != NULL ? meta->Value.Int : def; -} - -void FMetaTable::SetMetaFixed (DWORD id, fixed_t parm) -{ - FMetaData *meta = FindMetaDef (META_Fixed, id); - meta->Value.Fixed = parm; -} - -fixed_t FMetaTable::GetMetaFixed (DWORD id, fixed_t def) const -{ - FMetaData *meta = FindMeta (META_Fixed, id); - return meta != NULL ? meta->Value.Fixed : def; -} - -void FMetaTable::SetMetaString (DWORD id, const char *parm) -{ - FMetaData *meta = FindMetaDef (META_String, id); - ReplaceString (&meta->Value.String, parm); -} - -const char *FMetaTable::GetMetaString (DWORD id) const -{ - FMetaData *meta = FindMeta (META_String, id); - return meta != NULL ? meta->Value.String : NULL; -} - CCMD (dumpclasses) { // This is by no means speed-optimized. But it's an informational console diff --git a/src/dobject.h b/src/dobject.h index 5b6d99e46..23c284513 100644 --- a/src/dobject.h +++ b/src/dobject.h @@ -80,56 +80,6 @@ class DPillar; class PClassActor; -enum EMetaType -{ - META_Int, // An int - META_Fixed, // A fixed point number - META_String, // A string -}; - -class FMetaData -{ -private: - FMetaData (EMetaType type, uint32 id) : Type(type), ID(id) {} - - FMetaData *Next; - EMetaType Type; - uint32 ID; - union - { - int Int; - char *String; - fixed_t Fixed; - } Value; - - friend class FMetaTable; -}; - -class FMetaTable -{ -public: - FMetaTable() : Meta(NULL) {} - FMetaTable(const FMetaTable &other); - ~FMetaTable(); - FMetaTable &operator = (const FMetaTable &other); - - void SetMetaInt (uint32 id, int parm); - void SetMetaFixed (uint32 id, fixed_t parm); - void SetMetaString (uint32 id, const char *parm); // The string is copied - - int GetMetaInt (uint32 id, int def=0) const; - fixed_t GetMetaFixed (uint32 id, fixed_t def=0) const; - const char *GetMetaString (uint32 id) const; - - FMetaData *FindMeta (EMetaType type, uint32 id) const; - -private: - FMetaData *Meta; - FMetaData *FindMetaDef (EMetaType type, uint32 id); - void FreeMeta (); - void CopyMeta (const FMetaTable *other); -}; - #define RUNTIME_TYPE(object) (object->GetClass()) // Passed an object, returns the type of that object #define RUNTIME_CLASS_CASTLESS(cls) (cls::RegistrationInfo.MyClass) // Passed a native class name, returns a PClass representing that class #define RUNTIME_CLASS(cls) ((cls::MetaClass *)RUNTIME_CLASS_CASTLESS(cls)) // Like above, but returns the true type of the meta object @@ -140,6 +90,12 @@ enum { CLASSREG_PClass, CLASSREG_PClassActor, + CLASSREG_PClassInventory, + CLASSREG_PClassAmmo, + CLASSREG_PClassHealth, + CLASSREG_PClassPuzzleItem, + CLASSREG_PClassWeapon, + CLASSREG_PClassPlayerPawn }; struct ClassReg @@ -149,8 +105,8 @@ struct ClassReg ClassReg *ParentType; const size_t *Pointers; void (*ConstructNative)(void *); - unsigned int SizeOf:31; - unsigned int MetaClassNum:1; + unsigned int SizeOf:29; + unsigned int MetaClassNum:3; PClass *RegisterClass(); }; @@ -159,7 +115,7 @@ enum EInPlace { EC_InPlace }; #define DECLARE_ABSTRACT_CLASS(cls,parent) \ public: \ - virtual PClass *StaticType() const { return RegistrationInfo.MyClass; } \ + virtual PClass *StaticType() const; \ static ClassReg RegistrationInfo, * const RegistrationInfoPtr; \ private: \ typedef parent Super; \ @@ -205,7 +161,8 @@ protected: \ create, \ sizeof(cls), \ cls::MetaClassNum }; \ - _DECLARE_TI(cls) + _DECLARE_TI(cls) \ + PClass *cls::StaticType() const { return RegistrationInfo.MyClass; } #define _IMP_CREATE_OBJ(cls) \ void cls::InPlaceConstructor(void *mem) { new((EInPlace *)mem) cls; } diff --git a/src/dobjtype.cpp b/src/dobjtype.cpp index e0a4a0239..4e02dbba7 100644 --- a/src/dobjtype.cpp +++ b/src/dobjtype.cpp @@ -38,6 +38,8 @@ #include "templates.h" #include "autosegs.h" #include "v_text.h" +#include "a_pickups.h" +#include "d_player.h" IMPLEMENT_POINTY_CLASS(PClass) DECLARE_POINTER(ParentClass) @@ -121,6 +123,7 @@ PClass::PClass() Defaults = NULL; bRuntimeClass = false; ClassIndex = ~0; + ConstructNative = NULL; } PClass::~PClass() @@ -135,6 +138,18 @@ PClass::~PClass() PClass *ClassReg::RegisterClass() { + static ClassReg *const metaclasses[] = + { + &PClass::RegistrationInfo, + &PClassActor::RegistrationInfo, + &PClassInventory::RegistrationInfo, + &PClassAmmo::RegistrationInfo, + &PClassHealth::RegistrationInfo, + &PClassPuzzleItem::RegistrationInfo, + &PClassWeapon::RegistrationInfo, + &PClassPlayerPawn::RegistrationInfo, + }; + // MyClass may have already been created by a previous recursive call. // Or this may be a recursive call for a previously created class. if (MyClass != NULL) @@ -145,30 +160,35 @@ PClass *ClassReg::RegisterClass() // Add type to list PClass *cls; - switch (MetaClassNum) + if (MetaClassNum >= countof(metaclasses)) { - case CLASSREG_PClass: - cls = new PClass; - break; - - case CLASSREG_PClassActor: - cls = new PClassActor; - break; - - default: assert(0 && "Class registry has an invalid meta class identifier"); } + + if (this == &PClass::RegistrationInfo) + { + cls = new PClass; + } + else + { + if (metaclasses[MetaClassNum]->MyClass == NULL) + { // Make sure the meta class is already registered before registering this one + metaclasses[MetaClassNum]->RegisterClass(); + } + cls = static_cast(metaclasses[MetaClassNum]->MyClass->CreateNew()); + } + MyClass = cls; PClass::m_Types.Push(cls); cls->TypeName = FName(Name+1); - if (ParentType != NULL) - { - cls->ParentClass = ParentType->RegisterClass(); - } cls->Size = SizeOf; cls->Pointers = Pointers; cls->ConstructNative = ConstructNative; cls->InsertIntoHash(); + if (ParentType != NULL) + { + cls->ParentClass = ParentType->RegisterClass(); + } return cls; } @@ -231,7 +251,7 @@ PClass *PClass::FindClass (FName zaname) } // Create a new object that this class represents -DObject *PClass::CreateNew () const +DObject *PClass::CreateNew() const { BYTE *mem = (BYTE *)M_Malloc (Size); assert (mem != NULL); @@ -247,6 +267,23 @@ DObject *PClass::CreateNew () const return (DObject *)mem; } +// Copies inheritable values into the derived class and other miscellaneous setup. +void PClass::Derive(PClass *newclass) +{ + newclass->ParentClass = this; + newclass->ConstructNative = ConstructNative; + + // Set up default instance of the new class. + newclass->Defaults = (BYTE *)M_Malloc(newclass->Size); + memcpy(newclass->Defaults, Defaults, Size); + if (newclass->Size > Size) + { + memset(newclass->Defaults + Size, 0, newclass->Size - Size); + } + + newclass->Symbols.SetParentTable(&this->Symbols); +} + // Create a new class based on an existing class PClass *PClass::CreateDerivedClass (FName name, unsigned int size) { @@ -275,34 +312,16 @@ PClass *PClass::CreateDerivedClass (FName name, unsigned int size) } type->TypeName = name; - type->ParentClass = this; type->Size = size; - type->Pointers = NULL; - type->ConstructNative = ConstructNative; + type->bRuntimeClass = true; + Derive(type); if (!notnew) { type->ClassIndex = m_Types.Push (type); - } - type->Meta = Meta; - - // Set up default instance of the new class. - type->Defaults = (BYTE *)M_Malloc(size); - memcpy (type->Defaults, Defaults, Size); - if (size > Size) - { - memset (type->Defaults + Size, 0, size - Size); - } - - type->FlatPointers = NULL; - type->bRuntimeClass = true; - type->Symbols.SetParentTable (&this->Symbols); - if (!notnew) - { type->InsertIntoHash(); } - // If this class has an actor info, then any classes derived from it - // also need an actor info. + // If this class is for an actor, push it onto the RuntimeActors stack. if (type->IsKindOf(RUNTIME_CLASS(PClassActor))) { m_RuntimeActors.Push(static_cast(type)); @@ -351,17 +370,13 @@ PClass *PClass::FindClassTentative (FName name) break; } } - PClass *type = new PClassActor; + PClass *type = static_cast(GetClass()->CreateNew()); DPrintf("Creating placeholder class %s : %s\n", name.GetChars(), TypeName.GetChars()); type->TypeName = name; type->ParentClass = this; type->Size = -1; - type->Pointers = NULL; - type->ConstructNative = NULL; type->ClassIndex = m_Types.Push (type); - type->Defaults = NULL; - type->FlatPointers = NULL; type->bRuntimeClass = true; type->InsertIntoHash(); return type; diff --git a/src/dobjtype.h b/src/dobjtype.h index 091ec47ac..063c52a2c 100644 --- a/src/dobjtype.h +++ b/src/dobjtype.h @@ -153,6 +153,8 @@ class PClass : public DObject { DECLARE_CLASS(PClass, DObject); HAS_OBJECT_POINTERS; +protected: + virtual void Derive(PClass *newclass); public: static void StaticInit (); static void StaticShutdown (); @@ -164,7 +166,6 @@ public: const size_t *Pointers; // object pointers defined by this class *only* const size_t *FlatPointers; // object pointers defined by this class and all its superclasses; not initialized by default PClass *HashNext; - FMetaTable Meta; BYTE *Defaults; bool bRuntimeClass; // class was defined at run-time, not compile-time unsigned short ClassIndex; diff --git a/src/g_doom/a_bossbrain.cpp b/src/g_doom/a_bossbrain.cpp index 9e97f39dc..a91d5f0e9 100644 --- a/src/g_doom/a_bossbrain.cpp +++ b/src/g_doom/a_bossbrain.cpp @@ -180,8 +180,8 @@ static void SpawnFly(AActor *self, const PClass *spawntype, FSoundID sound) FName SpawnName; - FDropItem *di; // di will be our drop item list iterator - FDropItem *drop; // while drop stays as the reference point. + DDropItem *di; // di will be our drop item list iterator + DDropItem *drop; // while drop stays as the reference point. int n = 0; // First see if this cube has its own actor list @@ -197,11 +197,11 @@ static void SpawnFly(AActor *self, const PClass *spawntype, FSoundID sound) { if (di->Name != NAME_None) { - if (di->amount < 0) + if (di->Amount < 0) { - di->amount = 1; // default value is -1, we need a positive value. + di->Amount = 1; // default value is -1, we need a positive value. } - n += di->amount; // this is how we can weight the list. + n += di->Amount; // this is how we can weight the list. } } di = drop; @@ -210,7 +210,7 @@ static void SpawnFly(AActor *self, const PClass *spawntype, FSoundID sound) { if (di->Name != NAME_None) { - n -= di->amount; // logically, none of the -1 values have survived by now. + n -= di->Amount; // logically, none of the -1 values have survived by now. } if ((di->Next != NULL) && (n >= 0)) { diff --git a/src/g_doom/a_doomweaps.cpp b/src/g_doom/a_doomweaps.cpp index f7754fa86..a85af9dff 100644 --- a/src/g_doom/a_doomweaps.cpp +++ b/src/g_doom/a_doomweaps.cpp @@ -390,7 +390,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireMissile) if (!weapon->DepleteAmmo (weapon->bAltFire)) return 0; } - P_SpawnPlayerMissile (self, PClass::FindClass("Rocket")); + P_SpawnPlayerMissile (self, PClass::FindActor("Rocket")); return 0; } @@ -452,7 +452,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FirePlasma) } } - P_SpawnPlayerMissile (self, PClass::FindClass("PlasmaBall")); + P_SpawnPlayerMissile (self, PClass::FindActor("PlasmaBall")); return 0; } @@ -537,7 +537,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireBFG) return 0; } - P_SpawnPlayerMissile (self, 0, 0, 0, PClass::FindClass("BFGBall"), self->angle, NULL, NULL, !!(dmflags2 & DF2_NO_FREEAIMBFG)); + P_SpawnPlayerMissile (self, 0, 0, 0, PClass::FindActor("BFGBall"), self->angle, NULL, NULL, !!(dmflags2 & DF2_NO_FREEAIMBFG)); return 0; } @@ -619,7 +619,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_BFGsound) DEFINE_ACTION_FUNCTION(AActor, A_FireOldBFG) { PARAM_ACTION_PROLOGUE; - const PClass * plasma[] = {PClass::FindClass("PlasmaBall1"), PClass::FindClass("PlasmaBall2")}; + PClassActor *plasma[] = { PClass::FindActor("PlasmaBall1"), PClass::FindActor("PlasmaBall2") }; AActor * mo = NULL; player_t *player; diff --git a/src/g_doom/a_revenant.cpp b/src/g_doom/a_revenant.cpp index b03106892..4d78f359f 100644 --- a/src/g_doom/a_revenant.cpp +++ b/src/g_doom/a_revenant.cpp @@ -65,7 +65,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Tracer) return 0; // spawn a puff of smoke behind the rocket - P_SpawnPuff (self, PClass::FindClass(NAME_BulletPuff), self->x, self->y, self->z, 0, 3); + P_SpawnPuff (self, PClass::FindActor(NAME_BulletPuff), self->x, self->y, self->z, 0, 3); smoke = Spawn ("RevenantTracerSmoke", self->x - self->velx, self->y - self->vely, self->z, ALLOW_REPLACE); diff --git a/src/g_heretic/a_dsparil.cpp b/src/g_heretic/a_dsparil.cpp index 8ec664d84..4e1e0edfc 100644 --- a/src/g_heretic/a_dsparil.cpp +++ b/src/g_heretic/a_dsparil.cpp @@ -83,7 +83,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Srcr1Attack) return 0; } - const PClass *fx = PClass::FindClass("SorcererFX1"); + PClassActor *fx = PClass::FindActor("SorcererFX1"); if (self->health > (self->SpawnHealth()/3)*2) { // Spit one fireball P_SpawnMissileZ (self, self->z + 48*FRACUNIT, self->target, fx ); @@ -225,7 +225,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Srcr2Attack) if (pr_s2a() < chance) { // Wizard spawners - const PClass *fx = PClass::FindClass("Sorcerer2FX2"); + PClassActor *fx = PClass::FindActor("Sorcerer2FX2"); if (fx) { P_SpawnMissileAngle (self, fx, self->angle-ANG45, FRACUNIT/2); @@ -234,7 +234,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Srcr2Attack) } else { // Blue bolt - P_SpawnMissile (self, self->target, PClass::FindClass("Sorcerer2FX1")); + P_SpawnMissile (self, self->target, PClass::FindActor("Sorcerer2FX1")); } return 0; } diff --git a/src/g_heretic/a_hereticweaps.cpp b/src/g_heretic/a_hereticweaps.cpp index ec1a052e1..fface239b 100644 --- a/src/g_heretic/a_hereticweaps.cpp +++ b/src/g_heretic/a_hereticweaps.cpp @@ -168,8 +168,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireGoldWandPL2) angle_t pitch = P_BulletSlope(self); velz = FixedMul (GetDefaultByName("GoldWandFX2")->Speed, finetangent[FINEANGLES/4-((signed)pitch>>ANGLETOFINESHIFT)]); - P_SpawnMissileAngle (self, PClass::FindClass("GoldWandFX2"), self->angle-(ANG45/8), velz); - P_SpawnMissileAngle (self, PClass::FindClass("GoldWandFX2"), self->angle+(ANG45/8), velz); + P_SpawnMissileAngle (self, PClass::FindActor("GoldWandFX2"), self->angle-(ANG45/8), velz); + P_SpawnMissileAngle (self, PClass::FindActor("GoldWandFX2"), self->angle+(ANG45/8), velz); angle = self->angle-(ANG45/8); for(i = 0; i < 5; i++) { @@ -204,9 +204,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireCrossbowPL1) if (!weapon->DepleteAmmo (weapon->bAltFire)) return 0; } - P_SpawnPlayerMissile (self, PClass::FindClass("CrossbowFX1")); - P_SpawnPlayerMissile (self, PClass::FindClass("CrossbowFX3"), self->angle-(ANG45/10)); - P_SpawnPlayerMissile (self, PClass::FindClass("CrossbowFX3"), self->angle+(ANG45/10)); + P_SpawnPlayerMissile (self, PClass::FindActor("CrossbowFX1")); + P_SpawnPlayerMissile (self, PClass::FindActor("CrossbowFX3"), self->angle-(ANG45/10)); + P_SpawnPlayerMissile (self, PClass::FindActor("CrossbowFX3"), self->angle+(ANG45/10)); return 0; } @@ -233,11 +233,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireCrossbowPL2) if (!weapon->DepleteAmmo (weapon->bAltFire)) return 0; } - P_SpawnPlayerMissile (self, PClass::FindClass("CrossbowFX2")); - P_SpawnPlayerMissile (self, PClass::FindClass("CrossbowFX2"), self->angle-(ANG45/10)); - P_SpawnPlayerMissile (self, PClass::FindClass("CrossbowFX2"), self->angle+(ANG45/10)); - P_SpawnPlayerMissile (self, PClass::FindClass("CrossbowFX3"), self->angle-(ANG45/5)); - P_SpawnPlayerMissile (self, PClass::FindClass("CrossbowFX3"), self->angle+(ANG45/5)); + P_SpawnPlayerMissile (self, PClass::FindActor("CrossbowFX2")); + P_SpawnPlayerMissile (self, PClass::FindActor("CrossbowFX2"), self->angle-(ANG45/10)); + P_SpawnPlayerMissile (self, PClass::FindActor("CrossbowFX2"), self->angle+(ANG45/10)); + P_SpawnPlayerMissile (self, PClass::FindActor("CrossbowFX3"), self->angle-(ANG45/5)); + P_SpawnPlayerMissile (self, PClass::FindActor("CrossbowFX3"), self->angle+(ANG45/5)); return 0; } @@ -448,7 +448,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireMacePL1) } player->psprites[ps_weapon].sx = ((pr_maceatk()&3)-2)*FRACUNIT; player->psprites[ps_weapon].sy = WEAPONTOP+(pr_maceatk()&3)*FRACUNIT; - ball = P_SpawnPlayerMissile (self, PClass::FindClass("MaceFX1"), + ball = P_SpawnPlayerMissile (self, PClass::FindActor("MaceFX1"), self->angle+(((pr_maceatk()&7)-4)<<24)); if (ball) { @@ -942,7 +942,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireSkullRodPL1) if (!weapon->DepleteAmmo (weapon->bAltFire)) return 0; } - mo = P_SpawnPlayerMissile (self, PClass::FindClass("HornRodFX1")); + mo = P_SpawnPlayerMissile (self, PClass::FindActor("HornRodFX1")); // Randomize the first frame if (mo && pr_fsr1() > 128) { diff --git a/src/g_heretic/a_wizard.cpp b/src/g_heretic/a_wizard.cpp index 69611546d..458cb8afe 100644 --- a/src/g_heretic/a_wizard.cpp +++ b/src/g_heretic/a_wizard.cpp @@ -84,7 +84,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_WizAtk3) P_TraceBleed (damage, self->target, self); return 0; } - const PClass *fx = PClass::FindClass("WizardFX1"); + PClassActor *fx = PClass::FindActor("WizardFX1"); mo = P_SpawnMissile (self, self->target, fx); if (mo != NULL) { diff --git a/src/g_hexen/a_bats.cpp b/src/g_hexen/a_bats.cpp index c6d0389d9..d00422837 100644 --- a/src/g_hexen/a_bats.cpp +++ b/src/g_hexen/a_bats.cpp @@ -48,7 +48,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_BatSpawn) delta = self->args[1]; if (delta==0) delta=1; angle = self->angle + (((pr_batspawn()%delta)-(delta>>1))<<24); - mo = P_SpawnMissileAngle (self, PClass::FindClass ("Bat"), angle, 0); + mo = P_SpawnMissileAngle (self, PClass::FindActor("Bat"), angle, 0); if (mo) { mo->args[0] = pr_batspawn()&63; // floatbob index diff --git a/src/g_hexen/a_clericholy.cpp b/src/g_hexen/a_clericholy.cpp index 9cf1a79ad..d9171dc8b 100644 --- a/src/g_hexen/a_clericholy.cpp +++ b/src/g_hexen/a_clericholy.cpp @@ -249,8 +249,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_CHolyAttack) if (!weapon->DepleteAmmo (weapon->bAltFire)) return 0; } - AActor * missile = P_SpawnPlayerMissile (self, 0,0,0, PClass::FindClass ("HolyMissile"), self->angle, &linetarget); - if (missile != NULL) missile->tracer = linetarget; + AActor *missile = P_SpawnPlayerMissile (self, 0,0,0, PClass::FindActor("HolyMissile"), self->angle, &linetarget); + if (missile != NULL) + { + missile->tracer = linetarget; + } weapon->CHolyCount = 3; S_Sound (self, CHAN_WEAPON, "HolySymbolFire", 1, ATTN_NORM); diff --git a/src/g_hexen/a_fighterhammer.cpp b/src/g_hexen/a_fighterhammer.cpp index 2eb226f2a..e0dca5068 100644 --- a/src/g_hexen/a_fighterhammer.cpp +++ b/src/g_hexen/a_fighterhammer.cpp @@ -126,7 +126,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FHammerThrow) if (!weapon->DepleteAmmo (weapon->bAltFire, false)) return 0; } - mo = P_SpawnPlayerMissile (player->mo, PClass::FindClass ("HammerMissile")); + mo = P_SpawnPlayerMissile (player->mo, PClass::FindActor("HammerMissile")); if (mo) { mo->special1 = 0; diff --git a/src/g_hexen/a_healingradius.cpp b/src/g_hexen/a_healingradius.cpp index b827f666b..a18116dac 100644 --- a/src/g_hexen/a_healingradius.cpp +++ b/src/g_hexen/a_healingradius.cpp @@ -30,7 +30,12 @@ IMPLEMENT_CLASS (AArtiHealingRadius) bool AArtiHealingRadius::Use (bool pickup) { bool effective = false; - int mode = Owner->GetClass()->Meta.GetMetaInt(APMETA_HealingRadius); + FName mode; + + if (Owner->IsKindOf(RUNTIME_CLASS(APlayerPawn))) + { + mode = static_cast(Owner->GetClass())->HealingRadiusType; + } for (int i = 0; i < MAXPLAYERS; ++i) { diff --git a/src/g_hexen/a_heresiarch.cpp b/src/g_hexen/a_heresiarch.cpp index ecb27b5ed..62cecea14 100644 --- a/src/g_hexen/a_heresiarch.cpp +++ b/src/g_hexen/a_heresiarch.cpp @@ -574,7 +574,7 @@ void ASorcBall3::CastSorcererSpell () ang1 = angle - ANGLE_45; ang2 = angle + ANGLE_45; - const PClass *cls = PClass::FindClass("SorcFX3"); + PClassActor *cls = PClass::FindActor("SorcFX3"); if (health < (SpawnHealth()/3)) { // Spawn 2 at a time mo = P_SpawnMissileAngle(parent, cls, ang1, 4*FRACUNIT); @@ -623,7 +623,7 @@ void ASorcBall1::CastSorcererSpell () ang1 = angle + ANGLE_1*70; ang2 = angle - ANGLE_1*70; - const PClass *cls = PClass::FindClass("SorcFX1"); + PClassActor *cls = PClass::FindActor("SorcFX1"); mo = P_SpawnMissileAngle (parent, cls, ang1, 0); if (mo) { @@ -670,7 +670,7 @@ void A_SorcOffense2(AActor *actor) delta = (finesine[index])*SORCFX4_SPREAD_ANGLE; delta = (delta>>FRACBITS)*ANGLE_1; ang1 = actor->angle + delta; - mo = P_SpawnMissileAngle(parent, PClass::FindClass("SorcFX4"), ang1, 0); + mo = P_SpawnMissileAngle(parent, PClass::FindActor("SorcFX4"), ang1, 0); if (mo) { mo->special2 = 35*5/2; // 5 seconds diff --git a/src/g_hexen/a_iceguy.cpp b/src/g_hexen/a_iceguy.cpp index f43a76122..e4a501443 100644 --- a/src/g_hexen/a_iceguy.cpp +++ b/src/g_hexen/a_iceguy.cpp @@ -144,7 +144,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_IceGuyMissileExplode) for (i = 0; i < 8; i++) { mo = P_SpawnMissileAngleZ (self, self->z+3*FRACUNIT, - PClass::FindClass("IceGuyFX2"), i*ANG45, (fixed_t)(-0.3*FRACUNIT)); + PClass::FindActor("IceGuyFX2"), i*ANG45, (fixed_t)(-0.3*FRACUNIT)); if (mo) { mo->target = self->target; diff --git a/src/g_hexen/a_korax.cpp b/src/g_hexen/a_korax.cpp index a1f729865..d0509c408 100644 --- a/src/g_hexen/a_korax.cpp +++ b/src/g_hexen/a_korax.cpp @@ -164,8 +164,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_KoraxBonePop) // Spawn 6 spirits equalangularly for (i = 0; i < 6; ++i) { - mo = P_SpawnMissileAngle (self, PClass::FindClass("KoraxSpirit"), ANGLE_60*i, 5*FRACUNIT); - if (mo) KSpiritInit (mo, self); + mo = P_SpawnMissileAngle (self, PClass::FindActor("KoraxSpirit"), ANGLE_60*i, 5*FRACUNIT); + if (mo) + { + KSpiritInit (mo, self); + } } P_StartScript (self, NULL, 255, NULL, 0, 0, 0, 0, false, false); // Death script diff --git a/src/g_hexen/a_magelightning.cpp b/src/g_hexen/a_magelightning.cpp index 5d9880a40..7010aaceb 100644 --- a/src/g_hexen/a_magelightning.cpp +++ b/src/g_hexen/a_magelightning.cpp @@ -215,10 +215,15 @@ DEFINE_ACTION_FUNCTION(AActor, A_LightningZap) { PARAM_ACTION_PROLOGUE; - const PClass *lightning=PClass::FindClass((ENamedName) self->GetClass()->Meta.GetMetaInt (ACMETA_MissileName, NAME_LightningZap)); + PClassActor *lightning = PClass::FindActor(self->GetClass()->MissileName); AActor *mo; fixed_t deltaZ; + if (lightning == NULL) + { + lightning = PClass::FindActor(NAME_LightningZap); + } + CALL_ACTION(A_LightningClip, self); self->health -= 8; @@ -338,10 +343,14 @@ DEFINE_ACTION_FUNCTION(AActor, A_ZapMimic) DEFINE_ACTION_FUNCTION(AActor, A_LastZap) { PARAM_ACTION_PROLOGUE; - const PClass *lightning=PClass::FindClass((ENamedName) self->GetClass()->Meta.GetMetaInt (ACMETA_MissileName, NAME_LightningZap)); + PClassActor *lightning = PClass::FindActor(self->GetClass()->MissileName); AActor *mo; + if (lightning == NULL) + { + lightning = PClass::FindActor(NAME_LightningZap); + } mo = Spawn(lightning, self->x, self->y, self->z, ALLOW_REPLACE); if (mo) { diff --git a/src/g_hexen/a_summon.cpp b/src/g_hexen/a_summon.cpp index 6f698cbc2..14f0e4b7f 100644 --- a/src/g_hexen/a_summon.cpp +++ b/src/g_hexen/a_summon.cpp @@ -31,7 +31,7 @@ IMPLEMENT_CLASS (AArtiDarkServant) bool AArtiDarkServant::Use (bool pickup) { - AActor *mo = P_SpawnPlayerMissile (Owner, PClass::FindClass ("SummoningDoll")); + AActor *mo = P_SpawnPlayerMissile (Owner, PClass::FindActor("SummoningDoll")); if (mo) { mo->target = Owner; diff --git a/src/g_raven/a_minotaur.cpp b/src/g_raven/a_minotaur.cpp index cb51a32d0..138ef59f6 100644 --- a/src/g_raven/a_minotaur.cpp +++ b/src/g_raven/a_minotaur.cpp @@ -301,7 +301,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_MinotaurAtk2) return 0; } z = self->z + 40*FRACUNIT; - const PClass *fx = PClass::FindClass("MinotaurFX1"); + PClassActor *fx = PClass::FindActor("MinotaurFX1"); if (fx) { mo = P_SpawnMissileZ (self, z, self->target, fx); diff --git a/src/g_shared/a_action.cpp b/src/g_shared/a_action.cpp index 4c007ad17..abaaa4e3e 100644 --- a/src/g_shared/a_action.cpp +++ b/src/g_shared/a_action.cpp @@ -83,7 +83,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_NoBlocking) // If the self has attached metadata for items to drop, drop those. if (!self->IsKindOf (RUNTIME_CLASS (APlayerPawn))) // [GRB] { - FDropItem *di = self->GetDropItems(); + DDropItem *di = self->GetDropItems(); if (di != NULL) { @@ -92,7 +92,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_NoBlocking) if (di->Name != NAME_None) { const PClass *ti = PClass::FindClass(di->Name); - if (ti) P_DropItem (self, ti, di->amount, di->probability); + if (ti) P_DropItem (self, ti, di->Amount, di->Probability); } di = di->Next; } diff --git a/src/g_shared/a_artifacts.cpp b/src/g_shared/a_artifacts.cpp index ec49b683d..0dcfac57c 100644 --- a/src/g_shared/a_artifacts.cpp +++ b/src/g_shared/a_artifacts.cpp @@ -349,9 +349,9 @@ void APowerInvulnerable::InitEffect () { Owner->effects &= ~FX_RESPAWNINVUL; Owner->flags2 |= MF2_INVULNERABLE; - if (Mode == NAME_None) + if (Mode == NAME_None && Owner->IsKindOf(RUNTIME_CLASS(APlayerPawn))) { - Mode = (ENamedName)RUNTIME_TYPE(Owner)->Meta.GetMetaInt(APMETA_InvulMode); + Mode = static_cast(Owner->GetClass())->InvulMode; } if (Mode == NAME_Reflective) { @@ -1729,7 +1729,7 @@ void APowerMorph::InitEffect( ) player_t *realplayer = Owner->player; // Remember the identity of the player const PClass *morph_flash = PClass::FindClass (MorphFlash); const PClass *unmorph_flash = PClass::FindClass (UnMorphFlash); - const PClass *player_class = PClass::FindClass (PlayerClass); + PClassPlayerPawn *player_class = dyn_cast(PClass::FindClass (PlayerClass)); if (P_MorphPlayer(realplayer, realplayer, player_class, -1/*INDEFINITELY*/, MorphStyle, morph_flash, unmorph_flash)) { Owner = realplayer->mo; // Replace the new owner in our owner; safe because we are not attached to anything yet diff --git a/src/g_shared/a_fastprojectile.cpp b/src/g_shared/a_fastprojectile.cpp index 3bd2903ee..614985234 100644 --- a/src/g_shared/a_fastprojectile.cpp +++ b/src/g_shared/a_fastprojectile.cpp @@ -154,7 +154,7 @@ void AFastProjectile::Effect() { //if (pr_smoke() < 128) // [RH] I think it looks better if it's consistent { - FName name = (ENamedName) this->GetClass()->Meta.GetMetaInt (ACMETA_MissileName, NAME_None); + FName name = GetClass()->MissileName; if (name != NAME_None) { fixed_t hitz = z-8*FRACUNIT; diff --git a/src/g_shared/a_morph.cpp b/src/g_shared/a_morph.cpp index 7cbfbc5ad..70f79b3a0 100644 --- a/src/g_shared/a_morph.cpp +++ b/src/g_shared/a_morph.cpp @@ -25,7 +25,7 @@ static FRandom pr_morphmonst ("MorphMonster"); // //--------------------------------------------------------------------------- -bool P_MorphPlayer (player_t *activator, player_t *p, const PClass *spawntype, int duration, int style, const PClass *enter_flash, const PClass *exit_flash) +bool P_MorphPlayer (player_t *activator, player_t *p, PClassPlayerPawn *spawntype, int duration, int style, const PClass *enter_flash, const PClass *exit_flash) { AInventory *item; APlayerPawn *morphed; @@ -129,7 +129,7 @@ bool P_MorphPlayer (player_t *activator, player_t *p, const PClass *spawntype, i hxarmor->Slots[1] = 0; hxarmor->Slots[2] = 0; hxarmor->Slots[3] = 0; - hxarmor->Slots[4] = spawntype->Meta.GetMetaFixed (APMETA_Hexenarmor0); + hxarmor->Slots[4] = spawntype->HexenArmor[0]; } else if (item->ItemFlags & IF_KEEPDEPLETED) { @@ -157,9 +157,7 @@ bool P_MorphPlayer (player_t *activator, player_t *p, const PClass *spawntype, i // and for the original DOOM status bar. if (p == &players[consoleplayer]) { - const char *face = spawntype->Meta.GetMetaString (APMETA_Face); - - if (face != NULL && strcmp(face, "None") != 0) + if (spawntype->Face.IsNotEmpty() && strcmp(spawntype->Face, "None") != 0) { StatusBar->SetFace(&skins[p->MorphedPlayerClass]); } @@ -285,8 +283,8 @@ bool P_UndoPlayerMorph (player_t *activator, player_t *player, int unmorphflag, // and for the original DOOM status bar. if ((player == &players[consoleplayer])) { - const char *face = pmo->GetClass()->Meta.GetMetaString (APMETA_Face); - if (face != NULL && strcmp(face, "None") != 0) + FString face = pmo->GetClass()->Face; + if (face.IsNotEmpty() && strcmp(face, "None") != 0) { // Assume root-level base skin to begin with size_t skinindex = 0; @@ -361,7 +359,7 @@ bool P_UndoPlayerMorph (player_t *activator, player_t *player, int unmorphflag, AHexenArmor *hxarmor = mo->FindInventory(); if (hxarmor != NULL) { - hxarmor->Slots[4] = mo->GetClass()->Meta.GetMetaFixed (APMETA_Hexenarmor0); + hxarmor->Slots[4] = mo->GetClass()->HexenArmor[0]; } return true; } @@ -558,7 +556,7 @@ int AMorphProjectile::DoSpecialDamage (AActor *target, int damage) const PClass *unmorph_flash = PClass::FindClass (UnMorphFlash); if (target->player) { - const PClass *player_class = PClass::FindClass (PlayerClass); + PClassPlayerPawn *player_class = dyn_cast(PClass::FindClass(PlayerClass)); P_MorphPlayer (NULL, target->player, player_class, Duration, MorphStyle, morph_flash, unmorph_flash); } else diff --git a/src/g_shared/a_morph.h b/src/g_shared/a_morph.h index 891fe619b..8ea90bf5d 100644 --- a/src/g_shared/a_morph.h +++ b/src/g_shared/a_morph.h @@ -33,7 +33,7 @@ class AActor; class player_t; class AMorphedMonster; -bool P_MorphPlayer (player_t *activator, player_t *player, const PClass *morphclass, int duration = 0, int style = 0, +bool P_MorphPlayer (player_t *activator, player_t *player, PClassPlayerPawn *morphclass, int duration = 0, int style = 0, const PClass *enter_flash = NULL, const PClass *exit_flash = NULL); bool P_UndoPlayerMorph (player_t *activator, player_t *player, int unmorphflag = 0, bool force = false); bool P_MorphMonster (AActor *actor, const PClass *morphclass, int duration = 0, int style = 0, diff --git a/src/g_shared/a_pickups.cpp b/src/g_shared/a_pickups.cpp index eb7a25425..b64eaafea 100644 --- a/src/g_shared/a_pickups.cpp +++ b/src/g_shared/a_pickups.cpp @@ -20,6 +20,41 @@ static FRandom pr_restore ("RestorePos"); +IMPLEMENT_CLASS(PClassInventory) + +PClassInventory::PClassInventory() +{ + GiveQuest = 0; + AltHUDIcon.SetInvalid(); +} + +void PClassInventory::Derive(PClass *newclass) +{ + assert(newclass->IsKindOf(RUNTIME_CLASS(PClassInventory))); + Super::Derive(newclass); + PClassInventory *newc = static_cast(newclass); + + newc->PickupMessage = PickupMessage; + newc->GiveQuest = GiveQuest; + newc->AltHUDIcon = AltHUDIcon; +} + +IMPLEMENT_CLASS(PClassAmmo) + +PClassAmmo::PClassAmmo() +{ + DropAmount = 0; +} + +void PClassAmmo::Derive(PClass *newclass) +{ + assert(newclass->IsKindOf(RUNTIME_CLASS(PClassAmmo))); + Super::Derive(newclass); + PClassAmmo *newc = static_cast(newclass); + + newc->DropAmount = DropAmount; +} + IMPLEMENT_CLASS (AAmmo) //=========================================================================== @@ -970,9 +1005,9 @@ void AInventory::DoPickupSpecial (AActor *toucher) const char *AInventory::PickupMessage () { - const char *message = GetClass()->Meta.GetMetaString (AIMETA_PickupMessage); + FString message = GetClass()->PickupMessage; - return message != NULL? message : "You got a pickup"; + return message.IsNotEmpty() ? message : "You got a pickup"; } //=========================================================================== @@ -1169,8 +1204,8 @@ bool AInventory::DoRespawn () void AInventory::GiveQuest (AActor *toucher) { - int quest = GetClass()->Meta.GetMetaInt(AIMETA_GiveQuest); - if (quest>0 && quest<31) + int quest = GetClass()->GiveQuest; + if (quest > 0 && quest <= countof(QuestItemClasses)) { toucher->GiveInventoryType (QuestItemClasses[quest-1]); } @@ -1394,6 +1429,35 @@ bool ACustomInventory::TryPickup (AActor *&toucher) return useok; } +IMPLEMENT_CLASS(PClassHealth) + +//=========================================================================== +// +// PClassHealth Constructor +// +//=========================================================================== + +PClassHealth::PClassHealth() +{ + LowHealth = 0; +} + +//=========================================================================== +// +// PClassHealth :: Derive +// +//=========================================================================== + +void PClassHealth::Derive(PClass *newclass) +{ + assert(newclass->IsKindOf(RUNTIME_CLASS(PClassHealth))); + Super::Derive(newclass); + PClassHealth *newc = static_cast(newclass); + + newc->LowHealth = LowHealth; + newc->LowHealthMessage = LowHealthMessage; +} + IMPLEMENT_CLASS (AHealth) //=========================================================================== @@ -1403,13 +1467,13 @@ IMPLEMENT_CLASS (AHealth) //=========================================================================== const char *AHealth::PickupMessage () { - int threshold = GetClass()->Meta.GetMetaInt(AIMETA_LowHealth, 0); + int threshold = GetClass()->LowHealth; if (PrevHealth < threshold) { - const char *message = GetClass()->Meta.GetMetaString (AIMETA_LowHealthMessage); + FString message = GetClass()->LowHealthMessage; - if (message != NULL) + if (message.IsNotEmpty()) { return message; } diff --git a/src/g_shared/a_pickups.h b/src/g_shared/a_pickups.h index 0e531066f..06f21c8e9 100644 --- a/src/g_shared/a_pickups.h +++ b/src/g_shared/a_pickups.h @@ -10,6 +10,8 @@ class player_t; class FConfigFile; class AWeapon; +class PClassWeapon; +class PClassPlayerPawn; class FWeaponSlot { @@ -19,13 +21,13 @@ public: FWeaponSlot &operator= (const FWeaponSlot &other) { Weapons = other.Weapons; return *this; } void Clear() { Weapons.Clear(); } bool AddWeapon (const char *type); - bool AddWeapon (PClassActor *type); + bool AddWeapon (PClassWeapon *type); void AddWeaponList (const char *list, bool clear); AWeapon *PickWeapon (player_t *player); int Size () const { return (int)Weapons.Size(); } - int LocateWeapon (PClassActor *type); + int LocateWeapon (PClassWeapon *type); - inline PClassActor *GetWeapon (int index) const + inline PClassWeapon *GetWeapon (int index) const { if ((unsigned)index < Weapons.Size()) { @@ -42,7 +44,7 @@ public: private: struct WeaponInfo { - PClassActor *Type; + PClassWeapon *Type; fixed_t Position; }; void SetInitialPositions(); @@ -68,25 +70,25 @@ struct FWeaponSlots AWeapon *PickPrevWeapon (player_t *player); void Clear (); - bool LocateWeapon (PClassActor *type, int *const slot, int *const index); - ESlotDef AddDefaultWeapon (int slot, PClassActor *type); + bool LocateWeapon (PClassWeapon *type, int *const slot, int *const index); + ESlotDef AddDefaultWeapon (int slot, PClassWeapon *type); void AddExtraWeapons(); void SetFromGameInfo(); - void SetFromPlayer(PClassActor *type); - void StandardSetup(PClassActor *type); + void SetFromPlayer(PClassPlayerPawn *type); + void StandardSetup(PClassPlayerPawn *type); void LocalSetup(PClassActor *type); void SendDifferences(const FWeaponSlots &other); int RestoreSlots (FConfigFile *config, const char *section); void PrintSettings(); - void AddSlot(int slot, PClassActor *type, bool feedback); - void AddSlotDefault(int slot, PClassActor *type, bool feedback); + void AddSlot(int slot, PClassWeapon *type, bool feedback); + void AddSlotDefault(int slot, PClassWeapon *type, bool feedback); }; void P_PlaybackKeyConfWeapons(FWeaponSlots *slots); -void Net_WriteWeapon(PClassActor *type); -PClassActor *Net_ReadWeapon(BYTE **stream); +void Net_WriteWeapon(PClassWeapon *type); +PClassWeapon *Net_ReadWeapon(BYTE **stream); void P_SetupWeapons_ntohton(); void P_WriteDemoWeaponsChunk(BYTE **demo); @@ -98,17 +100,6 @@ void P_ReadDemoWeaponsChunk(BYTE **demo); // A pickup is anything the player can pickup (i.e. weapons, ammo, powerups, etc) -enum -{ - AIMETA_BASE = 0x71000, - AIMETA_PickupMessage, // string - AIMETA_GiveQuest, // optionally give one of the quest items. - AIMETA_DropAmount, // specifies the amount for a dropped ammo item - AIMETA_LowHealth, - AIMETA_LowHealthMessage, - AIMETA_PuzzFailMessage, -}; - enum { IF_ACTIVATABLE = 1<<0, // can be activated @@ -134,9 +125,22 @@ enum struct vissprite_t; +class PClassInventory : public PClassActor +{ + DECLARE_CLASS(PClassInventory, PClassActor) +protected: + virtual void Derive(PClass *newclass); +public: + PClassInventory(); + + FString PickupMessage; + int GiveQuest; // Optionally give one of the quest items. + FTextureID AltHUDIcon; +}; + class AInventory : public AActor { - DECLARE_CLASS (AInventory, AActor) + DECLARE_CLASS_WITH_META(AInventory, AActor, PClassInventory) HAS_OBJECT_POINTERS public: virtual void Touch (AActor *toucher); @@ -172,7 +176,7 @@ public: const PClass *SpawnPointClass; // For respawning like Heretic's mace DWORD ItemFlags; - const PClass *PickupFlash; // actor to spawn as pickup flash + PClassActor *PickupFlash; // actor to spawn as pickup flash FSoundIDNoInit PickupSound; @@ -220,9 +224,20 @@ public: }; // Ammo: Something a weapon needs to operate +class PClassAmmo : public PClassInventory +{ + DECLARE_CLASS(PClassAmmo, PClassInventory) +protected: + virtual void Derive(PClass *newclass); +public: + PClassAmmo(); + + int DropAmount; // Specifies the amount for a dropped ammo item. +}; + class AAmmo : public AInventory { - DECLARE_CLASS (AAmmo, AInventory) + DECLARE_CLASS_WITH_META(AAmmo, AInventory, PClassAmmo) public: void Serialize (FArchive &arc); AInventory *CreateCopy (AActor *other); @@ -234,27 +249,32 @@ public: }; // A weapon is just that. -enum +class PClassWeapon : public PClassInventory { - AWMETA_BASE = 0x72000, - AWMETA_SlotNumber, - AWMETA_SlotPriority, + DECLARE_CLASS(PClassWeapon, PClassInventory); +protected: + virtual void Derive(PClass *newclass); +public: + PClassWeapon(); + + int SlotNumber; + fixed_t SlotPriority; }; class AWeapon : public AInventory { - DECLARE_CLASS (AWeapon, AInventory) + DECLARE_CLASS_WITH_META(AWeapon, AInventory, PClassWeapon) HAS_OBJECT_POINTERS public: DWORD WeaponFlags; - PClassActor *AmmoType1, *AmmoType2; // Types of ammo used by this weapon + PClassAmmo *AmmoType1, *AmmoType2; // Types of ammo used by this weapon int AmmoGive1, AmmoGive2; // Amount of each ammo to get when picking up weapon int MinAmmo1, MinAmmo2; // Minimum ammo needed to switch to this weapon int AmmoUse1, AmmoUse2; // How much ammo to use with each shot int Kickback; fixed_t YAdjust; // For viewing the weapon fullscreen FSoundIDNoInit UpSound, ReadySound; // Sounds when coming up and idle - PClassActor *SisterWeaponType; // Another weapon to pick up with this one + PClassWeapon *SisterWeaponType; // Another weapon to pick up with this one PClassActor *ProjectileType; // Projectile used by primary attack PClassActor *AltProjectileType; // Projectile used by alternate attack int SelectionOrder; // Lower-numbered weapons get picked first @@ -302,7 +322,7 @@ public: protected: AAmmo *AddAmmo (AActor *other, PClassActor *ammotype, int amount); bool AddExistingAmmo (AAmmo *ammo, int amount); - AWeapon *AddWeapon (PClassActor *weapon); + AWeapon *AddWeapon (PClassWeapon *weapon); }; enum @@ -336,9 +356,21 @@ enum #define S_LIGHTDONE 0 // Health is some item that gives the player health when picked up. +class PClassHealth : public PClassInventory +{ + DECLARE_CLASS(PClassHealth, PClassInventory) +protected: + virtual void Derive(PClass *newclass); +public: + PClassHealth(); + + FString LowHealthMessage; + int LowHealth; +}; + class AHealth : public AInventory { - DECLARE_CLASS (AHealth, AInventory) + DECLARE_CLASS_WITH_META(AHealth, AInventory, PClassHealth) int PrevHealth; public: @@ -440,9 +472,18 @@ protected: }; // PuzzleItems work in conjunction with the UsePuzzleItem special +class PClassPuzzleItem : public PClassInventory +{ + DECLARE_CLASS(PClassPuzzleItem, PClassInventory); +protected: + virtual void Derive(PClass *newclass); +public: + FString PuzzFailMessage; +}; + class APuzzleItem : public AInventory { - DECLARE_CLASS (APuzzleItem, AInventory) + DECLARE_CLASS_WITH_META(APuzzleItem, AInventory, PClassPuzzleItem) public: void Serialize (FArchive &arc); bool ShouldStay (); diff --git a/src/g_shared/a_puzzleitems.cpp b/src/g_shared/a_puzzleitems.cpp index 0cbc7cc33..c32e03761 100644 --- a/src/g_shared/a_puzzleitems.cpp +++ b/src/g_shared/a_puzzleitems.cpp @@ -8,7 +8,16 @@ #include "doomstat.h" #include "v_font.h" -IMPLEMENT_CLASS (APuzzleItem) +IMPLEMENT_CLASS(PClassPuzzleItem) + +void PClassPuzzleItem::Derive(PClass *newclass) +{ + Super::Derive(newclass); + assert(newclass->IsKindOf(RUNTIME_CLASS(PClassPuzzleItem))); + static_cast(newclass)->PuzzFailMessage = PuzzFailMessage; +} + +IMPLEMENT_CLASS(APuzzleItem) void APuzzleItem::Serialize (FArchive &arc) { @@ -36,9 +45,9 @@ bool APuzzleItem::Use (bool pickup) S_Sound (Owner, CHAN_VOICE, "*puzzfail", 1, ATTN_IDLE); if (Owner != NULL && Owner->CheckLocalView (consoleplayer)) { - const char *message = GetClass()->Meta.GetMetaString (AIMETA_PuzzFailMessage); - if (message != NULL && *message=='$') message = GStrings[message + 1]; - if (message == NULL) message = GStrings("TXT_USEPUZZLEFAILED"); + FString message = GetClass()->PuzzFailMessage; + if (message.IsNotEmpty() && message[0] == '$') message = GStrings[&message[1]]; + if (message.IsEmpty()) message = GStrings("TXT_USEPUZZLEFAILED"); C_MidPrintBold (SmallFont, message); } return false; diff --git a/src/g_shared/a_randomspawner.cpp b/src/g_shared/a_randomspawner.cpp index 026788e78..48e21e791 100644 --- a/src/g_shared/a_randomspawner.cpp +++ b/src/g_shared/a_randomspawner.cpp @@ -28,9 +28,9 @@ class ARandomSpawner : public AActor // random spawner's velocity (0...) instead of their own. void BeginPlay() { - FDropItem *di; // di will be our drop item list iterator - FDropItem *drop; // while drop stays as the reference point. - int n=0; + DDropItem *di; // di will be our drop item list iterator + DDropItem *drop; // while drop stays as the reference point. + int n = 0; Super::BeginPlay(); drop = di = GetDropItems(); @@ -40,8 +40,8 @@ class ARandomSpawner : public AActor { if (di->Name != NAME_None) { - if (di->amount < 0) di->amount = 1; // default value is -1, we need a positive value. - n += di->amount; // this is how we can weight the list. + if (di->Amount < 0) di->Amount = 1; // default value is -1, we need a positive value. + n += di->Amount; // this is how we can weight the list. di = di->Next; } } @@ -54,7 +54,7 @@ class ARandomSpawner : public AActor { if (di->Name != NAME_None) { - n -= di->amount; + n -= di->Amount; if ((di->Next != NULL) && (n > -1)) di = di->Next; else n = -1; } } @@ -64,7 +64,7 @@ class ARandomSpawner : public AActor Spawn("Unknown", x, y, z, NO_REPLACE); // Show that there's a problem. Destroy(); return; } - else if (pr_randomspawn() <= di->probability) // prob 255 = always spawn, prob 0 = never spawn. + else if (pr_randomspawn() <= di->Probability) // prob 255 = always spawn, prob 0 = almost never spawn. { // Handle replacement here so as to get the proper speed and flags for missiles PClassActor *cls; diff --git a/src/g_shared/a_weaponpiece.h b/src/g_shared/a_weaponpiece.h index 3d609d8c5..bdc0c80f9 100644 --- a/src/g_shared/a_weaponpiece.h +++ b/src/g_shared/a_weaponpiece.h @@ -13,7 +13,7 @@ public: virtual void PlayPickupSound (AActor *toucher); int PieceValue; - PClassActor *WeaponClass; + PClassWeapon *WeaponClass; TObjPtr FullWeapon; }; diff --git a/src/g_shared/a_weapons.cpp b/src/g_shared/a_weapons.cpp index f1f488557..97b438853 100644 --- a/src/g_shared/a_weapons.cpp +++ b/src/g_shared/a_weapons.cpp @@ -30,11 +30,29 @@ FString WeaponSection; TArray KeyConfWeapons; FWeaponSlots *PlayingKeyConf; -TArray Weapons_ntoh; -TMap Weapons_hton; +TArray Weapons_ntoh; +TMap Weapons_hton; static int STACK_ARGS ntoh_cmp(const void *a, const void *b); +IMPLEMENT_CLASS(PClassWeapon) + +PClassWeapon::PClassWeapon() +{ + SlotNumber = -1; + SlotPriority = FIXED_MAX; +} + +void PClassWeapon::Derive(PClass *newclass) +{ + assert(newclass->IsKindOf(RUNTIME_CLASS(PClassWeapon))); + Super::Derive(newclass); + PClassWeapon *newc = static_cast(newclass); + + newc->SlotNumber = SlotNumber; + newc->SlotPriority = SlotPriority; +} + //=========================================================================== // // AWeapon :: Serialize @@ -357,7 +375,7 @@ bool AWeapon::AddExistingAmmo (AAmmo *ammo, int amount) // //=========================================================================== -AWeapon *AWeapon::AddWeapon (PClassActor *weapontype) +AWeapon *AWeapon::AddWeapon (PClassWeapon *weapontype) { AWeapon *weap; @@ -620,13 +638,13 @@ IMPLEMENT_CLASS(AWeaponGiver) bool AWeaponGiver::TryPickup(AActor *&toucher) { - FDropItem *di = GetDropItems(); + DDropItem *di = GetDropItems(); AWeapon *weap; if (di != NULL) { - PClassActor *ti = PClass::FindActor(di->Name); - if (ti != NULL && ti->IsDescendantOf(RUNTIME_CLASS(AWeapon))) + PClassWeapon *ti = dyn_cast(PClass::FindClass(di->Name)); + if (ti != NULL) { if (master == NULL) { @@ -662,10 +680,10 @@ bool AWeaponGiver::TryPickup(AActor *&toucher) bool FWeaponSlot::AddWeapon(const char *type) { - return AddWeapon (PClass::FindActor (type)); + return AddWeapon(static_cast(PClass::FindClass(type))); } -bool FWeaponSlot::AddWeapon(PClassActor *type) +bool FWeaponSlot::AddWeapon(PClassWeapon *type) { unsigned int i; @@ -726,7 +744,7 @@ void FWeaponSlot :: AddWeaponList(const char *list, bool clear) // //=========================================================================== -int FWeaponSlot::LocateWeapon(PClassActor *type) +int FWeaponSlot::LocateWeapon(PClassWeapon *type) { unsigned int i; @@ -842,7 +860,7 @@ void FWeaponSlot::Sort() for (i = 1; i < (int)Weapons.Size(); ++i) { fixed_t pos = Weapons[i].Position; - PClassActor *type = Weapons[i].Type; + PClassWeapon *type = Weapons[i].Type; for (j = i - 1; j >= 0 && Weapons[j].Position > pos; --j) { Weapons[j + 1] = Weapons[j]; @@ -891,7 +909,7 @@ void FWeaponSlots::Clear() // //=========================================================================== -ESlotDef FWeaponSlots::AddDefaultWeapon (int slot, PClassActor *type) +ESlotDef FWeaponSlots::AddDefaultWeapon (int slot, PClassWeapon *type) { int currSlot, index; @@ -916,7 +934,7 @@ ESlotDef FWeaponSlots::AddDefaultWeapon (int slot, PClassActor *type) // //=========================================================================== -bool FWeaponSlots::LocateWeapon (PClassActor *type, int *const slot, int *const index) +bool FWeaponSlots::LocateWeapon (PClassWeapon *type, int *const slot, int *const index) { int i, j; @@ -1014,7 +1032,7 @@ AWeapon *FWeaponSlots::PickNextWeapon(player_t *player) slot = 0; } } - PClassActor *type = Slots[slot].GetWeapon(index); + PClassWeapon *type = Slots[slot].GetWeapon(index); AWeapon *weap = static_cast(player->mo->FindInventory(type)); if (weap != NULL && weap->CheckAmmo(AWeapon::EitherFire, false)) { @@ -1069,7 +1087,7 @@ AWeapon *FWeaponSlots::PickPrevWeapon (player_t *player) } index = Slots[slot].Size() - 1; } - PClassActor *type = Slots[slot].GetWeapon(index); + PClassWeapon *type = Slots[slot].GetWeapon(index); AWeapon *weap = static_cast(player->mo->FindInventory(type)); if (weap != NULL && weap->CheckAmmo(AWeapon::EitherFire, false)) { @@ -1109,17 +1127,16 @@ void FWeaponSlots::AddExtraWeapons() { continue; } - PClassActor *acls = static_cast(cls); + PClassWeapon *acls = static_cast(cls); if ((acls->GameFilter == GAME_Any || (acls->GameFilter & gameinfo.gametype)) && acls->Replacement == NULL && // Replaced weapons don't get slotted. !LocateWeapon(acls, NULL, NULL) // Don't duplicate it if it's already present. ) { - int slot = acls->Meta.GetMetaInt(AWMETA_SlotNumber, -1); + int slot = acls->SlotNumber; if ((unsigned)slot < NUM_WEAPON_SLOTS) { - fixed_t position = acls->Meta.GetMetaFixed(AWMETA_SlotPriority, INT_MAX); - FWeaponSlot::WeaponInfo info = { acls, position }; + FWeaponSlot::WeaponInfo info = { acls, acls->SlotPriority }; Slots[slot].Weapons.Push(info); } } @@ -1156,7 +1173,7 @@ void FWeaponSlots::SetFromGameInfo() { for (unsigned j = 0; j < gameinfo.DefaultWeaponSlots[i].Size(); i++) { - PClassActor *cls = PClass::FindActor(gameinfo.DefaultWeaponSlots[i][j]); + PClassWeapon *cls = dyn_cast(PClass::FindClass(gameinfo.DefaultWeaponSlots[i][j])); if (cls == NULL) { Printf("Unknown weapon class '%s' found in default weapon slot assignments\n", @@ -1181,7 +1198,7 @@ void FWeaponSlots::SetFromGameInfo() // //=========================================================================== -void FWeaponSlots::StandardSetup(PClassActor *type) +void FWeaponSlots::StandardSetup(PClassPlayerPawn *type) { SetFromPlayer(type); AddExtraWeapons(); @@ -1266,15 +1283,14 @@ void FWeaponSlots::SendDifferences(const FWeaponSlots &other) // //=========================================================================== -void FWeaponSlots::SetFromPlayer(PClassActor *type) +void FWeaponSlots::SetFromPlayer(PClassPlayerPawn *type) { Clear(); for (int i = 0; i < NUM_WEAPON_SLOTS; ++i) { - const char *str = type->Meta.GetMetaString(APMETA_Slot0 + i); - if (str != NULL) + if (!type->Slot[i].IsEmpty()) { - Slots[i].AddWeaponList(str, false); + Slots[i].AddWeaponList(type->Slot[i], false); } } } @@ -1385,7 +1401,7 @@ CCMD (setslot) Net_WriteByte(argv.argc()-2); for (int i = 2; i < argv.argc(); i++) { - Net_WriteWeapon(PClass::FindActor(argv[i])); + Net_WriteWeapon(dyn_cast(PClass::FindClass(argv[i]))); } } } @@ -1396,7 +1412,7 @@ CCMD (setslot) // //=========================================================================== -void FWeaponSlots::AddSlot(int slot, PClassActor *type, bool feedback) +void FWeaponSlots::AddSlot(int slot, PClassWeapon *type, bool feedback) { if (type != NULL && !Slots[slot].AddWeapon(type) && feedback) { @@ -1414,19 +1430,26 @@ CCMD (addslot) return; } + PClassWeapon *type= dyn_cast(PClass::FindClass(argv[2])); + if (type == NULL) + { + Printf("%s is not a weapon\n", argv[2]); + return; + } + if (ParsingKeyConf) { KeyConfWeapons.Push(argv.args()); } else if (PlayingKeyConf != NULL) { - PlayingKeyConf->AddSlot(int(slot), PClass::FindActor(argv[2]), false); + PlayingKeyConf->AddSlot(int(slot), type, false); } else { Net_WriteByte(DEM_ADDSLOT); Net_WriteByte(slot); - Net_WriteWeapon(PClass::FindActor(argv[2])); + Net_WriteWeapon(type); } } @@ -1449,7 +1472,7 @@ CCMD (weaponsection) // CCMD addslotdefault // //=========================================================================== -void FWeaponSlots::AddSlotDefault(int slot, PClassActor *type, bool feedback) +void FWeaponSlots::AddSlotDefault(int slot, PClassWeapon *type, bool feedback) { if (type != NULL && type->IsDescendantOf(RUNTIME_CLASS(AWeapon))) { @@ -1474,7 +1497,7 @@ void FWeaponSlots::AddSlotDefault(int slot, PClassActor *type, bool feedback) CCMD (addslotdefault) { - PClassActor *type; + PClassWeapon *type; unsigned int slot; if (argv.argc() != 3 || (slot = atoi (argv[1])) >= NUM_WEAPON_SLOTS) @@ -1483,8 +1506,8 @@ CCMD (addslotdefault) return; } - type = PClass::FindActor(argv[2]); - if (type == NULL || !type->IsDescendantOf (RUNTIME_CLASS(AWeapon))) + type = dyn_cast(PClass::FindClass(argv[2])); + if (type == NULL) { Printf ("%s is not a weapon\n", argv[2]); return; @@ -1496,13 +1519,13 @@ CCMD (addslotdefault) } else if (PlayingKeyConf != NULL) { - PlayingKeyConf->AddSlotDefault(int(slot), PClass::FindActor(argv[2]), false); + PlayingKeyConf->AddSlotDefault(int(slot), type, false); } else { Net_WriteByte(DEM_ADDSLOTDEFAULT); Net_WriteByte(slot); - Net_WriteWeapon(PClass::FindActor(argv[2])); + Net_WriteWeapon(type); } } @@ -1539,7 +1562,7 @@ void P_PlaybackKeyConfWeapons(FWeaponSlots *slots) void P_SetupWeapons_ntohton() { unsigned int i; - PClassActor *cls; + PClassWeapon *cls; Weapons_ntoh.Clear(); Weapons_hton.Clear(); @@ -1552,7 +1575,7 @@ void P_SetupWeapons_ntohton() if (cls->IsDescendantOf(RUNTIME_CLASS(AWeapon))) { - Weapons_ntoh.Push(static_cast(cls)); + Weapons_ntoh.Push(static_cast(cls)); } } qsort(&Weapons_ntoh[1], Weapons_ntoh.Size() - 1, sizeof(Weapons_ntoh[0]), ntoh_cmp); @@ -1578,8 +1601,8 @@ void P_SetupWeapons_ntohton() static int STACK_ARGS ntoh_cmp(const void *a, const void *b) { - PClassActor *c1 = *(PClassActor **)a; - PClassActor *c2 = *(PClassActor **)b; + PClassWeapon *c1 = *(PClassWeapon **)a; + PClassWeapon *c2 = *(PClassWeapon **)b; int g1 = c1->GameFilter == GAME_Any ? 1 : (c1->GameFilter & gameinfo.gametype) ? 0 : 2; int g2 = c2->GameFilter == GAME_Any ? 1 : (c2->GameFilter & gameinfo.gametype) ? 0 : 2; if (g1 != g2) @@ -1619,7 +1642,7 @@ void P_WriteDemoWeaponsChunk(BYTE **demo) void P_ReadDemoWeaponsChunk(BYTE **demo) { int count, i; - PClassActor *type; + PClassWeapon *type; const char *s; count = ReadWord(demo); @@ -1632,7 +1655,7 @@ void P_ReadDemoWeaponsChunk(BYTE **demo) for (i = 1; i < count; ++i) { s = ReadStringConst(demo); - type = PClass::FindActor(s); + type = dyn_cast(PClass::FindClass(s)); // If a demo was recorded with a weapon that is no longer present, // should we report it? Weapons_ntoh[i] = type; @@ -1649,7 +1672,7 @@ void P_ReadDemoWeaponsChunk(BYTE **demo) // //=========================================================================== -void Net_WriteWeapon(PClassActor *type) +void Net_WriteWeapon(PClassWeapon *type) { int index, *index_p; @@ -1681,7 +1704,7 @@ void Net_WriteWeapon(PClassActor *type) // //=========================================================================== -PClassActor *Net_ReadWeapon(BYTE **stream) +PClassWeapon *Net_ReadWeapon(BYTE **stream) { int index; diff --git a/src/g_shared/sbarinfo_commands.cpp b/src/g_shared/sbarinfo_commands.cpp index cbde68ff9..08086e62c 100644 --- a/src/g_shared/sbarinfo_commands.cpp +++ b/src/g_shared/sbarinfo_commands.cpp @@ -2176,7 +2176,7 @@ class CommandPlayerClass : public SBarInfoCommandFlowControl bool foundClass = false; for(unsigned int c = 0;c < PlayerClasses.Size();c++) { - if(stricmp(sc.String, PlayerClasses[c].Type->Meta.GetMetaString(APMETA_DisplayName)) == 0) + if(stricmp(sc.String, PlayerClasses[c].Type->DisplayName) == 0) { foundClass = true; classes.Push(PlayerClasses[c].Type->ClassIndex); diff --git a/src/g_shared/shared_hud.cpp b/src/g_shared/shared_hud.cpp index d13fe3fe1..385971d59 100644 --- a/src/g_shared/shared_hud.cpp +++ b/src/g_shared/shared_hud.cpp @@ -104,16 +104,14 @@ static int statspace; void AM_GetPosition(fixed_t & x, fixed_t & y); -FTextureID GetHUDIcon(const PClass *cls) +FTextureID GetHUDIcon(PClassInventory *cls) { - FTextureID tex; - tex.texnum = cls->Meta.GetMetaInt(HUMETA_AltIcon, 0); - return tex; + return cls->AltHUDIcon; } -void SetHUDIcon(PClass *cls, FTextureID tex) +void SetHUDIcon(PClassInventory *cls, FTextureID tex) { - cls->Meta.SetMetaInt(HUMETA_AltIcon, tex.GetIndex()); + cls->AltHUDIcon = tex; } //--------------------------------------------------------------------------- @@ -450,14 +448,14 @@ static int DrawKeys(player_t * CPlayer, int x, int y) // Drawing Ammo // //--------------------------------------------------------------------------- -static TArray orderedammos; +static TArray orderedammos; static void AddAmmoToList(AWeapon * weapdef) { for(int i=0; i<2;i++) { - PClassActor * ti = i==0? weapdef->AmmoType1 : weapdef->AmmoType2; + PClassAmmo * ti = i==0? weapdef->AmmoType1 : weapdef->AmmoType2; if (ti) { AAmmo * ammodef=(AAmmo*)GetDefaultByType(ti); @@ -516,7 +514,7 @@ static int DrawAmmo(player_t *CPlayer, int x, int y) for(i=orderedammos.Size()-1;i>=0;i--) { - PClassActor * type = orderedammos[i]; + PClassAmmo * type = orderedammos[i]; AAmmo * ammoitem = (AAmmo*)CPlayer->mo->FindInventory(type); AAmmo * inv = ammoitem? ammoitem : (AAmmo*)GetDefaultByType(orderedammos[i]); @@ -605,16 +603,16 @@ static void DrawOneWeapon(player_t * CPlayer, int x, int & y, AWeapon * weapon) } -static void DrawWeapons(player_t * CPlayer, int x, int y) +static void DrawWeapons(player_t *CPlayer, int x, int y) { int k,j; - AInventory * inv; + AInventory *inv; // First draw all weapons in the inventory that are not assigned to a weapon slot - for(inv=CPlayer->mo->Inventory;inv;inv=inv->Inventory) + for(inv = CPlayer->mo->Inventory; inv; inv = inv->Inventory) { if (inv->IsKindOf(RUNTIME_CLASS(AWeapon)) && - !CPlayer->weapons.LocateWeapon(RUNTIME_TYPE(inv), NULL, NULL)) + !CPlayer->weapons.LocateWeapon(static_cast(inv)->GetClass(), NULL, NULL)) { DrawOneWeapon(CPlayer, x, y, static_cast(inv)); } @@ -931,7 +929,7 @@ void HUD_InitHud() } else { - const PClass * ti = PClass::FindClass(sc.String); + PClass *ti = PClass::FindClass(sc.String); if (!ti) { Printf("Unknown item class '%s' in ALTHUDCF\n", sc.String); @@ -950,9 +948,8 @@ void HUD_InitHud() } else tex.SetInvalid(); - if (ti) SetHUDIcon(const_cast(ti), tex); + if (ti) SetHUDIcon(static_cast(ti), tex); } } } } - diff --git a/src/g_strife/a_crusader.cpp b/src/g_strife/a_crusader.cpp index 1b32c8051..5d43b030d 100644 --- a/src/g_strife/a_crusader.cpp +++ b/src/g_strife/a_crusader.cpp @@ -29,18 +29,18 @@ DEFINE_ACTION_FUNCTION(AActor, A_CrusaderChoose) { A_FaceTarget (self); self->angle -= ANGLE_180/16; - P_SpawnMissileZAimed (self, self->z + 40*FRACUNIT, self->target, PClass::FindClass("FastFlameMissile")); + P_SpawnMissileZAimed (self, self->z + 40*FRACUNIT, self->target, PClass::FindActor("FastFlameMissile")); } else { if (P_CheckMissileRange (self)) { A_FaceTarget (self); - P_SpawnMissileZAimed (self, self->z + 56*FRACUNIT, self->target, PClass::FindClass("CrusaderMissile")); + P_SpawnMissileZAimed (self, self->z + 56*FRACUNIT, self->target, PClass::FindActor("CrusaderMissile")); self->angle -= ANGLE_45/32; - P_SpawnMissileZAimed (self, self->z + 40*FRACUNIT, self->target, PClass::FindClass("CrusaderMissile")); + P_SpawnMissileZAimed (self, self->z + 40*FRACUNIT, self->target, PClass::FindActor("CrusaderMissile")); self->angle += ANGLE_45/16; - P_SpawnMissileZAimed (self, self->z + 40*FRACUNIT, self->target, PClass::FindClass("CrusaderMissile")); + P_SpawnMissileZAimed (self, self->z + 40*FRACUNIT, self->target, PClass::FindActor("CrusaderMissile")); self->angle -= ANGLE_45/16; self->reactiontime += 15; } @@ -54,7 +54,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CrusaderSweepLeft) PARAM_ACTION_PROLOGUE; self->angle += ANGLE_90/16; - AActor *misl = P_SpawnMissileZAimed (self, self->z + 48*FRACUNIT, self->target, PClass::FindClass("FastFlameMissile")); + AActor *misl = P_SpawnMissileZAimed (self, self->z + 48*FRACUNIT, self->target, PClass::FindActor("FastFlameMissile")); if (misl != NULL) { misl->velz += FRACUNIT; @@ -67,7 +67,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CrusaderSweepRight) PARAM_ACTION_PROLOGUE; self->angle -= ANGLE_90/16; - AActor *misl = P_SpawnMissileZAimed (self, self->z + 48*FRACUNIT, self->target, PClass::FindClass("FastFlameMissile")); + AActor *misl = P_SpawnMissileZAimed (self, self->z + 48*FRACUNIT, self->target, PClass::FindActor("FastFlameMissile")); if (misl != NULL) { misl->velz += FRACUNIT; diff --git a/src/g_strife/a_inquisitor.cpp b/src/g_strife/a_inquisitor.cpp index 3835a314f..0894ffdf0 100644 --- a/src/g_strife/a_inquisitor.cpp +++ b/src/g_strife/a_inquisitor.cpp @@ -63,13 +63,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_InquisitorAttack) self->z += 32*FRACBITS; self->angle -= ANGLE_45/32; - proj = P_SpawnMissileZAimed (self, self->z, self->target, PClass::FindClass("InquisitorShot")); + proj = P_SpawnMissileZAimed (self, self->z, self->target, PClass::FindActor("InquisitorShot")); if (proj != NULL) { proj->velz += 9*FRACUNIT; } self->angle += ANGLE_45/16; - proj = P_SpawnMissileZAimed (self, self->z, self->target, PClass::FindClass("InquisitorShot")); + proj = P_SpawnMissileZAimed (self, self->z, self->target, PClass::FindActor("InquisitorShot")); if (proj != NULL) { proj->velz += 16*FRACUNIT; diff --git a/src/g_strife/a_sentinel.cpp b/src/g_strife/a_sentinel.cpp index 993cd1283..4e9303332 100644 --- a/src/g_strife/a_sentinel.cpp +++ b/src/g_strife/a_sentinel.cpp @@ -53,7 +53,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SentinelAttack) return 0; } - missile = P_SpawnMissileZAimed (self, self->z + 32*FRACUNIT, self->target, PClass::FindClass("SentinelFX2")); + missile = P_SpawnMissileZAimed (self, self->z + 32*FRACUNIT, self->target, PClass::FindActor("SentinelFX2")); if (missile != NULL && (missile->velx | missile->vely) != 0) { diff --git a/src/g_strife/a_strifeweapons.cpp b/src/g_strife/a_strifeweapons.cpp index 3cd8a15b2..4e3db52ae 100644 --- a/src/g_strife/a_strifeweapons.cpp +++ b/src/g_strife/a_strifeweapons.cpp @@ -341,7 +341,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireMiniMissile) savedangle = self->angle; self->angle += pr_minimissile.Random2() << (19 - player->accuracy * 5 / 100); player->mo->PlayAttacking2 (); - P_SpawnPlayerMissile (self, PClass::FindClass("MiniMissile")); + P_SpawnPlayerMissile (self, PClass::FindActor("MiniMissile")); self->angle = savedangle; return 0; } @@ -359,7 +359,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_RocketInFlight) AActor *trail; S_Sound (self, CHAN_VOICE, "misc/missileinflight", 1, ATTN_NORM); - P_SpawnPuff (self, PClass::FindClass("MiniMissilePuff"), self->x, self->y, self->z, self->angle - ANGLE_180, 2, PF_HITTHING); + P_SpawnPuff (self, PClass::FindActor("MiniMissilePuff"), self->x, self->y, self->z, self->angle - ANGLE_180, 2, PF_HITTHING); trail = Spawn("RocketTrail", self->x - self->velx, self->y - self->vely, self->z, ALLOW_REPLACE); if (trail != NULL) { @@ -409,7 +409,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireFlamer) } self->angle += pr_flamethrower.Random2() << 18; - self = P_SpawnPlayerMissile (self, PClass::FindClass("FlameMissile")); + self = P_SpawnPlayerMissile (self, PClass::FindActor("FlameMissile")); if (self != NULL) { self->velz += 5*FRACUNIT; @@ -508,7 +508,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireMauler2) } self->player->mo->PlayAttacking2 (); } - P_SpawnPlayerMissile (self, PClass::FindClass("MaulerTorpedo")); + P_SpawnPlayerMissile (self, PClass::FindActor("MaulerTorpedo")); P_DamageMobj (self, self, NULL, 20, self->DamageType); P_ThrustMobj (self, self->angle + ANGLE_180, 0x7D000); return 0; @@ -1012,7 +1012,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireSigil2) P_DamageMobj (self, self, NULL, 2*4, 0, DMG_NO_ARMOR); S_Sound (self, CHAN_WEAPON, "weapons/sigilcharge", 1, ATTN_NORM); - P_SpawnPlayerMissile (self, PClass::FindClass("SpectralLightningH1")); + P_SpawnPlayerMissile (self, PClass::FindActor("SpectralLightningH1")); return 0; } @@ -1073,7 +1073,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireSigil4) P_BulletSlope (self, &linetarget); if (linetarget != NULL) { - spot = P_SpawnPlayerMissile (self, 0,0,0, PClass::FindClass("SpectralLightningBigV1"), self->angle, &linetarget); + spot = P_SpawnPlayerMissile (self, 0,0,0, PClass::FindActor("SpectralLightningBigV1"), self->angle, &linetarget); if (spot != NULL) { spot->tracer = linetarget; @@ -1081,7 +1081,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireSigil4) } else { - spot = P_SpawnPlayerMissile (self, PClass::FindClass("SpectralLightningBigV1")); + spot = P_SpawnPlayerMissile (self, PClass::FindActor("SpectralLightningBigV1")); if (spot != NULL) { spot->velx += FixedMul (spot->Speed, finecosine[self->angle >> ANGLETOFINESHIFT]); @@ -1109,7 +1109,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireSigil5) P_DamageMobj (self, self, NULL, 5*4, 0, DMG_NO_ARMOR); S_Sound (self, CHAN_WEAPON, "weapons/sigilcharge", 1, ATTN_NORM); - P_SpawnPlayerMissile (self, PClass::FindClass("SpectralLightningBigBall1")); + P_SpawnPlayerMissile (self, PClass::FindActor("SpectralLightningBigBall1")); return 0; } diff --git a/src/info.cpp b/src/info.cpp index 4f666b767..652e1c1aa 100644 --- a/src/info.cpp +++ b/src/info.cpp @@ -107,7 +107,9 @@ int GetSpriteIndex(const char * spritename) return (lastindex = (int)sprites.Push (temp)); } -IMPLEMENT_CLASS(PClassActor) +IMPLEMENT_POINTY_CLASS(PClassActor) + DECLARE_POINTER(DropItems) +END_POINTERS //========================================================================== // @@ -173,6 +175,28 @@ PClassActor::PClassActor() StateList = NULL; DamageFactors = NULL; PainChances = NULL; + + Obituary = Obituary; + HitObituary = HitObituary; + DeathHeight = -1; + BurnHeight = -1; + GibHealth = INT_MIN; + WoundHealth = 6; + PoisonDamage = 0; + 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; } //========================================================================== @@ -202,6 +226,45 @@ PClassActor::~PClassActor() } } +//========================================================================== +// +// PClassActor :: Derive +// +//========================================================================== + +void PClassActor::Derive(PClass *newclass) +{ + assert(newclass->IsKindOf(RUNTIME_CLASS(PClassActor))); + Super::Derive(newclass); + PClassActor *newa = static_cast(newclass); + + newa->Obituary = Obituary; + newa->HitObituary = HitObituary; + newa->DeathHeight = DeathHeight; + newa->BurnHeight = BurnHeight; + newa->BloodColor = BloodColor; + newa->GibHealth = GibHealth; + newa->WoundHealth = WoundHealth; + newa->PoisonDamage = PoisonDamage; + newa->FastSpeed = FastSpeed; + newa->RDFactor = RDFactor; + newa->CameraHeight = CameraHeight; + newa->HowlSound = HowlSound; + newa->BloodType = BloodType; + newa->BloodType2 = BloodType2; + newa->BloodType3 = BloodType3; + + newa->DropItems = DropItems; + + newa->DontHurtShooter = DontHurtShooter; + newa->ExplosionRadius = ExplosionRadius; + newa->ExplosionDamage = ExplosionDamage; + newa->MeleeDamage = MeleeDamage; + newa->MeleeSound = MeleeSound; + newa->MissileName = MissileName; + newa->MissileHeight = MissileHeight; +} + //========================================================================== // // PClassActor :: PropagateMark diff --git a/src/info.h b/src/info.h index ebc2f1250..bf7a38fbc 100644 --- a/src/info.h +++ b/src/info.h @@ -44,6 +44,7 @@ #include "dobject.h" #include "doomdef.h" #include "vm.h" +#include "s_sound.h" const BYTE SF_FULLBRIGHT = 0x40; @@ -124,10 +125,14 @@ FArchive &operator<< (FArchive &arc, FState *&state); typedef TMap DmgFactors; typedef TMap PainChanceList; +class DDropItem; class PClassActor : public PClass { DECLARE_CLASS(PClassActor, PClass); + HAS_OBJECT_POINTERS; +protected: + virtual void Derive(PClass *newclass); public: static void StaticInit (); static void StaticSetActorNums (); @@ -163,6 +168,32 @@ public: FStateLabels *StateList; DmgFactors *DamageFactors; PainChanceList *PainChances; + FString Obituary; // Player was killed by this actor + FString HitObituary; // Player was killed by this actor in melee + fixed_t DeathHeight; // Height on normal death + fixed_t BurnHeight; // Height on burning death + PalEntry BloodColor; // Colorized blood + int GibHealth; // Negative health below which this monster dies an extreme death + int WoundHealth; // Health needed to enter wound state + int PoisonDamage; // Amount of poison damage + fixed_t FastSpeed; // Speed in fast mode + fixed_t RDFactor; // Radius damage factor + fixed_t CameraHeight; // Height of camera when used as such + FSoundID HowlSound; // Sound being played when electrocuted or poisoned + FName BloodType; // Blood replacement type + FName BloodType2; // Bloopsplatter replacement type + FName BloodType3; // AxeBlood replacement type + + DDropItem *DropItems; + + // Old Decorate compatibility stuff + bool DontHurtShooter; + int ExplosionRadius; + int ExplosionDamage; + int MeleeDamage; + FSoundID MeleeSound; + FName MissileName; + fixed_t MissileHeight; }; inline PClassActor *PClass::FindActor(FName name) diff --git a/src/m_cheat.cpp b/src/m_cheat.cpp index abf2983ae..ad948264e 100644 --- a/src/m_cheat.cpp +++ b/src/m_cheat.cpp @@ -144,7 +144,7 @@ void cht_DoCheat (player_t *player, int cheat) break; case CHT_MORPH: - msg = cht_Morph (player, PClass::FindClass (gameinfo.gametype == GAME_Heretic ? NAME_ChickenPlayer : NAME_PigPlayer), true); + msg = cht_Morph (player, static_cast(PClass::FindClass (gameinfo.gametype == GAME_Heretic ? NAME_ChickenPlayer : NAME_PigPlayer)), true); break; case CHT_NOTARGET: @@ -521,13 +521,13 @@ void cht_DoCheat (player_t *player, int cheat) Printf ("%s is a cheater: %s\n", player->userinfo.netname, msg); } -const char *cht_Morph (player_t *player, const PClass *morphclass, bool quickundo) +const char *cht_Morph (player_t *player, PClassPlayerPawn *morphclass, bool quickundo) { if (player->mo == NULL) { return ""; } - PClass *oldclass = player->mo->GetClass(); + PClassPlayerPawn *oldclass = player->mo->GetClass(); // Set the standard morph style for the current game int style = MORPH_UNDOBYTOMEOFPOWER; @@ -750,7 +750,7 @@ void cht_Give (player_t *player, const char *name, int amount) // is in a weapon slot. if (static_cast(type)->GameFilter == GAME_Any || (static_cast(type)->GameFilter & gameinfo.gametype) || - player->weapons.LocateWeapon(static_cast(type), NULL, NULL)) + player->weapons.LocateWeapon(static_cast(type), NULL, NULL)) { AWeapon *def = (AWeapon*)GetDefaultByType (type); if (!(def->WeaponFlags & WIF_CHEATNOTWEAPON)) diff --git a/src/m_cheat.h b/src/m_cheat.h index e56c69198..9480b3372 100644 --- a/src/m_cheat.h +++ b/src/m_cheat.h @@ -29,11 +29,12 @@ // [RH] Functions that actually perform the cheating class player_t; -class PClass; +class PClassPlayerPawn; + void cht_DoCheat (player_t *player, int cheat); void cht_Give (player_t *player, const char *item, int amount=1); void cht_Take (player_t *player, const char *item, int amount=1); void cht_Suicide (player_t *player); -const char *cht_Morph (player_t *player, const PClass *morphclass, bool quickundo); +const char *cht_Morph (player_t *player, PClassPlayerPawn *morphclass, bool quickundo); #endif diff --git a/src/m_menu.cpp b/src/m_menu.cpp index 88eac1edf..2045e064d 100644 --- a/src/m_menu.cpp +++ b/src/m_menu.cpp @@ -1883,7 +1883,7 @@ static void SCClass (int option) if (option == 3) playerclass = "Random"; else - playerclass = PlayerClasses[option].Type->Meta.GetMetaString (APMETA_DisplayName); + playerclass = PlayerClasses[option].Type->DisplayName; if (EpiDef.numitems > 1) { @@ -2299,7 +2299,7 @@ static void M_PlayerSetupDrawer () x = SmallFont->StringWidth ("Class") + 8 + PSetupDef.x; screen->DrawText (SmallFont, label, PSetupDef.x, PSetupDef.y + LINEHEIGHT*5+yo, "Class", DTA_Clean, true, TAG_DONE); screen->DrawText (SmallFont, value, x, PSetupDef.y + LINEHEIGHT*5+yo, - pclass == -1 ? "Random" : PlayerClasses[pclass].Type->Meta.GetMetaString (APMETA_DisplayName), + pclass == -1 ? "Random" : PlayerClasses[pclass].Type->DisplayName, DTA_Clean, true, TAG_DONE); // Draw skin setting @@ -2567,8 +2567,7 @@ static void M_ChangeClass (int choice) else type = (type < (int)PlayerClasses.Size () - 1) ? type + 1 : -1; - cvar_set ("playerclass", type < 0 ? "Random" : - PlayerClasses[type].Type->Meta.GetMetaString (APMETA_DisplayName)); + cvar_set ("playerclass", type < 0 ? "Random" : PlayerClasses[type].Type->DisplayName); } static void M_ChangeSkin (int choice) @@ -3964,8 +3963,7 @@ void M_Init (void) { if (!(PlayerClasses[i].Flags & PCF_NOMENU)) { - ClassMenuItems[n].name = - PlayerClasses[i].Type->Meta.GetMetaString (APMETA_DisplayName); + ClassMenuItems[n].name = PlayerClasses[i].Type->DisplayName; n++; } } @@ -3979,8 +3977,7 @@ void M_Init (void) { if (n == 0) { - ClassMenuItems[0].name = - PlayerClasses[0].Type->Meta.GetMetaString (APMETA_DisplayName); + ClassMenuItems[0].name = PlayerClasses[0].Type->DisplayName; } ClassMenuDef.numitems = 1; } diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 7afc750f7..576709a9d 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -3109,7 +3109,7 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, SDWORD *args) } else { - return actor->GetClass()->Meta.GetMetaFixed(AMETA_CameraHeight, actor->height/2); + return actor->GetCameraHeight(); } } else return 0; @@ -6358,7 +6358,7 @@ int DLevelScript::RunScript () { int tag = STACK(7); FName playerclass_name = FBehavior::StaticLookupString(STACK(6)); - const PClass *playerclass = PClass::FindClass (playerclass_name); + PClassPlayerPawn *playerclass = dyn_cast(PClass::FindClass (playerclass_name)); FName monsterclass_name = FBehavior::StaticLookupString(STACK(5)); const PClass *monsterclass = PClass::FindClass (monsterclass_name); int duration = STACK(4); diff --git a/src/p_enemy.cpp b/src/p_enemy.cpp index cd94bf76d..c08e9ff7f 100644 --- a/src/p_enemy.cpp +++ b/src/p_enemy.cpp @@ -2877,8 +2877,13 @@ void ModifyDropAmount(AInventory *inv, int dropamount) else if (inv->IsKindOf (RUNTIME_CLASS(AAmmo))) { // Half ammo when dropped by bad guys. - inv->Amount = inv->GetClass()->Meta.GetMetaInt (AIMETA_DropAmount, MAX(1, FixedMul(inv->Amount, dropammofactor))); - inv->ItemFlags|=flagmask; + int amount = static_cast(inv->GetClass())->DropAmount; + if (amount <= 0) + { + amount = FixedMul(inv->Amount, dropammofactor); + } + inv->Amount = amount; + inv->ItemFlags |= flagmask; } else if (inv->IsKindOf (RUNTIME_CLASS(AWeapon))) { diff --git a/src/p_interaction.cpp b/src/p_interaction.cpp index 3952251a2..176309f44 100644 --- a/src/p_interaction.cpp +++ b/src/p_interaction.cpp @@ -243,17 +243,13 @@ void ClientObituary (AActor *self, AActor *inflictor, AActor *attacker) { message = GStrings("OB_MONTELEFRAG"); } - else if (mod == NAME_Melee) + else if (mod == NAME_Melee && attacker->GetClass()->HitObituary.IsNotEmpty()) { - message = attacker->GetClass()->Meta.GetMetaString (AMETA_HitObituary); - if (message == NULL) - { - message = attacker->GetClass()->Meta.GetMetaString (AMETA_Obituary); - } + message = attacker->GetClass()->HitObituary; } - else + else if (attacker->GetClass()->Obituary.IsNotEmpty()) { - message = attacker->GetClass()->Meta.GetMetaString (AMETA_Obituary); + message = attacker->GetClass()->Obituary; } } } @@ -274,13 +270,13 @@ void ClientObituary (AActor *self, AActor *inflictor, AActor *attacker) if (mod == NAME_Telefrag) message = GStrings("OB_MPTELEFRAG"); if (message == NULL) { - if (inflictor != NULL) + if (inflictor != NULL && inflictor->GetClass()->Obituary.IsNotEmpty()) { - message = inflictor->GetClass()->Meta.GetMetaString (AMETA_Obituary); + message = inflictor->GetClass()->Obituary; } - if (message == NULL && attacker->player->ReadyWeapon != NULL) + if (message == NULL && attacker->player->ReadyWeapon != NULL && attacker->player->ReadyWeapon->GetClass()->Obituary.IsNotEmpty()) { - message = attacker->player->ReadyWeapon->GetClass()->Meta.GetMetaString (AMETA_Obituary); + message = attacker->player->ReadyWeapon->GetClass()->Obituary; } if (message == NULL) { @@ -320,12 +316,7 @@ EXTERN_CVAR (Int, fraglimit) static int GibHealth(AActor *actor) { - return -abs( - actor->GetClass()->Meta.GetMetaInt ( - AMETA_GibHealth, - gameinfo.gametype & GAME_DoomChex ? - -actor->SpawnHealth() : - -actor->SpawnHealth()/2)); + return -abs(actor->GetGibHealth()); } void AActor::Die (AActor *source, AActor *inflictor) @@ -399,22 +390,22 @@ void AActor::Die (AActor *source, AActor *inflictor) flags6 |= MF6_KILLED; // [RH] Allow the death height to be overridden using metadata. - fixed_t metaheight = 0; + fixed_t metaheight = -1; if (DamageType == NAME_Fire) { - metaheight = GetClass()->Meta.GetMetaFixed (AMETA_BurnHeight); + metaheight = GetClass()->BurnHeight; } - if (metaheight == 0) + if (metaheight < 0) { - metaheight = GetClass()->Meta.GetMetaFixed (AMETA_DeathHeight); + metaheight = GetClass()->DeathHeight; } - if (metaheight != 0) + if (metaheight < 0) { - height = MAX (metaheight, 0); + height >>= 2; } else { - height >>= 2; + height = MAX (metaheight, 0); } // [RH] If the thing has a special, execute and remove it @@ -1271,7 +1262,7 @@ void P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage woundstate = target->FindState(NAME_Wound, mod); if (woundstate != NULL) { - int woundhealth = RUNTIME_TYPE(target)->Meta.GetMetaInt (AMETA_WoundHealth, 6); + int woundhealth = target->GetClass()->WoundHealth; if (target->health <= woundhealth) { diff --git a/src/p_local.h b/src/p_local.h index 89c8f07ea..822d6f787 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -103,7 +103,7 @@ enum EPuffFlags PF_TEMPORARY = 4 }; -AActor *P_SpawnPuff (AActor *source, const PClass *pufftype, fixed_t x, fixed_t y, fixed_t z, angle_t dir, int updown, int flags = 0); +AActor *P_SpawnPuff (AActor *source, PClassActor *pufftype, fixed_t x, fixed_t y, fixed_t z, angle_t dir, int updown, int flags = 0); void P_SpawnBlood (fixed_t x, fixed_t y, fixed_t z, angle_t dir, int damage, AActor *originator); void P_BloodSplatter (fixed_t x, fixed_t y, fixed_t z, AActor *originator); void P_BloodSplatter2 (fixed_t x, fixed_t y, fixed_t z, AActor *originator); @@ -114,15 +114,15 @@ void P_ExplodeMissile (AActor *missile, line_t *explodeline, AActor *target); AActor *P_SpawnMissile (AActor* source, AActor* dest, const PClass *type, AActor* owner = NULL); AActor *P_SpawnMissileZ (AActor* source, fixed_t z, AActor* dest, const PClass *type); AActor *P_SpawnMissileXYZ (fixed_t x, fixed_t y, fixed_t z, AActor *source, AActor *dest, const PClass *type, bool checkspawn = true, AActor *owner = NULL); -AActor *P_SpawnMissileAngle (AActor *source, const PClass *type, angle_t angle, fixed_t velz); -AActor *P_SpawnMissileAngleSpeed (AActor *source, const PClass *type, angle_t angle, fixed_t velz, fixed_t speed); -AActor *P_SpawnMissileAngleZ (AActor *source, fixed_t z, const PClass *type, angle_t angle, fixed_t velz); -AActor *P_SpawnMissileAngleZSpeed (AActor *source, fixed_t z, const PClass *type, angle_t angle, fixed_t velz, fixed_t speed, AActor *owner=NULL, bool checkspawn = true); -AActor *P_SpawnMissileZAimed (AActor *source, fixed_t z, AActor *dest, const PClass *type); +AActor *P_SpawnMissileAngle (AActor *source, PClassActor *type, angle_t angle, fixed_t velz); +AActor *P_SpawnMissileAngleSpeed (AActor *source, PClassActor *type, angle_t angle, fixed_t velz, fixed_t speed); +AActor *P_SpawnMissileAngleZ (AActor *source, fixed_t z, PClassActor *type, angle_t angle, fixed_t velz); +AActor *P_SpawnMissileAngleZSpeed (AActor *source, fixed_t z, PClassActor *type, angle_t angle, fixed_t velz, fixed_t speed, AActor *owner=NULL, bool checkspawn = true); +AActor *P_SpawnMissileZAimed (AActor *source, fixed_t z, AActor *dest, PClassActor *type); -AActor *P_SpawnPlayerMissile (AActor* source, const PClass *type); -AActor *P_SpawnPlayerMissile (AActor *source, const PClass *type, angle_t angle); -AActor *P_SpawnPlayerMissile (AActor *source, fixed_t x, fixed_t y, fixed_t z, const PClass *type, angle_t angle, +AActor *P_SpawnPlayerMissile (AActor* source, PClassActor *type); +AActor *P_SpawnPlayerMissile (AActor *source, PClassActor *type, angle_t angle); +AActor *P_SpawnPlayerMissile (AActor *source, fixed_t x, fixed_t y, fixed_t z, PClassActor *type, angle_t angle, AActor **pLineTarget = NULL, AActor **MissileActor = NULL, bool nofreeaim = false); void P_CheckFakeFloorTriggers (AActor *mo, fixed_t oldz, bool oldz_has_viewheight=false); diff --git a/src/p_map.cpp b/src/p_map.cpp index 0642ee440..02eb8aa3f 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -3588,7 +3588,7 @@ void P_TraceBleed (int damage, fixed_t x, fixed_t y, fixed_t z, AActor *actor, a { if (bleedtrace.HitType == TRACE_HitWall) { - PalEntry bloodcolor = (PalEntry)actor->GetClass()->Meta.GetMetaInt(AMETA_BloodColor); + PalEntry bloodcolor = actor->GetClass()->BloodColor; if (bloodcolor != 0) { bloodcolor.r>>=1; // the full color is too bright for blood decals @@ -4325,7 +4325,7 @@ void P_RadiusAttack (AActor *bombspot, AActor *bombsource, int bombdamage, int b { points = points * splashfactor; } - points *= thing->GetClass()->Meta.GetMetaFixed(AMETA_RDFactor, FRACUNIT)/(float)FRACUNIT; + points *= thing->GetClass()->RDFactor/(float)FRACUNIT; if (points > 0.f && P_CheckSight (thing, bombspot, 1)) { // OK to damage; target is in direct path @@ -4391,7 +4391,7 @@ void P_RadiusAttack (AActor *bombspot, AActor *bombsource, int bombdamage, int b int damage = Scale (bombdamage, bombdistance-dist, bombdistance); damage = (int)((float)damage * splashfactor); - damage = Scale(damage, thing->GetClass()->Meta.GetMetaFixed(AMETA_RDFactor, FRACUNIT), FRACUNIT); + damage = Scale(damage, thing->GetClass()->RDFactor, FRACUNIT); if (damage > 0) { P_DamageMobj (thing, bombspot, bombsource, damage, bombmod); @@ -4598,8 +4598,8 @@ void P_DoCrunch (AActor *thing, FChangePosition *cpos) if ((!(thing->flags&MF_NOBLOOD)) && (!(thing->flags2&(MF2_INVULNERABLE|MF2_DORMANT)))) { - PalEntry bloodcolor = (PalEntry)thing->GetClass()->Meta.GetMetaInt(AMETA_BloodColor); - const PClass *bloodcls = PClass::FindClass((ENamedName)thing->GetClass()->Meta.GetMetaInt(AMETA_BloodType, NAME_Blood)); + PalEntry bloodcolor = thing->GetClass()->BloodColor; + PClassActor *bloodcls = PClass::FindActor(thing->GetClass()->BloodType); P_TraceBleed (cpos->crushchange, thing); if (cl_bloodtype <= 1 && bloodcls != NULL) diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index e3b0dbba8..9c0ddbdb3 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -1069,7 +1069,7 @@ bool AActor::Grind(bool items) if (isgeneric) // Not a custom crush state, so colorize it appropriately. { S_Sound (this, CHAN_BODY, "misc/fallingsplat", 1, ATTN_IDLE); - PalEntry bloodcolor = PalEntry(GetClass()->Meta.GetMetaInt(AMETA_BloodColor)); + PalEntry bloodcolor = GetClass()->BloodColor; if (bloodcolor!=0) Translation = TRANSLATION(TRANSLATION_Blood, bloodcolor.a); } return false; @@ -1113,7 +1113,7 @@ bool AActor::Grind(bool items) } S_Sound (this, CHAN_BODY, "misc/fallingsplat", 1, ATTN_IDLE); - PalEntry bloodcolor = (PalEntry)this->GetClass()->Meta.GetMetaInt(AMETA_BloodColor); + PalEntry bloodcolor = GetClass()->BloodColor; if (bloodcolor!=0) gib->Translation = TRANSLATION(TRANSLATION_Blood, bloodcolor.a); } if (flags & MF_ICECORPSE) @@ -2651,7 +2651,7 @@ int AActor::GetMissileDamage (int mask, int add) void AActor::Howl () { - int howl = GetClass()->Meta.GetMetaInt(AMETA_HowlSound); + FSoundID howl = GetClass()->HowlSound; if (!S_IsActorPlayingSomething(this, CHAN_BODY, howl)) { S_Sound (this, CHAN_BODY, howl, 1, ATTN_NORM); @@ -3553,9 +3553,8 @@ AActor *AActor::StaticSpawn (PClassActor *type, fixed_t ix, fixed_t iy, fixed_t actor->frame = st->GetFrame(); actor->renderflags = (actor->renderflags & ~RF_FULLBRIGHT) | st->GetFullbright(); actor->touching_sectorlist = NULL; // NULL head of sector list // phares 3/13/98 - if (G_SkillProperty(SKILLP_FastMonsters)) - actor->Speed = actor->GetClass()->Meta.GetMetaFixed(AMETA_FastSpeed, actor->Speed); - + if (G_SkillProperty(SKILLP_FastMonsters) && actor->GetClass()->FastSpeed >= 0) + actor->Speed = actor->GetClass()->FastSpeed; // set subsector and/or block links actor->LinkToWorld (SpawningMapThing); @@ -4445,7 +4444,7 @@ AActor *P_SpawnMapThing (FMapThing *mthing, int position) // P_SpawnPuff // -AActor *P_SpawnPuff (AActor *source, const PClass *pufftype, fixed_t x, fixed_t y, fixed_t z, angle_t dir, int updown, int flags) +AActor *P_SpawnPuff (AActor *source, PClassActor *pufftype, fixed_t x, fixed_t y, fixed_t z, angle_t dir, int updown, int flags) { AActor *puff; @@ -4507,8 +4506,8 @@ AActor *P_SpawnPuff (AActor *source, const PClass *pufftype, fixed_t x, fixed_t void P_SpawnBlood (fixed_t x, fixed_t y, fixed_t z, angle_t dir, int damage, AActor *originator) { AActor *th; - PalEntry bloodcolor = (PalEntry)originator->GetClass()->Meta.GetMetaInt(AMETA_BloodColor); - const PClass *bloodcls = PClass::FindClass((ENamedName)originator->GetClass()->Meta.GetMetaInt(AMETA_BloodType, NAME_Blood)); + PalEntry bloodcolor = originator->GetClass()->BloodColor; + PClassActor *bloodcls = PClass::FindActor(originator->GetClass()->BloodType); int bloodtype = cl_bloodtype; @@ -4569,15 +4568,15 @@ void P_SpawnBlood (fixed_t x, fixed_t y, fixed_t z, angle_t dir, int damage, AAc void P_BloodSplatter (fixed_t x, fixed_t y, fixed_t z, AActor *originator) { - PalEntry bloodcolor = (PalEntry)originator->GetClass()->Meta.GetMetaInt(AMETA_BloodColor); - const PClass *bloodcls = PClass::FindClass((ENamedName)originator->GetClass()->Meta.GetMetaInt(AMETA_BloodType2, NAME_BloodSplatter)); + PalEntry bloodcolor = originator->GetClass()->BloodColor; + PClassActor *bloodcls = PClass::FindActor(originator->GetClass()->BloodType2); int bloodtype = cl_bloodtype; if (bloodcls != NULL && !(GetDefaultByType(bloodcls)->flags4 & MF4_ALLOWPARTICLES)) bloodtype = 0; - if (bloodcls!=NULL && bloodtype <= 1) + if (bloodcls != NULL && bloodtype <= 1) { AActor *mo; @@ -4607,8 +4606,8 @@ void P_BloodSplatter (fixed_t x, fixed_t y, fixed_t z, AActor *originator) void P_BloodSplatter2 (fixed_t x, fixed_t y, fixed_t z, AActor *originator) { - PalEntry bloodcolor = (PalEntry)originator->GetClass()->Meta.GetMetaInt(AMETA_BloodColor); - const PClass *bloodcls = PClass::FindClass((ENamedName)originator->GetClass()->Meta.GetMetaInt(AMETA_BloodType3, NAME_AxeBlood)); + PalEntry bloodcolor = originator->GetClass()->BloodColor; + PClassActor *bloodcls = PClass::FindActor(originator->GetClass()->BloodType3); int bloodtype = cl_bloodtype; @@ -4646,8 +4645,8 @@ void P_BloodSplatter2 (fixed_t x, fixed_t y, fixed_t z, AActor *originator) void P_RipperBlood (AActor *mo, AActor *bleeder) { fixed_t x, y, z; - PalEntry bloodcolor = (PalEntry)bleeder->GetClass()->Meta.GetMetaInt(AMETA_BloodColor); - const PClass *bloodcls = PClass::FindClass((ENamedName)bleeder->GetClass()->Meta.GetMetaInt(AMETA_BloodType, NAME_Blood)); + PalEntry bloodcolor = bleeder->GetClass()->BloodColor; + PClassActor *bloodcls = PClass::FindActor(bleeder->GetClass()->BloodType); x = mo->x + (pr_ripperblood.Random2 () << 12); y = mo->y + (pr_ripperblood.Random2 () << 12); @@ -5031,11 +5030,12 @@ void P_PlaySpawnSound(AActor *missile, AActor *spawner) } } -static fixed_t GetDefaultSpeed(const PClass *type) +static fixed_t GetDefaultSpeed(PClassActor *type) { - if (type == NULL) return 0; - else if (G_SkillProperty(SKILLP_FastMonsters)) - return type->Meta.GetMetaFixed(AMETA_FastSpeed, GetDefaultByType(type)->Speed); + if (type == NULL) + return 0; + else if (G_SkillProperty(SKILLP_FastMonsters) && type->FastSpeed >= 0) + return type->FastSpeed; else return GetDefaultByType(type)->Speed; } @@ -5158,7 +5158,7 @@ AActor * P_OldSpawnMissile(AActor * source, AActor * owner, AActor * dest, const // //--------------------------------------------------------------------------- -AActor *P_SpawnMissileAngle (AActor *source, const PClass *type, +AActor *P_SpawnMissileAngle (AActor *source, PClassActor *type, angle_t angle, fixed_t velz) { return P_SpawnMissileAngleZSpeed (source, source->z + 32*FRACUNIT, @@ -5166,13 +5166,13 @@ AActor *P_SpawnMissileAngle (AActor *source, const PClass *type, } AActor *P_SpawnMissileAngleZ (AActor *source, fixed_t z, - const PClass *type, angle_t angle, fixed_t velz) + PClassActor *type, angle_t angle, fixed_t velz) { return P_SpawnMissileAngleZSpeed (source, z, type, angle, velz, GetDefaultSpeed (type)); } -AActor *P_SpawnMissileZAimed (AActor *source, fixed_t z, AActor *dest, const PClass *type) +AActor *P_SpawnMissileZAimed (AActor *source, fixed_t z, AActor *dest, PClassActor *type) { angle_t an; fixed_t dist; @@ -5201,7 +5201,7 @@ AActor *P_SpawnMissileZAimed (AActor *source, fixed_t z, AActor *dest, const PCl // //--------------------------------------------------------------------------- -AActor *P_SpawnMissileAngleSpeed (AActor *source, const PClass *type, +AActor *P_SpawnMissileAngleSpeed (AActor *source, PClassActor *type, angle_t angle, fixed_t velz, fixed_t speed) { return P_SpawnMissileAngleZSpeed (source, source->z + 32*FRACUNIT, @@ -5209,7 +5209,7 @@ AActor *P_SpawnMissileAngleSpeed (AActor *source, const PClass *type, } AActor *P_SpawnMissileAngleZSpeed (AActor *source, fixed_t z, - const PClass *type, angle_t angle, fixed_t velz, fixed_t speed, AActor *owner, bool checkspawn) + PClassActor *type, angle_t angle, fixed_t velz, fixed_t speed, AActor *owner, bool checkspawn) { AActor *mo; @@ -5239,18 +5239,18 @@ AActor *P_SpawnMissileAngleZSpeed (AActor *source, fixed_t z, ================ */ -AActor *P_SpawnPlayerMissile (AActor *source, const PClass *type) +AActor *P_SpawnPlayerMissile (AActor *source, PClassActor *type) { return P_SpawnPlayerMissile (source, 0, 0, 0, type, source->angle); } -AActor *P_SpawnPlayerMissile (AActor *source, const PClass *type, angle_t angle) +AActor *P_SpawnPlayerMissile (AActor *source, PClassActor *type, angle_t angle) { return P_SpawnPlayerMissile (source, 0, 0, 0, type, angle); } AActor *P_SpawnPlayerMissile (AActor *source, fixed_t x, fixed_t y, fixed_t z, - const PClass *type, angle_t angle, AActor **pLineTarget, AActor **pMissileActor, + PClassActor *type, angle_t angle, AActor **pLineTarget, AActor **pMissileActor, bool nofreeaim) { static const int angdiff[3] = { -1<<26, 1<<26, 0 }; @@ -5451,7 +5451,7 @@ int AActor::DoSpecialDamage (AActor *target, int damage) { if (target->player) { - int poisondamage = GetClass()->Meta.GetMetaInt(AMETA_PoisonDamage); + int poisondamage = GetClass()->PoisonDamage; if (poisondamage > 0) { P_PoisonPlayer (target->player, this, this->target, poisondamage); @@ -5512,8 +5512,7 @@ void AActor::Crash() } if (crashstate == NULL) { - int gibhealth = -abs(GetClass()->Meta.GetMetaInt (AMETA_GibHealth, - gameinfo.gametype & GAME_DoomChex ? -SpawnHealth() : -SpawnHealth()/2)); + int gibhealth = GetGibHealth(); if (health < gibhealth) { // Extreme death @@ -5538,7 +5537,7 @@ void AActor::SetIdle() SetState(idle); } -int AActor::SpawnHealth() +int AActor::SpawnHealth() const { if (!(flags3 & MF3_ISMONSTER) || GetDefault()->health == 0) { @@ -5556,15 +5555,32 @@ int AActor::SpawnHealth() } } -FDropItem *AActor::GetDropItems() +int AActor::GetGibHealth() const { - unsigned int index = GetClass()->Meta.GetMetaInt (ACMETA_DropItems) - 1; + int gibhealth = GetClass()->GibHealth; - if (index >= 0 && index < DropItemList.Size()) + if (gibhealth != INT_MIN) { - return DropItemList[index]; + return gibhealth; } - return NULL; + else if (gameinfo.gametype & GAME_DoomChex) + { + return -SpawnHealth(); + } + else + { + return -SpawnHealth()/2; + } +} + +fixed_t AActor::GetCameraHeight() const +{ + return GetClass()->CameraHeight == FIXED_MIN ? height / 2 : GetClass()->CameraHeight; +} + +DDropItem *AActor::GetDropItems() const +{ + return GetClass()->DropItems; } fixed_t AActor::GetGravity() const @@ -5595,30 +5611,9 @@ const char *AActor::GetTag(const char *def) const // DropItem handling // //---------------------------------------------------------------------------- -FDropItemPtrArray DropItemList; - -void FreeDropItemChain(FDropItem *chain) -{ - while (chain != NULL) - { - FDropItem *next = chain->Next; - delete chain; - chain = next; - } -} - -FDropItemPtrArray::~FDropItemPtrArray() -{ - for (unsigned int i = 0; i < Size(); ++i) - { - FreeDropItemChain ((*this)[i]); - } -} - -int StoreDropItemChain(FDropItem *chain) -{ - return DropItemList.Push (chain) + 1; -} +IMPLEMENT_POINTY_CLASS(DDropItem) + DECLARE_POINTER(Next) +END_POINTERS void PrintMiscActorInfo(AActor * query) { diff --git a/src/p_user.cpp b/src/p_user.cpp index 77cd52fb7..e76d706b8 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -104,32 +104,32 @@ void SetupPlayerClasses () if (gameinfo.gametype == GAME_Doom) { - newclass.Type = PClass::FindClass (NAME_DoomPlayer); - PlayerClasses.Push (newclass); + newclass.Type = static_cast(PClass::FindClass(NAME_DoomPlayer)); + PlayerClasses.Push(newclass); } else if (gameinfo.gametype == GAME_Heretic) { - newclass.Type = PClass::FindClass (NAME_HereticPlayer); - PlayerClasses.Push (newclass); + newclass.Type = static_cast(PClass::FindClass(NAME_HereticPlayer)); + PlayerClasses.Push(newclass); } else if (gameinfo.gametype == GAME_Hexen) { - newclass.Type = PClass::FindClass (NAME_FighterPlayer); - PlayerClasses.Push (newclass); - newclass.Type = PClass::FindClass (NAME_ClericPlayer); - PlayerClasses.Push (newclass); - newclass.Type = PClass::FindClass (NAME_MagePlayer); - PlayerClasses.Push (newclass); + newclass.Type = static_cast(PClass::FindClass(NAME_FighterPlayer)); + PlayerClasses.Push(newclass); + newclass.Type = static_cast(PClass::FindClass(NAME_ClericPlayer)); + PlayerClasses.Push(newclass); + newclass.Type = static_cast(PClass::FindClass(NAME_MagePlayer)); + PlayerClasses.Push(newclass); } else if (gameinfo.gametype == GAME_Strife) { - newclass.Type = PClass::FindClass (NAME_StrifePlayer); - PlayerClasses.Push (newclass); + newclass.Type = static_cast(PClass::FindClass(NAME_StrifePlayer)); + PlayerClasses.Push(newclass); } else if (gameinfo.gametype == GAME_Chex) { - newclass.Type = PClass::FindClass (NAME_ChexPlayer); - PlayerClasses.Push (newclass); + newclass.Type = static_cast(PClass::FindClass(NAME_ChexPlayer)); + PlayerClasses.Push(newclass); } } @@ -145,17 +145,13 @@ CCMD (addplayerclass) { if (ParsingKeyConf && argv.argc () > 1) { - const PClass *ti = PClass::FindClass (argv[1]); + PClassPlayerPawn *ti = dyn_cast(PClass::FindClass(argv[1])); - if (!ti) + if (ti == NULL) { Printf ("Unknown player class '%s'\n", argv[1]); } - else if (!ti->IsDescendantOf (RUNTIME_CLASS (APlayerPawn))) - { - Printf ("Invalid player class '%s'\n", argv[1]); - } - else if (ti->Meta.GetMetaString (APMETA_DisplayName) == NULL) + else if (ti->DisplayName.IsEmpty()) { Printf ("Missing displayname for player class '%s'\n", argv[1]); } @@ -180,7 +176,6 @@ CCMD (addplayerclass) arg++; } - PlayerClasses.Push (newclass); } } @@ -190,8 +185,7 @@ CCMD (playerclasses) { for (unsigned int i = 0; i < PlayerClasses.Size (); i++) { - Printf ("% 3d %s\n", i, - PlayerClasses[i].Type->Meta.GetMetaString (APMETA_DisplayName)); + Printf("% 3d %s\n", i, PlayerClasses[i].Type->DisplayName.GetChars()); } } @@ -396,6 +390,48 @@ int player_t::GetSpawnClass() return static_cast(GetDefaultByType(type))->SpawnMask; } +//=========================================================================== +// +// PClassPlayerPawn +// +//=========================================================================== + +IMPLEMENT_CLASS(PClassPlayerPawn) + +PClassPlayerPawn::PClassPlayerPawn() +{ + for (int i = 0; i < countof(HexenArmor); ++i) + { + HexenArmor[i] = 0; + } + ColorRangeStart = 0; + ColorRangeEnd = 0; +} + +void PClassPlayerPawn::Derive(PClass *newclass) +{ + assert(newclass->IsKindOf(RUNTIME_CLASS(PClassPlayerPawn))); + Super::Derive(newclass); + PClassPlayerPawn *newp = static_cast(newclass); + int i; + + newp->DisplayName = DisplayName; + newp->SoundClass = SoundClass; + newp->Face = Face; + newp->InvulMode = InvulMode; + newp->HealingRadiusType = HealingRadiusType; + newp->ColorRangeStart = ColorRangeStart; + newp->ColorRangeEnd = ColorRangeEnd; + for (i = 0; i < countof(HexenArmor); ++i) + { + newp->HexenArmor[i] = HexenArmor[i]; + } + for (i = 0; i < countof(Slot); ++i) + { + newp->Slot[i] = Slot[i]; + } +} + //=========================================================================== // // APlayerPawn @@ -908,8 +944,8 @@ const char *APlayerPawn::GetSoundClass () } // [GRB] - const char *sclass = GetClass ()->Meta.GetMetaString (APMETA_SoundClass); - return sclass != NULL ? sclass : "player"; + PClassPlayerPawn *pclass = GetClass(); + return pclass->SoundClass.IsNotEmpty() ? pclass->SoundClass : "player"; } //=========================================================================== @@ -1026,18 +1062,14 @@ void APlayerPawn::GiveDefaultInventory () // HexenArmor must always be the first item in the inventory because // it provides player class based protection that should not affect // any other protection item. - fixed_t hx[5]; - for(int i=0;i<5;i++) - { - hx[i] = GetClass()->Meta.GetMetaFixed(APMETA_Hexenarmor0+i); - } - GiveInventoryType (RUNTIME_CLASS(AHexenArmor)); + PClassPlayerPawn *myclass = GetClass(); + GiveInventoryType(RUNTIME_CLASS(AHexenArmor)); AHexenArmor *harmor = FindInventory(); - harmor->Slots[4] = hx[0]; - harmor->SlotsIncrement[0] = hx[1]; - harmor->SlotsIncrement[1] = hx[2]; - harmor->SlotsIncrement[2] = hx[3]; - harmor->SlotsIncrement[3] = hx[4]; + harmor->Slots[4] = myclass->HexenArmor[0]; + for (int i = 0; i < 4; ++i) + { + harmor->SlotsIncrement[i] = myclass->HexenArmor[i + 1]; + } // BasicArmor must come right after that. It should not affect any // other protection item as well but needs to process the damage @@ -1049,7 +1081,7 @@ void APlayerPawn::GiveDefaultInventory () AddInventory (barmor); // Now add the items from the DECORATE definition - FDropItem *di = GetDropItems(); + DDropItem *di = GetDropItems(); while (di) { @@ -1060,14 +1092,14 @@ void APlayerPawn::GiveDefaultInventory () if (item != NULL) { item->Amount = clamp( - item->Amount + (di->amount ? di->amount : ((AInventory *)item->GetDefault ())->Amount), + item->Amount + (di->Amount ? di->Amount : ((AInventory *)item->GetDefault ())->Amount), 0, item->MaxAmount); } else { item = static_cast(Spawn (ti, 0,0,0, NO_REPLACE)); - item->ItemFlags|=IF_IGNORESKILL; // no skill multiplicators here - item->Amount = di->amount; + item->ItemFlags |= IF_IGNORESKILL; // no skill multiplicators here + item->Amount = di->Amount; if (item->IsKindOf (RUNTIME_CLASS (AWeapon))) { // To allow better control any weapon is emptied of @@ -1341,7 +1373,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SkullPop) // [GRB] Parameterized version if (spawntype == NULL || !spawntype->IsDescendantOf(RUNTIME_CLASS(APlayerChunk))) { - spawntype = PClass::FindActor("BloodySkull"); + spawntype = dyn_cast(PClass::FindClass("BloodySkull")); if (spawntype == NULL) return 0; } diff --git a/src/r_main.cpp b/src/r_main.cpp index 789388842..080628fe2 100644 --- a/src/r_main.cpp +++ b/src/r_main.cpp @@ -1064,7 +1064,7 @@ void R_SetupFrame (AActor *actor) { iview->nviewx = camera->x; iview->nviewy = camera->y; - iview->nviewz = camera->player ? camera->player->viewz : camera->z + camera->GetClass()->Meta.GetMetaFixed(AMETA_CameraHeight); + iview->nviewz = camera->player ? camera->player->viewz : camera->z + camera->GetCameraHeight(); viewsector = camera->Sector; r_showviewer = false; } diff --git a/src/r_things.cpp b/src/r_things.cpp index a2f18de5f..a9c683a70 100644 --- a/src/r_things.cpp +++ b/src/r_things.cpp @@ -442,7 +442,7 @@ void R_InitSkins (void) int lastlump; int aliasid; bool remove; - const PClass *basetype, *transtype; + PClassPlayerPawn *basetype, *transtype; key[sizeof(key)-1] = 0; i = PlayerClasses.Size () - 1; @@ -527,11 +527,11 @@ void R_InitSkins (void) else if (0 == stricmp (key, "game")) { if (gameinfo.gametype == GAME_Heretic) - basetype = PClass::FindClass (NAME_HereticPlayer); + basetype = static_cast(PClass::FindClass (NAME_HereticPlayer)); else if (gameinfo.gametype == GAME_Strife) - basetype = PClass::FindClass (NAME_StrifePlayer); + basetype = static_cast(PClass::FindClass (NAME_StrifePlayer)); else - basetype = PClass::FindClass (NAME_DoomPlayer); + basetype = static_cast(PClass::FindClass (NAME_DoomPlayer)); transtype = basetype; @@ -539,7 +539,7 @@ void R_InitSkins (void) { if (gameinfo.gametype & GAME_DoomChex) { - transtype = PClass::FindClass (NAME_HereticPlayer); + transtype = static_cast(PClass::FindClass (NAME_HereticPlayer)); skins[i].othergame = true; } else if (gameinfo.gametype != GAME_Heretic) @@ -558,7 +558,7 @@ void R_InitSkins (void) { if (gameinfo.gametype == GAME_Heretic) { - transtype = PClass::FindClass (NAME_DoomPlayer); + transtype = static_cast(PClass::FindClass (NAME_DoomPlayer)); skins[i].othergame = true; } else if (!(gameinfo.gametype & GAME_DoomChex)) @@ -634,12 +634,12 @@ void R_InitSkins (void) { if (gameinfo.gametype & GAME_DoomChex) { - basetype = transtype = PClass::FindClass (NAME_DoomPlayer); + basetype = transtype = static_cast(PClass::FindClass (NAME_DoomPlayer)); } else if (gameinfo.gametype == GAME_Heretic) { - basetype = PClass::FindClass (NAME_HereticPlayer); - transtype = PClass::FindClass (NAME_DoomPlayer); + basetype = static_cast(PClass::FindClass (NAME_HereticPlayer)); + transtype = static_cast(PClass::FindClass (NAME_DoomPlayer)); skins[i].othergame = true; } else @@ -650,17 +650,18 @@ void R_InitSkins (void) if (!remove) { - skins[i].range0start = transtype->Meta.GetMetaInt (APMETA_ColorRange) & 0xff; - skins[i].range0end = transtype->Meta.GetMetaInt (APMETA_ColorRange) >> 8; + skins[i].range0start = transtype->ColorRangeStart; + skins[i].range0end = transtype->ColorRangeEnd; remove = true; for (j = 0; j < (int)PlayerClasses.Size (); j++) { - const PClass *type = PlayerClasses[j].Type; + PClassPlayerPawn *type = PlayerClasses[j].Type; if (type->IsDescendantOf (basetype) && GetDefaultByType (type)->SpawnState->sprite == GetDefaultByType (basetype)->SpawnState->sprite && - type->Meta.GetMetaInt (APMETA_ColorRange) == basetype->Meta.GetMetaInt (APMETA_ColorRange)) + type->ColorRangeStart == basetype->ColorRangeStart && + type->ColorRangeEnd == basetype->ColorRangeEnd) { PlayerClasses[j].Skins.Push ((int)i); remove = false; @@ -871,9 +872,9 @@ void R_InitSprites () memset (skins, 0, sizeof(*skins) * numskins); for (i = 0; i < numskins; i++) { // Assume Doom skin by default - const PClass *type = PlayerClasses[0].Type; - skins[i].range0start = type->Meta.GetMetaInt (APMETA_ColorRange) & 255; - skins[i].range0end = type->Meta.GetMetaInt (APMETA_ColorRange) >> 8; + PClassPlayerPawn *type = PlayerClasses[0].Type; + skins[i].range0start = type->ColorRangeStart; + skins[i].range0end = type->ColorRangeEnd; skins[i].ScaleX = GetDefaultByType (type)->scaleX; skins[i].ScaleY = GetDefaultByType (type)->scaleY; } @@ -886,11 +887,11 @@ void R_InitSprites () // [GRB] Each player class has its own base skin for (i = 0; i < PlayerClasses.Size (); i++) { - const PClass *basetype = PlayerClasses[i].Type; - const char *pclassface = basetype->Meta.GetMetaString (APMETA_Face); + PClassPlayerPawn *basetype = PlayerClasses[i].Type; + FString pclassface = basetype->Face; strcpy (skins[i].name, "Base"); - if (pclassface == NULL || strcmp(pclassface, "None") == 0) + if (pclassface.IsEmpty() || strcmp(pclassface, "None") == 0) { skins[i].face[0] = 'S'; skins[i].face[1] = 'T'; @@ -901,8 +902,8 @@ void R_InitSprites () { strcpy(skins[i].face, pclassface); } - skins[i].range0start = basetype->Meta.GetMetaInt (APMETA_ColorRange) & 255; - skins[i].range0end = basetype->Meta.GetMetaInt (APMETA_ColorRange) >> 8; + skins[i].range0start = basetype->ColorRangeStart; + skins[i].range0end = basetype->ColorRangeEnd; skins[i].ScaleX = GetDefaultByType (basetype)->scaleX; skins[i].ScaleY = GetDefaultByType (basetype)->scaleY; skins[i].sprite = GetDefaultByType (basetype)->SpawnState->sprite; diff --git a/src/textures/textures.h b/src/textures/textures.h index 4bfffe54b..ab4595bf0 100644 --- a/src/textures/textures.h +++ b/src/textures/textures.h @@ -7,7 +7,7 @@ class FBitmap; struct FRemapTable; struct FCopyInfo; class FScanner; -class PClass; +class PClassInventory; class FArchive; // Texture IDs @@ -18,7 +18,7 @@ class FTextureID { friend class FTextureManager; friend FArchive &operator<< (FArchive &arc, FTextureID &tex); - friend FTextureID GetHUDIcon(const PClass *cls); + friend FTextureID GetHUDIcon(PClassInventory *cls); friend void R_InitSpriteDefs (); public: diff --git a/src/thingdef/olddecorations.cpp b/src/thingdef/olddecorations.cpp index 44afb3351..3fe2f6e39 100644 --- a/src/thingdef/olddecorations.cpp +++ b/src/thingdef/olddecorations.cpp @@ -256,7 +256,7 @@ void ParseOldDecoration(FScanner &sc, EDefinitionType def) { extra.DeathHeight = ((AActor*)(type->Defaults))->height; } - type->Meta.SetMetaFixed (AMETA_DeathHeight, extra.DeathHeight); + type->DeathHeight = extra.DeathHeight; } bag.statedef.SetStateLabel("Death", &type->OwnedStates[extra.DeathStart]); } @@ -294,7 +294,7 @@ void ParseOldDecoration(FScanner &sc, EDefinitionType def) } if (extra.BurnHeight == 0) extra.BurnHeight = ((AActor*)(type->Defaults))->height; - type->Meta.SetMetaFixed (AMETA_BurnHeight, extra.BurnHeight); + type->BurnHeight = extra.BurnHeight; bag.statedef.SetStateLabel("Burn", &type->OwnedStates[extra.FireDeathStart]); } @@ -475,18 +475,18 @@ static void ParseInsideDecoration (Baggage &bag, AActor *defaults, else if (def == DEF_Projectile && sc.Compare ("ExplosionRadius")) { sc.MustGetNumber (); - bag.Info->Meta.SetMetaInt(ACMETA_ExplosionRadius, sc.Number); + bag.Info->ExplosionRadius = sc.Number; extra.bExplosive = true; } else if (def == DEF_Projectile && sc.Compare ("ExplosionDamage")) { sc.MustGetNumber (); - bag.Info->Meta.SetMetaInt(ACMETA_ExplosionDamage, sc.Number); + bag.Info->ExplosionDamage = sc.Number; extra.bExplosive = true; } else if (def == DEF_Projectile && sc.Compare ("DoNotHurtShooter")) { - bag.Info->Meta.SetMetaInt(ACMETA_DontHurtShooter, true); + bag.Info->DontHurtShooter = true; } else if (def == DEF_Projectile && sc.Compare ("Damage")) { @@ -571,7 +571,7 @@ static void ParseInsideDecoration (Baggage &bag, AActor *defaults, else if (def == DEF_Pickup && sc.Compare ("PickupMessage")) { sc.MustGetString (); - bag.Info->Meta.SetMetaString(AIMETA_PickupMessage, sc.String); + static_cast(bag.Info)->PickupMessage = sc.String; } else if (def == DEF_Pickup && sc.Compare ("Respawns")) { diff --git a/src/thingdef/thingdef.cpp b/src/thingdef/thingdef.cpp index 00694457c..3d4106050 100644 --- a/src/thingdef/thingdef.cpp +++ b/src/thingdef/thingdef.cpp @@ -208,17 +208,7 @@ void FinishActor(const FScriptPosition &sc, PClassActor *info, Baggage &bag) bag.statedef.MakeStateDefines(NULL); if (bag.DropItemSet) { - if (bag.DropItemList == NULL) - { - if (info->Meta.GetMetaInt (ACMETA_DropItems) != 0) - { - info->Meta.SetMetaInt (ACMETA_DropItems, 0); - } - } - else - { - info->Meta.SetMetaInt (ACMETA_DropItems, StoreDropItemChain(bag.DropItemList)); - } + info->DropItems = bag.DropItemList; } if (info->IsDescendantOf (RUNTIME_CLASS(AInventory))) { diff --git a/src/thingdef/thingdef.h b/src/thingdef/thingdef.h index 31b1d1274..a430ae878 100644 --- a/src/thingdef/thingdef.h +++ b/src/thingdef/thingdef.h @@ -152,7 +152,7 @@ extern FStateExpressions StateParams; // Extra info maintained while defining an actor. // //========================================================================== -struct FDropItem; +class DDropItem; struct Baggage { @@ -166,7 +166,7 @@ struct Baggage int Lumpnum; FStateDefinitions statedef; - FDropItem *DropItemList; + DDropItem *DropItemList; FScriptPosition ScriptPosition; }; @@ -235,13 +235,6 @@ enum { ACMETA_BASE = 0x83000, ACMETA_DropItems, // Int (index into DropItemList) - ACMETA_ExplosionDamage, - ACMETA_ExplosionRadius, - ACMETA_DontHurtShooter, - ACMETA_MeleeSound, - ACMETA_MeleeDamage, - ACMETA_MissileName, - ACMETA_MissileHeight, }; diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index a5d7ef98c..c501daf04 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -213,8 +213,8 @@ static void DoAttack (AActor *self, bool domelee, bool domissile, DEFINE_ACTION_FUNCTION(AActor, A_MeleeAttack) { PARAM_ACTION_PROLOGUE; - int MeleeDamage = self->GetClass()->Meta.GetMetaInt(ACMETA_MeleeDamage, 0); - FSoundID MeleeSound = self->GetClass()->Meta.GetMetaInt(ACMETA_MeleeSound, 0); + int MeleeDamage = self->GetClass()->MeleeDamage; + FSoundID MeleeSound = self->GetClass()->MeleeSound; DoAttack(self, true, false, MeleeDamage, MeleeSound, NULL, 0); return 0; } @@ -222,8 +222,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_MeleeAttack) DEFINE_ACTION_FUNCTION(AActor, A_MissileAttack) { PARAM_ACTION_PROLOGUE; - const PClass *MissileType = PClass::FindClass(ENamedName(self->GetClass()->Meta.GetMetaInt(ACMETA_MissileName, NAME_None))); - fixed_t MissileHeight = self->GetClass()->Meta.GetMetaFixed(ACMETA_MissileHeight, 32*FRACUNIT); + PClassActor *MissileType = PClass::FindActor(self->GetClass()->MissileName); + fixed_t MissileHeight = self->GetClass()->MissileHeight; DoAttack(self, false, true, 0, 0, MissileType, MissileHeight); return 0; } @@ -231,10 +231,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_MissileAttack) DEFINE_ACTION_FUNCTION(AActor, A_ComboAttack) { PARAM_ACTION_PROLOGUE; - int MeleeDamage = self->GetClass()->Meta.GetMetaInt(ACMETA_MeleeDamage, 0); - FSoundID MeleeSound = self->GetClass()->Meta.GetMetaInt(ACMETA_MeleeSound, 0); - const PClass *MissileType = PClass::FindClass(ENamedName(self->GetClass()->Meta.GetMetaInt(ACMETA_MissileName, NAME_None))); - fixed_t MissileHeight = self->GetClass()->Meta.GetMetaFixed(ACMETA_MissileHeight, 32*FRACUNIT); + int MeleeDamage = self->GetClass()->MeleeDamage; + FSoundID MeleeSound = self->GetClass()->MeleeSound; + PClassActor *MissileType = PClass::FindActor(self->GetClass()->MissileName); + fixed_t MissileHeight = self->GetClass()->MissileHeight; DoAttack(self, true, true, MeleeDamage, MeleeSound, MissileType, MissileHeight); return 0; } @@ -622,9 +622,13 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Explode) if (damage < 0) // get parameters from metadata { - damage = self->GetClass()->Meta.GetMetaInt (ACMETA_ExplosionDamage, 128); - distance = self->GetClass()->Meta.GetMetaInt (ACMETA_ExplosionRadius, damage); - hurtSource = !self->GetClass()->Meta.GetMetaInt (ACMETA_DontHurtShooter); + damage = self->GetClass()->ExplosionDamage; + distance = self->GetClass()->ExplosionRadius; + if (distance < 0) + { + distance = damage; + } + hurtSource = !self->GetClass()->DontHurtShooter; alert = false; } else diff --git a/src/thingdef/thingdef_properties.cpp b/src/thingdef/thingdef_properties.cpp index 9690756b5..1a0c0b062 100644 --- a/src/thingdef/thingdef_properties.cpp +++ b/src/thingdef/thingdef_properties.cpp @@ -74,7 +74,7 @@ // Gets a class pointer and performs an error check for correct type // //========================================================================== -static PClassActor *FindClassTentative(const char *name, const char *ancestor) +static PClassActor *FindClassTentative(const char *name, PClass *ancestor) { // "" and "none" mean 'no class' if (name == NULL || *name == 0 || !stricmp(name, "none")) @@ -82,16 +82,26 @@ static PClassActor *FindClassTentative(const char *name, const char *ancestor) return NULL; } - PClass *anc = PClass::FindClass(ancestor); - assert(anc != NULL); // parent classes used here should always be natively defined - PClass *cls = anc->FindClassTentative(name); - assert (cls != NULL); // cls can not ne NULL here - if (!cls->IsDescendantOf(anc)) + PClass *cls = ancestor->FindClassTentative(name); + assert(cls != NULL); // cls can not be NULL here + if (!cls->IsDescendantOf(ancestor)) { I_Error("%s does not inherit from %s\n", name, ancestor); } return static_cast(cls); } +static AAmmo::MetaClass *FindClassTentativeAmmo(const char *name) +{ + return static_cast(FindClassTentative(name, RUNTIME_CLASS(AAmmo))); +} +static AWeapon::MetaClass *FindClassTentativeWeapon(const char *name) +{ + return static_cast(FindClassTentative(name, RUNTIME_CLASS(AWeapon))); +} +static APowerup::MetaClass *FindClassTentativePowerup(const char *name) +{ + return static_cast(FindClassTentative(name, RUNTIME_CLASS(APowerup))); +} //=========================================================================== // @@ -144,7 +154,7 @@ void HandleDeprecatedFlags(AActor *defaults, PClassActor *info, bool set, int in case DEPF_PICKUPFLASH: if (set) { - static_cast(defaults)->PickupFlash = FindClassTentative("PickupFlash", "Actor"); + static_cast(defaults)->PickupFlash = FindClassTentative("PickupFlash", RUNTIME_CLASS(AActor)); } else { @@ -293,10 +303,6 @@ DEFINE_PROPERTY(skip_super, 0, Actor) } memcpy (defaults, GetDefault(), sizeof(AActor)); - if (bag.DropItemList != NULL) - { - FreeDropItemChain (bag.DropItemList); - } ResetBaggage (&bag, RUNTIME_CLASS(AActor)); } @@ -324,7 +330,8 @@ DEFINE_PROPERTY(health, I, Actor) DEFINE_PROPERTY(gibhealth, I, Actor) { PROP_INT_PARM(id, 0); - info->Meta.SetMetaInt (AMETA_GibHealth, id); + assert(info->IsKindOf(RUNTIME_CLASS(PClassActor))); + static_cast(info)->GibHealth = id; } //========================================================================== @@ -333,7 +340,8 @@ DEFINE_PROPERTY(gibhealth, I, Actor) DEFINE_PROPERTY(woundhealth, I, Actor) { PROP_INT_PARM(id, 0); - info->Meta.SetMetaInt (AMETA_WoundHealth, id); + assert(info->IsKindOf(RUNTIME_CLASS(PClassActor))); + static_cast(info)->WoundHealth = id; } //========================================================================== @@ -556,7 +564,8 @@ DEFINE_PROPERTY(activesound, S, Actor) DEFINE_PROPERTY(howlsound, S, Actor) { PROP_STRING_PARM(str, 0); - info->Meta.SetMetaInt (AMETA_HowlSound, S_FindSound(str)); + assert(info->IsKindOf(RUNTIME_CLASS(PClassActor))); + static_cast(info)->HowlSound = str; } //========================================================================== @@ -573,20 +582,20 @@ DEFINE_PROPERTY(dropitem, S_i_i, Actor) bag.DropItemList = NULL; } - FDropItem *di = new FDropItem; + DDropItem *di = new DDropItem; - di->Name =type; - di->probability=255; - di->amount=-1; + di->Name = type; + di->Probability = 255; + di->Amount = -1; if (PROP_PARM_COUNT > 1) { PROP_INT_PARM(prob, 1); - di->probability = prob; + di->Probability = prob; if (PROP_PARM_COUNT > 2) { PROP_INT_PARM(amt, 2); - di->amount = amt; + di->Amount = amt; } } di->Next = bag.DropItemList; @@ -637,7 +646,8 @@ DEFINE_PROPERTY(alpha, F, Actor) DEFINE_PROPERTY(obituary, S, Actor) { PROP_STRING_PARM(str, 0); - info->Meta.SetMetaString (AMETA_Obituary, str); + assert(info->IsKindOf(RUNTIME_CLASS(PClassActor))); + static_cast(info)->Obituary = str; } //========================================================================== @@ -646,7 +656,8 @@ DEFINE_PROPERTY(obituary, S, Actor) DEFINE_PROPERTY(hitobituary, S, Actor) { PROP_STRING_PARM(str, 0); - info->Meta.SetMetaString (AMETA_HitObituary, str); + assert(info->IsKindOf(RUNTIME_CLASS(PClassActor))); + static_cast(info)->HitObituary = str; } //========================================================================== @@ -654,7 +665,8 @@ DEFINE_PROPERTY(hitobituary, S, Actor) //========================================================================== DEFINE_PROPERTY(donthurtshooter, 0, Actor) { - info->Meta.SetMetaInt (ACMETA_DontHurtShooter, true); + assert(info->IsKindOf(RUNTIME_CLASS(PClassActor))); + static_cast(info)->DontHurtShooter = true; } //========================================================================== @@ -663,7 +675,8 @@ DEFINE_PROPERTY(donthurtshooter, 0, Actor) DEFINE_PROPERTY(explosionradius, I, Actor) { PROP_INT_PARM(id, 0); - info->Meta.SetMetaInt (ACMETA_ExplosionRadius, id); + assert(info->IsKindOf(RUNTIME_CLASS(PClassActor))); + static_cast(info)->ExplosionRadius = id; } //========================================================================== @@ -672,7 +685,8 @@ DEFINE_PROPERTY(explosionradius, I, Actor) DEFINE_PROPERTY(explosiondamage, I, Actor) { PROP_INT_PARM(id, 0); - info->Meta.SetMetaInt (ACMETA_ExplosionDamage, id); + assert(info->IsKindOf(RUNTIME_CLASS(PClassActor))); + static_cast(info)->ExplosionDamage = id; } //========================================================================== @@ -681,9 +695,8 @@ DEFINE_PROPERTY(explosiondamage, I, Actor) DEFINE_PROPERTY(deathheight, F, Actor) { PROP_FIXED_PARM(h, 0); - // AActor::Die() uses a height of 0 to mean "cut the height to 1/4", - // so if a height of 0 is desired, store it as -1. - info->Meta.SetMetaFixed (AMETA_DeathHeight, h <= 0 ? -1 : h); + assert(info->IsKindOf(RUNTIME_CLASS(PClassActor))); + static_cast(info)->DeathHeight = MAX(0, h); } //========================================================================== @@ -692,8 +705,8 @@ DEFINE_PROPERTY(deathheight, F, Actor) DEFINE_PROPERTY(burnheight, F, Actor) { PROP_FIXED_PARM(h, 0); - // The note above for AMETA_DeathHeight also applies here. - info->Meta.SetMetaFixed (AMETA_BurnHeight, h <= 0 ? -1 : h); + assert(info->IsKindOf(RUNTIME_CLASS(PClassActor))); + static_cast(info)->BurnHeight = MAX(0, h); } //========================================================================== @@ -720,7 +733,8 @@ DEFINE_PROPERTY(meleethreshold, F, Actor) DEFINE_PROPERTY(meleedamage, I, Actor) { PROP_INT_PARM(id, 0); - info->Meta.SetMetaInt (ACMETA_MeleeDamage, id); + assert(info->IsKindOf(RUNTIME_CLASS(PClassActor))); + static_cast(info)->MeleeDamage = id; } //========================================================================== @@ -738,7 +752,8 @@ DEFINE_PROPERTY(meleerange, F, Actor) DEFINE_PROPERTY(meleesound, S, Actor) { PROP_STRING_PARM(str, 0); - info->Meta.SetMetaInt (ACMETA_MeleeSound, S_FindSound(str)); + assert(info->IsKindOf(RUNTIME_CLASS(PClassActor))); + static_cast(info)->MeleeSound = str; } //========================================================================== @@ -747,7 +762,8 @@ DEFINE_PROPERTY(meleesound, S, Actor) DEFINE_PROPERTY(missiletype, S, Actor) { PROP_STRING_PARM(str, 0); - info->Meta.SetMetaInt (ACMETA_MissileName, FName(str)); + assert(info->IsKindOf(RUNTIME_CLASS(PClassActor))); + static_cast(info)->MissileName = str; } //========================================================================== @@ -756,7 +772,8 @@ DEFINE_PROPERTY(missiletype, S, Actor) DEFINE_PROPERTY(missileheight, F, Actor) { PROP_FIXED_PARM(id, 0); - info->Meta.SetMetaFixed (ACMETA_MissileHeight, id); + assert(info->IsKindOf(RUNTIME_CLASS(PClassActor))); + static_cast(info)->MissileHeight = id; } //========================================================================== @@ -826,7 +843,8 @@ DEFINE_PROPERTY(bloodcolor, C, Actor) PalEntry pe = color; pe.a = CreateBloodTranslation(pe); - info->Meta.SetMetaInt (AMETA_BloodColor, pe); + assert(info->IsKindOf(RUNTIME_CLASS(PClassActor))); + static_cast(info)->BloodColor = pe; } @@ -839,23 +857,26 @@ DEFINE_PROPERTY(bloodtype, Sss, Actor) PROP_STRING_PARM(str1, 1) PROP_STRING_PARM(str2, 2) + assert(info->IsKindOf(RUNTIME_CLASS(PClassActor))); + PClassActor *ainfo = static_cast(info); + FName blood = str; // normal blood - info->Meta.SetMetaInt (AMETA_BloodType, blood); + ainfo->BloodType = blood; if (PROP_PARM_COUNT > 1) { blood = str1; } // blood splatter - info->Meta.SetMetaInt (AMETA_BloodType2, blood); + ainfo->BloodType2 = blood; if (PROP_PARM_COUNT > 2) { blood = str2; } // axe blood - info->Meta.SetMetaInt (AMETA_BloodType3, blood); + ainfo->BloodType3 = blood; } //========================================================================== @@ -1000,7 +1021,8 @@ DEFINE_PROPERTY(maxdropoffheight, F, Actor) DEFINE_PROPERTY(poisondamage, I, Actor) { PROP_INT_PARM(i, 0); - info->Meta.SetMetaInt (AMETA_PoisonDamage, i); + assert(info->IsKindOf(RUNTIME_CLASS(PClassActor))); + static_cast(info)->PoisonDamage = i; } //========================================================================== @@ -1009,7 +1031,8 @@ DEFINE_PROPERTY(poisondamage, I, Actor) DEFINE_PROPERTY(fastspeed, F, Actor) { PROP_FIXED_PARM(i, 0); - info->Meta.SetMetaFixed (AMETA_FastSpeed, i); + assert(info->IsKindOf(RUNTIME_CLASS(PClassActor))); + static_cast(info)->FastSpeed = i; } //========================================================================== @@ -1018,7 +1041,8 @@ DEFINE_PROPERTY(fastspeed, F, Actor) DEFINE_PROPERTY(radiusdamagefactor, F, Actor) { PROP_FIXED_PARM(i, 0); - info->Meta.SetMetaFixed (AMETA_RDFactor, i); + assert(info->IsKindOf(RUNTIME_CLASS(PClassActor))); + static_cast(info)->RDFactor = i; } //========================================================================== @@ -1027,7 +1051,8 @@ DEFINE_PROPERTY(radiusdamagefactor, F, Actor) DEFINE_PROPERTY(cameraheight, F, Actor) { PROP_FIXED_PARM(i, 0); - info->Meta.SetMetaFixed (AMETA_CameraHeight, i); + assert(info->IsKindOf(RUNTIME_CLASS(PClassActor))); + static_cast(info)->CameraHeight = i; } //========================================================================== @@ -1135,7 +1160,8 @@ DEFINE_CLASS_PROPERTY(backpackmaxamount, I, Ammo) DEFINE_CLASS_PROPERTY(dropamount, I, Ammo) { PROP_INT_PARM(i, 0); - info->Meta.SetMetaInt (AIMETA_DropAmount, i); + assert(info->IsKindOf(RUNTIME_CLASS(PClassAmmo))); + static_cast(info)->DropAmount = i; } //========================================================================== @@ -1317,7 +1343,7 @@ DEFINE_CLASS_PROPERTY(defmaxamount, 0, Inventory) DEFINE_CLASS_PROPERTY(pickupflash, S, Inventory) { PROP_STRING_PARM(str, 0); - defaults->PickupFlash = FindClassTentative(str, "Actor"); + defaults->PickupFlash = FindClassTentative(str, RUNTIME_CLASS(AActor)); } //========================================================================== @@ -1326,7 +1352,8 @@ DEFINE_CLASS_PROPERTY(pickupflash, S, Inventory) DEFINE_CLASS_PROPERTY(pickupmessage, T, Inventory) { PROP_STRING_PARM(str, 0); - info->Meta.SetMetaString(AIMETA_PickupMessage, str); + assert(info->IsKindOf(RUNTIME_CLASS(PClassInventory))); + static_cast(info)->PickupMessage = str; } //========================================================================== @@ -1369,7 +1396,8 @@ DEFINE_CLASS_PROPERTY(usesound, S, Inventory) DEFINE_CLASS_PROPERTY(givequest, I, Inventory) { PROP_INT_PARM(i, 0); - info->Meta.SetMetaInt(AIMETA_GiveQuest, i); + assert(info->IsKindOf(RUNTIME_CLASS(PClassInventory))); + static_cast(info)->GiveQuest = i; } //========================================================================== @@ -1379,8 +1407,9 @@ DEFINE_CLASS_PROPERTY(lowmessage, IT, Health) { PROP_INT_PARM(i, 0); PROP_STRING_PARM(str, 1); - info->Meta.SetMetaInt(AIMETA_LowHealth, i); - info->Meta.SetMetaString(AIMETA_LowHealthMessage, str); + assert(info->IsKindOf(RUNTIME_CLASS(PClassHealth))); + static_cast(info)->LowHealth = i; + static_cast(info)->LowHealthMessage = str; } //========================================================================== @@ -1407,7 +1436,8 @@ DEFINE_CLASS_PROPERTY(number, I, PuzzleItem) DEFINE_CLASS_PROPERTY(failmessage, T, PuzzleItem) { PROP_STRING_PARM(str, 0); - info->Meta.SetMetaString(AIMETA_PuzzFailMessage, str); + assert(info->IsKindOf(RUNTIME_CLASS(PClassPuzzleItem))); + static_cast(info)->PuzzFailMessage = str; } //========================================================================== @@ -1444,7 +1474,7 @@ DEFINE_CLASS_PROPERTY(ammotype, S, Weapon) { PROP_STRING_PARM(str, 0); if (!stricmp(str, "none") || *str == 0) defaults->AmmoType1 = NULL; - else defaults->AmmoType1 = FindClassTentative(str, "Ammo"); + else defaults->AmmoType1 = FindClassTentativeAmmo(str); } //========================================================================== @@ -1454,7 +1484,7 @@ DEFINE_CLASS_PROPERTY(ammotype1, S, Weapon) { PROP_STRING_PARM(str, 0); if (!stricmp(str, "none") || *str == 0) defaults->AmmoType1 = NULL; - else defaults->AmmoType1 = FindClassTentative(str, "Ammo"); + else defaults->AmmoType1 = FindClassTentativeAmmo(str); } //========================================================================== @@ -1464,7 +1494,7 @@ DEFINE_CLASS_PROPERTY(ammotype2, S, Weapon) { PROP_STRING_PARM(str, 0); if (!stricmp(str, "none") || *str == 0) defaults->AmmoType1 = NULL; - else defaults->AmmoType2 = FindClassTentative(str, "Ammo"); + else defaults->AmmoType2 = FindClassTentativeAmmo(str); } //========================================================================== @@ -1535,7 +1565,7 @@ DEFINE_CLASS_PROPERTY(selectionorder, I, Weapon) DEFINE_CLASS_PROPERTY(sisterweapon, S, Weapon) { PROP_STRING_PARM(str, 0); - defaults->SisterWeaponType = FindClassTentative(str, "Weapon"); + defaults->SisterWeaponType = FindClassTentativeWeapon(str); } //========================================================================== @@ -1562,7 +1592,8 @@ DEFINE_CLASS_PROPERTY(yadjust, F, Weapon) DEFINE_CLASS_PROPERTY(slotnumber, I, Weapon) { PROP_INT_PARM(i, 0); - info->Meta.SetMetaInt(AWMETA_SlotNumber, i); + assert(info->IsKindOf(RUNTIME_CLASS(PClassWeapon))); + static_cast(info)->SlotNumber = i; } //========================================================================== @@ -1571,7 +1602,8 @@ DEFINE_CLASS_PROPERTY(slotnumber, I, Weapon) DEFINE_CLASS_PROPERTY(slotpriority, F, Weapon) { PROP_FIXED_PARM(i, 0); - info->Meta.SetMetaFixed(AWMETA_SlotPriority, i); + assert(info->IsKindOf(RUNTIME_CLASS(PClassWeapon))); + static_cast(info)->SlotPriority = i; } //========================================================================== @@ -1589,7 +1621,7 @@ DEFINE_CLASS_PROPERTY(number, I, WeaponPiece) DEFINE_CLASS_PROPERTY(weapon, S, WeaponPiece) { PROP_STRING_PARM(str, 0); - defaults->WeaponClass = FindClassTentative(str, "Weapon"); + defaults->WeaponClass = FindClassTentativeWeapon(str); } //========================================================================== @@ -1777,7 +1809,7 @@ DEFINE_CLASS_PROPERTY_PREFIX(powerup, type, S, PowerupGiver) { FString st; st.Format("%s%s", strnicmp(str, "power", 5)? "Power" : "", str); - cls = FindClassTentative(st, "Powerup"); + cls = FindClassTentativePowerup(st); } defaults->PowerupType = cls; @@ -1795,7 +1827,8 @@ DEFINE_CLASS_PROPERTY_PREFIX(powerup, type, S, PowerupGiver) DEFINE_CLASS_PROPERTY_PREFIX(player, displayname, S, PlayerPawn) { PROP_STRING_PARM(str, 0); - info->Meta.SetMetaString (APMETA_DisplayName, str); + assert(info->IsKindOf(RUNTIME_CLASS(PClassPlayerPawn))); + static_cast(info)->DisplayName = str; } //========================================================================== @@ -1807,7 +1840,8 @@ DEFINE_CLASS_PROPERTY_PREFIX(player, soundclass, S, PlayerPawn) FString tmp = str; tmp.ReplaceChars (' ', '_'); - info->Meta.SetMetaString (APMETA_SoundClass, tmp); + assert(info->IsKindOf(RUNTIME_CLASS(PClassPlayerPawn))); + static_cast(info)->SoundClass = tmp; } //========================================================================== @@ -1838,7 +1872,8 @@ DEFINE_CLASS_PROPERTY_PREFIX(player, face, S, PlayerPawn) tmp.GetChars(), info->TypeName.GetChars ()); } - info->Meta.SetMetaString (APMETA_Face, tmp); + assert(info->IsKindOf(RUNTIME_CLASS(PClassPlayerPawn))); + static_cast(info)->Face = tmp; } //========================================================================== @@ -1852,7 +1887,9 @@ DEFINE_CLASS_PROPERTY_PREFIX(player, colorrange, I_I, PlayerPawn) if (start > end) swap (start, end); - info->Meta.SetMetaInt (APMETA_ColorRange, (start & 255) | ((end & 255) << 8)); + assert(info->IsKindOf(RUNTIME_CLASS(PClassPlayerPawn))); + static_cast(info)->ColorRangeStart = start; + static_cast(info)->ColorRangeEnd = end; } //========================================================================== @@ -2036,15 +2073,15 @@ DEFINE_CLASS_PROPERTY_PREFIX(player, startitem, S_i, PlayerPawn) bag.DropItemList = NULL; } - FDropItem * di=new FDropItem; + DDropItem *di = new DDropItem; di->Name = str; - di->probability = 255; - di->amount = 1; + di->Probability = 255; + di->Amount = 1; if (PROP_PARM_COUNT > 1) { PROP_INT_PARM(amt, 1); - di->amount = amt; + di->Amount = amt; } di->Next = bag.DropItemList; bag.DropItemList = di; @@ -2056,7 +2093,8 @@ DEFINE_CLASS_PROPERTY_PREFIX(player, startitem, S_i, PlayerPawn) DEFINE_CLASS_PROPERTY_PREFIX(player, invulnerabilitymode, S, PlayerPawn) { PROP_STRING_PARM(str, 0); - info->Meta.SetMetaInt (APMETA_InvulMode, (FName)str); + assert(info->IsKindOf(RUNTIME_CLASS(PClassPlayerPawn))); + static_cast(info)->InvulMode = str; } //========================================================================== @@ -2065,7 +2103,8 @@ DEFINE_CLASS_PROPERTY_PREFIX(player, invulnerabilitymode, S, PlayerPawn) DEFINE_CLASS_PROPERTY_PREFIX(player, healradiustype, S, PlayerPawn) { PROP_STRING_PARM(str, 0); - info->Meta.SetMetaInt (APMETA_HealingRadius, (FName)str); + assert(info->IsKindOf(RUNTIME_CLASS(PClassPlayerPawn))); + static_cast(info)->HealingRadiusType = str; } //========================================================================== @@ -2073,10 +2112,11 @@ DEFINE_CLASS_PROPERTY_PREFIX(player, healradiustype, S, PlayerPawn) //========================================================================== DEFINE_CLASS_PROPERTY_PREFIX(player, hexenarmor, FFFFF, PlayerPawn) { - for (int i=0;i<5;i++) + assert(info->IsKindOf(RUNTIME_CLASS(PClassPlayerPawn))); + for (int i = 0; i < 5; i++) { PROP_FIXED_PARM(val, i); - info->Meta.SetMetaFixed (APMETA_Hexenarmor0+i, val); + static_cast(info)->HexenArmor[i] = val; } } @@ -2087,6 +2127,7 @@ DEFINE_CLASS_PROPERTY_PREFIX(player, weaponslot, ISsssssssssssssssssssssssssssss { PROP_INT_PARM(slot, 0); + assert(info->IsKindOf(RUNTIME_CLASS(PClassPlayerPawn))); if (slot < 0 || slot > 9) { I_Error("Slot must be between 0 and 9."); @@ -2100,7 +2141,7 @@ DEFINE_CLASS_PROPERTY_PREFIX(player, weaponslot, ISsssssssssssssssssssssssssssss PROP_STRING_PARM(str, i); weapons << ' ' << str; } - info->Meta.SetMetaString(APMETA_Slot0 + slot, &weapons[1]); + static_cast(info)->Slot[slot] = &weapons[1]; } }