- moved Restricted/ForbiddenToPlayerClass fully to the script side.

This required some fixes for allowing to read from metadata arrays.
This commit is contained in:
Christoph Oelckers 2017-04-11 15:11:13 +02:00
parent 45691e91c9
commit 6a3ddaa8fa
7 changed files with 49 additions and 55 deletions

View file

@ -484,43 +484,6 @@ bool AInventory::CallTryPickup(AActor *toucher, AActor **toucher_return)
return !!res; return !!res;
} }
//===========================================================================
//
// AInventory :: CanPickup
//
//===========================================================================
DEFINE_ACTION_FUNCTION(AInventory, CanPickup)
{
PARAM_SELF_PROLOGUE(AInventory);
PARAM_OBJECT(toucher, AActor);
if (!toucher)
ACTION_RETURN_BOOL(false);
auto ai = self->GetClass();
// Is the item restricted to certain player classes?
if (ai->RestrictedToPlayerClass.Size() != 0)
{
for (unsigned i = 0; i < ai->RestrictedToPlayerClass.Size(); ++i)
{
if (toucher->IsKindOf(ai->RestrictedToPlayerClass[i]))
ACTION_RETURN_BOOL(true);
}
ACTION_RETURN_BOOL(false);
}
// Or is it forbidden to certain other classes?
else
{
for (unsigned i = 0; i < ai->ForbiddenToPlayerClass.Size(); ++i)
{
if (toucher->IsKindOf(ai->ForbiddenToPlayerClass[i]))
ACTION_RETURN_BOOL(false);
}
}
ACTION_RETURN_BOOL(true);
}
//=========================================================================== //===========================================================================
// //
// CCMD printinv // CCMD printinv

View file

@ -314,10 +314,6 @@ void PClassActor::DeriveData(PClass *newclass)
*newa->PainChances = *PainChances; *newa->PainChances = *PainChances;
} }
// Inventory stuff
newa->ForbiddenToPlayerClass = ForbiddenToPlayerClass;
newa->RestrictedToPlayerClass = RestrictedToPlayerClass;
newa->DisplayName = DisplayName; newa->DisplayName = DisplayName;
} }

View file

@ -291,10 +291,6 @@ public:
FString SourceLumpName; FString SourceLumpName;
FIntCVar *distancecheck; FIntCVar *distancecheck;
// These are only valid for inventory items.
TArray<PClassActor *> RestrictedToPlayerClass;
TArray<PClassActor *> ForbiddenToPlayerClass;
// This is from PClassPlayerPawn // This is from PClassPlayerPawn
FString DisplayName; FString DisplayName;

View file

@ -902,3 +902,5 @@ xx(Player6)
xx(Player7) xx(Player7)
xx(Player8) xx(Player8)
xx(PlayerChunk) xx(PlayerChunk)
xx(RestrictedToPlayerClass)
xx(ForbiddenToPlayerClass)

View file

@ -6914,13 +6914,13 @@ FxStructMember::~FxStructMember()
bool FxStructMember::RequestAddress(FCompileContext &ctx, bool *writable) bool FxStructMember::RequestAddress(FCompileContext &ctx, bool *writable)
{ {
// Cannot take the address of metadata variables. AddressRequested = true;
if (membervar->Flags & VARF_Meta) if (membervar->Flags & VARF_Meta)
{ {
return false; // Meta variables are read only.
*writable = false;
} }
AddressRequested = true; else if (writable != nullptr)
if (writable != nullptr)
{ {
// [ZZ] original check. // [ZZ] original check.
bool bWritable = (AddressWritable && !ctx.CheckWritable(membervar->Flags) && bool bWritable = (AddressWritable && !ctx.CheckWritable(membervar->Flags) &&
@ -7314,11 +7314,13 @@ ExpEmit FxArrayElement::Emit(VMFunctionBuilder *build)
if (SizeAddr != ~0u) if (SizeAddr != ~0u)
{ {
bool ismeta = Array->ExprType == EFX_ClassMember && static_cast<FxClassMember*>(Array)->membervar->Flags & VARF_Meta;
arrayvar.Free(build); arrayvar.Free(build);
start = ExpEmit(build, REGT_POINTER); start = ExpEmit(build, REGT_POINTER);
build->Emit(OP_LP, start.RegNum, arrayvar.RegNum, build->GetConstantInt(0)); build->Emit(OP_LP, start.RegNum, arrayvar.RegNum, build->GetConstantInt(0));
auto f = new PField(NAME_None, TypeUInt32, 0, SizeAddr); auto f = new PField(NAME_None, TypeUInt32, ismeta? VARF_Meta : 0, SizeAddr);
static_cast<FxMemberBase *>(Array)->membervar = f; static_cast<FxMemberBase *>(Array)->membervar = f;
static_cast<FxMemberBase *>(Array)->AddressRequested = false; static_cast<FxMemberBase *>(Array)->AddressRequested = false;
Array->ValueType = TypeUInt32; Array->ValueType = TypeUInt32;

View file

@ -1090,12 +1090,14 @@ DEFINE_PROPERTY(distancecheck, S, Actor)
//========================================================================== //==========================================================================
DEFINE_CLASS_PROPERTY(restrictedto, Ssssssssssssssssssss, Inventory) DEFINE_CLASS_PROPERTY(restrictedto, Ssssssssssssssssssss, Inventory)
{ {
static_cast<PClassActor*>(info)->RestrictedToPlayerClass.Clear(); auto restrictarray = (TArray<PClassActor*>*)defaults->ScriptVar(NAME_RestrictedToPlayerClass, nullptr);
restrictarray->Clear();
for(int i = 0;i < PROP_PARM_COUNT;++i) for(int i = 0;i < PROP_PARM_COUNT;++i)
{ {
PROP_STRING_PARM(n, i); PROP_STRING_PARM(n, i);
if (*n != 0) if (*n != 0)
static_cast<PClassActor*>(info)->RestrictedToPlayerClass.Push(FindClassTentative(n, RUNTIME_CLASS(APlayerPawn))); restrictarray->Push(FindClassTentative(n, RUNTIME_CLASS(APlayerPawn)));
} }
} }
@ -1104,12 +1106,14 @@ DEFINE_CLASS_PROPERTY(restrictedto, Ssssssssssssssssssss, Inventory)
//========================================================================== //==========================================================================
DEFINE_CLASS_PROPERTY(forbiddento, Ssssssssssssssssssss, Inventory) DEFINE_CLASS_PROPERTY(forbiddento, Ssssssssssssssssssss, Inventory)
{ {
static_cast<PClassActor*>(info)->ForbiddenToPlayerClass.Clear(); auto forbidarray = (TArray<PClassActor*>*)defaults->ScriptVar(NAME_ForbiddenToPlayerClass, nullptr);
forbidarray->Clear();
for(int i = 0;i < PROP_PARM_COUNT;++i) for(int i = 0;i < PROP_PARM_COUNT;++i)
{ {
PROP_STRING_PARM(n, i); PROP_STRING_PARM(n, i);
if (*n != 0) if (*n != 0)
static_cast<PClassActor*>(info)->ForbiddenToPlayerClass.Push(FindClassTentative(n, RUNTIME_CLASS(APlayerPawn))); forbidarray->Push(FindClassTentative(n, RUNTIME_CLASS(APlayerPawn)));
} }
} }

View file

@ -25,6 +25,8 @@ class Inventory : Actor native
native bool bInitEffectFailed; native bool bInitEffectFailed;
meta String PickupMsg; meta String PickupMsg;
meta int GiveQuest; meta int GiveQuest;
meta array<class<Actor> > ForbiddenToPlayerClass;
meta array<class<Actor> > RestrictedToPlayerClass;
property PickupMessage: PickupMsg; property PickupMessage: PickupMsg;
property GiveQuest: GiveQuest; property GiveQuest: GiveQuest;
@ -46,7 +48,6 @@ class Inventory : Actor native
Inventory.PickupMessage "$TXT_DEFAULTPICKUPMSG"; Inventory.PickupMessage "$TXT_DEFAULTPICKUPMSG";
} }
native bool CanPickup(Actor toucher);
native bool DoRespawn(); native bool DoRespawn();
native void BecomeItem(); native void BecomeItem();
native void BecomePickup(); native void BecomePickup();
@ -330,6 +331,36 @@ class Inventory : Actor native
} }
} }
//===========================================================================
//
// AInventory :: CanPickup
//
//===========================================================================
virtual bool CanPickup(Actor toucher)
{
if (toucher == null) return false;
int rsize = RestrictedToPlayerClass.Size();
if (rsize > 0)
{
for (int i=0; i < rsize; i++)
{
if (toucher is RestrictedToPlayerClass[i]) return true;
}
return false;
}
rsize = ForbiddenToPlayerClass.Size();
if (rsize > 0)
{
for (int i=0; i < rsize; i++)
{
if (toucher is ForbiddenToPlayerClass[i]) return false;
}
}
return true;
}
//=========================================================================== //===========================================================================
// //
// AInventory :: CallTryPickup // AInventory :: CallTryPickup