by FDARI » Wed Mar 23, 2011 6:10 pm
What is the correct behaviour for damage factor? I'd expect it to treat the resultant amount of damage (may be 0) exactly as it would an equal amount of unmodified damage.
In P_DamageMobj the following seem effectively to have precedence over +FORCEPAIN:
- Health at 0 or lower: Dead, rightly feel no pain. Returns from the function before pain processing.*
*Death after damage also avoids painhandling.
- Spectral (when damage does not apply to spectral being): Returns.
- Invulnerability (when not foiled by damage flags or inflicting actor +FOILINVUL): Returns. *
* Is this behaviour different for players? Damage processings seems to continue normally unless the player has PPF_NOTHRUSTWHENINVUL.
*Player invulnerability turns out to be fully handled later in code, but the inflictor flag MF3_FOILINVUL seems ineffective against players.
- Actor is dormant (and damage is not forced): Returns.
- Some more spectral complexity that I don't think is relevant. (Altought if DoSpecialDamage returns -1 pain processing will be omitted.)
- If PowerDamage or PowerProtection cause damage to change to 0, the function returns.
- DamageFactor appears to be very special:
- First, any type specific damage factor is applied. If it reduces damage to 0 or less, the function returns.
- Then, a general damage factor (probably 1 by default) is applied. If it reduces damage to 0 or less, the function returns.
- Any non-forced damage will now go through TakeSpecialDamage. A result of -1 causes immediate return.
- If damage is reduced to 0 or less by team-damage factor, the function returns.
- If monster damage is reduced to 0 or less by armour, the function returns.
- If wound-state is executed, pain-state is not.
There is one explicit check of forcepain: When armour reduces damage sustained by a player, to 0 or less. If forcepain is checked, a jump to the label "dopain" is executed. The dopain label is found after checks for NOPAIN and PAINLESS flags, so if pain is not supposed to be inflicted, 0 damage will cause pain anyway.
I think the "dopain" label is an attempt at the quick fix I had in mind, but perhaps not the ideal one. In any of the above scenarios where pain should be a possibility, "return" could be replaced with "goto checkpain", which would be a label immediately before the full pain-handling code. (Starting by checking the +NOPAIN and +PAINLESS flags, which are ignored when jumping with "goto Dopain".)
What is the correct behaviour for damage factor? I'd expect it to treat the resultant amount of damage (may be 0) exactly as it would an equal amount of unmodified damage.
In P_DamageMobj the following seem effectively to have precedence over +FORCEPAIN:
[list][*]Health at 0 or lower: Dead, rightly feel no pain. Returns from the function before pain processing.*
*Death after damage also avoids painhandling.
[*]Spectral (when damage does not apply to spectral being): Returns.
[*]Invulnerability (when not foiled by damage flags or inflicting actor +FOILINVUL): Returns. *
[i]* Is this behaviour different for players? Damage processings seems to continue normally unless the player has PPF_NOTHRUSTWHENINVUL.
*Player invulnerability turns out to be fully handled later in code, but the inflictor flag MF3_FOILINVUL seems ineffective against players.[/i]
[*]Actor is dormant (and damage is not forced): Returns.
[*]Some more spectral complexity that I don't think is relevant. (Altought if DoSpecialDamage returns -1 pain processing will be omitted.)
[*]If PowerDamage or PowerProtection cause damage to [i]change[/i] to 0, the function returns.
[*]DamageFactor appears to be very special:
- First, any type specific damage factor is applied. If it reduces damage to 0 or less, the function returns.
- Then, a general damage factor (probably 1 by default) is applied. If it reduces damage to 0 or less, the function returns.
[*]Any non-forced damage will now go through TakeSpecialDamage. A result of -1 causes immediate return.
[*]If damage is reduced to 0 or less by team-damage factor, the function returns.
[*]If monster damage is reduced to 0 or less by armour, the function returns.
[*]If wound-state is executed, pain-state is not.[/list]
There is one explicit check of forcepain: When armour reduces damage sustained by a player, to 0 or less. If forcepain is checked, a jump to the label "dopain" is executed. The dopain label is found after checks for NOPAIN and PAINLESS flags, so if pain is not supposed to be inflicted, 0 damage will cause pain anyway.
I think the "dopain" label is an attempt at the quick fix I had in mind, but perhaps not the ideal one. In any of the above scenarios where pain should be a possibility, "return" could be replaced with "goto checkpain", which would be a label immediately before the full pain-handling code. (Starting by checking the +NOPAIN and +PAINLESS flags, which are ignored when jumping with "goto Dopain".)