From cd0d17dbd5c389f778c9339ff826a0d0e33645fb Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 16 Jan 2017 01:16:11 +0100 Subject: [PATCH] - made AbsorbDamage work iteratively to avoid large stack use in the VM. --- src/actor.h | 1 + src/g_inventory/a_armor.cpp | 8 -------- src/g_inventory/a_artifacts.cpp | 4 ---- src/g_inventory/a_pickups.cpp | 4 ---- src/p_interaction.cpp | 4 ++-- src/p_mobj.cpp | 14 ++++++++++++++ 6 files changed, 17 insertions(+), 18 deletions(-) diff --git a/src/actor.h b/src/actor.h index 6b4ce4ae7..09c1b9918 100644 --- a/src/actor.h +++ b/src/actor.h @@ -616,6 +616,7 @@ public: // Adjusts the angle for deflection/reflection of incoming missiles // Returns true if the missile should be allowed to explode anyway bool AdjustReflectionAngle (AActor *thing, DAngle &angle); + int AbsorbDamage(int damage, FName dmgtype); // Returns true if this actor is within melee range of its target bool CheckMeleeRange(); diff --git a/src/g_inventory/a_armor.cpp b/src/g_inventory/a_armor.cpp index ebe8f49f6..e19b50259 100644 --- a/src/g_inventory/a_armor.cpp +++ b/src/g_inventory/a_armor.cpp @@ -235,10 +235,6 @@ void ABasicArmor::AbsorbDamage (int damage, FName damageType, int &newdamage) damage = newdamage = df->Apply(damageType, damage); } } - if (Inventory != NULL) - { - Inventory->AbsorbDamage (damage, damageType, newdamage); - } } //=========================================================================== @@ -629,10 +625,6 @@ void AHexenArmor::AbsorbDamage (int damage, FName damageType, int &newdamage) damage = newdamage; } } - if (Inventory != NULL) - { - Inventory->AbsorbDamage (damage, damageType, newdamage); - } } //=========================================================================== diff --git a/src/g_inventory/a_artifacts.cpp b/src/g_inventory/a_artifacts.cpp index f8e34c9a7..2ab8ca51a 100644 --- a/src/g_inventory/a_artifacts.cpp +++ b/src/g_inventory/a_artifacts.cpp @@ -845,10 +845,6 @@ void APowerIronFeet::AbsorbDamage (int damage, FName damageType, int &newdamage) { newdamage = 0; } - else if (Inventory != NULL) - { - Inventory->AbsorbDamage (damage, damageType, newdamage); - } } //=========================================================================== diff --git a/src/g_inventory/a_pickups.cpp b/src/g_inventory/a_pickups.cpp index 72e51b0c9..c82c146d2 100644 --- a/src/g_inventory/a_pickups.cpp +++ b/src/g_inventory/a_pickups.cpp @@ -697,10 +697,6 @@ DEFINE_ACTION_FUNCTION(AInventory, BecomePickup) void AInventory::AbsorbDamage (int damage, FName damageType, int &newdamage) { - if (Inventory != NULL) - { - Inventory->AbsorbDamage (damage, damageType, newdamage); - } } //=========================================================================== diff --git a/src/p_interaction.cpp b/src/p_interaction.cpp index 97787fd9c..d3dbe0232 100644 --- a/src/p_interaction.cpp +++ b/src/p_interaction.cpp @@ -1305,7 +1305,7 @@ static int DamageMobj (AActor *target, AActor *inflictor, AActor *source, int da int newdam = damage; if (damage > 0) { - player->mo->Inventory->AbsorbDamage(damage, mod, newdam); + newdam = player->mo->AbsorbDamage(damage, mod); } if (!telefragDamage || (player->mo->flags7 & MF7_LAXTELEFRAGDMG)) //rawdamage is never modified. { @@ -1385,7 +1385,7 @@ static int DamageMobj (AActor *target, AActor *inflictor, AActor *source, int da if (!(flags & (DMG_NO_ARMOR|DMG_FORCED)) && target->Inventory != NULL && damage > 0) { int newdam = damage; - target->Inventory->AbsorbDamage (damage, mod, newdam); + newdam = target->AbsorbDamage damage, mod); damage = newdam; if (damage <= 0) { diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index b40b8baa3..4985454ae 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -3615,6 +3615,20 @@ bool AActor::AdjustReflectionAngle (AActor *thing, DAngle &angle) return false; } +int AActor::AbsorbDamage(int damage, FName dmgtype) +{ + for (AInventory *item = Inventory; item != nullptr; item = item->Inventory) + { + IFVIRTUALPTR(item, AInventory, AbsorbDamage) + { + VMValue params[4] = { (item, damage, dmgtype.GetIndex(), &damage }; + GlobalVMStack.Call(func, params, 4, nullptr, 0, nullptr); + } + else item->AbsorbDamage(damage, dmgtype, damage); + } + return damage; +} + void AActor::PlayActiveSound () { if (ActiveSound && !S_IsActorPlayingSomething (this, CHAN_VOICE, -1))