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]; } }