- made AbsorbDamage work iteratively to avoid large stack use in the VM.

This commit is contained in:
Christoph Oelckers 2017-01-16 01:16:11 +01:00
parent ae7b95fc52
commit cd0d17dbd5
6 changed files with 17 additions and 18 deletions

View file

@ -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();

View file

@ -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);
}
}
//===========================================================================

View file

@ -845,10 +845,6 @@ void APowerIronFeet::AbsorbDamage (int damage, FName damageType, int &newdamage)
{
newdamage = 0;
}
else if (Inventory != NULL)
{
Inventory->AbsorbDamage (damage, damageType, newdamage);
}
}
//===========================================================================

View file

@ -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);
}
}
//===========================================================================

View file

@ -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)
{

View file

@ -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))