mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-10 23:02:08 +00:00
- properly handle all meta properties for inventory items.
This commit is contained in:
parent
f343d36ea9
commit
78a66e001a
17 changed files with 60 additions and 46 deletions
|
@ -486,6 +486,7 @@ public:
|
|||
PalEntry &ColorVar(FName field);
|
||||
FName &NameVar(FName field);
|
||||
double &FloatVar(FName field);
|
||||
FString &StringVar(FName field);
|
||||
template<class T> T*& PointerVar(FName field);
|
||||
|
||||
// If you need to replace one object with another and want to
|
||||
|
|
|
@ -2892,6 +2892,7 @@ PClass::PClass()
|
|||
bExported = false;
|
||||
bDecorateClass = false;
|
||||
ConstructNative = nullptr;
|
||||
Meta = nullptr;
|
||||
mDescriptiveName = "Class";
|
||||
|
||||
PClass::AllClasses.Push(this);
|
||||
|
@ -3085,11 +3086,10 @@ void PClass::InitializeSpecials(void *addr, void *defaults, TArray<FTypeAndOffse
|
|||
{
|
||||
// Once we reach a native class, we can stop going up the family tree,
|
||||
// since native classes handle initialization natively.
|
||||
if (!bRuntimeClass)
|
||||
if ((!bRuntimeClass && Inits == &PClass::SpecialInits) || ParentClass == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
assert(ParentClass != nullptr);
|
||||
ParentClass->InitializeSpecials(addr, defaults, Inits);
|
||||
for (auto tao : (this->*Inits))
|
||||
{
|
||||
|
@ -3179,11 +3179,27 @@ void PClass::InitializeDefaults()
|
|||
memset(Defaults + sizeof(DObject), 0, Size - sizeof(DObject));
|
||||
}
|
||||
|
||||
assert(MetaSize >= ParentClass->MetaSize);
|
||||
if (MetaSize != 0)
|
||||
{
|
||||
Meta = (BYTE*)M_Malloc(MetaSize);
|
||||
|
||||
// Copy the defaults from the parent but leave the DObject part alone because it contains important data.
|
||||
if (ParentClass->Meta != nullptr)
|
||||
{
|
||||
memcpy(Meta, ParentClass->Meta, ParentClass->MetaSize);
|
||||
if (MetaSize > ParentClass->MetaSize)
|
||||
{
|
||||
memset(Meta + ParentClass->MetaSize, 0, MetaSize - ParentClass->MetaSize);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(Meta, 0, MetaSize);
|
||||
if (ParentClass->MetaSize > 0) memcpy(Meta, ParentClass->Meta, ParentClass->MetaSize);
|
||||
}
|
||||
|
||||
if (MetaSize > 0) memcpy(Meta, ParentClass->Meta, ParentClass->MetaSize);
|
||||
else memset(Meta, 0, MetaSize);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3199,12 +3215,16 @@ void PClass::InitializeDefaults()
|
|||
{
|
||||
field->Type->SetDefaultValue(Defaults, unsigned(field->Offset), &SpecialInits);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (Meta != nullptr) ParentClass->InitializeSpecials(Meta, ParentClass->Meta, &PClass::MetaInits);
|
||||
for (const PField *field : Fields)
|
||||
{
|
||||
if (!(field->Flags & VARF_Native) && (field->Flags & VARF_Meta))
|
||||
{
|
||||
field->Type->SetDefaultValue(Meta, unsigned(field->Offset), &MetaInits);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -3264,6 +3284,7 @@ PClass *PClass::CreateDerivedClass(FName name, unsigned int size)
|
|||
type->bRuntimeClass = true;
|
||||
Derive(type, name);
|
||||
type->Size = size;
|
||||
type->MetaSize = MetaSize;
|
||||
if (size != TentativeClass)
|
||||
{
|
||||
type->InitializeDefaults();
|
||||
|
@ -3344,7 +3365,7 @@ PField *PClass::AddField(FName name, PType *type, DWORD flags)
|
|||
// Only initialize the defaults if they have already been created.
|
||||
// For ZScript this is not the case, it will first define all fields before
|
||||
// setting up any defaults for any class.
|
||||
if (field != nullptr && !(flags & VARF_Native) && Meta != nullptr)
|
||||
if (field != nullptr && !(flags & VARF_Native))
|
||||
{
|
||||
Meta = (BYTE *)M_Realloc(Meta, MetaSize);
|
||||
memset(Meta + oldsize, 0, MetaSize - oldsize);
|
||||
|
@ -3380,6 +3401,7 @@ PClass *PClass::FindClassTentative(FName name)
|
|||
PClass *type = static_cast<PClass *>(GetClass()->CreateNew());
|
||||
DPrintf(DMSG_SPAMMY, "Creating placeholder class %s : %s\n", name.GetChars(), TypeName.GetChars());
|
||||
|
||||
assert(MetaSize == 0);
|
||||
Derive(type, name);
|
||||
type->Size = TentativeClass;
|
||||
TypeTable.AddType(type, RUNTIME_CLASS(PClass), 0, name, bucket);
|
||||
|
|
|
@ -603,6 +603,7 @@ public:
|
|||
void InitializeActorInfo();
|
||||
void BuildFlatPointers();
|
||||
void BuildArrayPointers();
|
||||
void InitMeta();
|
||||
void DestroySpecials(void *addr);
|
||||
const PClass *NativeClass() const;
|
||||
|
||||
|
@ -742,6 +743,11 @@ inline double &DObject::FloatVar(FName field)
|
|||
return *(double*)ScriptVar(field, TypeFloat64);
|
||||
}
|
||||
|
||||
inline FString &DObject::StringVar(FName field)
|
||||
{
|
||||
return *(FString*)ScriptVar(field, TypeString);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline T *&DObject::PointerVar(FName field)
|
||||
{
|
||||
|
|
|
@ -50,8 +50,6 @@ DEFINE_FIELD(AInventory, DropTime)
|
|||
DEFINE_FIELD(AInventory, SpawnPointClass)
|
||||
DEFINE_FIELD(AInventory, PickupFlash)
|
||||
DEFINE_FIELD(AInventory, PickupSound)
|
||||
DEFINE_FIELD(AInventory, GiveQuest)
|
||||
DEFINE_FIELD(PClassActor, PickupMsg)
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
|
@ -115,8 +113,7 @@ void AInventory::Serialize(FSerializer &arc)
|
|||
("icon", Icon, def->Icon)
|
||||
("pickupsound", PickupSound, def->PickupSound)
|
||||
("spawnpointclass", SpawnPointClass, def->SpawnPointClass)
|
||||
("droptime", DropTime, def->DropTime)
|
||||
("givequest", GiveQuest, def->GiveQuest);
|
||||
("droptime", DropTime, def->DropTime);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
|
|
@ -87,7 +87,6 @@ public:
|
|||
FTextureID Icon; // Icon to show on status bar or HUD
|
||||
int DropTime; // Countdown after dropping
|
||||
PClassActor *SpawnPointClass; // For respawning like Heretic's mace
|
||||
int GiveQuest; // Optionally give one of the quest items.
|
||||
FTextureID AltHUDIcon;
|
||||
|
||||
DWORD ItemFlags;
|
||||
|
|
|
@ -354,7 +354,6 @@ void PClassActor::DeriveData(PClass *newclass)
|
|||
}
|
||||
|
||||
// Inventory stuff
|
||||
newa->PickupMsg = PickupMsg;
|
||||
newa->ForbiddenToPlayerClass = ForbiddenToPlayerClass;
|
||||
newa->RestrictedToPlayerClass = RestrictedToPlayerClass;
|
||||
|
||||
|
|
|
@ -321,7 +321,6 @@ public:
|
|||
double MissileHeight;
|
||||
|
||||
// These are only valid for inventory items.
|
||||
FString PickupMsg;
|
||||
TArray<PClassActor *> RestrictedToPlayerClass;
|
||||
TArray<PClassActor *> ForbiddenToPlayerClass;
|
||||
|
||||
|
|
|
@ -398,6 +398,8 @@ xx(VisibleStartPitch)
|
|||
xx(VisibleEndAngle)
|
||||
xx(VisibleEndPitch)
|
||||
xx(Format)
|
||||
xx(PickupMsg)
|
||||
xx(Respawnable)
|
||||
|
||||
// Various actor names which are used internally
|
||||
xx(MapSpot)
|
||||
|
|
|
@ -541,11 +541,11 @@ static void ParseInsideDecoration (Baggage &bag, AActor *defaults,
|
|||
else if (def == DEF_Pickup && sc.Compare ("PickupMessage"))
|
||||
{
|
||||
sc.MustGetString ();
|
||||
bag.Info->PickupMsg = sc.String;
|
||||
inv->StringVar(NAME_PickupMsg) = sc.String;
|
||||
}
|
||||
else if (def == DEF_Pickup && sc.Compare ("Respawns"))
|
||||
{
|
||||
inv->BoolVar("Respawnable") = true;
|
||||
inv->BoolVar(NAME_Respawnable) = true;
|
||||
}
|
||||
else if (def == DEF_BreakableDecoration && sc.Compare ("SolidOnDeath"))
|
||||
{
|
||||
|
|
|
@ -874,7 +874,7 @@ static void DispatchScriptProperty(FScanner &sc, PProperty *prop, AActor *defaul
|
|||
else if (f->Type->IsKindOf(RUNTIME_CLASS(PString)))
|
||||
{
|
||||
sc.MustGetString();
|
||||
*(FString*)addr = sc.String;
|
||||
*(FString*)addr = strbin1(sc.String);
|
||||
}
|
||||
else if (f->Type->IsKindOf(RUNTIME_CLASS(PClassPointer)))
|
||||
{
|
||||
|
|
|
@ -1831,16 +1831,6 @@ DEFINE_CLASS_PROPERTY(pickupflash, S, Inventory)
|
|||
defaults->PickupFlash = FindClassTentative(str, RUNTIME_CLASS(AActor));
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//==========================================================================
|
||||
DEFINE_CLASS_PROPERTY(pickupmessage, T, Inventory)
|
||||
{
|
||||
PROP_STRING_PARM(str, 0);
|
||||
assert(info->IsKindOf(RUNTIME_CLASS(PClassActor)));
|
||||
static_cast<PClassActor *>(info)->PickupMsg = str;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//==========================================================================
|
||||
|
@ -1875,15 +1865,6 @@ DEFINE_CLASS_PROPERTY(usesound, S, Inventory)
|
|||
defaults->UseSound = str;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//==========================================================================
|
||||
DEFINE_CLASS_PROPERTY(givequest, I, Inventory)
|
||||
{
|
||||
PROP_INT_PARM(i, 0);
|
||||
defaults->GiveQuest = i;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//==========================================================================
|
||||
|
|
|
@ -1007,6 +1007,11 @@ void ZCCCompiler::CompileAllFields()
|
|||
type->Size = Classes[i]->Type()->ParentClass->Size;
|
||||
}
|
||||
}
|
||||
if (Classes[i]->Type()->ParentClass)
|
||||
type->MetaSize = Classes[i]->Type()->ParentClass->MetaSize;
|
||||
else
|
||||
type->MetaSize = 0;
|
||||
|
||||
if (CompileFields(type, Classes[i]->Fields, nullptr, &Classes[i]->TreeNodes, false, !!HasNativeChildren.CheckKey(type)))
|
||||
{
|
||||
// Remove from the list if all fields got compiled.
|
||||
|
|
|
@ -37,7 +37,7 @@ class Ammo : Inventory
|
|||
{
|
||||
int BackpackAmount;
|
||||
int BackpackMaxAmount;
|
||||
/*meta*/ int DropAmount;
|
||||
meta int DropAmount;
|
||||
|
||||
property BackpackAmount: BackpackAmount;
|
||||
property BackpackMaxAmount: BackpackMaxAmount;
|
||||
|
|
|
@ -36,8 +36,8 @@
|
|||
class Health : Inventory
|
||||
{
|
||||
transient int PrevHealth;
|
||||
/*meta*/ int LowHealth;
|
||||
/*meta*/ String LowHealthMessage;
|
||||
meta int LowHealth;
|
||||
meta String LowHealthMessage;
|
||||
|
||||
property LowMessage: LowHealth, LowHealthMessage;
|
||||
|
||||
|
|
|
@ -87,8 +87,8 @@ class MapRevealer : Inventory
|
|||
|
||||
class PuzzleItem : Inventory
|
||||
{
|
||||
/*meta*/ int PuzzleItemNumber;
|
||||
/*meta*/ String PuzzFailMessage;
|
||||
meta int PuzzleItemNumber;
|
||||
meta String PuzzFailMessage;
|
||||
|
||||
property Number: PuzzleItemNumber;
|
||||
property FailMessage: PuzzFailMessage;
|
||||
|
|
|
@ -23,8 +23,11 @@ class Inventory : Actor native
|
|||
native bool bPickupGood;
|
||||
native bool bCreateCopyMoved;
|
||||
native bool bInitEffectFailed;
|
||||
native meta String PickupMsg;
|
||||
native /*meta*/ int GiveQuest;
|
||||
meta String PickupMsg;
|
||||
meta int GiveQuest;
|
||||
|
||||
Property PickupMessage: PickupMsg;
|
||||
Property GiveQuest: GiveQuest;
|
||||
|
||||
Default
|
||||
{
|
||||
|
|
|
@ -33,7 +33,7 @@ class Weapon : StateProvider native
|
|||
native float FOVScale;
|
||||
native int Crosshair; // 0 to use player's crosshair
|
||||
native bool GivenAsMorphWeapon;
|
||||
native bool bAltFire; // Set when self weapon's alternate fire is used.
|
||||
native bool bAltFire; // Set when this weapon's alternate fire is used.
|
||||
native readonly bool bDehAmmo;
|
||||
|
||||
Default
|
||||
|
|
Loading…
Reference in a new issue