ModifyDamage

From ZDoom Wiki
Jump to navigation Jump to search

Inventory

virtual void ModifyDamage(int damage, Name damageType, out int newdamage, bool passive, Actor inflictor = null, Actor source = null, int flags = 0)

Usage

Allows inventory items to manipulate the damage their owner receives or deals. It is called when the owner of the item is damaged or deals damage to another actor. There are two modes of operations for this function: active and passive:

  • In active the function modifies the damage dealt by the source (the owner of the item) to other actors. The function is not called if damage is zero or less.
  • In passive it modifies the damage received by the owner (with the source being whoever damaged them). It will not be called if damage is zero or less or if the damage is set up to bypass protection powerups.

Note that the function is called before AbsorbDamage, another similar function for damage manipulation.

This function's main usage is with powerups such as PowerProtection and PowerDamage, but could be used with any inventory item.

Parameters

  • int damage
The amount of damage the attack would deal without modification.
  • Name damageType
The damage type applied to the attack. By default regular attacks use 'Normal', hitscan attacks use 'Hitscan'. Otherwise this can be any custom damage type name used in a specific project.
  • out int newdamage
The amount of damage the attack will deal after this function has been called. If nothing is done with this value, damage will be used unmodified. Note, if the idea is to use this function to obtain data without modifying the damage, calling newdamage = damage is redundant; it's enough to simply not do anything with newdamage at all.
  • bool passive
True if the attack is being received by the owner. False if the attack is being dealt by the owner.
  • Actor inflictor
The actor dealing the damage. This is the missile for projectiles and the puff for hitscan attacks. For monster melee attacks this is the same as the source.
  • Actor source
The actor responsible for the inflictor.
  • int flags - The damage flags to use in the attack:
  • DMG_NO_ARMOR - The attack won't call AbsorbDamage on any of the victim's inventory items.
  • DMG_NO_PAIN - The attack will not cause the victim to enter their Pain state sequence.
  • DMG_INFLICTOR_IS_PUFF - Used by ApplyKickback to determine whether the origin should be the source (if the flag is set) or the inflictor. Automatically set by hitscan attacks.
  • DMG_THRUSTLESS - The attack won't call ApplyKickback on the victim.
  • DMG_FORCED - The attack ignores all damage negation flags/properties the victim has, such as NODAMAGE, and doesn't call special damage functions e.g. TakeSpecialDamage. Players with the NODAMAGE flag, god2, or buddha2 cheats are immune due to potential abuse.
  • DMG_NO_FACTOR - The attack won't apply the victim's damage factors.
  • DMG_PLAYERATTACK - Set if the attack came from a hitscan weapon fired by a player.
  • DMG_FOILINVUL - The attack ignores the INVULNERABLE flag if the victim has it set.
  • DMG_FOILBUDDHA - The attack ignores the BUDDHA flag if the victim has it set.
  • DMG_NO_PROTECT - The attack won't call ModifyDamage or AbsorbDamage on any of the victim's inventory items.
  • DMG_NO_ENHANCE - The attack won't call ModifyDamage on any of the source's inventory items.
  • DMG_USEANGLE - The attack will use the angle parameter when applying kickback instead of having ApplyKickback calculate the angle from the origin of the attack.
  • DMG_EXPLOSION - The attack will be marked as splash damage from an explosion. This is set automatically if the damage came from an explosive projectile.
NOTE: While the list of flags is the same as used by DamageMobj, this function, naturally, won't be able to intercept attacks that are specifically set to bypass it, so DMG_NO_ENHANCE in active mode and DMG_NO_PROTECT in passive mode will never be readable.

Examples

An example of active mode: PowerDamage.

override void ModifyDamage (int damage, Name damageType, out int newdamage, bool passive, Actor inflictor, Actor source, int flags)
{
    if (!passive && damage > 0)
    {
        newdamage = max(1, ApplyDamageFactors(GetClass(), damageType, damage, damage * 4));

        if (Owner != null && newdamage > damage)
        {
            Owner.A_StartSound(ActiveSound, CHAN_AUTO, CHANF_DEFAULT, 1.0, ATTN_NONE);
        }
    }
}


An example of passive mode: PowerProtection.

override void ModifyDamage (int damage, Name damageType, out int newdamage, bool passive, Actor inflictor, Actor source, int flags)
{
    if (passive && damage > 0)
    {
        newdamage = max(0, ApplyDamageFactors(GetClass(), damageType, damage, damage / 4));

        if (Owner != null && newdamage < damage)
        {
            Owner.A_StartSound(ActiveSound, CHAN_AUTO, CHANF_DEFAULT, 1.0, ATTN_NONE);
        }
    }
}

See also