diff --git a/src/g_inventory/a_pickups.cpp b/src/g_inventory/a_pickups.cpp index df6679d41..0a44e6d14 100644 --- a/src/g_inventory/a_pickups.cpp +++ b/src/g_inventory/a_pickups.cpp @@ -484,43 +484,6 @@ bool AInventory::CallTryPickup(AActor *toucher, AActor **toucher_return) 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 diff --git a/src/info.cpp b/src/info.cpp index 5e9653336..b8f7db995 100644 --- a/src/info.cpp +++ b/src/info.cpp @@ -314,10 +314,6 @@ void PClassActor::DeriveData(PClass *newclass) *newa->PainChances = *PainChances; } - // Inventory stuff - newa->ForbiddenToPlayerClass = ForbiddenToPlayerClass; - newa->RestrictedToPlayerClass = RestrictedToPlayerClass; - newa->DisplayName = DisplayName; } diff --git a/src/info.h b/src/info.h index 248d1cd35..5af8ac5f5 100644 --- a/src/info.h +++ b/src/info.h @@ -291,10 +291,6 @@ public: FString SourceLumpName; FIntCVar *distancecheck; - // These are only valid for inventory items. - TArray RestrictedToPlayerClass; - TArray ForbiddenToPlayerClass; - // This is from PClassPlayerPawn FString DisplayName; diff --git a/src/namedef.h b/src/namedef.h index a193945de..4346844fc 100644 --- a/src/namedef.h +++ b/src/namedef.h @@ -902,3 +902,5 @@ xx(Player6) xx(Player7) xx(Player8) xx(PlayerChunk) +xx(RestrictedToPlayerClass) +xx(ForbiddenToPlayerClass) diff --git a/src/scripting/backend/codegen.cpp b/src/scripting/backend/codegen.cpp index ba1c72c28..4327bde9d 100644 --- a/src/scripting/backend/codegen.cpp +++ b/src/scripting/backend/codegen.cpp @@ -6914,13 +6914,13 @@ FxStructMember::~FxStructMember() bool FxStructMember::RequestAddress(FCompileContext &ctx, bool *writable) { - // Cannot take the address of metadata variables. + AddressRequested = true; if (membervar->Flags & VARF_Meta) { - return false; + // Meta variables are read only. + *writable = false; } - AddressRequested = true; - if (writable != nullptr) + else if (writable != nullptr) { // [ZZ] original check. bool bWritable = (AddressWritable && !ctx.CheckWritable(membervar->Flags) && @@ -7314,11 +7314,13 @@ ExpEmit FxArrayElement::Emit(VMFunctionBuilder *build) if (SizeAddr != ~0u) { + bool ismeta = Array->ExprType == EFX_ClassMember && static_cast(Array)->membervar->Flags & VARF_Meta; + arrayvar.Free(build); start = ExpEmit(build, REGT_POINTER); 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(Array)->membervar = f; static_cast(Array)->AddressRequested = false; Array->ValueType = TypeUInt32; diff --git a/src/scripting/thingdef_properties.cpp b/src/scripting/thingdef_properties.cpp index 03fe4128a..50994f1e7 100644 --- a/src/scripting/thingdef_properties.cpp +++ b/src/scripting/thingdef_properties.cpp @@ -1090,12 +1090,14 @@ DEFINE_PROPERTY(distancecheck, S, Actor) //========================================================================== DEFINE_CLASS_PROPERTY(restrictedto, Ssssssssssssssssssss, Inventory) { - static_cast(info)->RestrictedToPlayerClass.Clear(); + auto restrictarray = (TArray*)defaults->ScriptVar(NAME_RestrictedToPlayerClass, nullptr); + + restrictarray->Clear(); for(int i = 0;i < PROP_PARM_COUNT;++i) { PROP_STRING_PARM(n, i); if (*n != 0) - static_cast(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) { - static_cast(info)->ForbiddenToPlayerClass.Clear(); + auto forbidarray = (TArray*)defaults->ScriptVar(NAME_ForbiddenToPlayerClass, nullptr); + + forbidarray->Clear(); for(int i = 0;i < PROP_PARM_COUNT;++i) { PROP_STRING_PARM(n, i); if (*n != 0) - static_cast(info)->ForbiddenToPlayerClass.Push(FindClassTentative(n, RUNTIME_CLASS(APlayerPawn))); + forbidarray->Push(FindClassTentative(n, RUNTIME_CLASS(APlayerPawn))); } } diff --git a/wadsrc/static/zscript/inventory/inventory.txt b/wadsrc/static/zscript/inventory/inventory.txt index fe371ebea..43de6b527 100644 --- a/wadsrc/static/zscript/inventory/inventory.txt +++ b/wadsrc/static/zscript/inventory/inventory.txt @@ -25,6 +25,8 @@ class Inventory : Actor native native bool bInitEffectFailed; meta String PickupMsg; meta int GiveQuest; + meta array > ForbiddenToPlayerClass; + meta array > RestrictedToPlayerClass; property PickupMessage: PickupMsg; property GiveQuest: GiveQuest; @@ -46,7 +48,6 @@ class Inventory : Actor native Inventory.PickupMessage "$TXT_DEFAULTPICKUPMSG"; } - native bool CanPickup(Actor toucher); native bool DoRespawn(); native void BecomeItem(); 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