diff --git a/src/p_enemy.cpp b/src/p_enemy.cpp index 72e9b6e09..a87e0c812 100644 --- a/src/p_enemy.cpp +++ b/src/p_enemy.cpp @@ -3210,64 +3210,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_ActiveSound) //--------------------------------------------------------------------------- void ModifyDropAmount(AInventory *inv, int dropamount) { - auto flagmask = IF_IGNORESKILL; - double dropammofactor = G_SkillProperty(SKILLP_DropAmmoFactor); - // Default drop amount is half of regular amount * regular ammo multiplication - if (dropammofactor == -1) + IFVIRTUALPTR(inv, AInventory, ModifyDropAmount) { - dropammofactor = 0.5; - flagmask = ItemFlag(0); + VMValue params[] = { inv, dropamount }; + VMCall(func, params, 2, nullptr, 0); } - - if (dropamount > 0) - { - if (flagmask != 0 && inv->IsKindOf(NAME_Ammo)) - { - inv->Amount = int(dropamount * dropammofactor); - inv->ItemFlags |= IF_IGNORESKILL; - } - else - { - inv->Amount = dropamount; - } - } - else if (inv->IsKindOf (PClass::FindActor(NAME_Ammo))) - { - // Half ammo when dropped by bad guys. - int amount = inv->IntVar("DropAmount"); - if (amount <= 0) - { - amount = MAX(1, int(inv->Amount * dropammofactor)); - } - inv->Amount = amount; - inv->ItemFlags |= flagmask; - } - else if (inv->IsKindOf (PClass::FindActor(NAME_WeaponGiver))) - { - inv->FloatVar("AmmoFactor") = dropammofactor; - inv->ItemFlags |= flagmask; - } - else if (inv->IsKindOf(NAME_Weapon)) - { - // The same goes for ammo from a weapon. - static_cast(inv)->AmmoGive1 = int(static_cast(inv)->AmmoGive1 * dropammofactor); - static_cast(inv)->AmmoGive2 = int(static_cast(inv)->AmmoGive2 * dropammofactor); - inv->ItemFlags |= flagmask; - } - else if (inv->IsKindOf (PClass::FindClass(NAME_DehackedPickup))) - { - // For weapons and ammo modified by Dehacked we need to flag the item. - inv->BoolVar("droppedbymonster") = true; - } -} - -// todo: make this a scripted virtual function so it can better deal with some of the classes involved. -DEFINE_ACTION_FUNCTION(AInventory, ModifyDropAmount) -{ - PARAM_SELF_PROLOGUE(AInventory); - PARAM_INT(dropamount); - ModifyDropAmount(self, dropamount); - return 0; } //--------------------------------------------------------------------------- diff --git a/wadsrc/static/zscript/inventory/ammo.txt b/wadsrc/static/zscript/inventory/ammo.txt index 092a93846..b08f39601 100644 --- a/wadsrc/static/zscript/inventory/ammo.txt +++ b/wadsrc/static/zscript/inventory/ammo.txt @@ -184,6 +184,48 @@ class Ammo : Inventory return copy; } + //--------------------------------------------------------------------------- + // + // Modifies the drop amount of this item according to the current skill's + // settings (also called by ADehackedPickup::TryPickup) + // + //--------------------------------------------------------------------------- + + override void ModifyDropAmount(int dropamount) + { + bool ignoreskill = true; + double dropammofactor = G_SkillPropertyFloat(SKILLP_DropAmmoFactor); + // Default drop amount is half of regular amount * regular ammo multiplication + if (dropammofactor == -1) + { + dropammofactor = 0.5; + ignoreskill = false; + } + + if (dropamount > 0) + { + if (ignoreskill) + { + self.Amount = int(dropamount * dropammofactor); + bIgnoreSkill = true; + } + else + { + self.Amount = dropamount; + } + } + else + { + // Half ammo when dropped by bad guys. + int amount = self.DropAmount; + if (amount <= 0) + { + amount = MAX(1, int(self.Amount * dropammofactor)); + } + self.Amount = amount; + bIgnoreSkill = ignoreskill; + } + } } diff --git a/wadsrc/static/zscript/inventory/inventory.txt b/wadsrc/static/zscript/inventory/inventory.txt index d724c90d9..b903a09b6 100644 --- a/wadsrc/static/zscript/inventory/inventory.txt +++ b/wadsrc/static/zscript/inventory/inventory.txt @@ -52,7 +52,6 @@ class Inventory : Actor native native bool DoRespawn(); native void BecomeItem(); native void BecomePickup(); - native void ModifyDropAmount(int dropamount); native static void PrintPickupMessage (bool localview, String str); States(Actor) @@ -917,6 +916,22 @@ class Inventory : Actor native //=========================================================================== virtual void OnDrop (Actor dropper) {} + + //--------------------------------------------------------------------------- + // + // Modifies the drop amount of this item according to the current skill's + // settings (also called by ADehackedPickup::TryPickup) + // + //--------------------------------------------------------------------------- + + virtual void ModifyDropAmount(int dropamount) + { + if (dropamount > 0) + { + Amount = dropamount; + } + } + } //=========================================================================== @@ -1014,6 +1029,14 @@ class DehackedPickup : Inventory } Super.OnDestroy(); } + + override void ModifyDropAmount(int dropamount) + { + // Must forward the adjustment to the real item. + // dropamount is not relevant here because Dehacked cannot change it. + droppedbymonster = true; + } + } //=========================================================================== diff --git a/wadsrc/static/zscript/inventory/weapons.txt b/wadsrc/static/zscript/inventory/weapons.txt index dd63a6159..9f4196de2 100644 --- a/wadsrc/static/zscript/inventory/weapons.txt +++ b/wadsrc/static/zscript/inventory/weapons.txt @@ -842,6 +842,33 @@ class Weapon : StateProvider native } + //--------------------------------------------------------------------------- + // + // Modifies the drop amount of this item according to the current skill's + // settings (also called by ADehackedPickup::TryPickup) + // + //--------------------------------------------------------------------------- + override void ModifyDropAmount(int dropamount) + { + bool ignoreskill = true; + double dropammofactor = G_SkillPropertyFloat(SKILLP_DropAmmoFactor); + // Default drop amount is half of regular amount * regular ammo multiplication + if (dropammofactor == -1) + { + dropammofactor = 0.5; + ignoreskill = false; + } + + if (dropamount > 0) + { + self.Amount = dropamount; + } + // Adjust the ammo given by this weapon + AmmoGive1 = int(AmmoGive1 * dropammofactor); + AmmoGive2 = int(AmmoGive2 * dropammofactor); + bIgnoreSkill = ignoreskill; + } + } class WeaponGiver : Weapon @@ -905,6 +932,29 @@ class WeaponGiver : Weapon return false; } + //--------------------------------------------------------------------------- + // + // Modifies the drop amount of this item according to the current skill's + // settings (also called by ADehackedPickup::TryPickup) + // + //--------------------------------------------------------------------------- + + override void ModifyDropAmount(int dropamount) + { + bool ignoreskill = true; + double dropammofactor = G_SkillPropertyFloat(SKILLP_DropAmmoFactor); + // Default drop amount is half of regular amount * regular ammo multiplication + if (dropammofactor == -1) + { + dropammofactor = 0.5; + ignoreskill = false; + } + + AmmoFactor = dropammofactor; + bIgnoreSkill = ignoreskill; + } + + } struct WeaponSlots native