- turned many of PClassPlayerPawn's strings into names and moved all scalar properties into APlayerPawn.

The goal is to get rid of PClassPlayerPawn and PClassInventory so that the old assumption that all actor class descriptors have the same size can be restored
This is important to remove some code that seriously blocks optimization of the type table because that can only be done if types do not need to be replaced.
This commit is contained in:
Christoph Oelckers 2017-02-08 16:42:13 +01:00
parent a6785afddb
commit 2ca0e34785
9 changed files with 82 additions and 98 deletions

View file

@ -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;
};
//

View file

@ -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);
}
}
}

View file

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

View file

@ -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;

View file

@ -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);

View file

@ -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<PClassPlayerPawn *>(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)

View file

@ -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);

View file

@ -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<PClassPlayerPawn *>(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<PClassPlayerPawn *>(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<PClassPlayerPawn *>(info)->ColorRangeStart = start;
static_cast<PClassPlayerPawn *>(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<PClassPlayerPawn *>(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<PClassPlayerPawn *>(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<PClassPlayerPawn *>(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<PClassPlayerPawn *>(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<PClassPlayerPawn *>(info)->Slot[slot] = &weapons[1];
defaults->Slot[slot] = weapons.IsEmpty()? NAME_None : FName(weapons);
}
}

View file

@ -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;