This commit is contained in:
Christoph Oelckers 2016-02-10 00:49:35 +01:00
commit 012f10400c
20 changed files with 200 additions and 92 deletions

View file

@ -73,13 +73,14 @@ class PClassPlayerPawn : public PClassActor
{
DECLARE_CLASS(PClassPlayerPawn, PClassActor);
protected:
virtual void Derive(PClass *newclass);
public:
PClassPlayerPawn();
virtual void DeriveData(PClass *newclass);
void EnumColorSets(TArray<int> *out);
FPlayerColorSet *GetColorSet(int setnum) { return ColorSets.CheckKey(setnum); }
void SetPainFlash(FName type, PalEntry color);
bool GetPainFlash(FName type, PalEntry *color) const;
virtual void ReplaceClassRef(PClass *oldclass, PClass *newclass);
FString DisplayName; // Display name (used in menus, etc.)
FString SoundClass; // Sound class

View file

@ -98,6 +98,7 @@ enum
CLASSREG_PClassPlayerPawn,
CLASSREG_PClassType,
CLASSREG_PClassClass,
CLASSREG_PClassWeaponPiece
};
struct ClassReg

View file

@ -44,6 +44,7 @@
#include "autosegs.h"
#include "v_text.h"
#include "a_pickups.h"
#include "a_weaponpiece.h"
#include "d_player.h"
#include "fragglescript/t_fs.h"
@ -2163,6 +2164,7 @@ PClass *ClassReg::RegisterClass()
&PClassPlayerPawn::RegistrationInfo,
&PClassType::RegistrationInfo,
&PClassClass::RegistrationInfo,
&PClassWeaponPiece::RegistrationInfo,
};
// Skip classes that have already been registered
@ -2318,42 +2320,50 @@ PClass *PClass::CreateDerivedClass(FName name, unsigned int size)
assert (size >= Size);
PClass *type;
bool notnew;
size_t bucket;
const PClass *existclass = FindClass(name);
PClass *existclass = static_cast<PClass *>(TypeTable.FindType(RUNTIME_CLASS(PClass), /*FIXME:Outer*/0, name, &bucket));
// This is a placeholder so fill it in
if (existclass != NULL && (existclass->Size == TClass_Fatal || existclass->Size == TClass_Nonfatal))
if (existclass != NULL && (existclass->Size == TentativeClass))
{
type = const_cast<PClass*>(existclass);
if (!IsDescendantOf(type->ParentClass))
{
if (existclass->Size == TClass_Fatal)
{
I_Error("%s must inherit from %s but doesn't.", name.GetChars(), type->ParentClass->TypeName.GetChars());
}
else
{
Printf(TEXTCOLOR_RED "%s must inherit from %s but doesn't.", name.GetChars(), type->ParentClass->TypeName.GetChars());
}
I_Error("%s must inherit from %s but doesn't.", name.GetChars(), type->ParentClass->TypeName.GetChars());
}
DPrintf("Defining placeholder class %s\n", name.GetChars());
notnew = true;
}
else
{
// Create a new type object of the same type as us. (We may be a derived class of PClass.)
type = static_cast<PClass *>(GetClass()->CreateNew());
notnew = false;
}
// Create a new type object of the same type as us. (We may be a derived class of PClass.)
type = static_cast<PClass *>(GetClass()->CreateNew());
type->TypeName = name;
type->Size = size;
type->bRuntimeClass = true;
Derive(type);
DeriveData(type);
if (!notnew)
{
type->InsertIntoHash();
}
else
{
PClassActor::AllActorClasses.Pop(); // remove the newly added class from the list
// todo: replace all affected fields
for (unsigned i = 0; i < PClassActor::AllActorClasses.Size(); i++)
{
PClassActor::AllActorClasses[i]->ReplaceClassRef(existclass, type);
if (PClassActor::AllActorClasses[i] == existclass)
PClassActor::AllActorClasses[i] = static_cast<PClassActor*>(type);
}
TypeTable.ReplaceType(type, existclass, bucket);
}
return type;
}
@ -2403,11 +2413,11 @@ PClass *PClass::FindClassTentative(FName name, bool fatal)
return static_cast<PClass *>(found);
}
PClass *type = static_cast<PClass *>(GetClass()->CreateNew());
DPrintf("Creating placeholder class %s : %s\n", name.GetChars(), TypeName.GetChars());
Printf("Creating placeholder class %s : %s\n", name.GetChars(), TypeName.GetChars());
type->TypeName = name;
type->ParentClass = this;
type->Size = fatal? TClass_Fatal : TClass_Nonfatal;
type->Size = TentativeClass;
type->bRuntimeClass = true;
TypeTable.AddType(type, RUNTIME_CLASS(PClass), (intptr_t)type->Outer, name, bucket);
return type;

View file

@ -601,8 +601,7 @@ public:
enum
{
TClass_Fatal = UINT_MAX,
TClass_Nonfatal = UINT_MAX - 1
TentativeClass = UINT_MAX,
};
class PClassClass;
@ -611,13 +610,14 @@ class PClass : public PStruct
DECLARE_CLASS(PClass, PStruct);
HAS_OBJECT_POINTERS;
protected:
virtual void Derive(PClass *newclass);
// We unravel _WITH_META here just as we did for PType.
enum { MetaClassNum = CLASSREG_PClassClass };
virtual void Derive(PClass *newclass);
public:
typedef PClassClass MetaClass;
MetaClass *GetClass() const;
virtual void DeriveData(PClass *newclass) {}
static void StaticInit();
static void StaticShutdown();
static void StaticBootstrap();
@ -678,9 +678,9 @@ class PClassType : public PClass
{
DECLARE_CLASS(PClassType, PClass);
protected:
virtual void Derive(PClass *newclass);
public:
PClassType();
virtual void Derive(PClass *newclass);
PClass *TypeTableType; // The type to use for hashing into the type table
};

View file

@ -30,15 +30,37 @@ PClassInventory::PClassInventory()
AltHUDIcon.SetNull();
}
void PClassInventory::Derive(PClass *newclass)
void PClassInventory::DeriveData(PClass *newclass)
{
assert(newclass->IsKindOf(RUNTIME_CLASS(PClassInventory)));
Super::Derive(newclass);
Super::DeriveData(newclass);
PClassInventory *newc = static_cast<PClassInventory *>(newclass);
newc->PickupMessage = PickupMessage;
newc->GiveQuest = GiveQuest;
newc->AltHUDIcon = AltHUDIcon;
newc->ForbiddenToPlayerClass = ForbiddenToPlayerClass;
newc->RestrictedToPlayerClass = RestrictedToPlayerClass;
}
void PClassInventory::ReplaceClassRef(PClass *oldclass, PClass *newclass)
{
Super::ReplaceClassRef(oldclass, newclass);
AInventory *def = (AInventory*)Defaults;
if (def != NULL)
{
if (def->PickupFlash == oldclass) def->PickupFlash = static_cast<PClassActor *>(newclass);
for (unsigned i = 0; i < ForbiddenToPlayerClass.Size(); i++)
{
if (ForbiddenToPlayerClass[i] == oldclass)
ForbiddenToPlayerClass[i] = static_cast<PClassPlayerPawn*>(newclass);
}
for (unsigned i = 0; i < RestrictedToPlayerClass.Size(); i++)
{
if (RestrictedToPlayerClass[i] == oldclass)
RestrictedToPlayerClass[i] = static_cast<PClassPlayerPawn*>(newclass);
}
}
}
IMPLEMENT_CLASS(PClassAmmo)
@ -48,10 +70,10 @@ PClassAmmo::PClassAmmo()
DropAmount = 0;
}
void PClassAmmo::Derive(PClass *newclass)
void PClassAmmo::DeriveData(PClass *newclass)
{
assert(newclass->IsKindOf(RUNTIME_CLASS(PClassAmmo)));
Super::Derive(newclass);
Super::DeriveData(newclass);
PClassAmmo *newc = static_cast<PClassAmmo *>(newclass);
newc->DropAmount = DropAmount;
@ -1524,7 +1546,7 @@ bool AInventory::CanPickup (AActor *toucher)
if (!toucher)
return false;
PClassActor *ai = GetClass();
PClassInventory *ai = GetClass();
// Is the item restricted to certain player classes?
if (ai->RestrictedToPlayerClass.Size() != 0)
{
@ -1672,10 +1694,10 @@ PClassHealth::PClassHealth()
//
//===========================================================================
void PClassHealth::Derive(PClass *newclass)
void PClassHealth::DeriveData(PClass *newclass)
{
assert(newclass->IsKindOf(RUNTIME_CLASS(PClassHealth)));
Super::Derive(newclass);
Super::DeriveData(newclass);
PClassHealth *newc = static_cast<PClassHealth *>(newclass);
newc->LowHealth = LowHealth;

View file

@ -135,14 +135,16 @@ enum
class PClassInventory : public PClassActor
{
DECLARE_CLASS(PClassInventory, PClassActor)
protected:
virtual void Derive(PClass *newclass);
public:
PClassInventory();
virtual void DeriveData(PClass *newclass);
virtual void ReplaceClassRef(PClass *oldclass, PClass *newclass);
FString PickupMessage;
int GiveQuest; // Optionally give one of the quest items.
FTextureID AltHUDIcon;
TArray<PClassPlayerPawn *> RestrictedToPlayerClass;
TArray<PClassPlayerPawn *> ForbiddenToPlayerClass;
};
class AInventory : public AActor
@ -241,7 +243,7 @@ class PClassAmmo : public PClassInventory
{
DECLARE_CLASS(PClassAmmo, PClassInventory)
protected:
virtual void Derive(PClass *newclass);
virtual void DeriveData(PClass *newclass);
public:
PClassAmmo();
@ -266,9 +268,10 @@ class PClassWeapon : public PClassInventory
{
DECLARE_CLASS(PClassWeapon, PClassInventory);
protected:
virtual void Derive(PClass *newclass);
virtual void DeriveData(PClass *newclass);
public:
PClassWeapon();
virtual void ReplaceClassRef(PClass *oldclass, PClass *newclass);
int SlotNumber;
fixed_t SlotPriority;
@ -401,9 +404,9 @@ class PClassHealth : public PClassInventory
{
DECLARE_CLASS(PClassHealth, PClassInventory)
protected:
virtual void Derive(PClass *newclass);
public:
PClassHealth();
virtual void DeriveData(PClass *newclass);
FString LowHealthMessage;
int LowHealth;
@ -518,8 +521,8 @@ class PClassPuzzleItem : public PClassInventory
{
DECLARE_CLASS(PClassPuzzleItem, PClassInventory);
protected:
virtual void Derive(PClass *newclass);
public:
virtual void DeriveData(PClass *newclass);
FString PuzzFailMessage;
};

View file

@ -11,9 +11,9 @@
IMPLEMENT_CLASS(PClassPuzzleItem)
void PClassPuzzleItem::Derive(PClass *newclass)
void PClassPuzzleItem::DeriveData(PClass *newclass)
{
Super::Derive(newclass);
Super::DeriveData(newclass);
assert(newclass->IsKindOf(RUNTIME_CLASS(PClassPuzzleItem)));
static_cast<PClassPuzzleItem *>(newclass)->PuzzFailMessage = PuzzFailMessage;
}

View file

@ -3,8 +3,20 @@
#include "doomstat.h"
#include "farchive.h"
IMPLEMENT_CLASS(PClassWeaponPiece)
IMPLEMENT_CLASS (AWeaponHolder)
void PClassWeaponPiece::ReplaceClassRef(PClass *oldclass, PClass *newclass)
{
Super::ReplaceClassRef(oldclass, newclass);
AWeaponPiece *def = (AWeaponPiece*)Defaults;
if (def != NULL)
{
if (def->WeaponClass == oldclass) def->WeaponClass = static_cast<PClassWeapon *>(newclass);
}
}
void AWeaponHolder::Serialize (FArchive &arc)
{
Super::Serialize(arc);

View file

@ -1,7 +1,16 @@
// Ammo: Something a weapon needs to operate
class PClassWeaponPiece : public PClassInventory
{
DECLARE_CLASS(PClassWeaponPiece, PClassInventory)
protected:
public:
virtual void ReplaceClassRef(PClass *oldclass, PClass *newclass);
};
class AWeaponPiece : public AInventory
{
DECLARE_CLASS (AWeaponPiece, AInventory)
DECLARE_CLASS_WITH_META(AWeaponPiece, AInventory, PClassWeaponPiece)
HAS_OBJECT_POINTERS
protected:
bool PrivateShouldStay ();

View file

@ -44,16 +44,29 @@ PClassWeapon::PClassWeapon()
SlotPriority = FIXED_MAX;
}
void PClassWeapon::Derive(PClass *newclass)
void PClassWeapon::DeriveData(PClass *newclass)
{
assert(newclass->IsKindOf(RUNTIME_CLASS(PClassWeapon)));
Super::Derive(newclass);
Super::DeriveData(newclass);
PClassWeapon *newc = static_cast<PClassWeapon *>(newclass);
newc->SlotNumber = SlotNumber;
newc->SlotPriority = SlotPriority;
}
void PClassWeapon::ReplaceClassRef(PClass *oldclass, PClass *newclass)
{
Super::ReplaceClassRef(oldclass, newclass);
AWeapon *def = (AWeapon*)Defaults;
if (def != NULL)
{
if (def->AmmoType1 == oldclass) def->AmmoType1 = static_cast<PClassAmmo *>(newclass);
if (def->AmmoType2 == oldclass) def->AmmoType2 = static_cast<PClassAmmo *>(newclass);
if (def->SisterWeaponType == oldclass) def->SisterWeaponType = static_cast<PClassWeapon *>(newclass);
}
}
//===========================================================================
//
// AWeapon :: Serialize

View file

@ -201,16 +201,11 @@ PClassActor::PClassActor()
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;
// Record this in the master list.
@ -250,10 +245,9 @@ PClassActor::~PClassActor()
//
//==========================================================================
void PClassActor::Derive(PClass *newclass)
void PClassActor::DeriveData(PClass *newclass)
{
assert(newclass->IsKindOf(RUNTIME_CLASS(PClassActor)));
Super::Derive(newclass);
PClassActor *newa = static_cast<PClassActor *>(newclass);
newa->Obituary = Obituary;
@ -281,6 +275,22 @@ void PClassActor::Derive(PClass *newclass)
newa->MeleeSound = MeleeSound;
newa->MissileName = MissileName;
newa->MissileHeight = MissileHeight;
newa->VisibleToPlayerClass = VisibleToPlayerClass;
if (DamageFactors != NULL)
{
// copy damage factors from parent
newa->DamageFactors = new DmgFactors;
*newa->DamageFactors = *DamageFactors;
}
if (PainChances != NULL)
{
// copy pain chances from parent
newa->PainChances = new PainChanceList;
*newa->PainChances = *PainChances;
}
}
//==========================================================================
@ -522,6 +532,27 @@ void PClassActor::SetPainChance(FName type, int chance)
}
}
//==========================================================================
//
// PClassActor :: ReplaceClassRef
//
//==========================================================================
void PClassActor::ReplaceClassRef(PClass *oldclass, PClass *newclass)
{
for (unsigned i = 0; i < VisibleToPlayerClass.Size(); i++)
{
if (VisibleToPlayerClass[i] == oldclass)
VisibleToPlayerClass[i] = static_cast<PClassPlayerPawn*>(newclass);
}
AActor *def = (AActor*)Defaults;
if (def != NULL)
{
if (def->TeleFogSourceType == oldclass) def->TeleFogSourceType = static_cast<PClassActor *>(newclass);
if (def->TeleFogDestType == oldclass) def->TeleFogDestType = static_cast<PClassActor *>(newclass);
}
}
//==========================================================================
//
// DmgFactors :: CheckFactor

View file

@ -192,14 +192,15 @@ class PClassActor : public PClass
DECLARE_CLASS(PClassActor, PClass);
HAS_OBJECT_POINTERS;
protected:
virtual void Derive(PClass *newclass);
public:
static void StaticInit ();
static void StaticSetActorNums ();
virtual void DeriveData(PClass *newclass);
PClassActor();
~PClassActor();
virtual void ReplaceClassRef(PClass *oldclass, PClass *newclass);
void BuildDefaults();
void ApplyDefaults(BYTE *defaults);
void RegisterIDs();
@ -236,8 +237,6 @@ public:
PainChanceList *PainChances;
TArray<PClassPlayerPawn *> VisibleToPlayerClass;
TArray<PClassPlayerPawn *> RestrictedToPlayerClass;
TArray<PClassPlayerPawn *> ForbiddenToPlayerClass;
FString Obituary; // Player was killed by this actor
FString HitObituary; // Player was killed by this actor in melee

View file

@ -515,10 +515,10 @@ PClassPlayerPawn::PClassPlayerPawn()
ColorRangeEnd = 0;
}
void PClassPlayerPawn::Derive(PClass *newclass)
void PClassPlayerPawn::DeriveData(PClass *newclass)
{
assert(newclass->IsKindOf(RUNTIME_CLASS(PClassPlayerPawn)));
Super::Derive(newclass);
Super::DeriveData(newclass);
PClassPlayerPawn *newp = static_cast<PClassPlayerPawn *>(newclass);
size_t i;
@ -581,6 +581,16 @@ bool PClassPlayerPawn::GetPainFlash(FName type, PalEntry *color) const
return false;
}
void PClassPlayerPawn::ReplaceClassRef(PClass *oldclass, PClass *newclass)
{
Super::ReplaceClassRef(oldclass, newclass);
APlayerPawn *def = (APlayerPawn*)Defaults;
if (def != NULL)
{
if (def->FlechetteType == oldclass) def->FlechetteType = static_cast<PClassInventory *>(newclass);
}
}
//===========================================================================
//
// player_t :: SendPitchLimits

View file

@ -137,6 +137,7 @@ PClassActor *CreateNewActor(const FScriptPosition &sc, FName typeName, FName par
goto create;
}
ti->InitializeNativeDefaults();
ti->ParentClass->DeriveData(ti);
}
else
{
@ -144,23 +145,6 @@ PClassActor *CreateNewActor(const FScriptPosition &sc, FName typeName, FName par
ti = static_cast<PClassActor *>(parent->CreateDerivedClass (typeName, parent->Size));
}
// Copy class lists from parent
ti->ForbiddenToPlayerClass = parent->ForbiddenToPlayerClass;
ti->RestrictedToPlayerClass = parent->RestrictedToPlayerClass;
ti->VisibleToPlayerClass = parent->VisibleToPlayerClass;
if (parent->DamageFactors != NULL)
{
// copy damage factors from parent
ti->DamageFactors = new DmgFactors;
*ti->DamageFactors = *parent->DamageFactors;
}
if (parent->PainChances != NULL)
{
// copy pain chances from parent
ti->PainChances = new PainChanceList;
*ti->PainChances = *parent->PainChances;
}
ti->Replacee = ti->Replacement = NULL;
ti->DoomEdNum = -1;
return ti;
@ -340,15 +324,10 @@ static void FinishThingdef()
{
PClassActor *ti = PClassActor::AllActorClasses[i];
if (ti->Size == TClass_Fatal || ti->Size == TClass_Nonfatal)
if (ti->Size == TentativeClass)
{
Printf(TEXTCOLOR_RED "Class %s referenced but not defined\n", ti->TypeName.GetChars());
if (ti->Size == TClass_Fatal) errorcount++;
else
{
// In order to prevent a crash, this class needs to be completed, even though it defines nothing.
ti->ParentClass->CreateDerivedClass(ti->TypeName, ti->ParentClass->Size);
}
errorcount++;
continue;
}

View file

@ -72,12 +72,15 @@ static FxExpression *ParseExpressionB (FScanner &sc, PClassActor *cls);
static FxExpression *ParseExpressionA (FScanner &sc, PClassActor *cls);
static FxExpression *ParseExpression0 (FScanner &sc, PClassActor *cls);
FxExpression *ParseExpression (FScanner &sc, PClassActor *cls)
FxExpression *ParseExpression (FScanner &sc, PClassActor *cls, bool mustresolve)
{
FxExpression *data = ParseExpressionM (sc, cls);
FCompileContext ctx(cls);
data = data->Resolve(ctx);
if (mustresolve)
{
FCompileContext ctx(cls);
data = data->Resolve(ctx);
}
return data;
}

View file

@ -984,7 +984,7 @@ public:
};
FxExpression *ParseExpression (FScanner &sc, PClassActor *cls);
FxExpression *ParseExpression (FScanner &sc, PClassActor *cls, bool mustresolve = false);
#endif

View file

@ -52,6 +52,7 @@
#include "thingdef_exp.h"
#include "m_fixed.h"
#include "vmbuilder.h"
#include "v_text.h"
ExpEmit::ExpEmit(VMFunctionBuilder *build, int type)
: RegNum(build->Registers[type].Get(1)), RegType(type), Konst(false), Fixed(false)
@ -3546,15 +3547,25 @@ FxExpression *FxClassTypeCast::Resolve(FCompileContext &ctx)
if (clsname != NAME_None)
{
// for backwards compatibility with old times it cannot be made a fatal error, if the class is not defined. :(
cls = desttype->FindClassTentative(clsname, false);
if (!cls->IsDescendantOf(desttype))
cls = PClass::FindClass(clsname);
if (cls == NULL)
{
ScriptPosition.Message(MSG_ERROR,"class '%s' is not compatible with '%s'", clsname.GetChars(), desttype->TypeName.GetChars());
delete this;
return NULL;
/* lax */
// Since this happens in released WADs it must pass without a terminal error... :(
ScriptPosition.Message(MSG_WARNING,
"Unknown class name '%s'",
clsname.GetChars(), desttype->TypeName.GetChars());
}
else
{
if (!cls->IsDescendantOf(desttype))
{
ScriptPosition.Message(MSG_ERROR, "class '%s' is not compatible with '%s'", clsname.GetChars(), desttype->TypeName.GetChars());
delete this;
return NULL;
}
ScriptPosition.Message(MSG_DEBUG, "resolving '%s' as class name", clsname.GetChars());
}
ScriptPosition.Message(MSG_DEBUG,"resolving '%s' as class name", clsname.GetChars());
}
FxExpression *x = new FxConstant(cls, ScriptPosition);
delete this;

View file

@ -79,7 +79,7 @@ FxExpression *ParseParameter(FScanner &sc, PClassActor *cls, PType *type, bool c
}
else if (type == TypeSInt32 || type == TypeFloat64)
{
x = ParseExpression (sc, cls);
x = ParseExpression (sc, cls, constant);
if (constant && !x->isConstant())
{
sc.ScriptMessage("Default parameter must be constant.");
@ -190,7 +190,7 @@ static void ParseConstant (FScanner &sc, PSymbolTable *symt, PClassActor *cls)
sc.MustGetToken(TK_Identifier);
FName symname = sc.String;
sc.MustGetToken('=');
FxExpression *expr = ParseExpression (sc, cls);
FxExpression *expr = ParseExpression (sc, cls, true);
sc.MustGetToken(';');
if (!expr->isConstant())
@ -248,7 +248,7 @@ static void ParseEnum (FScanner &sc, PSymbolTable *symt, PClassActor *cls)
FName symname = sc.String;
if (sc.CheckToken('='))
{
FxExpression *expr = ParseExpression (sc, cls);
FxExpression *expr = ParseExpression (sc, cls, true);
if (!expr->isConstant())
{
sc.ScriptMessage("'%s' must be constant", symname.GetChars());
@ -536,7 +536,7 @@ static void ParseUserVariable (FScanner &sc, PSymbolTable *symt, PClassActor *cl
if (sc.CheckToken('['))
{
FxExpression *expr = ParseExpression(sc, cls);
FxExpression *expr = ParseExpression(sc, cls, true);
if (!expr->isConstant())
{
sc.ScriptMessage("Array size must be a constant");

View file

@ -1534,12 +1534,12 @@ DEFINE_PROPERTY(riplevelmax, I, Actor)
//==========================================================================
DEFINE_CLASS_PROPERTY(restrictedto, Ssssssssssssssssssss, Inventory)
{
info->RestrictedToPlayerClass.Clear();
static_cast<PClassInventory*>(info)->RestrictedToPlayerClass.Clear();
for(int i = 0;i < PROP_PARM_COUNT;++i)
{
PROP_STRING_PARM(n, i);
if (*n != 0)
info->RestrictedToPlayerClass.Push(FindClassTentativePlayerPawn(n));
static_cast<PClassInventory*>(info)->RestrictedToPlayerClass.Push(FindClassTentativePlayerPawn(n));
}
}
@ -1548,12 +1548,12 @@ DEFINE_CLASS_PROPERTY(restrictedto, Ssssssssssssssssssss, Inventory)
//==========================================================================
DEFINE_CLASS_PROPERTY(forbiddento, Ssssssssssssssssssss, Inventory)
{
info->ForbiddenToPlayerClass.Clear();
static_cast<PClassInventory*>(info)->ForbiddenToPlayerClass.Clear();
for(int i = 0;i < PROP_PARM_COUNT;++i)
{
PROP_STRING_PARM(n, i);
if (*n != 0)
info->ForbiddenToPlayerClass.Push(FindClassTentativePlayerPawn(n));
static_cast<PClassInventory*>(info)->ForbiddenToPlayerClass.Push(FindClassTentativePlayerPawn(n));
}
}

View file

@ -32,6 +32,10 @@ ACTOR Actor native //: Thinker
RipLevelMin 0
RipLevelMax 0
DefThreshold 100
BloodType "Blood", "BloodSplatter", "AxeBlood"
ExplosionDamage 128
MissileHeight 32
// Functions
native bool CheckClass(class<Actor> checkclass, int ptr_select = AAPTR_DEFAULT, bool match_superclass = false);