From 2dd6fb95958f506c67053c2a7c26b41af74d9b50 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 18 Jan 2017 20:23:13 +0100 Subject: [PATCH] - scriptified BasicArmorBonus. --- src/d_dehacked.cpp | 5 +- src/d_player.h | 5 - src/g_inventory/a_armor.cpp | 151 +--------------------- src/g_inventory/a_armor.h | 20 --- src/m_cheat.cpp | 2 +- src/namedef.h | 7 + src/p_actionfunctions.cpp | 13 +- src/p_mobj.cpp | 8 +- src/p_user.cpp | 8 +- src/scripting/thingdef_properties.cpp | 59 ++------- src/scripting/zscript/zcc_compile.cpp | 24 ++-- wadsrc/static/zscript/inventory/armor.txt | 141 ++++++++++++++++++-- wadsrc/static/zscript/shared/player.txt | 2 +- 13 files changed, 180 insertions(+), 265 deletions(-) diff --git a/src/d_dehacked.cpp b/src/d_dehacked.cpp index 7bda9b994..abe25a753 100644 --- a/src/d_dehacked.cpp +++ b/src/d_dehacked.cpp @@ -1963,11 +1963,10 @@ static int PatchMisc (int dummy) armor->SavePercent = deh.BlueAC == 1 ? 0.33335 : 0.5; } - ABasicArmorBonus *barmor; - barmor = static_cast (GetDefaultByName ("ArmorBonus")); + auto barmor = GetDefaultByName ("ArmorBonus"); if (barmor!=NULL) { - barmor->MaxSaveAmount = deh.MaxArmor; + barmor->IntVar("MaxSaveAmount") = deh.MaxArmor; } AInventory *health; diff --git a/src/d_player.h b/src/d_player.h index e4db7336f..05facd9fe 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -177,11 +177,6 @@ public: }; -class APlayerChunk : public APlayerPawn -{ - DECLARE_CLASS (APlayerChunk, APlayerPawn) -}; - // // PlayerPawn flags // diff --git a/src/g_inventory/a_armor.cpp b/src/g_inventory/a_armor.cpp index 8bb32c921..5f4b0dbbe 100644 --- a/src/g_inventory/a_armor.cpp +++ b/src/g_inventory/a_armor.cpp @@ -48,7 +48,6 @@ IMPLEMENT_CLASS(AArmor, false, false) IMPLEMENT_CLASS(ABasicArmor, false, false) IMPLEMENT_CLASS(ABasicArmorPickup, false, false) -IMPLEMENT_CLASS(ABasicArmorBonus, false, false) IMPLEMENT_CLASS(AHexenArmor, false, false) //=========================================================================== @@ -133,34 +132,6 @@ AInventory *ABasicArmor::CreateCopy (AActor *other) return copy; } -//=========================================================================== -// -// ABasicArmor :: HandlePickup -// -//=========================================================================== - -bool ABasicArmor::HandlePickup (AInventory *item) -{ - if (item->GetClass() == RUNTIME_CLASS(ABasicArmor)) - { - // You shouldn't be picking up BasicArmor anyway. - return true; - } - if (item->IsKindOf(RUNTIME_CLASS(ABasicArmorBonus)) && !(item->ItemFlags & IF_IGNORESKILL)) - { - ABasicArmorBonus *armor = static_cast(item); - - armor->SaveAmount = int(armor->SaveAmount * G_SkillProperty(SKILLP_ArmorFactor)); - } - else if (item->IsKindOf(RUNTIME_CLASS(ABasicArmorPickup)) && !(item->ItemFlags & IF_IGNORESKILL)) - { - ABasicArmorPickup *armor = static_cast(item); - - armor->SaveAmount = int(armor->SaveAmount * G_SkillProperty(SKILLP_ArmorFactor)); - } - return false; -} - //=========================================================================== // // ABasicArmor :: AbsorbDamage @@ -205,7 +176,7 @@ void ABasicArmor::AbsorbDamage (int damage, FName damageType, int &newdamage) AInventory *probe = Owner->Inventory; while (probe != NULL) { - if (probe->IsKindOf (RUNTIME_CLASS(ABasicArmorPickup))) + if (probe->IsKindOf (PClass::FindActor(NAME_BasicArmorPickup))) { ABasicArmorPickup *inInv = static_cast(probe); if (best == NULL || best->SavePercent < inInv->SavePercent) @@ -339,126 +310,6 @@ bool ABasicArmorPickup::Use (bool pickup) return true; } -//=========================================================================== -// -// -// BasicArmorBonus -// -// -//=========================================================================== - - -DEFINE_FIELD(ABasicArmorBonus, SavePercent) -DEFINE_FIELD(ABasicArmorBonus, MaxSaveAmount) -DEFINE_FIELD(ABasicArmorBonus, MaxAbsorb) -DEFINE_FIELD(ABasicArmorBonus, MaxFullAbsorb) -DEFINE_FIELD(ABasicArmorBonus, SaveAmount) -DEFINE_FIELD(ABasicArmorBonus, BonusCount) -DEFINE_FIELD(ABasicArmorBonus, BonusMax) - -//=========================================================================== -// -// ABasicArmorBonus :: Serialize -// -//=========================================================================== - -void ABasicArmorBonus::Serialize(FSerializer &arc) -{ - Super::Serialize (arc); - auto def = (ABasicArmorBonus *)GetDefault(); - arc("savepercent", SavePercent, def->SavePercent) - ("saveamount", SaveAmount, def->SaveAmount) - ("maxsaveamount", MaxSaveAmount, def->MaxSaveAmount) - ("bonuscount", BonusCount, def->BonusCount) - ("bonusmax", BonusMax, def->BonusMax) - ("maxabsorb", MaxAbsorb, def->MaxAbsorb) - ("maxfullabsorb", MaxFullAbsorb, def->MaxFullAbsorb); -} - -//=========================================================================== -// -// ABasicArmorBonus :: CreateCopy -// -//=========================================================================== - -AInventory *ABasicArmorBonus::CreateCopy (AActor *other) -{ - ABasicArmorBonus *copy = static_cast (Super::CreateCopy (other)); - - if (!(ItemFlags & IF_IGNORESKILL)) - { - SaveAmount = int(SaveAmount * G_SkillProperty(SKILLP_ArmorFactor)); - } - - copy->SavePercent = SavePercent; - copy->SaveAmount = SaveAmount; - copy->MaxSaveAmount = MaxSaveAmount; - copy->BonusCount = BonusCount; - copy->BonusMax = BonusMax; - copy->MaxAbsorb = MaxAbsorb; - copy->MaxFullAbsorb = MaxFullAbsorb; - - return copy; -} - -//=========================================================================== -// -// ABasicArmorBonus :: Use -// -// Tries to add to the amount of BasicArmor a player has. -// -//=========================================================================== - -bool ABasicArmorBonus::Use (bool pickup) -{ - ABasicArmor *armor = Owner->FindInventory (); - bool result = false; - - if (armor == NULL) - { - armor = Spawn (); - armor->BecomeItem (); - armor->Amount = 0; - armor->MaxAmount = MaxSaveAmount; - Owner->AddInventory (armor); - } - - if (BonusCount > 0 && armor->BonusCount < BonusMax) - { - armor->BonusCount = MIN (armor->BonusCount + BonusCount, BonusMax); - result = true; - } - - int saveAmount = MIN (SaveAmount, MaxSaveAmount); - - if (saveAmount <= 0) - { // If it can't give you anything, it's as good as used. - return BonusCount > 0 ? result : true; - } - - // If you already have more armor than this item can give you, you can't - // use it. - if (armor->Amount >= MaxSaveAmount + armor->BonusCount) - { - return result; - } - - if (armor->Amount <= 0) - { // Should never be less than 0, but might as well check anyway - armor->Amount = 0; - armor->Icon = Icon; - armor->SavePercent = SavePercent; - armor->MaxAbsorb = MaxAbsorb; - armor->ArmorType = this->GetClass()->TypeName; - armor->MaxFullAbsorb = MaxFullAbsorb; - armor->ActualSaveAmount = MaxSaveAmount; - } - - armor->Amount = MIN(armor->Amount + saveAmount, MaxSaveAmount + armor->BonusCount); - armor->MaxAmount = MAX (armor->MaxAmount, MaxSaveAmount); - return true; -} - //=========================================================================== // // diff --git a/src/g_inventory/a_armor.h b/src/g_inventory/a_armor.h index 63febda91..7bfb40a0a 100644 --- a/src/g_inventory/a_armor.h +++ b/src/g_inventory/a_armor.h @@ -19,7 +19,6 @@ public: virtual void Serialize(FSerializer &arc) override; virtual void Tick () override; virtual AInventory *CreateCopy (AActor *other) override; - virtual bool HandlePickup (AInventory *item) override; virtual void AbsorbDamage (int damage, FName damageType, int &newdamage) override; int AbsorbCount; @@ -47,25 +46,6 @@ public: int SaveAmount; }; -// BasicArmorBonus adds to the armor you have. -class ABasicArmorBonus : public AArmor -{ - DECLARE_CLASS (ABasicArmorBonus, AArmor) -public: - - virtual void Serialize(FSerializer &arc) override; - virtual AInventory *CreateCopy (AActor *other) override; - virtual bool Use (bool pickup) override; - - double SavePercent; // The default, for when you don't already have armor - int MaxSaveAmount; - int MaxAbsorb; - int MaxFullAbsorb; - int SaveAmount; - int BonusCount; - int BonusMax; -}; - // Hexen armor consists of four separate armor types plus a conceptual armor // type (the player himself) that work together as a single armor. class AHexenArmor : public AArmor diff --git a/src/m_cheat.cpp b/src/m_cheat.cpp index 94e0bde5e..708bccf90 100644 --- a/src/m_cheat.cpp +++ b/src/m_cheat.cpp @@ -318,7 +318,7 @@ void cht_DoCheat (player_t *player, int cheat) case CHT_RESSURECT: if (player->playerstate != PST_LIVE && player->mo != nullptr) { - if (player->mo->IsKindOf(RUNTIME_CLASS(APlayerChunk))) + if (player->mo->IsKindOf(PClass::FindActor("PlayerChunk"))) { Printf("Unable to resurrect. Player is no longer connected to its body.\n"); } diff --git a/src/namedef.h b/src/namedef.h index 255177789..e0ac61bf3 100644 --- a/src/namedef.h +++ b/src/namedef.h @@ -83,6 +83,13 @@ xx(PointPuller) xx(UpperStackLookOnly) xx(LowerStackLookOnly) +xx(BasicArmorBonus) +xx(BasicArmorPickup) +xx(SaveAmount) +xx(SavePercent) +xx(MaxAbsorb) +xx(MaxFullAbsorb) + xx(BulletPuff) xx(StrifePuff) xx(MaulerPuff) diff --git a/src/p_actionfunctions.cpp b/src/p_actionfunctions.cpp index 172e17198..929a5dafd 100644 --- a/src/p_actionfunctions.cpp +++ b/src/p_actionfunctions.cpp @@ -2059,7 +2059,7 @@ DEFINE_ACTION_FUNCTION(AStateProvider, A_CustomPunch) PARAM_FLOAT_DEF (range); PARAM_FLOAT_DEF (lifesteal); PARAM_INT_DEF (lifestealmax); - PARAM_CLASS_DEF (armorbonustype, ABasicArmorBonus); + PARAM_CLASS_DEF (armorbonustype, AActor); PARAM_SOUND_DEF (MeleeSound); PARAM_SOUND_DEF (MissSound); @@ -2107,18 +2107,17 @@ DEFINE_ACTION_FUNCTION(AStateProvider, A_CustomPunch) { if (armorbonustype == NULL) { - armorbonustype = dyn_cast(PClass::FindClass("ArmorBonus")); + armorbonustype = PClass::FindActor("ArmorBonus"); } if (armorbonustype != NULL) { - assert(armorbonustype->IsDescendantOf(RUNTIME_CLASS(ABasicArmorBonus))); - ABasicArmorBonus *armorbonus = static_cast(Spawn(armorbonustype)); - armorbonus->SaveAmount *= int(actualdamage * lifesteal); - armorbonus->MaxSaveAmount = lifestealmax <= 0 ? armorbonus->MaxSaveAmount : lifestealmax; + auto armorbonus = Spawn(armorbonustype); + armorbonus->IntVar(NAME_SaveAmount) *= int(actualdamage * lifesteal); + if (lifestealmax > 0) armorbonus->IntVar("MaxSaveAmount") = lifestealmax; armorbonus->flags |= MF_DROPPED; armorbonus->ClearCounters(); - if (!armorbonus->CallTryPickup(self)) + if (!static_cast(armorbonus)->CallTryPickup(self)) { armorbonus->Destroy (); } diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 78873a322..2a6caaae8 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -790,13 +790,9 @@ bool AActor::GiveInventory(PClassInventory *type, int amount, bool givecheat) item->ClearCounters(); if (!givecheat || amount > 0) { - if (type->IsDescendantOf (RUNTIME_CLASS(ABasicArmorPickup))) + if (type->IsDescendantOf (PClass::FindActor(NAME_BasicArmorPickup)) || type->IsDescendantOf(PClass::FindActor(NAME_BasicArmorBonus))) { - static_cast(item)->SaveAmount *= amount; - } - else if (type->IsDescendantOf (RUNTIME_CLASS(ABasicArmorBonus))) - { - static_cast(item)->SaveAmount *= amount; + item->IntVar(NAME_SaveAmount) *= amount; } else { diff --git a/src/p_user.cpp b/src/p_user.cpp index 906e3180f..967890cf1 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -659,8 +659,6 @@ IMPLEMENT_POINTERS_START(APlayerPawn) IMPLEMENT_POINTER(FlechetteType) IMPLEMENT_POINTERS_END -IMPLEMENT_CLASS(APlayerChunk, false, false) - void APlayerPawn::Serialize(FSerializer &arc) { Super::Serialize (arc); @@ -1700,13 +1698,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_PlayerScream) DEFINE_ACTION_FUNCTION(AActor, A_SkullPop) { PARAM_SELF_PROLOGUE(AActor); - PARAM_CLASS_DEF(spawntype, APlayerChunk); + PARAM_CLASS_DEF(spawntype, APlayerPawn); APlayerPawn *mo; player_t *player; // [GRB] Parameterized version - if (spawntype == NULL || !spawntype->IsDescendantOf(RUNTIME_CLASS(APlayerChunk))) + if (spawntype == NULL || !spawntype->IsDescendantOf(PClass::FindActor("PlayerChunk"))) { spawntype = dyn_cast(PClass::FindClass("BloodySkull")); if (spawntype == NULL) @@ -2203,7 +2201,7 @@ void P_DeathThink (player_t *player) player->TickPSprites(); player->onground = (player->mo->Z() <= player->mo->floorz); - if (player->mo->IsKindOf (RUNTIME_CLASS(APlayerChunk))) + if (player->mo->IsKindOf (PClass::FindActor("PlayerChunk"))) { // Flying bloody skull or flying ice chunk player->viewheight = 6; player->deltaviewheight = 0; diff --git a/src/scripting/thingdef_properties.cpp b/src/scripting/thingdef_properties.cpp index 27165de84..08a394ffe 100644 --- a/src/scripting/thingdef_properties.cpp +++ b/src/scripting/thingdef_properties.cpp @@ -1723,33 +1723,6 @@ DEFINE_CLASS_PROPERTY(forbiddento, Ssssssssssssssssssss, Inventory) } } -//========================================================================== -// -//========================================================================== -DEFINE_CLASS_PROPERTY_PREFIX(armor, maxsaveamount, I, BasicArmorBonus) -{ - PROP_INT_PARM(i, 0); - defaults->MaxSaveAmount = i; -} - -//========================================================================== -// -//========================================================================== -DEFINE_CLASS_PROPERTY_PREFIX(armor, maxbonus, I, BasicArmorBonus) -{ - PROP_INT_PARM(i, 0); - defaults->BonusCount = i; -} - -//========================================================================== -// -//========================================================================== -DEFINE_CLASS_PROPERTY_PREFIX(armor, maxbonusmax, I, BasicArmorBonus) -{ - PROP_INT_PARM(i, 0); - defaults->BonusMax = i; -} - //========================================================================== // //========================================================================== @@ -1758,13 +1731,9 @@ DEFINE_CLASS_PROPERTY(saveamount, I, Armor) PROP_INT_PARM(i, 0); // Special case here because this property has to work for 2 unrelated classes - if (info->IsDescendantOf(RUNTIME_CLASS(ABasicArmorPickup))) + if (info->IsDescendantOf(PClass::FindActor(NAME_BasicArmorPickup)) || info->IsDescendantOf(PClass::FindActor(NAME_BasicArmorBonus))) { - ((ABasicArmorPickup*)defaults)->SaveAmount=i; - } - else if (info->IsDescendantOf(RUNTIME_CLASS(ABasicArmorBonus))) - { - ((ABasicArmorBonus*)defaults)->SaveAmount=i; + defaults->IntVar(NAME_SaveAmount)=i; } else { @@ -1781,13 +1750,9 @@ DEFINE_CLASS_PROPERTY(savepercent, F, Armor) i = clamp(i, 0., 100.)/100.; // Special case here because this property has to work for 2 unrelated classes - if (info->IsDescendantOf(RUNTIME_CLASS(ABasicArmorPickup))) + if (info->IsDescendantOf(PClass::FindActor(NAME_BasicArmorPickup)) || info->IsDescendantOf(PClass::FindActor(NAME_BasicArmorBonus))) { - ((ABasicArmorPickup*)defaults)->SavePercent = i; - } - else if (info->IsDescendantOf(RUNTIME_CLASS(ABasicArmorBonus))) - { - ((ABasicArmorBonus*)defaults)->SavePercent = i; + defaults->FloatVar(NAME_SavePercent) = i; } else { @@ -1803,13 +1768,9 @@ DEFINE_CLASS_PROPERTY(maxabsorb, I, Armor) PROP_INT_PARM(i, 0); // Special case here because this property has to work for 2 unrelated classes - if (info->IsDescendantOf(RUNTIME_CLASS(ABasicArmorPickup))) + if (info->IsDescendantOf(PClass::FindActor(NAME_BasicArmorPickup)) || info->IsDescendantOf(PClass::FindActor(NAME_BasicArmorBonus))) { - ((ABasicArmorPickup*)defaults)->MaxAbsorb = i; - } - else if (info->IsDescendantOf(RUNTIME_CLASS(ABasicArmorBonus))) - { - ((ABasicArmorBonus*)defaults)->MaxAbsorb = i; + defaults->IntVar(NAME_MaxAbsorb) = i; } else { @@ -1825,13 +1786,9 @@ DEFINE_CLASS_PROPERTY(maxfullabsorb, I, Armor) PROP_INT_PARM(i, 0); // Special case here because this property has to work for 2 unrelated classes - if (info->IsDescendantOf(RUNTIME_CLASS(ABasicArmorPickup))) + if (info->IsDescendantOf(PClass::FindActor(NAME_BasicArmorPickup)) || info->IsDescendantOf(PClass::FindActor(NAME_BasicArmorBonus))) { - ((ABasicArmorPickup*)defaults)->MaxFullAbsorb = i; - } - else if (info->IsDescendantOf(RUNTIME_CLASS(ABasicArmorBonus))) - { - ((ABasicArmorBonus*)defaults)->MaxFullAbsorb = i; + defaults->IntVar(NAME_MaxFullAbsorb) = i; } else { diff --git a/src/scripting/zscript/zcc_compile.cpp b/src/scripting/zscript/zcc_compile.cpp index da10c0cfb..f03122edf 100644 --- a/src/scripting/zscript/zcc_compile.cpp +++ b/src/scripting/zscript/zcc_compile.cpp @@ -1380,16 +1380,24 @@ bool ZCCCompiler::CompileProperties(PClass *type, TArray &Proper TArray fields; ZCC_Identifier *id = (ZCC_Identifier *)p->Body; - do + if (FName(p->NodeName) == FName("prefix") && Wads.GetLumpFile(Lump) == 0) { - auto f = dyn_cast(type->Symbols.FindSymbol(id->Id, true)); - if (f == nullptr) + // only for internal definitions: Allow setting a prefix. This is only for compatiblity with the old DECORATE property parser, but not for general use. + prefix = id->Id; + } + else + { + do { - Error(id, "Variable %s not found in %s", FName(id->Id).GetChars(), type->TypeName.GetChars()); - } - fields.Push(f); - id = (ZCC_Identifier*)id->SiblingNext; - } while (id != p->Body); + auto f = dyn_cast(type->Symbols.FindSymbol(id->Id, true)); + if (f == nullptr) + { + Error(id, "Variable %s not found in %s", FName(id->Id).GetChars(), type->TypeName.GetChars()); + } + fields.Push(f); + id = (ZCC_Identifier*)id->SiblingNext; + } while (id != p->Body); + } FString qualifiedname; // Store the full qualified name and prepend some 'garbage' to the name so that no conflicts with other symbol types can happen. diff --git a/wadsrc/static/zscript/inventory/armor.txt b/wadsrc/static/zscript/inventory/armor.txt index 73ad73d1b..16bffa78e 100644 --- a/wadsrc/static/zscript/inventory/armor.txt +++ b/wadsrc/static/zscript/inventory/armor.txt @@ -21,17 +21,55 @@ class BasicArmor : Armor native { +Inventory.KEEPDEPLETED } + + //=========================================================================== + // + // ABasicArmor :: HandlePickup + // + //=========================================================================== + + override bool HandlePickup (Inventory item) + { + if (item.GetClass() == "BasicArmor") + { + // You shouldn't be picking up BasicArmor anyway. + return true; + } + if (!item.bIgnoreSkill) + { + if (item is "BasicArmorBonus") + { + let armor = BasicArmorBonus(item); + armor.SaveAmount = int(armor.SaveAmount * G_SkillPropertyFloat(SKILLP_ArmorFactor)); + } + else if (item is "BasicArmorPickup") + { + let armor = BasicArmorPickup(item); + armor.SaveAmount = int(armor.SaveAmount * G_SkillPropertyFloat(SKILLP_ArmorFactor)); + } + } + return false; + } } -class BasicArmorBonus : Armor native +class BasicArmorBonus : Armor { - native double SavePercent; // The default, for when you don't already have armor - native int MaxSaveAmount; - native int MaxAbsorb; - native int MaxFullAbsorb; - native int SaveAmount; - native int BonusCount; - native int BonusMax; + double SavePercent; // The default, for when you don't already have armor + int MaxSaveAmount; + int MaxAbsorb; + int MaxFullAbsorb; + int SaveAmount; + int BonusCount; + int BonusMax; + + property prefix: Armor; + property MaxSaveAmount: MaxSaveAmount; + property SaveAmount : SaveAmount; + property SavePercent: SavePercent; + property MaxAbsorb: MaxAbsorb; + property MaxFullAbsorb: MaxFullAbsorb; + property MaxBonus: BonusCount; + property MaxBonusMax: BonusMax; Default { @@ -40,6 +78,93 @@ class BasicArmorBonus : Armor native Inventory.MaxAmount 0; Armor.SavePercent 33.335; } + + //=========================================================================== + // + // ABasicArmorBonus :: CreateCopy + // + //=========================================================================== + + override Inventory CreateCopy (Actor other) + { + let copy = BasicArmorBonus(Super.CreateCopy (other)); + + if (!bIgnoreSkill) + { + SaveAmount = int(SaveAmount * G_SkillPropertyFloat(SKILLP_ArmorFactor)); + } + + copy.SavePercent = SavePercent; + copy.SaveAmount = SaveAmount; + copy.MaxSaveAmount = MaxSaveAmount; + copy.BonusCount = BonusCount; + copy.BonusMax = BonusMax; + copy.MaxAbsorb = MaxAbsorb; + copy.MaxFullAbsorb = MaxFullAbsorb; + + return copy; + } + + //=========================================================================== + // + // ABasicArmorBonus :: Use + // + // Tries to add to the amount of BasicArmor a player has. + // + //=========================================================================== + + override bool Use (bool pickup) + { + let armor = BasicArmor(Owner.FindInventory("BasicArmor")); + bool result = false; + + // This should really never happen but let's be prepared for a broken inventory. + if (armor == NULL) + { + armor = BasicArmor(Spawn("BasicArmor")); + armor.BecomeItem (); + armor.Amount = 0; + armor.MaxAmount = MaxSaveAmount; + Owner.AddInventory (armor); + } + + if (BonusCount > 0 && armor.BonusCount < BonusMax) + { + armor.BonusCount = min(armor.BonusCount + BonusCount, BonusMax); + result = true; + } + + int saveAmount = min(SaveAmount, MaxSaveAmount); + + if (saveAmount <= 0) + { // If it can't give you anything, it's as good as used. + return BonusCount > 0 ? result : true; + } + + // If you already have more armor than this item can give you, you can't + // use it. + if (armor.Amount >= MaxSaveAmount + armor.BonusCount) + { + return result; + } + + if (armor.Amount <= 0) + { // Should never be less than 0, but might as well check anyway + armor.Amount = 0; + armor.Icon = Icon; + armor.SavePercent = clamp(SavePercent, 0, 100); + armor.MaxAbsorb = MaxAbsorb; + armor.ArmorType = GetClassName(); + armor.MaxFullAbsorb = MaxFullAbsorb; + armor.ActualSaveAmount = MaxSaveAmount; + } + + armor.Amount = min(armor.Amount + saveAmount, MaxSaveAmount + armor.BonusCount); + armor.MaxAmount = max(armor.MaxAmount, MaxSaveAmount); + return true; + } + + } class BasicArmorPickup : Armor native diff --git a/wadsrc/static/zscript/shared/player.txt b/wadsrc/static/zscript/shared/player.txt index c3f3c6768..25261c53e 100644 --- a/wadsrc/static/zscript/shared/player.txt +++ b/wadsrc/static/zscript/shared/player.txt @@ -138,7 +138,7 @@ class PlayerPawn : Actor native native void CheckWeaponSwitch(class item); } -class PlayerChunk : PlayerPawn native +class PlayerChunk : PlayerPawn { Default {