From 549712e719d843a9ca7c2f20360efe3f2674201b Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Wed, 2 Jan 2013 04:39:59 +0000 Subject: [PATCH] - P_DamageMobj() now returns the amount of damage actually done so that the bleed functions can perform based on the amount of damage actually taken after all modifications are done to it. However, if the damage is canceled away, blood will still spawn for the original damage amount rather than the modified amount. SVN r4012 (trunk) --- src/g_doom/a_archvile.cpp | 4 +- src/g_doom/a_bruiser.cpp | 4 +- src/g_doom/a_cacodemon.cpp | 4 +- src/g_doom/a_demon.cpp | 4 +- src/g_doom/a_doomimp.cpp | 4 +- src/g_doom/a_doomweaps.cpp | 4 +- src/g_doom/a_revenant.cpp | 4 +- src/g_heretic/a_chicken.cpp | 4 +- src/g_heretic/a_dsparil.cpp | 8 +-- src/g_heretic/a_ironlich.cpp | 4 +- src/g_heretic/a_knight.cpp | 4 +- src/g_heretic/a_wizard.cpp | 4 +- src/g_hexen/a_bishop.cpp | 4 +- src/g_hexen/a_dragon.cpp | 8 +-- src/g_hexen/a_serpent.cpp | 4 +- src/g_hexen/a_spike.cpp | 4 +- src/g_raven/a_minotaur.cpp | 16 ++--- src/g_shared/a_artifacts.cpp | 2 +- src/g_strife/a_programmer.cpp | 4 +- src/g_strife/a_stalker.cpp | 4 +- src/p_interaction.cpp | 56 ++++++++-------- src/p_local.h | 2 +- src/p_map.cpp | 102 ++++++++++++++++-------------- src/p_mobj.cpp | 4 +- src/po_man.cpp | 4 +- src/thingdef/thingdef_codeptr.cpp | 18 +++--- 26 files changed, 148 insertions(+), 136 deletions(-) diff --git a/src/g_doom/a_archvile.cpp b/src/g_doom/a_archvile.cpp index 2bd65b7a09..e2fb689c2a 100644 --- a/src/g_doom/a_archvile.cpp +++ b/src/g_doom/a_archvile.cpp @@ -123,8 +123,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_VileAttack) return; S_Sound (self, CHAN_WEAPON, snd, 1, ATTN_NORM); - P_TraceBleed (dmg, target); - P_DamageMobj (target, self, self, dmg, NAME_None); + int newdam = P_DamageMobj (target, self, self, dmg, NAME_None); + P_TraceBleed (newdam > 0 ? newdam : dmg, target); an = self->angle >> ANGLETOFINESHIFT; fire = self->tracer; diff --git a/src/g_doom/a_bruiser.cpp b/src/g_doom/a_bruiser.cpp index 24c6c48eb1..ba1d92bc15 100644 --- a/src/g_doom/a_bruiser.cpp +++ b/src/g_doom/a_bruiser.cpp @@ -10,8 +10,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_BruisAttack) { int damage = (pr_bruisattack()%8+1)*10; S_Sound (self, CHAN_WEAPON, "baron/melee", 1, ATTN_NORM); - P_DamageMobj (self->target, self, self, damage, NAME_Melee); - P_TraceBleed (damage, self->target, self); + int newdam = P_DamageMobj (self->target, self, self, damage, NAME_Melee); + P_TraceBleed (newdam > 0 ? newdam : damage, self->target, self); return; } diff --git a/src/g_doom/a_cacodemon.cpp b/src/g_doom/a_cacodemon.cpp index 0eb9238906..856360a13c 100644 --- a/src/g_doom/a_cacodemon.cpp +++ b/src/g_doom/a_cacodemon.cpp @@ -22,8 +22,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_HeadAttack) { int damage = (pr_headattack()%6+1)*10; S_Sound (self, CHAN_WEAPON, self->AttackSound, 1, ATTN_NORM); - P_DamageMobj (self->target, self, self, damage, NAME_Melee); - P_TraceBleed (damage, self->target, self); + int newdam = P_DamageMobj (self->target, self, self, damage, NAME_Melee); + P_TraceBleed (newdam > 0 ? newdam : damage, self->target, self); return; } diff --git a/src/g_doom/a_demon.cpp b/src/g_doom/a_demon.cpp index c890c32b04..f4a9f461f2 100644 --- a/src/g_doom/a_demon.cpp +++ b/src/g_doom/a_demon.cpp @@ -20,7 +20,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SargAttack) if (self->CheckMeleeRange ()) { int damage = ((pr_sargattack()%10)+1)*4; - P_DamageMobj (self->target, self, self, damage, NAME_Melee); - P_TraceBleed (damage, self->target, self); + int newdam = P_DamageMobj (self->target, self, self, damage, NAME_Melee); + P_TraceBleed (newdam > 0 ? newdam : damage, self->target, self); } } diff --git a/src/g_doom/a_doomimp.cpp b/src/g_doom/a_doomimp.cpp index 401fa4577f..4c607f6e1d 100644 --- a/src/g_doom/a_doomimp.cpp +++ b/src/g_doom/a_doomimp.cpp @@ -25,8 +25,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_TroopAttack) { int damage = (pr_troopattack()%8+1)*3; S_Sound (self, CHAN_WEAPON, "imp/melee", 1, ATTN_NORM); - P_DamageMobj (self->target, self, self, damage, NAME_Melee); - P_TraceBleed (damage, self->target, self); + int newdam = P_DamageMobj (self->target, self, self, damage, NAME_Melee); + P_TraceBleed (newdam > 0 ? newdam : damage, self->target, self); return; } diff --git a/src/g_doom/a_doomweaps.cpp b/src/g_doom/a_doomweaps.cpp index 8cb3739f6b..642c319ec7 100644 --- a/src/g_doom/a_doomweaps.cpp +++ b/src/g_doom/a_doomweaps.cpp @@ -584,8 +584,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BFGSpray) damage += (pr_bfgspray() & 7) + 1; thingToHit = linetarget; - P_DamageMobj (thingToHit, self->target, self->target, damage, spray != NULL? FName(spray->DamageType) : FName(NAME_BFGSplash)); - P_TraceBleed (damage, thingToHit, self->target); + int newdam = P_DamageMobj (thingToHit, self->target, self->target, damage, spray != NULL? FName(spray->DamageType) : FName(NAME_BFGSplash)); + P_TraceBleed (newdam > 0 ? newdam : damage, thingToHit, self->target); } } diff --git a/src/g_doom/a_revenant.cpp b/src/g_doom/a_revenant.cpp index 92a3dc13f7..0600a59eb2 100644 --- a/src/g_doom/a_revenant.cpp +++ b/src/g_doom/a_revenant.cpp @@ -146,7 +146,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SkelFist) { int damage = ((pr_skelfist()%10)+1)*6; S_Sound (self, CHAN_WEAPON, "skeleton/melee", 1, ATTN_NORM); - P_DamageMobj (self->target, self, self, damage, NAME_Melee); - P_TraceBleed (damage, self->target, self); + int newdam = P_DamageMobj (self->target, self, self, damage, NAME_Melee); + P_TraceBleed (newdam > 0 ? newdam : damage, self->target, self); } } diff --git a/src/g_heretic/a_chicken.cpp b/src/g_heretic/a_chicken.cpp index a8b8c98d33..082774a3de 100644 --- a/src/g_heretic/a_chicken.cpp +++ b/src/g_heretic/a_chicken.cpp @@ -73,8 +73,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_ChicAttack) if (self->CheckMeleeRange()) { int damage = 1 + (pr_chicattack() & 1); - P_DamageMobj (self->target, self, self, damage, NAME_Melee); - P_TraceBleed (damage, self->target, self); + int newdam = P_DamageMobj (self->target, self, self, damage, NAME_Melee); + P_TraceBleed (newdam > 0 ? newdam : damage, self->target, self); } } diff --git a/src/g_heretic/a_dsparil.cpp b/src/g_heretic/a_dsparil.cpp index 080deb8d7e..e4d86c83af 100644 --- a/src/g_heretic/a_dsparil.cpp +++ b/src/g_heretic/a_dsparil.cpp @@ -70,8 +70,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_Srcr1Attack) if (self->CheckMeleeRange ()) { int damage = pr_scrc1atk.HitDice (8); - P_DamageMobj (self->target, self, self, damage, NAME_Melee); - P_TraceBleed (damage, self->target, self); + int newdam = P_DamageMobj (self->target, self, self, damage, NAME_Melee); + P_TraceBleed (newdam > 0 ? newdam : damage, self->target, self); return; } @@ -203,8 +203,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_Srcr2Attack) if (self->CheckMeleeRange()) { int damage = pr_s2a.HitDice (20); - P_DamageMobj (self->target, self, self, damage, NAME_Melee); - P_TraceBleed (damage, self->target, self); + int newdam = P_DamageMobj (self->target, self, self, damage, NAME_Melee); + P_TraceBleed (newdam > 0 ? newdam : damage, self->target, self); return; } chance = self->health < self->SpawnHealth()/2 ? 96 : 48; diff --git a/src/g_heretic/a_ironlich.cpp b/src/g_heretic/a_ironlich.cpp index 8efa08273f..8efaa8d82d 100644 --- a/src/g_heretic/a_ironlich.cpp +++ b/src/g_heretic/a_ironlich.cpp @@ -83,8 +83,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_LichAttack) if (self->CheckMeleeRange ()) { int damage = pr_atk.HitDice (6); - P_DamageMobj (target, self, self, damage, NAME_Melee); - P_TraceBleed (damage, target, self); + int newdam = P_DamageMobj (target, self, self, damage, NAME_Melee); + P_TraceBleed (newdam > 0 ? newdam : damage, target, self); return; } dist = P_AproxDistance (self->x-target->x, self->y-target->y) diff --git a/src/g_heretic/a_knight.cpp b/src/g_heretic/a_knight.cpp index 2fb8a0ef4b..18280326a4 100644 --- a/src/g_heretic/a_knight.cpp +++ b/src/g_heretic/a_knight.cpp @@ -47,8 +47,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_KnightAttack) if (self->CheckMeleeRange ()) { int damage = pr_knightatk.HitDice (3); - P_DamageMobj (self->target, self, self, damage, NAME_Melee); - P_TraceBleed (damage, self->target, self); + int newdam = P_DamageMobj (self->target, self, self, damage, NAME_Melee); + P_TraceBleed (newdam > 0 ? newdam : damage, self->target, self); S_Sound (self, CHAN_BODY, "hknight/melee", 1, ATTN_NORM); return; } diff --git a/src/g_heretic/a_wizard.cpp b/src/g_heretic/a_wizard.cpp index 119a1b1efe..ea5e6559b7 100644 --- a/src/g_heretic/a_wizard.cpp +++ b/src/g_heretic/a_wizard.cpp @@ -69,8 +69,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_WizAtk3) if (self->CheckMeleeRange()) { int damage = pr_wizatk3.HitDice (4); - P_DamageMobj (self->target, self, self, damage, NAME_Melee); - P_TraceBleed (damage, self->target, self); + int newdam = P_DamageMobj (self->target, self, self, damage, NAME_Melee); + P_TraceBleed (newdam > 0 ? newdam : damage, self->target, self); return; } const PClass *fx = PClass::FindClass("WizardFX1"); diff --git a/src/g_hexen/a_bishop.cpp b/src/g_hexen/a_bishop.cpp index f80b91cbd2..08faee955d 100644 --- a/src/g_hexen/a_bishop.cpp +++ b/src/g_hexen/a_bishop.cpp @@ -32,8 +32,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_BishopAttack) if (self->CheckMeleeRange()) { int damage = pr_atk.HitDice (4); - P_DamageMobj (self->target, self, self, damage, NAME_Melee); - P_TraceBleed (damage, self->target, self); + int newdam = P_DamageMobj (self->target, self, self, damage, NAME_Melee); + P_TraceBleed (newdam > 0 ? newdam : damage, self->target, self); return; } self->special1 = (pr_atk() & 3) + 5; diff --git a/src/g_hexen/a_dragon.cpp b/src/g_hexen/a_dragon.cpp index 0c5ea81b51..22c92b4d72 100644 --- a/src/g_hexen/a_dragon.cpp +++ b/src/g_hexen/a_dragon.cpp @@ -87,8 +87,8 @@ static void DragonSeek (AActor *actor, angle_t thresh, angle_t turnMax) if (actor->CheckMeleeRange ()) { int damage = pr_dragonseek.HitDice (10); - P_DamageMobj (actor->target, actor, actor, damage, NAME_Melee); - P_TraceBleed (damage, actor->target, actor); + int newdam = P_DamageMobj (actor->target, actor, actor, damage, NAME_Melee); + P_TraceBleed (newdam > 0 ? newdam : damage, actor->target, actor); S_Sound (actor, CHAN_WEAPON, actor->AttackSound, 1, ATTN_NORM); } else if (pr_dragonseek() < 128 && P_CheckMissileRange(actor)) @@ -201,8 +201,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_DragonFlight) if (abs(self->angle-angle) < ANGLE_45/2 && self->CheckMeleeRange()) { int damage = pr_dragonflight.HitDice (8); - P_DamageMobj (self->target, self, self, damage, NAME_Melee); - P_TraceBleed (damage, self->target, self); + int newdam = P_DamageMobj (self->target, self, self, damage, NAME_Melee); + P_TraceBleed (newdam > 0 ? newdam : damage, self->target, self); S_Sound (self, CHAN_WEAPON, self->AttackSound, 1, ATTN_NORM); } else if (abs(self->angle-angle) <= ANGLE_1*20) diff --git a/src/g_hexen/a_serpent.cpp b/src/g_hexen/a_serpent.cpp index b44a6175dd..cf552897fe 100644 --- a/src/g_hexen/a_serpent.cpp +++ b/src/g_hexen/a_serpent.cpp @@ -174,8 +174,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_SerpentMeleeAttack) if (self->CheckMeleeRange ()) { int damage = pr_serpentmeattack.HitDice (5); - P_DamageMobj (self->target, self, self, damage, NAME_Melee); - P_TraceBleed (damage, self->target, self); + int newdam = P_DamageMobj (self->target, self, self, damage, NAME_Melee); + P_TraceBleed (newdam > 0 ? newdam : damage, self->target, self); S_Sound (self, CHAN_BODY, "SerpentMeleeHit", 1, ATTN_NORM); } if (pr_serpentmeattack() < 96) diff --git a/src/g_hexen/a_spike.cpp b/src/g_hexen/a_spike.cpp index f7269c40cb..9c9f9ab204 100644 --- a/src/g_hexen/a_spike.cpp +++ b/src/g_hexen/a_spike.cpp @@ -154,8 +154,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_ThrustImpale) if (thing == self) continue; // don't clip against self - P_DamageMobj (thing, self, self, 10001, NAME_Crush); - P_TraceBleed (10001, thing); + int newdam = P_DamageMobj (thing, self, self, 10001, NAME_Crush); + P_TraceBleed (newdam > 0 ? newdam : 10001, thing); self->args[1] = 1; // Mark thrust thing as bloody } } diff --git a/src/g_raven/a_minotaur.cpp b/src/g_raven/a_minotaur.cpp index 36a5537bc9..949e38d01c 100644 --- a/src/g_raven/a_minotaur.cpp +++ b/src/g_raven/a_minotaur.cpp @@ -149,8 +149,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_MinotaurAtk1) if (self->CheckMeleeRange()) { int damage = pr_minotauratk1.HitDice (4); - P_DamageMobj (self->target, self, self, damage, NAME_Melee); - P_TraceBleed (damage, self->target, self); + int newdam = P_DamageMobj (self->target, self, self, damage, NAME_Melee); + P_TraceBleed (newdam > 0 ? newdam : damage, self->target, self); if ((player = self->target->player) != NULL && player->mo == self->target) { // Squish the player @@ -281,8 +281,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_MinotaurAtk2) { int damage; damage = pr_atk.HitDice (friendly ? 3 : 5); - P_DamageMobj (self->target, self, self, damage, NAME_Melee); - P_TraceBleed (damage, self->target, self); + int newdam = P_DamageMobj (self->target, self, self, damage, NAME_Melee); + P_TraceBleed (newdam > 0 ? newdam : damage, self->target, self); return; } z = self->z + 40*FRACUNIT; @@ -327,8 +327,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_MinotaurAtk3) int damage; damage = pr_minotauratk3.HitDice (friendly ? 3 : 5); - P_DamageMobj (self->target, self, self, damage, NAME_Melee); - P_TraceBleed (damage, self->target, self); + int newdam = P_DamageMobj (self->target, self, self, damage, NAME_Melee); + P_TraceBleed (newdam > 0 ? newdam : damage, self->target, self); if ((player = self->target->player) != NULL && player->mo == self->target) { // Squish the player @@ -396,8 +396,8 @@ void P_MinotaurSlam (AActor *source, AActor *target) target->velx += FixedMul (thrust, finecosine[angle]); target->vely += FixedMul (thrust, finesine[angle]); damage = pr_minotaurslam.HitDice (static_cast(source) ? 4 : 6); - P_DamageMobj (target, NULL, NULL, damage, NAME_Melee); - P_TraceBleed (damage, target, angle, 0); + int newdam = P_DamageMobj (target, NULL, NULL, damage, NAME_Melee); + P_TraceBleed (newdam > 0 ? newdam : damage, target, angle, 0); if (target->player) { target->reactiontime = 14+(pr_minotaurslam()&7); diff --git a/src/g_shared/a_artifacts.cpp b/src/g_shared/a_artifacts.cpp index 114c4832d3..4f44cfc209 100644 --- a/src/g_shared/a_artifacts.cpp +++ b/src/g_shared/a_artifacts.cpp @@ -1503,7 +1503,7 @@ void APowerDamage::EndEffect( ) //=========================================================================== // -// APowerDamage :: AbsorbDamage +// APowerDamage :: ModifyDamage // //=========================================================================== diff --git a/src/g_strife/a_programmer.cpp b/src/g_strife/a_programmer.cpp index 0f843c55c1..78689468b7 100644 --- a/src/g_strife/a_programmer.cpp +++ b/src/g_strife/a_programmer.cpp @@ -87,8 +87,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_ProgrammerMelee) S_Sound (self, CHAN_WEAPON, "programmer/clank", 1, ATTN_NORM); damage = ((pr_prog() % 10) + 1) * 6; - P_DamageMobj (self->target, self, self, damage, NAME_Melee); - P_TraceBleed (damage, self->target, self); + int newdam = P_DamageMobj (self->target, self, self, damage, NAME_Melee); + P_TraceBleed (newdam > 0 ? newdam : damage, self->target, self); } //============================================================================ diff --git a/src/g_strife/a_stalker.cpp b/src/g_strife/a_stalker.cpp index 67cbd3282d..258cbef3f7 100644 --- a/src/g_strife/a_stalker.cpp +++ b/src/g_strife/a_stalker.cpp @@ -59,8 +59,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_StalkerAttack) { int damage = (pr_stalker() & 7) * 2 + 2; - P_DamageMobj (self->target, self, self, damage, NAME_Melee); - P_TraceBleed (damage, self->target, self); + int newdam = P_DamageMobj (self->target, self, self, damage, NAME_Melee); + P_TraceBleed (newdam > 0 ? newdam : damage, self->target, self); } } } diff --git a/src/p_interaction.cpp b/src/p_interaction.cpp index 3ad2770e93..b98c1d3cf5 100644 --- a/src/p_interaction.cpp +++ b/src/p_interaction.cpp @@ -888,7 +888,9 @@ static inline bool MustForcePain(AActor *target, AActor *inflictor) } -void P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage, FName mod, int flags) +// Returns the amount of damage actually inflicted upon the target, or -1 if +// the damage was cancelled. +int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage, FName mod, int flags) { unsigned ang; player_t *player = NULL; @@ -901,7 +903,7 @@ void P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage if (target == NULL || !((target->flags & MF_SHOOTABLE) || (target->flags6 & MF6_VULNERABLE))) { // Shouldn't happen - return; + return -1; } // Spectral targets only take damage from spectral projectiles. @@ -909,14 +911,14 @@ void P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage { if (inflictor == NULL || !(inflictor->flags4 & MF4_SPECTRAL)) { - return; + return -1; } } if (target->health <= 0) { if (inflictor && mod == NAME_Ice) { - return; + return -1; } else if (target->flags & MF_ICECORPSE) // frozen { @@ -924,7 +926,7 @@ void P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage target->flags6 |= MF6_SHATTERING; target->velx = target->vely = target->velz = 0; } - return; + return -1; } if ((target->flags2 & MF2_INVULNERABLE) && damage < TELEFRAG_DAMAGE && !(flags & DMG_FORCED)) { // actor is invulnerable @@ -932,7 +934,7 @@ void P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage { if (inflictor == NULL || !(inflictor->flags3 & MF3_FOILINVUL)) { - return; + return -1; } } else @@ -940,7 +942,7 @@ void P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage // Players are optionally excluded from getting thrust by damage. if (static_cast(target)->PlayerFlags & PPF_NOTHRUSTWHENINVUL) { - return; + return -1; } } @@ -968,7 +970,7 @@ void P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage if (target->flags2 & MF2_DORMANT) { // Invulnerable, and won't wake up - return; + return -1; } player = target->player; if (player && damage > 1 && damage < TELEFRAG_DAMAGE) @@ -984,19 +986,19 @@ void P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage if (player != NULL) { if (!deathmatch && inflictor->FriendPlayer > 0) - return; + return -1; } else if (target->flags4 & MF4_SPECTRAL) { if (inflictor->FriendPlayer == 0 && !target->IsHostile(inflictor)) - return; + return -1; } } damage = inflictor->DoSpecialDamage (target, damage, mod); if (damage == -1) { - return; + return -1; } } // Handle active damage modifiers (e.g. PowerDamage) @@ -1010,7 +1012,7 @@ void P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage { goto dopain; } - return; + return -1; } } // Handle passive damage modifiers (e.g. PowerProtection) @@ -1024,7 +1026,7 @@ void P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage { goto dopain; } - return; + return -1; } } @@ -1041,7 +1043,7 @@ void P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage { goto dopain; } - return; + return -1; } } @@ -1049,7 +1051,7 @@ void P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage } if (damage == -1) { - return; + return -1; } // Push the target unless the source's weapon's kickback is 0. // (i.e. Gauntlets/Chainsaw) @@ -1133,7 +1135,7 @@ void P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage { // Still allow telefragging :-( damage = (int)((float)damage * level.teamdamage); if (damage <= 0) - return; + return damage; } } @@ -1162,7 +1164,7 @@ void P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage if (damage < TELEFRAG_DAMAGE && ((player->mo->flags2 & MF2_INVULNERABLE) || (player->cheats & CF_GODMODE))) { // player is invulnerable, so don't hurt him - return; + return -1; } if (!(flags & DMG_NO_ARMOR) && player->mo->Inventory != NULL) @@ -1173,12 +1175,12 @@ void P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage if (damage <= 0) { // If MF6_FORCEPAIN is set, make the player enter the pain state. - if (!(target->flags5 & MF5_NOPAIN) && inflictor != NULL && - (inflictor->flags6 & MF6_FORCEPAIN) && !(inflictor->flags5 & MF5_PAINLESS)) - { - goto dopain; - } - return; + if (!(target->flags5 & MF5_NOPAIN) && inflictor != NULL && + (inflictor->flags6 & MF6_FORCEPAIN) && !(inflictor->flags5 & MF5_PAINLESS)) + { + goto dopain; + } + return damage; } } @@ -1237,7 +1239,7 @@ void P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage damage = newdam; if (damage <= 0) { - return; + return damage; } } @@ -1296,7 +1298,7 @@ void P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage } } target->Die (source, inflictor, flags); - return; + return damage; } woundstate = target->FindState(NAME_Wound, mod); @@ -1307,7 +1309,7 @@ void P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage if (target->health <= woundhealth) { target->SetState (woundstate); - return; + return damage; } } @@ -1401,6 +1403,8 @@ dopain: // killough 11/98: Don't attack a friend, unless hit by that friend. if (justhit && (target->target == source || !target->target || !target->IsFriend(target->target))) target->flags |= MF_JUSTHIT; // fight back! + + return damage; } void P_PoisonMobj (AActor *target, AActor *inflictor, AActor *source, int damage, int duration, int period, FName type) diff --git a/src/p_local.h b/src/p_local.h index a045f897bd..eb66907264 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -530,7 +530,7 @@ extern FBlockNode** blocklinks; // for thing chains // P_INTER // void P_TouchSpecialThing (AActor *special, AActor *toucher); -void P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage, FName mod, int flags=0); +int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage, FName mod, int flags=0); void P_PoisonMobj (AActor *target, AActor *inflictor, AActor *source, int damage, int duration, int period, FName type); bool P_GiveBody (AActor *actor, int num, int max=0); bool P_PoisonPlayer (player_t *player, AActor *poisoner, AActor *source, int poison); diff --git a/src/p_map.cpp b/src/p_map.cpp index 830c7b9d81..289f146bb5 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -966,12 +966,13 @@ bool PIT_CheckThing (AActor *thing, FCheckPosition &tm) thing->vely += tm.thing->vely; if ((thing->velx + thing->vely) > 3*FRACUNIT) { + int newdam; damage = (tm.thing->Mass / 100) + 1; - P_DamageMobj (thing, tm.thing, tm.thing, damage, tm.thing->DamageType); - P_TraceBleed (damage, thing, tm.thing); + newdam = P_DamageMobj (thing, tm.thing, tm.thing, damage, tm.thing->DamageType); + P_TraceBleed (newdam > 0 ? newdam : damage, thing, tm.thing); damage = (thing->Mass / 100) + 1; - P_DamageMobj (tm.thing, thing, thing, damage >> 2, tm.thing->DamageType); - P_TraceBleed (damage, tm.thing, thing); + newdam = P_DamageMobj (tm.thing, thing, thing, damage >> 2, tm.thing->DamageType); + P_TraceBleed (newdam > 0 ? newdam : damage, tm.thing, thing); } return false; } @@ -1149,10 +1150,10 @@ bool PIT_CheckThing (AActor *thing, FCheckPosition &tm) } damage = tm.thing->GetMissileDamage (3, 2); - P_DamageMobj (thing, tm.thing, tm.thing->target, damage, tm.thing->DamageType); + int newdam = P_DamageMobj (thing, tm.thing, tm.thing->target, damage, tm.thing->DamageType); if (!(tm.thing->flags3 & MF3_BLOODLESSIMPACT)) { - P_TraceBleed (damage, thing, tm.thing); + P_TraceBleed (newdam > 0 ? newdam : damage, thing, tm.thing); } if (thing->flags2 & MF2_PUSHABLE && !(tm.thing->flags2 & MF2_CANNOTPUSH)) @@ -1180,7 +1181,7 @@ bool PIT_CheckThing (AActor *thing, FCheckPosition &tm) damage = tm.thing->GetMissileDamage ((tm.thing->flags4 & MF4_STRIFEDAMAGE) ? 3 : 7, 1); if ((damage > 0) || (tm.thing->flags6 & MF6_FORCEPAIN)) { - P_DamageMobj (thing, tm.thing, tm.thing->target, damage, tm.thing->DamageType); + int newdam = P_DamageMobj (thing, tm.thing, tm.thing->target, damage, tm.thing->DamageType); if (damage > 0) { if ((tm.thing->flags5 & MF5_BLOODSPLATTER) && @@ -1194,7 +1195,7 @@ bool PIT_CheckThing (AActor *thing, FCheckPosition &tm) } if (!(tm.thing->flags3 & MF3_BLOODLESSIMPACT)) { - P_TraceBleed (damage, thing, tm.thing); + P_TraceBleed (newdam > 0 ? newdam : damage, thing, tm.thing); } } } @@ -3612,13 +3613,42 @@ AActor *P_LineAttack (AActor *t1, angle_t angle, fixed_t distance, // We must pass the unreplaced puff type here puff = P_SpawnPuff (t1, pufftype, hitx, hity, hitz, angle - ANG180, 2, flags|PF_HITTHING); } + + // Allow puffs to inflict poison damage, so that hitscans can poison, too. + if (puffDefaults->PoisonDamage > 0 && puffDefaults->PoisonDuration != INT_MIN) + { + P_PoisonMobj(trace.Actor, puff ? puff : t1, t1, puffDefaults->PoisonDamage, puffDefaults->PoisonDuration, puffDefaults->PoisonPeriod, puffDefaults->PoisonDamageType); + } + + // [GZ] If MF6_FORCEPAIN is set, we need to call P_DamageMobj even if damage is 0! + // Note: The puff may not yet be spawned here so we must check the class defaults, not the actor. + int newdam = damage; + if (damage || (puffDefaults->flags6 & MF6_FORCEPAIN)) + { + int dmgflags = DMG_INFLICTOR_IS_PUFF | pflag; + // Allow MF5_PIERCEARMOR on a weapon as well. + if (t1->player != NULL && (dmgflags & DMG_PLAYERATTACK) && t1->player->ReadyWeapon != NULL && + t1->player->ReadyWeapon->flags5 & MF5_PIERCEARMOR) + { + dmgflags |= DMG_NO_ARMOR; + } + + if (puff == NULL) + { + // Since the puff is the damage inflictor we need it here + // regardless of whether it is displayed or not. + puff = P_SpawnPuff (t1, pufftype, hitx, hity, hitz, angle - ANG180, 2, flags|PF_HITTHING|PF_TEMPORARY); + killPuff = true; + } + newdam = P_DamageMobj (trace.Actor, puff ? puff : t1, t1, damage, damageType, dmgflags); + } if (!(puffDefaults->flags3&MF3_BLOODLESSIMPACT)) { if (!bloodsplatter && !axeBlood && !(trace.Actor->flags & MF_NOBLOOD) && !(trace.Actor->flags2 & (MF2_INVULNERABLE|MF2_DORMANT))) { - P_SpawnBlood (hitx, hity, hitz, angle - ANG180, damage, trace.Actor); + P_SpawnBlood (hitx, hity, hitz, angle - ANG180, newdam > 0 ? newdam : damage, trace.Actor); } if (damage) @@ -3639,38 +3669,10 @@ AActor *P_LineAttack (AActor *t1, angle_t angle, fixed_t distance, } } // [RH] Stick blood to walls - P_TraceBleed (damage, trace.X, trace.Y, trace.Z, + P_TraceBleed (newdam > 0 ? newdam : damage, trace.X, trace.Y, trace.Z, trace.Actor, srcangle, srcpitch); } } - - // Allow puffs to inflict poison damage, so that hitscans can poison, too. - if (puffDefaults->PoisonDamage > 0 && puffDefaults->PoisonDuration != INT_MIN) - { - P_PoisonMobj(trace.Actor, puff ? puff : t1, t1, puffDefaults->PoisonDamage, puffDefaults->PoisonDuration, puffDefaults->PoisonPeriod, puffDefaults->PoisonDamageType); - } - - // [GZ] If MF6_FORCEPAIN is set, we need to call P_DamageMobj even if damage is 0! - // Note: The puff may not yet be spawned here so we must check the class defaults, not the actor. - if (damage || (puffDefaults->flags6 & MF6_FORCEPAIN)) - { - int dmgflags = DMG_INFLICTOR_IS_PUFF | pflag; - // Allow MF5_PIERCEARMOR on a weapon as well. - if (t1->player != NULL && (dmgflags & DMG_PLAYERATTACK) && t1->player->ReadyWeapon != NULL && - t1->player->ReadyWeapon->flags5 & MF5_PIERCEARMOR) - { - dmgflags |= DMG_NO_ARMOR; - } - - if (puff == NULL) - { - // Since the puff is the damage inflictor we need it here - // regardless of whether it is displayed or not. - puff = P_SpawnPuff (t1, pufftype, hitx, hity, hitz, angle - ANG180, 2, flags|PF_HITTHING|PF_TEMPORARY); - killPuff = true; - } - P_DamageMobj (trace.Actor, puff ? puff : t1, t1, damage, damageType, dmgflags); - } if (victim != NULL) { *victim = trace.Actor; @@ -3995,6 +3997,7 @@ void P_RailAttack (AActor *source, int damage, int offset, int color1, int color { fixed_t x, y, z; bool spawnpuff; + bool bleed = false; int puffflags = PF_HITTHING; x = x1 + FixedMul (RailHits[i].Distance, vx); @@ -4012,8 +4015,7 @@ void P_RailAttack (AActor *source, int damage, int offset, int color1, int color puffflags |= PF_HITTHINGBLEED; // [XA] Allow for puffs to jump to XDeath state. if(!(puffDefaults->flags3 & MF3_BLOODLESSIMPACT)) { - P_SpawnBlood (x, y, z, (source->angle + angleoffset) - ANG180, damage, RailHits[i].HitActor); - P_TraceBleed (damage, x, y, z, RailHits[i].HitActor, source->angle, pitch); + bleed = true; } } if (spawnpuff) @@ -4021,7 +4023,12 @@ void P_RailAttack (AActor *source, int damage, int offset, int color1, int color if (puffDefaults && puffDefaults->PoisonDamage > 0 && puffDefaults->PoisonDuration != INT_MIN) P_PoisonMobj(RailHits[i].HitActor, thepuff ? thepuff : source, source, puffDefaults->PoisonDamage, puffDefaults->PoisonDuration, puffDefaults->PoisonPeriod, puffDefaults->PoisonDamageType); - P_DamageMobj (RailHits[i].HitActor, thepuff? thepuff:source, source, damage, damagetype, DMG_INFLICTOR_IS_PUFF); + int newdam = P_DamageMobj (RailHits[i].HitActor, thepuff? thepuff:source, source, damage, damagetype, DMG_INFLICTOR_IS_PUFF); + if (bleed) + { + P_SpawnBlood (x, y, z, (source->angle + angleoffset) - ANG180, newdam > 0 ? newdam : damage, RailHits[i].HitActor); + P_TraceBleed (newdam > 0 ? newdam : damage, x, y, z, RailHits[i].HitActor, source->angle, pitch); + } } // Spawn a decal or puff at the point where the trace ended. @@ -4551,16 +4558,17 @@ void P_RadiusAttack (AActor *bombspot, AActor *bombsource, int bombdamage, int b double velz; double thrust; int damage = (int)points; + int newdam = damage; if (!(flags & RADF_NODAMAGE)) - P_DamageMobj (thing, bombspot, bombsource, damage, bombmod); + newdam = P_DamageMobj (thing, bombspot, bombsource, damage, bombmod); else if (thing->player == NULL && !(flags & RADF_NOIMPACTDAMAGE)) thing->flags2 |= MF2_BLASTED; if (!(thing->flags & MF_ICECORPSE)) { if (!(flags & RADF_NODAMAGE) && !(bombspot->flags3 & MF3_BLOODLESSIMPACT)) - P_TraceBleed (damage, thing, bombspot); + P_TraceBleed (newdam > 0 ? newdam : damage, thing, bombspot); if (!(flags & RADF_NODAMAGE) || !(bombspot->flags2 & MF2_NODMGTHRUST)) { @@ -4616,8 +4624,8 @@ void P_RadiusAttack (AActor *bombspot, AActor *bombsource, int bombdamage, int b damage = Scale(damage, thing->GetClass()->Meta.GetMetaFixed(AMETA_RDFactor, FRACUNIT), FRACUNIT); if (damage > 0) { - P_DamageMobj (thing, bombspot, bombsource, damage, bombmod); - P_TraceBleed (damage, thing, bombspot); + int newdam = P_DamageMobj (thing, bombspot, bombsource, damage, bombmod); + P_TraceBleed (newdam > 0 ? newdam : damage, thing, bombspot); } } } @@ -4819,7 +4827,7 @@ void P_DoCrunch (AActor *thing, FChangePosition *cpos) if ((cpos->crushchange > 0) && !(level.maptime & 3)) { - P_DamageMobj (thing, NULL, NULL, cpos->crushchange, NAME_Crush); + int newdam = P_DamageMobj (thing, NULL, NULL, cpos->crushchange, NAME_Crush); // spray blood in a random direction if (!(thing->flags2&(MF2_INVULNERABLE|MF2_DORMANT))) @@ -4829,7 +4837,7 @@ void P_DoCrunch (AActor *thing, FChangePosition *cpos) PalEntry bloodcolor = thing->GetBloodColor(); const PClass *bloodcls = thing->GetBloodType(); - P_TraceBleed (cpos->crushchange, thing); + P_TraceBleed (newdam > 0 ? newdam : cpos->crushchange, thing); if (cl_bloodtype <= 1 && bloodcls != NULL) { AActor *mo; diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index de97f89ee0..cfb909a010 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -2806,8 +2806,8 @@ bool AActor::Slam (AActor *thing) if (!(flags2 & MF2_DORMANT)) { int dam = GetMissileDamage (7, 1); - P_DamageMobj (thing, this, this, dam, NAME_Melee); - P_TraceBleed (dam, thing, this); + int newdam = P_DamageMobj (thing, this, this, dam, NAME_Melee); + P_TraceBleed (newdam > 0 ? newdam : dam, thing, this); // The charging monster may have died by the target's actions here. if (health > 0) { diff --git a/src/po_man.cpp b/src/po_man.cpp index 6e301377e4..3355b6ca1e 100644 --- a/src/po_man.cpp +++ b/src/po_man.cpp @@ -907,8 +907,8 @@ void FPolyObj::ThrustMobj (AActor *actor, side_t *side) { if (bHurtOnTouch || !P_CheckMove (actor, actor->x + thrustX, actor->y + thrustY)) { - P_DamageMobj (actor, NULL, NULL, crush, NAME_Crush); - P_TraceBleed (crush, actor); + int newdam = P_DamageMobj (actor, NULL, NULL, crush, NAME_Crush); + P_TraceBleed (newdam > 0 ? newdam : crush, actor); } } if (level.flags2 & LEVEL2_POLYGRIND) actor->Grind(false); // crush corpses that get caught in a polyobject's way diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index 36efe7e8fd..efba0cb4ae 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -315,8 +315,8 @@ static void DoAttack (AActor *self, bool domelee, bool domissile, { int damage = pr_camelee.HitDice(MeleeDamage); if (MeleeSound) S_Sound (self, CHAN_WEAPON, MeleeSound, 1, ATTN_NORM); - P_DamageMobj (self->target, self, self, damage, NAME_Melee); - P_TraceBleed (damage, self->target, self); + int newdam = P_DamageMobj (self->target, self, self, damage, NAME_Melee); + P_TraceBleed (newdam > 0 ? newdam : damage, self->target, self); } else if (domissile && MissileType != NULL) { @@ -1119,8 +1119,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomMeleeAttack) if (self->CheckMeleeRange ()) { if (MeleeSound) S_Sound (self, CHAN_WEAPON, MeleeSound, 1, ATTN_NORM); - P_DamageMobj (self->target, self, self, damage, DamageType); - if (bleed) P_TraceBleed (damage, self->target, self); + int newdam = P_DamageMobj (self->target, self, self, damage, DamageType); + if (bleed) P_TraceBleed (newdam > 0 ? newdam : damage, self->target, self); } else { @@ -1151,8 +1151,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomComboAttack) { if (DamageType==NAME_None) DamageType = NAME_Melee; // Melee is the default type if (MeleeSound) S_Sound (self, CHAN_WEAPON, MeleeSound, 1, ATTN_NORM); - P_DamageMobj (self->target, self, self, damage, DamageType); - if (bleed) P_TraceBleed (damage, self->target, self); + int newdam = P_DamageMobj (self->target, self, self, damage, DamageType); + if (bleed) P_TraceBleed (newdam > 0 ? newdam : damage, self->target, self); } else if (ti) { @@ -4053,11 +4053,11 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_WolfAttack) damage >>= 2; if (damage) { - P_DamageMobj(self->target, self, self, damage, mod, DMG_THRUSTLESS); + int newdam = P_DamageMobj(self->target, self, self, damage, mod, DMG_THRUSTLESS); if (spawnblood) { - P_SpawnBlood(dx, dy, dz, angle, damage, self->target); - P_TraceBleed(damage, self->target, R_PointToAngle2(self->x, self->y, dx, dy), 0); + P_SpawnBlood(dx, dy, dz, angle, newdam > 0 ? newdam : damage, self->target); + P_TraceBleed(newdam > 0 ? newdam : damage, self->target, R_PointToAngle2(self->x, self->y, dx, dy), 0); } } }