diff --git a/src/d_player.h b/src/d_player.h index e09db38a3..b79e56862 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -82,15 +82,6 @@ public: bool GetPainFlash(FName type, PalEntry *color) const; FString DisplayName; // Display name (used in menus, etc.) - FString SoundClass; // Sound class - FString Face; // Doom status bar face (when used) - FString Portrait; - FString Slot[10]; - FName InvulMode; - FName HealingRadiusType; - double HexenArmor[5]; - BYTE ColorRangeStart; // Skin color range - BYTE ColorRangeEnd; FPlayerColorSetMap ColorSets; PainFlashList PainFlashes; }; @@ -176,6 +167,17 @@ public: // [SP] ViewBob Multiplier double ViewBob; + // Former class properties that were moved into the object to get rid of the meta class. + FName SoundClass; // Sound class + FName Face; // Doom status bar face (when used) + FName Portrait; + FName Slot[10]; + FName InvulMode; + FName HealingRadiusType; + double HexenArmor[5]; + BYTE ColorRangeStart; // Skin color range + BYTE ColorRangeEnd; + }; // diff --git a/src/g_inventory/a_weapons.cpp b/src/g_inventory/a_weapons.cpp index 888259098..afa55cc10 100644 --- a/src/g_inventory/a_weapons.cpp +++ b/src/g_inventory/a_weapons.cpp @@ -1154,11 +1154,12 @@ void FWeaponSlots::SendDifferences(int playernum, const FWeaponSlots &other) void FWeaponSlots::SetFromPlayer(PClassPlayerPawn *type) { Clear(); + auto Slot = ((APlayerPawn*)GetDefaultByType(type))->Slot; for (int i = 0; i < NUM_WEAPON_SLOTS; ++i) { - if (!type->Slot[i].IsEmpty()) + if (Slot[i] != NAME_None) { - Slots[i].AddWeaponList(type->Slot[i], false); + Slots[i].AddWeaponList(Slot[i], false); } } } diff --git a/src/g_shared/a_morph.cpp b/src/g_shared/a_morph.cpp index cd72bca79..246073010 100644 --- a/src/g_shared/a_morph.cpp +++ b/src/g_shared/a_morph.cpp @@ -290,8 +290,8 @@ bool P_UndoPlayerMorph (player_t *activator, player_t *player, int unmorphflag, // and for the original DOOM status bar. if (player == &players[consoleplayer]) { - FString face = pmo->GetClass()->Face; - if (face.IsNotEmpty() && strcmp(face, "None") != 0) + FName face = pmo->Face; + if (face != NAME_None) { // Assume root-level base skin to begin with size_t skinindex = 0; @@ -367,7 +367,7 @@ bool P_UndoPlayerMorph (player_t *activator, player_t *player, int unmorphflag, if (hxarmor != nullptr) { double *Slots = (double*)hxarmor->ScriptVar(NAME_Slots, nullptr); - Slots[4] = mo->GetClass()->HexenArmor[0]; + Slots[4] = mo->HexenArmor[0]; } return true; } diff --git a/src/g_statusbar/sbar_mugshot.cpp b/src/g_statusbar/sbar_mugshot.cpp index d88ad40f2..d24298b94 100644 --- a/src/g_statusbar/sbar_mugshot.cpp +++ b/src/g_statusbar/sbar_mugshot.cpp @@ -489,7 +489,7 @@ FTexture *FMugShot::GetFace(player_t *player, const char *default_face, int accu if (CurrentState != NULL) { int skin = player->userinfo.GetSkin(); - const char *skin_face = (stateflags & FMugShot::CUSTOM) ? nullptr : (player->morphTics ? player->MorphedPlayerClass->Face.GetChars() : skins[skin].face); + const char *skin_face = (stateflags & FMugShot::CUSTOM) ? nullptr : (player->morphTics ? ((APlayerPawn*)GetDefaultByType(player->MorphedPlayerClass))->Face.GetChars() : skins[skin].face); return CurrentState->GetCurrentFrameTexture(default_face, skin_face, level, angle); } return NULL; diff --git a/src/menu/playerdisplay.cpp b/src/menu/playerdisplay.cpp index 57c8ecf26..821c2ea70 100644 --- a/src/menu/playerdisplay.cpp +++ b/src/menu/playerdisplay.cpp @@ -557,11 +557,11 @@ void DListMenuItemPlayerDisplay::Drawer(bool selected) return; } - FString portrait = mPlayerClass->Type->Portrait; + FName portrait = ((APlayerPawn*)GetDefaultByType(mPlayerClass->Type))->Portrait; - if (portrait.IsNotEmpty() && !mNoportrait) + if (portrait != NAME_None && !mNoportrait) { - FTextureID texid = TexMan.CheckForTexture(portrait, FTexture::TEX_MiscPatch); + FTextureID texid = TexMan.CheckForTexture(portrait.GetChars(), FTexture::TEX_MiscPatch); if (texid.isValid()) { FTexture *tex = TexMan(texid); diff --git a/src/p_user.cpp b/src/p_user.cpp index 1b9cedf4a..ab1920ae8 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -542,12 +542,6 @@ IMPLEMENT_CLASS(PClassPlayerPawn, false, false) PClassPlayerPawn::PClassPlayerPawn() { - for (size_t i = 0; i < countof(HexenArmor); ++i) - { - HexenArmor[i] = 0; - } - ColorRangeStart = 0; - ColorRangeEnd = 0; } void PClassPlayerPawn::DeriveData(PClass *newclass) @@ -555,24 +549,9 @@ void PClassPlayerPawn::DeriveData(PClass *newclass) assert(newclass->IsKindOf(RUNTIME_CLASS(PClassPlayerPawn))); Super::DeriveData(newclass); PClassPlayerPawn *newp = static_cast(newclass); - size_t i; newp->DisplayName = DisplayName; - newp->SoundClass = SoundClass; - newp->Face = Face; - newp->InvulMode = InvulMode; - newp->HealingRadiusType = HealingRadiusType; - newp->ColorRangeStart = ColorRangeStart; - newp->ColorRangeEnd = ColorRangeEnd; newp->ColorSets = ColorSets; - for (i = 0; i < countof(HexenArmor); ++i) - { - newp->HexenArmor[i] = HexenArmor[i]; - } - for (i = 0; i < countof(Slot); ++i) - { - newp->Slot[i] = Slot[i]; - } } static int intcmp(const void *a, const void *b) @@ -1230,7 +1209,7 @@ const char *APlayerPawn::GetSoundClass() const // [GRB] PClassPlayerPawn *pclass = GetClass(); - return pclass->SoundClass.IsNotEmpty() ? pclass->SoundClass.GetChars() : "player"; + return SoundClass != NAME_None? SoundClass.GetChars() : "player"; } //=========================================================================== @@ -1373,10 +1352,10 @@ void APlayerPawn::GiveDefaultInventory () double *Slots = (double*)harmor->ScriptVar(NAME_Slots, nullptr); double *SlotsIncrement = (double*)harmor->ScriptVar(NAME_SlotsIncrement, nullptr); - Slots[4] = myclass->HexenArmor[0]; + Slots[4] = HexenArmor[0]; for (int i = 0; i < 4; ++i) { - SlotsIncrement[i] = myclass->HexenArmor[i + 1]; + SlotsIncrement[i] = HexenArmor[i + 1]; } // BasicArmor must come right after that. It should not affect any @@ -3248,16 +3227,17 @@ DEFINE_FIELD(APlayerPawn, DamageFade) DEFINE_FIELD(APlayerPawn, ViewBob) DEFINE_FIELD(APlayerPawn, FullHeight) -DEFINE_FIELD(PClassPlayerPawn, HealingRadiusType) +DEFINE_FIELD(APlayerPawn, HealingRadiusType) +DEFINE_FIELD(APlayerPawn, SoundClass) +DEFINE_FIELD(APlayerPawn, Face) +DEFINE_FIELD(APlayerPawn, Portrait) +DEFINE_FIELD(APlayerPawn, Slot) +DEFINE_FIELD(APlayerPawn, InvulMode) +DEFINE_FIELD(APlayerPawn, HexenArmor) +DEFINE_FIELD(APlayerPawn, ColorRangeStart) +DEFINE_FIELD(APlayerPawn, ColorRangeEnd) + DEFINE_FIELD(PClassPlayerPawn, DisplayName) -DEFINE_FIELD(PClassPlayerPawn, SoundClass) -DEFINE_FIELD(PClassPlayerPawn, Face) -DEFINE_FIELD(PClassPlayerPawn, Portrait) -DEFINE_FIELD(PClassPlayerPawn, Slot) -DEFINE_FIELD(PClassPlayerPawn, InvulMode) -DEFINE_FIELD(PClassPlayerPawn, HexenArmor) -DEFINE_FIELD(PClassPlayerPawn, ColorRangeStart) -DEFINE_FIELD(PClassPlayerPawn, ColorRangeEnd) DEFINE_FIELD(PClassPlayerPawn, ColorSets) DEFINE_FIELD(PClassPlayerPawn, PainFlashes) diff --git a/src/r_data/sprites.cpp b/src/r_data/sprites.cpp index 7fb59ef94..be44e9d82 100644 --- a/src/r_data/sprites.cpp +++ b/src/r_data/sprites.cpp @@ -725,18 +725,22 @@ void R_InitSkins (void) if (!remove) { - skins[i].range0start = transtype->ColorRangeStart; - skins[i].range0end = transtype->ColorRangeEnd; + auto transdef = ((APlayerPawn*)GetDefaultByType(transtype)); + auto basedef = ((APlayerPawn*)GetDefaultByType(basetype)); + + skins[i].range0start = transdef->ColorRangeStart; + skins[i].range0end = transdef->ColorRangeEnd; remove = true; for (j = 0; j < (int)PlayerClasses.Size (); j++) { PClassPlayerPawn *type = PlayerClasses[j].Type; + auto type_def = ((APlayerPawn*)GetDefaultByType(type)); if (type->IsDescendantOf (basetype) && GetDefaultByType(type)->SpawnState->sprite == GetDefaultByType(basetype)->SpawnState->sprite && - type->ColorRangeStart == basetype->ColorRangeStart && - type->ColorRangeEnd == basetype->ColorRangeEnd) + type_def->ColorRangeStart == basedef->ColorRangeStart && + type_def->ColorRangeEnd == basedef->ColorRangeEnd) { PlayerClasses[j].Skins.Push ((int)i); remove = false; @@ -935,10 +939,10 @@ void R_InitSprites () memset (skins, 0, sizeof(*skins) * numskins); for (i = 0; i < numskins; i++) { // Assume Doom skin by default - PClassPlayerPawn *type = PlayerClasses[0].Type; + auto type = ((APlayerPawn*)GetDefaultByType(PlayerClasses[0].Type)); skins[i].range0start = type->ColorRangeStart; skins[i].range0end = type->ColorRangeEnd; - skins[i].Scale = GetDefaultByType (type)->Scale; + skins[i].Scale = type->Scale; } R_InitSpriteDefs (); @@ -950,11 +954,10 @@ void R_InitSprites () // [GRB] Each player class has its own base skin for (i = 0; i < PlayerClasses.Size (); i++) { - PClassPlayerPawn *basetype = PlayerClasses[i].Type; - FString classface = basetype->Face; + auto basetype = ((APlayerPawn*)GetDefaultByType(PlayerClasses[i].Type)); strcpy (skins[i].name, "Base"); - if (classface.IsEmpty() || strcmp(classface, "None") == 0) + if (basetype->Face == NAME_None) { skins[i].face[0] = 'S'; skins[i].face[1] = 'T'; @@ -963,12 +966,12 @@ void R_InitSprites () } else { - strcpy(skins[i].face, classface); + strcpy(skins[i].face, basetype->Face); } skins[i].range0start = basetype->ColorRangeStart; skins[i].range0end = basetype->ColorRangeEnd; - skins[i].Scale = GetDefaultByType (basetype)->Scale; - skins[i].sprite = GetDefaultByType (basetype)->SpawnState->sprite; + skins[i].Scale = basetype->Scale; + skins[i].sprite = basetype->SpawnState->sprite; skins[i].namespc = ns_global; PlayerClasses[i].Skins.Push (i); diff --git a/src/scripting/thingdef_properties.cpp b/src/scripting/thingdef_properties.cpp index 8cffbc347..ef9a905a3 100644 --- a/src/scripting/thingdef_properties.cpp +++ b/src/scripting/thingdef_properties.cpp @@ -2274,8 +2274,7 @@ DEFINE_CLASS_PROPERTY_PREFIX(player, soundclass, S, PlayerPawn) FString tmp = str; tmp.ReplaceChars (' ', '_'); - assert(info->IsKindOf(RUNTIME_CLASS(PClassPlayerPawn))); - static_cast(info)->SoundClass = tmp; + defaults->SoundClass = tmp.IsNotEmpty()? FName(tmp) : NAME_None; } //========================================================================== @@ -2286,21 +2285,23 @@ DEFINE_CLASS_PROPERTY_PREFIX(player, face, S, PlayerPawn) PROP_STRING_PARM(str, 0); FString tmp = str; - tmp.ToUpper(); - bool valid = (tmp.Len() == 3 && - (((tmp[0] >= 'A') && (tmp[0] <= 'Z')) || ((tmp[0] >= '0') && (tmp[0] <= '9'))) && - (((tmp[1] >= 'A') && (tmp[1] <= 'Z')) || ((tmp[1] >= '0') && (tmp[1] <= '9'))) && - (((tmp[2] >= 'A') && (tmp[2] <= 'Z')) || ((tmp[2] >= '0') && (tmp[2] <= '9'))) - ); - if (!valid) + if (tmp.Len() == 0) defaults->Face = NAME_None; + else { - bag.ScriptPosition.Message(MSG_OPTERROR, - "Invalid face '%s' for '%s';\nSTF replacement codes must be 3 alphanumeric characters.\n", - tmp.GetChars(), info->TypeName.GetChars ()); + tmp.ToUpper(); + bool valid = (tmp.Len() == 3 && + (((tmp[0] >= 'A') && (tmp[0] <= 'Z')) || ((tmp[0] >= '0') && (tmp[0] <= '9'))) && + (((tmp[1] >= 'A') && (tmp[1] <= 'Z')) || ((tmp[1] >= '0') && (tmp[1] <= '9'))) && + (((tmp[2] >= 'A') && (tmp[2] <= 'Z')) || ((tmp[2] >= '0') && (tmp[2] <= '9'))) + ); + if (!valid) + { + bag.ScriptPosition.Message(MSG_OPTERROR, + "Invalid face '%s' for '%s';\nSTF replacement codes must be 3 alphanumeric characters.\n", + tmp.GetChars(), info->TypeName.GetChars()); + } + defaults->Face = tmp; } - - assert(info->IsKindOf(RUNTIME_CLASS(PClassPlayerPawn))); - static_cast(info)->Face = tmp; } //========================================================================== @@ -2314,9 +2315,8 @@ DEFINE_CLASS_PROPERTY_PREFIX(player, colorrange, I_I, PlayerPawn) if (start > end) swapvalues (start, end); - assert(info->IsKindOf(RUNTIME_CLASS(PClassPlayerPawn))); - static_cast(info)->ColorRangeStart = start; - static_cast(info)->ColorRangeEnd = end; + defaults->ColorRangeStart = start; + defaults->ColorRangeEnd = end; } //========================================================================== @@ -2693,8 +2693,7 @@ DEFINE_CLASS_PROPERTY_PREFIX(player, startitem, S_i, PlayerPawn) DEFINE_CLASS_PROPERTY_PREFIX(player, invulnerabilitymode, S, PlayerPawn) { PROP_STRING_PARM(str, 0); - assert(info->IsKindOf(RUNTIME_CLASS(PClassPlayerPawn))); - static_cast(info)->InvulMode = str; + defaults->InvulMode = str; } //========================================================================== @@ -2704,7 +2703,7 @@ DEFINE_CLASS_PROPERTY_PREFIX(player, healradiustype, S, PlayerPawn) { PROP_STRING_PARM(str, 0); assert(info->IsKindOf(RUNTIME_CLASS(PClassPlayerPawn))); - static_cast(info)->HealingRadiusType = str; + defaults->HealingRadiusType = str; } //========================================================================== @@ -2716,7 +2715,7 @@ DEFINE_CLASS_PROPERTY_PREFIX(player, hexenarmor, FFFFF, PlayerPawn) for (int i = 0; i < 5; i++) { PROP_DOUBLE_PARM(val, i); - static_cast(info)->HexenArmor[i] = val; + defaults->HexenArmor[i] = val; } } @@ -2727,7 +2726,7 @@ DEFINE_CLASS_PROPERTY_PREFIX(player, portrait, S, PlayerPawn) { assert(info->IsKindOf(RUNTIME_CLASS(PClassPlayerPawn))); PROP_STRING_PARM(val, 0); - static_cast(info)->Portrait = val; + defaults->Portrait = val; } //========================================================================== @@ -2751,7 +2750,7 @@ DEFINE_CLASS_PROPERTY_PREFIX(player, weaponslot, ISsssssssssssssssssssssssssssss PROP_STRING_PARM(str, i); weapons << ' ' << str; } - static_cast(info)->Slot[slot] = &weapons[1]; + defaults->Slot[slot] = weapons.IsEmpty()? NAME_None : FName(weapons); } } diff --git a/wadsrc/static/zscript/shared/player.txt b/wadsrc/static/zscript/shared/player.txt index 0a7798ace..dc1d1ba1d 100644 --- a/wadsrc/static/zscript/shared/player.txt +++ b/wadsrc/static/zscript/shared/player.txt @@ -9,17 +9,16 @@ class PlayerPawn : Actor native native Inventory InvFirst; // first inventory item displayed on inventory bar native Inventory InvSel; // selected inventory item native meta String DisplayName; // Display name (used in menus, etc.) - native meta String SoundClass; // Sound class - native meta String Face; // Doom status bar face (when used) - native meta String Portrait; - native meta String Slot[10]; - native meta Name InvulMode; - native meta Name HealingRadiusType; - native meta double HexenArmor[5]; - native meta uint8 ColorRangeStart; // Skin color range - native meta uint8 ColorRangeEnd; - //FPlayerColorSetMap ColorSets; - //PainFlashList PainFlashes; + + native /*meta*/ Name SoundClass; // Sound class + native /*meta*/ Name Face; // Doom status bar face (when used) + native /*meta*/ Name Portrait; + native /*meta*/ Name Slot[10]; + native /*meta*/ Name InvulMode; + native /*meta*/ Name HealingRadiusType; + native /*meta*/ double HexenArmor[5]; + native /*meta*/ uint8 ColorRangeStart; // Skin color range + native /*meta*/ uint8 ColorRangeEnd; // [GRB] Player class properties native double JumpZ;