diff --git a/src/actor.h b/src/actor.h index dc2ee0510..9c4fd9ff7 100644 --- a/src/actor.h +++ b/src/actor.h @@ -604,7 +604,7 @@ public: // Perform some special damage action. Returns the amount of damage to do. // Returning -1 signals the damage routine to exit immediately - virtual int DoSpecialDamage (AActor *target, int damage); + virtual int DoSpecialDamage (AActor *target, int damage, FName damagetype); // Like DoSpecialDamage, but called on the actor receiving the damage. virtual int TakeSpecialDamage (AActor *inflictor, AActor *source, int damage, FName damagetype); diff --git a/src/g_heretic/a_hereticweaps.cpp b/src/g_heretic/a_hereticweaps.cpp index 79291659f..e8f287f69 100644 --- a/src/g_heretic/a_hereticweaps.cpp +++ b/src/g_heretic/a_hereticweaps.cpp @@ -335,12 +335,12 @@ class AMaceFX4 : public AActor { DECLARE_CLASS (AMaceFX4, AActor) public: - int DoSpecialDamage (AActor *target, int damage); + int DoSpecialDamage (AActor *target, int damage, FName damagetype); }; IMPLEMENT_CLASS (AMaceFX4) -int AMaceFX4::DoSpecialDamage (AActor *target, int damage) +int AMaceFX4::DoSpecialDamage (AActor *target, int damage, FName damagetype) { if ((target->flags2 & MF2_BOSS) || (target->flags3 & MF3_DONTSQUASH) || target->IsTeammate (this->target)) { // Don't allow cheap boss kills and don't instagib teammates @@ -703,10 +703,10 @@ class ABlasterFX1 : public AFastProjectile DECLARE_CLASS(ABlasterFX1, AFastProjectile) public: void Effect (); - int DoSpecialDamage (AActor *target, int damage); + int DoSpecialDamage (AActor *target, int damage, FName damagetype); }; -int ABlasterFX1::DoSpecialDamage (AActor *target, int damage) +int ABlasterFX1::DoSpecialDamage (AActor *target, int damage, FName damagetype) { if (target->IsKindOf (PClass::FindClass ("Ironlich"))) { // Less damage to Ironlich bosses @@ -736,12 +736,12 @@ class ARipper : public AActor { DECLARE_CLASS (ARipper, AActor) public: - int DoSpecialDamage (AActor *target, int damage); + int DoSpecialDamage (AActor *target, int damage, FName damagetype); }; IMPLEMENT_CLASS(ARipper) -int ARipper::DoSpecialDamage (AActor *target, int damage) +int ARipper::DoSpecialDamage (AActor *target, int damage, FName damagetype) { if (target->IsKindOf (PClass::FindClass ("Ironlich"))) { // Less damage to Ironlich bosses @@ -822,12 +822,12 @@ class AHornRodFX2 : public AActor { DECLARE_CLASS (AHornRodFX2, AActor) public: - int DoSpecialDamage (AActor *target, int damage); + int DoSpecialDamage (AActor *target, int damage, FName damagetype); }; IMPLEMENT_CLASS (AHornRodFX2) -int AHornRodFX2::DoSpecialDamage (AActor *target, int damage) +int AHornRodFX2::DoSpecialDamage (AActor *target, int damage, FName damagetype) { if (target->IsKindOf (PClass::FindClass("Sorcerer2")) && pr_hrfx2() < 96) { // D'Sparil teleports away @@ -843,12 +843,12 @@ class ARainPillar : public AActor { DECLARE_CLASS (ARainPillar, AActor) public: - int DoSpecialDamage (AActor *target, int damage); + int DoSpecialDamage (AActor *target, int damage, FName damagetype); }; IMPLEMENT_CLASS (ARainPillar) -int ARainPillar::DoSpecialDamage (AActor *target, int damage) +int ARainPillar::DoSpecialDamage (AActor *target, int damage, FName damagetype) { if (target->flags2 & MF2_BOSS) { // Decrease damage for bosses @@ -1154,13 +1154,13 @@ class APhoenixFX1 : public AActor { DECLARE_CLASS (APhoenixFX1, AActor) public: - int DoSpecialDamage (AActor *target, int damage); + int DoSpecialDamage (AActor *target, int damage, FName damagetype); }; IMPLEMENT_CLASS (APhoenixFX1) -int APhoenixFX1::DoSpecialDamage (AActor *target, int damage) +int APhoenixFX1::DoSpecialDamage (AActor *target, int damage, FName damagetype) { if (target->IsKindOf (PClass::FindClass("Sorcerer2")) && pr_hrfx2() < 96) { // D'Sparil teleports away @@ -1176,12 +1176,12 @@ class APhoenixFX2 : public AActor { DECLARE_CLASS (APhoenixFX2, AActor) public: - int DoSpecialDamage (AActor *target, int damage); + int DoSpecialDamage (AActor *target, int damage, FName damagetype); }; IMPLEMENT_CLASS (APhoenixFX2) -int APhoenixFX2::DoSpecialDamage (AActor *target, int damage) +int APhoenixFX2::DoSpecialDamage (AActor *target, int damage, FName damagetype) { if (target->player && pr_pfx2 () < 128) { // Freeze player for a bit diff --git a/src/g_heretic/a_ironlich.cpp b/src/g_heretic/a_ironlich.cpp index 61220f419..8efa08273 100644 --- a/src/g_heretic/a_ironlich.cpp +++ b/src/g_heretic/a_ironlich.cpp @@ -19,12 +19,12 @@ class AWhirlwind : public AActor { DECLARE_CLASS (AWhirlwind, AActor) public: - int DoSpecialDamage (AActor *target, int damage); + int DoSpecialDamage (AActor *target, int damage, FName damagetype); }; IMPLEMENT_CLASS(AWhirlwind) -int AWhirlwind::DoSpecialDamage (AActor *target, int damage) +int AWhirlwind::DoSpecialDamage (AActor *target, int damage, FName damagetype) { int randVal; diff --git a/src/g_hexen/a_clericstaff.cpp b/src/g_hexen/a_clericstaff.cpp index 8dc8c0916..36f0c7686 100644 --- a/src/g_hexen/a_clericstaff.cpp +++ b/src/g_hexen/a_clericstaff.cpp @@ -22,12 +22,12 @@ class ACStaffMissile : public AActor { DECLARE_CLASS (ACStaffMissile, AActor) public: - int DoSpecialDamage (AActor *target, int damage); + int DoSpecialDamage (AActor *target, int damage, FName damagetype); }; IMPLEMENT_CLASS (ACStaffMissile) -int ACStaffMissile::DoSpecialDamage (AActor *target, int damage) +int ACStaffMissile::DoSpecialDamage (AActor *target, int damage, FName damagetype) { // Cleric Serpent Staff does poison damage if (target->player) diff --git a/src/g_hexen/a_fighterquietus.cpp b/src/g_hexen/a_fighterquietus.cpp index 8bc27751c..0ba8abd6f 100644 --- a/src/g_hexen/a_fighterquietus.cpp +++ b/src/g_hexen/a_fighterquietus.cpp @@ -58,12 +58,12 @@ class AFSwordMissile : public AActor { DECLARE_CLASS (AFSwordMissile, AActor) public: - int DoSpecialDamage(AActor *victim, AActor *source, int damage); + int DoSpecialDamage(AActor *victim, AActor *source, int damage, FName damagetype); }; IMPLEMENT_CLASS (AFSwordMissile) -int AFSwordMissile::DoSpecialDamage(AActor *victim, AActor *source, int damage) +int AFSwordMissile::DoSpecialDamage(AActor *victim, AActor *source, int damage, FName damagetype) { if (victim->player) { diff --git a/src/g_hexen/a_flechette.cpp b/src/g_hexen/a_flechette.cpp index 779b9424c..11352a41d 100644 --- a/src/g_hexen/a_flechette.cpp +++ b/src/g_hexen/a_flechette.cpp @@ -307,7 +307,7 @@ class APoisonCloud : public AActor { DECLARE_CLASS (APoisonCloud, AActor) public: - int DoSpecialDamage (AActor *target, int damage); + int DoSpecialDamage (AActor *target, int damage, FName damagetype); void BeginPlay (); }; @@ -320,7 +320,7 @@ void APoisonCloud::BeginPlay () special2 = 0; } -int APoisonCloud::DoSpecialDamage (AActor *victim, int damage) +int APoisonCloud::DoSpecialDamage (AActor *victim, int damage, FName damagetype) { if (victim->player) { @@ -343,12 +343,18 @@ int APoisonCloud::DoSpecialDamage (AActor *victim, int damage) { damage = (int)((float)damage * level.teamdamage); } + // Modify with damage factors + damage = FixedMul(damage, victim->DamageFactor); + if (damage > 0) + { + damage = DamageTypeDefinition::ApplyMobjDamageFactor(damage, damagetype, victim->GetClass()->ActorInfo->DamageFactors); + } if (damage > 0) { P_PoisonDamage (victim->player, this, 15+(pr_poisoncloudd()&15), false); // Don't play painsound - // If successful, play the posion sound. + // If successful, play the poison sound. if (P_PoisonPlayer (victim->player, this, this->target, 50)) S_Sound (victim, CHAN_VOICE, "*poison", 1, ATTN_NORM); } diff --git a/src/g_hexen/a_magecone.cpp b/src/g_hexen/a_magecone.cpp index 84d53db56..6356fbb2f 100644 --- a/src/g_hexen/a_magecone.cpp +++ b/src/g_hexen/a_magecone.cpp @@ -29,12 +29,12 @@ class AFrostMissile : public AActor { DECLARE_CLASS (AFrostMissile, AActor) public: - int DoSpecialDamage (AActor *victim, int damage); + int DoSpecialDamage (AActor *victim, int damage, FName damagetype); }; IMPLEMENT_CLASS (AFrostMissile) -int AFrostMissile::DoSpecialDamage (AActor *victim, int damage) +int AFrostMissile::DoSpecialDamage (AActor *victim, int damage, FName damagetype) { if (special2 > 0) { diff --git a/src/g_hexen/a_teleportother.cpp b/src/g_hexen/a_teleportother.cpp index 8de2ab0c3..8bd17b62b 100644 --- a/src/g_hexen/a_teleportother.cpp +++ b/src/g_hexen/a_teleportother.cpp @@ -42,7 +42,7 @@ class ATelOtherFX1 : public AActor { DECLARE_CLASS (ATelOtherFX1, AActor) public: - int DoSpecialDamage (AActor *target, int damage); + int DoSpecialDamage (AActor *target, int damage, FName damagetype); }; IMPLEMENT_CLASS (ATelOtherFX1) @@ -115,7 +115,7 @@ bool AArtiTeleportOther::Use (bool pickup) // //=========================================================================== -int ATelOtherFX1::DoSpecialDamage (AActor *target, int damage) +int ATelOtherFX1::DoSpecialDamage (AActor *target, int damage, FName damagetype) { if ((target->flags3 & MF3_ISMONSTER || target->player != NULL) && !(target->flags2 & MF2_BOSS) && diff --git a/src/g_raven/a_minotaur.cpp b/src/g_raven/a_minotaur.cpp index 8565a9b2a..36a5537bc 100644 --- a/src/g_raven/a_minotaur.cpp +++ b/src/g_raven/a_minotaur.cpp @@ -56,9 +56,9 @@ bool AMinotaur::Slam (AActor *thing) return Super::Slam (thing); } -int AMinotaur::DoSpecialDamage (AActor *target, int damage) +int AMinotaur::DoSpecialDamage (AActor *target, int damage, FName damagetype) { - damage = Super::DoSpecialDamage (target, damage); + damage = Super::DoSpecialDamage (target, damage, damagetype); if ((damage != -1) && (flags & MF_SKULLFLY)) { // Slam only when in charge mode P_MinotaurSlam (this, target); diff --git a/src/g_raven/ravenshared.h b/src/g_raven/ravenshared.h index 16ae44796..726dc1a38 100644 --- a/src/g_raven/ravenshared.h +++ b/src/g_raven/ravenshared.h @@ -7,7 +7,7 @@ class AMinotaur : public AActor { DECLARE_CLASS (AMinotaur, AActor) public: - int DoSpecialDamage (AActor *target, int damage); + int DoSpecialDamage (AActor *target, int damage, FName damagetype); public: bool Slam (AActor *); diff --git a/src/g_shared/a_morph.cpp b/src/g_shared/a_morph.cpp index 0f51d373b..d3b8d4ac8 100644 --- a/src/g_shared/a_morph.cpp +++ b/src/g_shared/a_morph.cpp @@ -535,7 +535,7 @@ bool P_MorphedDeath(AActor *actor, AActor **morphed, int *morphedstyle, int *mor IMPLEMENT_CLASS(AMorphProjectile) -int AMorphProjectile::DoSpecialDamage (AActor *target, int damage) +int AMorphProjectile::DoSpecialDamage (AActor *target, int damage, FName damagetype) { const PClass *morph_flash = PClass::FindClass (MorphFlash); const PClass *unmorph_flash = PClass::FindClass (UnMorphFlash); diff --git a/src/g_shared/a_sharedglobal.h b/src/g_shared/a_sharedglobal.h index 1b7521357..87e103975 100644 --- a/src/g_shared/a_sharedglobal.h +++ b/src/g_shared/a_sharedglobal.h @@ -156,7 +156,7 @@ class AMorphProjectile : public AActor { DECLARE_CLASS (AMorphProjectile, AActor) public: - int DoSpecialDamage (AActor *target, int damage); + int DoSpecialDamage (AActor *target, int damage, FName damagetype); void Serialize (FArchive &arc); FNameNoInit PlayerClass, MonsterClass, MorphFlash, UnMorphFlash; diff --git a/src/g_strife/a_loremaster.cpp b/src/g_strife/a_loremaster.cpp index 8613aacee..3c42ea181 100644 --- a/src/g_strife/a_loremaster.cpp +++ b/src/g_strife/a_loremaster.cpp @@ -14,12 +14,12 @@ class ALoreShot : public AActor { DECLARE_CLASS (ALoreShot, AActor) public: - int DoSpecialDamage (AActor *target, int damage); + int DoSpecialDamage (AActor *target, int damage, FName damagetype); }; IMPLEMENT_CLASS (ALoreShot) -int ALoreShot::DoSpecialDamage (AActor *target, int damage) +int ALoreShot::DoSpecialDamage (AActor *target, int damage, FName damagetype) { FVector3 thrust; diff --git a/src/g_strife/a_strifeweapons.cpp b/src/g_strife/a_strifeweapons.cpp index e7a9a8533..596e91e07 100644 --- a/src/g_strife/a_strifeweapons.cpp +++ b/src/g_strife/a_strifeweapons.cpp @@ -158,12 +158,12 @@ class APoisonBolt : public AActor { DECLARE_CLASS (APoisonBolt, AActor) public: - int DoSpecialDamage (AActor *target, int damage); + int DoSpecialDamage (AActor *target, int damage, FName damagetype); }; IMPLEMENT_CLASS (APoisonBolt) -int APoisonBolt::DoSpecialDamage (AActor *target, int damage) +int APoisonBolt::DoSpecialDamage (AActor *target, int damage, FName damagetype) { if (target->flags & MF_NOBLOOD) { @@ -551,18 +551,18 @@ class APhosphorousFire : public AActor { DECLARE_CLASS (APhosphorousFire, AActor) public: - int DoSpecialDamage (AActor *target, int damage); + int DoSpecialDamage (AActor *target, int damage, FName damagetype); }; IMPLEMENT_CLASS (APhosphorousFire) -int APhosphorousFire::DoSpecialDamage (AActor *target, int damage) +int APhosphorousFire::DoSpecialDamage (AActor *target, int damage, FName damagetype) { if (target->flags & MF_NOBLOOD) { return damage / 2; } - return Super::DoSpecialDamage (target, damage); + return Super::DoSpecialDamage (target, damage, damagetype); } DEFINE_ACTION_FUNCTION(AActor, A_BurnArea) diff --git a/src/p_interaction.cpp b/src/p_interaction.cpp index 538581327..b22c60bc1 100644 --- a/src/p_interaction.cpp +++ b/src/p_interaction.cpp @@ -991,7 +991,7 @@ void P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage } } - damage = inflictor->DoSpecialDamage (target, damage); + damage = inflictor->DoSpecialDamage (target, damage, mod); if (damage == -1) { return; @@ -1566,6 +1566,19 @@ void P_PoisonDamage (player_t *player, AActor *source, int damage, // Take half damage in trainer mode damage = FixedMul(damage, G_SkillProperty(SKILLP_DamageFactor)); } + // Modify with damage factors + if (damage > 0) + { + damage = FixedMul(damage, target->DamageFactor); + if (damage > 0) + { + damage = DamageTypeDefinition::ApplyMobjDamageFactor(damage, player->poisontype, target->GetClass()->ActorInfo->DamageFactors); + } + if (damage <= 0) + { // Damage was reduced to 0, so don't bother further. + return; + } + } if (damage >= player->health && (G_SkillProperty(SKILLP_AutoUseHealth) || deathmatch) && !player->morphTics) diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 0f2a7e8ae..4f0ca0069 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -5755,7 +5755,7 @@ bool AActor::IsHostile (AActor *other) return true; } -int AActor::DoSpecialDamage (AActor *target, int damage) +int AActor::DoSpecialDamage (AActor *target, int damage, FName damagetype) { if (target->player && target->player->mo == target && damage < 1000 && (target->player->cheats & CF_GODMODE))