aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/game/Entities/Player/Player.cpp6
-rw-r--r--src/server/game/Entities/Player/Player.h2
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp715
-rw-r--r--src/server/game/Entities/Unit/Unit.h41
-rw-r--r--src/server/game/Handlers/MovementHandler.cpp2
-rw-r--r--src/server/game/Instances/InstanceScript.cpp2
-rw-r--r--src/server/game/Spells/Auras/SpellAuraEffects.cpp243
-rw-r--r--src/server/game/Spells/Auras/SpellAuraEffects.h18
-rw-r--r--src/server/game/Spells/Auras/SpellAuras.cpp71
-rw-r--r--src/server/game/Spells/Auras/SpellAuras.h12
-rw-r--r--src/server/game/Spells/Spell.cpp25
-rw-r--r--src/server/game/Spells/Spell.h2
-rw-r--r--src/server/game/Spells/SpellEffects.cpp20
-rw-r--r--src/server/game/Spells/SpellMgr.cpp13
-rw-r--r--src/server/game/Spells/SpellScript.cpp4
-rw-r--r--src/server/game/Spells/SpellScript.h8
-rw-r--r--src/server/scripts/Commands/cs_misc.cpp20
-rw-r--r--src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_ragnaros.cpp2
-rw-r--r--src/server/scripts/EasternKingdoms/Karazhan/karazhan.cpp2
-rw-r--r--src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp2
-rw-r--r--src/server/scripts/EasternKingdoms/ScarletEnclave/chapter2.cpp2
-rw-r--r--src/server/scripts/EasternKingdoms/SunwellPlateau/boss_brutallus.cpp2
-rw-r--r--src/server/scripts/EasternKingdoms/SunwellPlateau/boss_felmyst.cpp2
-rw-r--r--src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kalecgos.cpp2
-rw-r--r--src/server/scripts/EasternKingdoms/zone_western_plaguelands.cpp2
-rw-r--r--src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_archimonde.cpp2
-rw-r--r--src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/instance_culling_of_stratholme.cpp2
-rw-r--r--src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/boss_aeonus.cpp2
-rw-r--r--src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/boss_chrono_lord_deja.cpp2
-rw-r--r--src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/boss_temporus.cpp2
-rw-r--r--src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/instance_the_black_morass.cpp2
-rw-r--r--src/server/scripts/Kalimdor/OnyxiasLair/boss_onyxia.cpp2
-rw-r--r--src/server/scripts/Kalimdor/RuinsOfAhnQiraj/boss_buru.cpp2
-rw-r--r--src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_viscidus.cpp2
-rw-r--r--src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/obsidian_sanctum.cpp2
-rw-r--r--src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_baltharus_the_warborn.cpp2
-rw-r--r--src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp2
-rw-r--r--src/server/scripts/Northrend/Gundrak/boss_drakkari_colossus.cpp2
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_blood_prince_council.cpp2
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp2
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp2
-rw-r--r--src/server/scripts/Northrend/IsleOfConquest/boss_ioc_horde_alliance.cpp2
-rw-r--r--src/server/scripts/Northrend/Naxxramas/boss_faerlina.cpp2
-rw-r--r--src/server/scripts/Northrend/Ulduar/HallsOfStone/halls_of_stone.cpp2
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp2
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp6
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/boss_xt002.cpp2
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/boss_yogg_saron.cpp4
-rw-r--r--src/server/scripts/Northrend/zone_borean_tundra.cpp2
-rw-r--r--src/server/scripts/Northrend/zone_grizzly_hills.cpp2
-rw-r--r--src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_fathomlord_karathress.cpp2
-rw-r--r--src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_leotheras_the_blind.cpp2
-rw-r--r--src/server/scripts/Outland/CoilfangReservoir/TheSlavePens/boss_ahune.cpp6
-rw-r--r--src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/shattered_halls.cpp2
-rw-r--r--src/server/scripts/Outland/TempestKeep/Eye/boss_alar.cpp2
-rw-r--r--src/server/scripts/Outland/TempestKeep/botanica/boss_warp_splinter.cpp2
-rw-r--r--src/server/scripts/Outland/zone_shadowmoon_valley.cpp2
-rw-r--r--src/server/scripts/Spells/spell_dk.cpp2
-rw-r--r--src/server/scripts/Spells/spell_monk.cpp4
59 files changed, 657 insertions, 643 deletions
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 008b5c12956..b780408e67a 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -648,7 +648,7 @@ uint32 Player::EnvironmentalDamage(EnviromentalDamage type, uint32 damage)
case DAMAGE_SLIME:
{
DamageInfo dmgInfo(this, this, damage, nullptr, type == DAMAGE_LAVA ? SPELL_SCHOOL_MASK_FIRE : SPELL_SCHOOL_MASK_NATURE, DIRECT_DAMAGE, BASE_ATTACK);
- CalcAbsorbResist(dmgInfo);
+ Unit::CalcAbsorbResist(dmgInfo);
absorb = dmgInfo.GetAbsorb();
resist = dmgInfo.GetResist();
damage = dmgInfo.GetDamage();
@@ -658,7 +658,7 @@ uint32 Player::EnvironmentalDamage(EnviromentalDamage type, uint32 damage)
break;
}
- DealDamageMods(this, damage, &absorb);
+ Unit::DealDamageMods(nullptr, this, damage, &absorb);
WorldPackets::CombatLog::EnvironmentalDamageLog packet;
packet.Victim = GetGUID();
@@ -667,7 +667,7 @@ uint32 Player::EnvironmentalDamage(EnviromentalDamage type, uint32 damage)
packet.Absorbed = absorb;
packet.Resisted = resist;
- uint32 final_damage = DealDamage(this, damage, nullptr, SELF_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, nullptr, false);
+ uint32 final_damage = Unit::DealDamage(this, this, damage, nullptr, SELF_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, nullptr, false);
packet.LogData.Initialize(this);
SendCombatLogMessage(&packet);
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index 6298598605a..7d10604eea1 100644
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -1960,6 +1960,8 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
uint32 GetBaseSpellPowerBonus() const { return m_baseSpellPower; }
int32 GetSpellPenetrationItemMod() const { return m_spellPenetrationItemMod; }
+ bool CanApplyResilience() const override { return true; }
+
float GetExpertiseDodgeOrParryReduction(WeaponAttackType attType) const;
void UpdateBlockPercentage();
void UpdateCritPercentage(WeaponAttackType attType);
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index 33c528d54f7..9bb993c6ed1 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -669,7 +669,7 @@ bool Unit::HasBreakableByDamageCrowdControlAura(Unit* excludeCasterChannel) cons
|| HasBreakableByDamageAuraType(SPELL_AURA_TRANSFORM, excludeAura));
}
-void Unit::DealDamageMods(Unit const* victim, uint32 &damage, uint32* absorb) const
+/*static*/ void Unit::DealDamageMods(Unit const* attacker, Unit const* victim, uint32& damage, uint32* absorb)
{
if (!victim || !victim->IsAlive() || victim->HasUnitState(UNIT_STATE_IN_FLIGHT) || (victim->GetTypeId() == TYPEID_UNIT && victim->ToCreature()->IsEvadingAttacks()))
{
@@ -679,21 +679,22 @@ void Unit::DealDamageMods(Unit const* victim, uint32 &damage, uint32* absorb) co
return;
}
- damage *= GetDamageMultiplierForTarget(victim);
+ if (attacker)
+ damage *= attacker->GetDamageMultiplierForTarget(victim);
}
-uint32 Unit::DealDamage(Unit* victim, uint32 damage, CleanDamage const* cleanDamage, DamageEffectType damagetype, SpellSchoolMask damageSchoolMask, SpellInfo const* spellProto, bool durabilityLoss)
+/*static*/ uint32 Unit::DealDamage(Unit* attacker, Unit* victim, uint32 damage, CleanDamage const* cleanDamage, DamageEffectType damagetype, SpellSchoolMask damageSchoolMask, SpellInfo const* spellProto, bool durabilityLoss)
{
if (victim->IsAIEnabled)
- victim->GetAI()->DamageTaken(this, damage);
+ victim->GetAI()->DamageTaken(attacker, damage);
- if (IsAIEnabled)
- GetAI()->DamageDealt(victim, damage, damagetype);
+ if (attacker && attacker->IsAIEnabled)
+ attacker->GetAI()->DamageDealt(victim, damage, damagetype);
// Hook for OnDamage Event
- sScriptMgr->OnDamage(this, victim, damage);
+ sScriptMgr->OnDamage(attacker, victim, damage);
- if (victim->GetTypeId() == TYPEID_PLAYER && this != victim)
+ if (victim->GetTypeId() == TYPEID_PLAYER && attacker != victim)
{
// Signal to pets that their owner was attacked - except when DOT.
if (damagetype != DOT)
@@ -701,7 +702,7 @@ uint32 Unit::DealDamage(Unit* victim, uint32 damage, CleanDamage const* cleanDam
for (Unit* controlled : victim->m_Controlled)
if (Creature* cControlled = controlled->ToCreature())
if (cControlled->IsAIEnabled)
- cControlled->AI()->OwnerAttackedBy(this);
+ cControlled->AI()->OwnerAttackedBy(attacker);
}
if (victim->ToPlayer()->GetCommandStatus(CHEAT_GOD))
@@ -720,7 +721,7 @@ uint32 Unit::DealDamage(Unit* victim, uint32 damage, CleanDamage const* cleanDam
victim->RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags::Damage, 0);
if (!damage && damagetype != DOT && cleanDamage && cleanDamage->absorbed_damage)
- if (victim != this && victim->GetTypeId() == TYPEID_PLAYER)
+ if (victim != attacker && victim->GetTypeId() == TYPEID_PLAYER)
if (Spell* spell = victim->m_currentSpells[CURRENT_GENERIC_SPELL])
if (spell->getState() == SPELL_STATE_PREPARING && spell->m_spellInfo->InterruptFlags.HasFlag(SpellInterruptFlags::DamageAbsorb))
victim->InterruptNonMeleeSpells(false);
@@ -746,35 +747,35 @@ uint32 Unit::DealDamage(Unit* victim, uint32 damage, CleanDamage const* cleanDam
uint32 share = CalculatePct(damage, (*i)->GetAmount());
/// @todo check packets if damage is done by victim, or by attacker of victim
- DealDamageMods(shareDamageTarget, share, nullptr);
- DealDamage(shareDamageTarget, share, nullptr, NODAMAGE, spell->GetSchoolMask(), spell, false);
+ Unit::DealDamageMods(attacker, shareDamageTarget, share, nullptr);
+ Unit::DealDamage(attacker, shareDamageTarget, share, nullptr, NODAMAGE, spell->GetSchoolMask(), spell, false);
}
}
// Rage from Damage made (only from direct weapon damage)
- if (cleanDamage && (cleanDamage->attackType == BASE_ATTACK || cleanDamage->attackType == OFF_ATTACK) && damagetype == DIRECT_DAMAGE && this != victim && GetPowerType() == POWER_RAGE)
+ if (attacker && cleanDamage && (cleanDamage->attackType == BASE_ATTACK || cleanDamage->attackType == OFF_ATTACK) && damagetype == DIRECT_DAMAGE && attacker != victim && attacker->GetPowerType() == POWER_RAGE)
{
- uint32 rage = uint32(GetBaseAttackTime(cleanDamage->attackType) / 1000.f * 1.75f);
+ uint32 rage = uint32(attacker->GetBaseAttackTime(cleanDamage->attackType) / 1000.f * 1.75f);
if (cleanDamage->attackType == OFF_ATTACK)
rage /= 2;
- RewardRage(rage);
+ attacker->RewardRage(rage);
}
if (!damage)
return 0;
- TC_LOG_DEBUG("entities.unit", "DealDamageStart");
-
uint32 health = victim->GetHealth();
- TC_LOG_DEBUG("entities.unit", "%s dealt %u damage to %s", GetGUID().ToString().c_str(), damage, victim->GetGUID().ToString().c_str());
// duel ends when player has 1 or less hp
bool duel_hasEnded = false;
bool duel_wasMounted = false;
if (victim->GetTypeId() == TYPEID_PLAYER && victim->ToPlayer()->duel && damage >= (health-1))
{
+ if (!attacker)
+ return 0;
+
// prevent kill only if killed in duel and killed by opponent or opponent controlled creature
- if (victim->ToPlayer()->duel->opponent == this || victim->ToPlayer()->duel->opponent->GetGUID() == GetOwnerGUID())
+ if (victim->ToPlayer()->duel->opponent == attacker || victim->ToPlayer()->duel->opponent->GetGUID() == attacker->GetOwnerGUID())
damage = health - 1;
duel_hasEnded = true;
@@ -785,8 +786,11 @@ uint32 Unit::DealDamage(Unit* victim, uint32 damage, CleanDamage const* cleanDam
if (victimRider && victimRider->duel && victimRider->duel->isMounted)
{
+ if (!attacker)
+ return 0;
+
// prevent kill only if killed in duel and killed by opponent or opponent controlled creature
- if (victimRider->duel->opponent == this || victimRider->duel->opponent->GetGUID() == GetCharmerGUID())
+ if (victimRider->duel->opponent == attacker || victimRider->duel->opponent->GetGUID() == attacker->GetCharmerGUID())
damage = health - 1;
duel_wasMounted = true;
@@ -794,30 +798,32 @@ uint32 Unit::DealDamage(Unit* victim, uint32 damage, CleanDamage const* cleanDam
}
}
- if (GetTypeId() == TYPEID_PLAYER && this != victim)
+ if (attacker && attacker != victim)
{
- Player* killer = ToPlayer();
-
- // in bg, count dmg if victim is also a player
- if (victim->GetTypeId() == TYPEID_PLAYER)
- if (Battleground* bg = killer->GetBattleground())
- bg->UpdatePlayerScore(killer, SCORE_DAMAGE_DONE, damage);
+ if (Player* killer = attacker->ToPlayer())
+ {
+ // in bg, count dmg if victim is also a player
+ if (victim->GetTypeId() == TYPEID_PLAYER)
+ if (Battleground* bg = killer->GetBattleground())
+ bg->UpdatePlayerScore(killer, SCORE_DAMAGE_DONE, damage);
- killer->UpdateCriteria(CRITERIA_TYPE_DAMAGE_DONE, health > damage ? damage : health, 0, 0, victim);
- killer->UpdateCriteria(CRITERIA_TYPE_HIGHEST_HIT_DEALT, damage);
+ killer->UpdateCriteria(CRITERIA_TYPE_DAMAGE_DONE, health > damage ? damage : health, 0, 0, victim);
+ killer->UpdateCriteria(CRITERIA_TYPE_HIGHEST_HIT_DEALT, damage);
+ }
}
if (victim->GetTypeId() == TYPEID_PLAYER)
victim->ToPlayer()->UpdateCriteria(CRITERIA_TYPE_HIGHEST_HIT_RECEIVED, damage);
- damage /= victim->GetHealthMultiplierForTarget(this);
+ if (attacker)
+ damage /= victim->GetHealthMultiplierForTarget(attacker);
if (victim->GetTypeId() != TYPEID_PLAYER && (!victim->IsControlledByPlayer() || victim->IsVehicle()))
{
if (!victim->ToCreature()->hasLootRecipient())
- victim->ToCreature()->SetLootRecipient(this);
+ victim->ToCreature()->SetLootRecipient(attacker);
- if (IsControlledByPlayer())
+ if (!attacker || attacker->IsControlledByPlayer())
victim->ToCreature()->LowerPlayerDamageReq(health < damage ? health : damage);
}
@@ -828,15 +834,13 @@ uint32 Unit::DealDamage(Unit* victim, uint32 damage, CleanDamage const* cleanDam
{
killed = true;
- TC_LOG_DEBUG("entities.unit", "DealDamage: victim just died");
-
- if (victim->GetTypeId() == TYPEID_PLAYER && victim != this)
+ if (victim->GetTypeId() == TYPEID_PLAYER && victim != attacker)
victim->ToPlayer()->UpdateCriteria(CRITERIA_TYPE_TOTAL_DAMAGE_RECEIVED, health);
if (damagetype != NODAMAGE && damagetype != SELF_DAMAGE && victim->HasAuraType(SPELL_AURA_SCHOOL_ABSORB_OVERKILL))
{
AuraEffectList vAbsorbOverkill = victim->GetAuraEffectsByType(SPELL_AURA_SCHOOL_ABSORB_OVERKILL);
- DamageInfo damageInfo = DamageInfo(this, victim, damage, spellProto, damageSchoolMask, damagetype,
+ DamageInfo damageInfo = DamageInfo(attacker, victim, damage, spellProto, damageSchoolMask, damagetype,
cleanDamage ? cleanDamage->attackType : BASE_ATTACK);
for (AuraEffect* absorbAurEff : vAbsorbOverkill)
{
@@ -879,7 +883,7 @@ uint32 Unit::DealDamage(Unit* victim, uint32 damage, CleanDamage const* cleanDam
if (currentAbsorb)
{
WorldPackets::CombatLog::SpellAbsorbLog absorbLog;
- absorbLog.Attacker = GetGUID();
+ absorbLog.Attacker = attacker ? attacker->GetGUID() : ObjectGuid::Empty;
absorbLog.Victim = victim->GetGUID();
absorbLog.Caster = base->GetCasterGUID();
absorbLog.AbsorbedSpellID = spellProto ? spellProto->Id : 0;
@@ -887,7 +891,7 @@ uint32 Unit::DealDamage(Unit* victim, uint32 damage, CleanDamage const* cleanDam
absorbLog.Absorbed = currentAbsorb;
absorbLog.OriginalDamage = damageInfo.GetOriginalDamage();
absorbLog.LogData.Initialize(victim);
- SendCombatLogMessage(&absorbLog);
+ victim->SendCombatLogMessage(&absorbLog);
}
}
@@ -896,11 +900,9 @@ uint32 Unit::DealDamage(Unit* victim, uint32 damage, CleanDamage const* cleanDam
}
if (killed)
- Kill(victim, durabilityLoss, skipSettingDeathState);
+ Unit::Kill(attacker, victim, durabilityLoss, skipSettingDeathState);
else
{
- TC_LOG_DEBUG("entities.unit", "DealDamageAlive");
-
if (victim->GetTypeId() == TYPEID_PLAYER)
victim->ToPlayer()->UpdateCriteria(CRITERIA_TYPE_TOTAL_DAMAGE_RECEIVED, damage);
@@ -915,7 +917,8 @@ uint32 Unit::DealDamage(Unit* victim, uint32 damage, CleanDamage const* cleanDam
if (damagetype != DOT && damage > 0 && !victim->GetOwnerGUID().IsPlayer() && (!spellProto || !spellProto->HasAura(SPELL_AURA_DAMAGE_SHIELD)))
victim->ToCreature()->SetLastDamagedTime(GameTime::GetGameTime() + MAX_AGGRO_RESET_TIME);
- victim->GetThreatManager().AddThreat(this, float(damage), spellProto);
+ if (attacker)
+ victim->GetThreatManager().AddThreat(attacker, float(damage), spellProto);
}
else // victim is a player
{
@@ -927,19 +930,19 @@ uint32 Unit::DealDamage(Unit* victim, uint32 damage, CleanDamage const* cleanDam
}
}
- if (GetTypeId() == TYPEID_PLAYER)
+ if (attacker && attacker->GetTypeId() == TYPEID_PLAYER)
{
// random durability for items (HIT DONE)
if (roll_chance_f(sWorld->getRate(RATE_DURABILITY_LOSS_DAMAGE)))
{
EquipmentSlots slot = EquipmentSlots(urand(0, EQUIPMENT_SLOT_END-1));
- ToPlayer()->DurabilityPointLossForEquipSlot(slot);
+ attacker->ToPlayer()->DurabilityPointLossForEquipSlot(slot);
}
}
if (damagetype != NODAMAGE)
{
- if (victim != this
+ if (victim != attacker
&& (!spellProto || !(spellProto->HasAttribute(SPELL_ATTR7_NO_PUSHBACK_ON_DAMAGE) || spellProto->HasAttribute(SPELL_ATTR3_TREAT_AS_PERIODIC))))
{
if (damagetype != DOT)
@@ -1011,8 +1014,6 @@ uint32 Unit::DealDamage(Unit* victim, uint32 damage, CleanDamage const* cleanDam
}
}
- TC_LOG_DEBUG("entities.unit", "DealDamageEnd returned %d damage", damage);
-
return damage;
}
@@ -1079,8 +1080,8 @@ void Unit::CalculateSpellDamageTaken(SpellNonMeleeDamage* damageInfo, int32 dama
// Spells with SPELL_ATTR4_FIXED_DAMAGE ignore resilience because their damage is based off another spell's damage.
if (!spellInfo->HasAttribute(SPELL_ATTR4_FIXED_DAMAGE))
{
- if (IsDamageReducedByArmor(damageSchoolMask, spellInfo))
- damage = CalcArmorReducedDamage(damageInfo->attacker, victim, damage, spellInfo, attackType);
+ if (Unit::IsDamageReducedByArmor(damageSchoolMask, spellInfo))
+ damage = Unit::CalcArmorReducedDamage(damageInfo->attacker, victim, damage, spellInfo, attackType);
bool blocked = false;
// Per-school calc
@@ -1135,7 +1136,8 @@ void Unit::CalculateSpellDamageTaken(SpellNonMeleeDamage* damageInfo, int32 dama
damage -= damageInfo->blocked;
}
- ApplyResilience(victim, &damage);
+ if (CanApplyResilience())
+ Unit::ApplyResilience(victim, &damage);
break;
}
// Magical Attacks
@@ -1146,10 +1148,11 @@ void Unit::CalculateSpellDamageTaken(SpellNonMeleeDamage* damageInfo, int32 dama
if (crit)
{
damageInfo->HitInfo |= SPELL_HIT_TYPE_CRIT;
- damage = SpellCriticalDamageBonus(spellInfo, damage, victim);
+ damage = Unit::SpellCriticalDamageBonus(this, spellInfo, damage, victim);
}
- ApplyResilience(victim, &damage);
+ if (CanApplyResilience())
+ Unit::ApplyResilience(victim, &damage);
break;
}
@@ -1168,7 +1171,7 @@ void Unit::CalculateSpellDamageTaken(SpellNonMeleeDamage* damageInfo, int32 dama
damageInfo->damage = damage;
damageInfo->originalDamage = damage;
DamageInfo dmgInfo(*damageInfo, SPELL_DIRECT_DAMAGE, BASE_ATTACK, PROC_HIT_NONE);
- CalcAbsorbResist(dmgInfo);
+ Unit::CalcAbsorbResist(dmgInfo);
damageInfo->absorb = dmgInfo.GetAbsorb();
damageInfo->resist = dmgInfo.GetResist();
@@ -1201,7 +1204,7 @@ void Unit::DealSpellDamage(SpellNonMeleeDamage const* damageInfo, bool durabilit
// Call default DealDamage
CleanDamage cleanDamage(damageInfo->cleanDamage, damageInfo->absorb, BASE_ATTACK, MELEE_HIT_NORMAL);
- DealDamage(victim, damageInfo->damage, &cleanDamage, SPELL_DIRECT_DAMAGE, SpellSchoolMask(damageInfo->schoolMask), damageInfo->Spell, durabilityLoss);
+ Unit::DealDamage(this, victim, damageInfo->damage, &cleanDamage, SPELL_DIRECT_DAMAGE, SpellSchoolMask(damageInfo->schoolMask), damageInfo->Spell, durabilityLoss);
}
/// @todo for melee need create structure as in
@@ -1266,9 +1269,9 @@ void Unit::CalculateMeleeDamage(Unit* victim, uint32 damage, CalcDamageInfo* dam
sScriptMgr->ModifyMeleeDamage(damageInfo->target, damageInfo->attacker, damage);
// Calculate armor reduction
- if (IsDamageReducedByArmor((SpellSchoolMask)(damageInfo->damageSchoolMask)))
+ if (Unit::IsDamageReducedByArmor((SpellSchoolMask)(damageInfo->damageSchoolMask)))
{
- damageInfo->damage = CalcArmorReducedDamage(damageInfo->attacker, damageInfo->target, damage, nullptr, damageInfo->attackType);
+ damageInfo->damage = Unit::CalcArmorReducedDamage(damageInfo->attacker, damageInfo->target, damage, nullptr, damageInfo->attackType);
damageInfo->cleanDamage += damage - damageInfo->damage;
}
else
@@ -1364,7 +1367,8 @@ void Unit::CalculateMeleeDamage(Unit* victim, uint32 damage, CalcDamageInfo* dam
damageInfo->HitInfo |= HITINFO_AFFECTS_VICTIM;
int32 resilienceReduction = damageInfo->damage;
- ApplyResilience(victim, &resilienceReduction);
+ if (CanApplyResilience())
+ Unit::ApplyResilience(victim, &resilienceReduction);
resilienceReduction = damageInfo->damage - resilienceReduction;
damageInfo->damage -= resilienceReduction;
damageInfo->cleanDamage += resilienceReduction;
@@ -1376,7 +1380,7 @@ void Unit::CalculateMeleeDamage(Unit* victim, uint32 damage, CalcDamageInfo* dam
damageInfo->procVictim |= PROC_FLAG_TAKEN_DAMAGE;
// Calculate absorb & resists
DamageInfo dmgInfo(*damageInfo);
- CalcAbsorbResist(dmgInfo);
+ Unit::CalcAbsorbResist(dmgInfo);
damageInfo->absorb = dmgInfo.GetAbsorb();
damageInfo->resist = dmgInfo.GetResist();
@@ -1440,7 +1444,7 @@ void Unit::DealMeleeDamage(CalcDamageInfo* damageInfo, bool durabilityLoss)
// Call default DealDamage
CleanDamage cleanDamage(damageInfo->cleanDamage, damageInfo->absorb, damageInfo->attackType, damageInfo->hitOutCome);
- DealDamage(victim, damageInfo->damage, &cleanDamage, DIRECT_DAMAGE, SpellSchoolMask(damageInfo->damageSchoolMask), nullptr, durabilityLoss);
+ Unit::DealDamage(this, victim, damageInfo->damage, &cleanDamage, DIRECT_DAMAGE, SpellSchoolMask(damageInfo->damageSchoolMask), nullptr, durabilityLoss);
// If this is a creature and it attacks from behind it has a probability to daze it's victim
if ((damageInfo->hitOutCome == MELEE_HIT_CRIT || damageInfo->hitOutCome == MELEE_HIT_CRUSHING || damageInfo->hitOutCome == MELEE_HIT_NORMAL || damageInfo->hitOutCome == MELEE_HIT_GLANCING) &&
@@ -1500,13 +1504,13 @@ void Unit::DealMeleeDamage(CalcDamageInfo* damageInfo, bool durabilityLoss)
if (Unit* caster = aurEff->GetCaster())
{
damage = caster->SpellDamageBonusDone(this, spellInfo, damage, SPELL_DIRECT_DAMAGE, aurEff->GetSpellEffectInfo());
- damage = this->SpellDamageBonusTaken(caster, spellInfo, damage, SPELL_DIRECT_DAMAGE, aurEff->GetSpellEffectInfo());
+ damage = SpellDamageBonusTaken(caster, spellInfo, damage, SPELL_DIRECT_DAMAGE, aurEff->GetSpellEffectInfo());
}
DamageInfo damageInfo(this, victim, damage, spellInfo, spellInfo->GetSchoolMask(), SPELL_DIRECT_DAMAGE, BASE_ATTACK);
victim->CalcAbsorbResist(damageInfo);
damage = damageInfo.GetDamage();
- victim->DealDamageMods(this, damage, nullptr);
+ Unit::DealDamageMods(victim, this, damage, nullptr);
WorldPackets::CombatLog::SpellDamageShield damageShield;
damageShield.Attacker = victim->GetGUID();
@@ -1518,7 +1522,7 @@ void Unit::DealMeleeDamage(CalcDamageInfo* damageInfo, bool durabilityLoss)
damageShield.SchoolMask = spellInfo->SchoolMask;
damageShield.LogAbsorbed = damageInfo.GetAbsorb();
- victim->DealDamage(this, damage, nullptr, SPELL_DIRECT_DAMAGE, spellInfo->GetSchoolMask(), spellInfo, true);
+ Unit::DealDamage(victim, this, damage, nullptr, SPELL_DIRECT_DAMAGE, spellInfo->GetSchoolMask(), spellInfo, true);
damageShield.LogData.Initialize(this);
victim->SendCombatLogMessage(&damageShield);
@@ -1539,7 +1543,7 @@ void Unit::HandleEmoteCommand(uint32 anim_id, Trinity::IteratorPair<int32 const*
SendMessageToSet(packet.Write(), true);
}
-bool Unit::IsDamageReducedByArmor(SpellSchoolMask schoolMask, SpellInfo const* spellInfo /*= nullptr*/, int8 effIndex /*= -1*/)
+/*static*/ bool Unit::IsDamageReducedByArmor(SpellSchoolMask schoolMask, SpellInfo const* spellInfo /*= nullptr*/, int8 effIndex /*= -1*/)
{
// only physical spells damage gets reduced by armor
if ((schoolMask & SPELL_SCHOOL_MASK_NORMAL) == 0)
@@ -1566,58 +1570,63 @@ bool Unit::IsDamageReducedByArmor(SpellSchoolMask schoolMask, SpellInfo const* s
return true;
}
-uint32 Unit::CalcArmorReducedDamage(Unit* attacker, Unit* victim, const uint32 damage, SpellInfo const* spellInfo, WeaponAttackType /*attackType*/) const
+/*static*/ uint32 Unit::CalcArmorReducedDamage(Unit const* attacker, Unit* victim, uint32 damage, SpellInfo const* spellInfo, uint8 attackerLevel /*= 0*/, WeaponAttackType /*attackType*/ /*= MAX_ATTACK*/)
{
float armor = float(victim->GetArmor());
- armor *= victim->GetArmorMultiplierForTarget(attacker);
+ if (attacker)
+ {
+ armor *= victim->GetArmorMultiplierForTarget(attacker);
- // bypass enemy armor by SPELL_AURA_BYPASS_ARMOR_FOR_CASTER
- int32 armorBypassPct = 0;
- AuraEffectList const & reductionAuras = victim->GetAuraEffectsByType(SPELL_AURA_BYPASS_ARMOR_FOR_CASTER);
- for (AuraEffectList::const_iterator i = reductionAuras.begin(); i != reductionAuras.end(); ++i)
- if ((*i)->GetCasterGUID() == GetGUID())
- armorBypassPct += (*i)->GetAmount();
- armor = CalculatePct(armor, 100 - std::min(armorBypassPct, 100));
+ // bypass enemy armor by SPELL_AURA_BYPASS_ARMOR_FOR_CASTER
+ int32 armorBypassPct = 0;
+ AuraEffectList const & reductionAuras = victim->GetAuraEffectsByType(SPELL_AURA_BYPASS_ARMOR_FOR_CASTER);
+ for (AuraEffectList::const_iterator i = reductionAuras.begin(); i != reductionAuras.end(); ++i)
+ if ((*i)->GetCasterGUID() == attacker->GetGUID())
+ armorBypassPct += (*i)->GetAmount();
+ armor = CalculatePct(armor, 100 - std::min(armorBypassPct, 100));
- // Ignore enemy armor by SPELL_AURA_MOD_TARGET_RESISTANCE aura
- armor += GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_TARGET_RESISTANCE, SPELL_SCHOOL_MASK_NORMAL);
+ // Ignore enemy armor by SPELL_AURA_MOD_TARGET_RESISTANCE aura
+ armor += attacker->GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_TARGET_RESISTANCE, SPELL_SCHOOL_MASK_NORMAL);
- if (spellInfo)
- if (Player* modOwner = GetSpellModOwner())
- modOwner->ApplySpellMod(spellInfo, SpellModOp::TargetResistance, armor);
+ if (spellInfo)
+ if (Player* modOwner = attacker->GetSpellModOwner())
+ modOwner->ApplySpellMod(spellInfo, SpellModOp::TargetResistance, armor);
- AuraEffectList const& resIgnoreAuras = GetAuraEffectsByType(SPELL_AURA_MOD_IGNORE_TARGET_RESIST);
- for (AuraEffectList::const_iterator j = resIgnoreAuras.begin(); j != resIgnoreAuras.end(); ++j)
- {
- if ((*j)->GetMiscValue() & SPELL_SCHOOL_MASK_NORMAL && (*j)->IsAffectingSpell(spellInfo))
- armor = std::floor(AddPct(armor, -(*j)->GetAmount()));
- }
+ AuraEffectList const& resIgnoreAuras = attacker->GetAuraEffectsByType(SPELL_AURA_MOD_IGNORE_TARGET_RESIST);
+ for (AuraEffect const* aurEff : resIgnoreAuras)
+ {
+ if (aurEff->GetMiscValue() & SPELL_SCHOOL_MASK_NORMAL && aurEff->IsAffectingSpell(spellInfo))
+ armor = std::floor(AddPct(armor, -aurEff->GetAmount()));
+ }
- // Apply Player CR_ARMOR_PENETRATION rating
- if (GetTypeId() == TYPEID_PLAYER)
- {
- float arpPct = ToPlayer()->GetRatingBonusValue(CR_ARMOR_PENETRATION);
+ // Apply Player CR_ARMOR_PENETRATION rating
+ if (attacker->GetTypeId() == TYPEID_PLAYER)
+ {
+ float arpPct = attacker->ToPlayer()->GetRatingBonusValue(CR_ARMOR_PENETRATION);
- // no more than 100%
- RoundToInterval(arpPct, 0.f, 100.f);
+ // no more than 100%
+ RoundToInterval(arpPct, 0.f, 100.f);
- float maxArmorPen = 0.f;
- if (victim->GetLevelForTarget(attacker) < 60)
- maxArmorPen = float(400 + 85 * victim->GetLevelForTarget(attacker));
- else
- maxArmorPen = 400 + 85 * victim->GetLevelForTarget(attacker) + 4.5f * 85 * (victim->GetLevelForTarget(attacker) - 59);
+ float maxArmorPen = 0.f;
+ if (victim->GetLevelForTarget(attacker) < 60)
+ maxArmorPen = float(400 + 85 * victim->GetLevelForTarget(attacker));
+ else
+ maxArmorPen = 400 + 85 * victim->GetLevelForTarget(attacker) + 4.5f * 85 * (victim->GetLevelForTarget(attacker) - 59);
- // Cap armor penetration to this number
- maxArmorPen = std::min((armor + maxArmorPen) / 3.f, armor);
- // Figure out how much armor do we ignore
- armor -= CalculatePct(maxArmorPen, arpPct);
+ // Cap armor penetration to this number
+ maxArmorPen = std::min((armor + maxArmorPen) / 3.f, armor);
+ // Figure out how much armor do we ignore
+ armor -= CalculatePct(maxArmorPen, arpPct);
+ }
}
if (G3D::fuzzyLe(armor, 0.0f))
return damage;
- uint8 attackerLevel = attacker->GetLevelForTarget(victim);
+ if (attacker)
+ attackerLevel = attacker->GetLevelForTarget(victim);
+
// Expansion and ContentTuningID necessary? Does Player get a ContentTuningID too ?
float armorConstant = sDB2Manager.EvaluateExpectedStat(ExpectedStatType::ArmorConstant, attackerLevel, -2, 0, Classes(attacker->getClass()));
@@ -1628,7 +1637,7 @@ uint32 Unit::CalcArmorReducedDamage(Unit* attacker, Unit* victim, const uint32 d
return std::max<uint32>(damage * (1.0f - mitigation), 1);
}
-uint32 Unit::CalcSpellResistedDamage(Unit* attacker, Unit* victim, uint32 damage, SpellSchoolMask schoolMask, SpellInfo const* spellInfo)
+/*static*/ uint32 Unit::CalcSpellResistedDamage(Unit const* attacker, Unit* victim, uint32 damage, SpellSchoolMask schoolMask, SpellInfo const* spellInfo)
{
// Magic damage, check for resists
if (!(schoolMask & SPELL_SCHOOL_MASK_MAGIC))
@@ -1649,8 +1658,7 @@ uint32 Unit::CalcSpellResistedDamage(Unit* attacker, Unit* victim, uint32 damage
return 0;
}
- float const averageResist = CalculateAverageResistReduction(schoolMask, victim, spellInfo);
-
+ float const averageResist = Unit::CalculateAverageResistReduction(attacker, schoolMask, victim, spellInfo);
float discreteResistProbability[11] = { };
if (averageResist <= 0.1f)
{
@@ -1677,7 +1685,8 @@ uint32 Unit::CalcSpellResistedDamage(Unit* attacker, Unit* victim, uint32 damage
{
int32 ignoredResistance = 0;
- ignoredResistance += GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_IGNORE_TARGET_RESIST, schoolMask);
+ if (attacker)
+ ignoredResistance += attacker->GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_IGNORE_TARGET_RESIST, schoolMask);
ignoredResistance = std::min<int32>(ignoredResistance, 100);
ApplyPct(damageResisted, 100 - ignoredResistance);
@@ -1685,7 +1694,7 @@ uint32 Unit::CalcSpellResistedDamage(Unit* attacker, Unit* victim, uint32 damage
// Spells with melee and magic school mask, decide whether resistance or armor absorb is higher
if (spellInfo && spellInfo->HasAttribute(SPELL_ATTR0_CU_SCHOOLMASK_NORMAL_WITH_MAGIC))
{
- uint32 damageAfterArmor = CalcArmorReducedDamage(attacker, victim, damage, spellInfo, BASE_ATTACK);
+ uint32 damageAfterArmor = Unit::CalcArmorReducedDamage(attacker, victim, damage, spellInfo, BASE_ATTACK);
float armorReduction = damage - damageAfterArmor;
// pick the lower one, the weakest resistance counts
@@ -1697,20 +1706,22 @@ uint32 Unit::CalcSpellResistedDamage(Unit* attacker, Unit* victim, uint32 damage
return uint32(damageResisted);
}
-float Unit::CalculateAverageResistReduction(SpellSchoolMask schoolMask, Unit const* victim, SpellInfo const* spellInfo) const
+/*static*/ float Unit::CalculateAverageResistReduction(Unit const* attacker, SpellSchoolMask schoolMask, Unit const* victim, SpellInfo const* spellInfo /*= nullptr*/)
{
float victimResistance = float(victim->GetResistance(schoolMask));
-
- // pets inherit 100% of masters penetration
- // excluding traps
- Player const* player = GetSpellModOwner();
- if (player && GetEntry() != WORLD_TRIGGER)
+ if (attacker)
{
- victimResistance += float(player->GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_TARGET_RESISTANCE, schoolMask));
- victimResistance -= float(player->GetSpellPenetrationItemMod());
+ // pets inherit 100% of masters penetration
+ // excluding traps
+ Player const* player = attacker->GetSpellModOwner();
+ if (player && attacker->GetEntry() != WORLD_TRIGGER)
+ {
+ victimResistance += float(player->GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_TARGET_RESISTANCE, schoolMask));
+ victimResistance -= float(player->GetSpellPenetrationItemMod());
+ }
+ else
+ victimResistance += float(attacker->GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_TARGET_RESISTANCE, schoolMask));
}
- else
- victimResistance += float(GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_TARGET_RESISTANCE, schoolMask));
// holy resistance exists in pve and comes from level difference, ignore template values
if (schoolMask & SPELL_SCHOOL_MASK_HOLY)
@@ -1723,12 +1734,12 @@ float Unit::CalculateAverageResistReduction(SpellSchoolMask schoolMask, Unit con
victimResistance = std::max(victimResistance, 0.0f);
// level-based resistance does not apply to binary spells, and cannot be overcome by spell penetration
- if (!spellInfo || !spellInfo->HasAttribute(SPELL_ATTR0_CU_BINARY_SPELL))
- victimResistance += std::max((float(victim->GetLevelForTarget(this)) - float(GetLevelForTarget(victim))) * 5.0f, 0.0f);
+ if (attacker && (!spellInfo || !spellInfo->HasAttribute(SPELL_ATTR0_CU_BINARY_SPELL)))
+ victimResistance += std::max((float(victim->GetLevelForTarget(attacker)) - float(attacker->GetLevelForTarget(victim))) * 5.0f, 0.0f);
static uint32 const bossLevel = 83;
static float const bossResistanceConstant = 510.0f;
- uint32 level = victim->GetLevelForTarget(this);
+ uint32 level = attacker ? victim->GetLevelForTarget(attacker) : victim->getLevel();
float resistanceConstant = 0.0f;
if (level == bossLevel)
@@ -1739,16 +1750,18 @@ float Unit::CalculateAverageResistReduction(SpellSchoolMask schoolMask, Unit con
return victimResistance / (victimResistance + resistanceConstant);
}
-void Unit::CalcAbsorbResist(DamageInfo& damageInfo)
+/*static*/ void Unit::CalcAbsorbResist(DamageInfo& damageInfo)
{
if (!damageInfo.GetVictim() || !damageInfo.GetVictim()->IsAlive() || !damageInfo.GetDamage())
return;
- uint32 resistedDamage = CalcSpellResistedDamage(damageInfo.GetAttacker(), damageInfo.GetVictim(), damageInfo.GetDamage(), damageInfo.GetSchoolMask(), damageInfo.GetSpellInfo());
+ uint32 resistedDamage = Unit::CalcSpellResistedDamage(damageInfo.GetAttacker(), damageInfo.GetVictim(), damageInfo.GetDamage(), damageInfo.GetSchoolMask(), damageInfo.GetSpellInfo());
damageInfo.ResistDamage(resistedDamage);
// Ignore Absorption Auras
- float auraAbsorbMod(GetMaxPositiveAuraModifierByMiscMask(SPELL_AURA_MOD_TARGET_ABSORB_SCHOOL, damageInfo.GetSchoolMask()));
+ float auraAbsorbMod = 0.f;
+ if (Unit* attacker = damageInfo.GetAttacker())
+ auraAbsorbMod = attacker->GetMaxPositiveAuraModifierByMiscMask(SPELL_AURA_MOD_TARGET_ABSORB_SCHOOL, damageInfo.GetSchoolMask());
RoundToInterval(auraAbsorbMod, 0.0f, 100.0f);
@@ -1808,7 +1821,7 @@ void Unit::CalcAbsorbResist(DamageInfo& damageInfo)
if (currentAbsorb)
{
WorldPackets::CombatLog::SpellAbsorbLog absorbLog;
- absorbLog.Attacker = damageInfo.GetAttacker()->GetGUID();
+ absorbLog.Attacker = damageInfo.GetAttacker() ? damageInfo.GetAttacker()->GetGUID() : ObjectGuid::Empty;
absorbLog.Victim = damageInfo.GetVictim()->GetGUID();
absorbLog.Caster = absorbAurEff->GetBase()->GetCasterGUID();
absorbLog.AbsorbedSpellID = damageInfo.GetSpellInfo() ? damageInfo.GetSpellInfo()->Id : 0;
@@ -1816,7 +1829,7 @@ void Unit::CalcAbsorbResist(DamageInfo& damageInfo)
absorbLog.Absorbed = currentAbsorb;
absorbLog.OriginalDamage = damageInfo.GetOriginalDamage();
absorbLog.LogData.Initialize(damageInfo.GetVictim());
- SendCombatLogMessage(&absorbLog);
+ damageInfo.GetVictim()->SendCombatLogMessage(&absorbLog);
}
}
@@ -1879,7 +1892,7 @@ void Unit::CalcAbsorbResist(DamageInfo& damageInfo)
if (currentAbsorb)
{
WorldPackets::CombatLog::SpellAbsorbLog absorbLog;
- absorbLog.Attacker = damageInfo.GetAttacker()->GetGUID();
+ absorbLog.Attacker = damageInfo.GetAttacker() ? damageInfo.GetAttacker()->GetGUID() : ObjectGuid::Empty;
absorbLog.Victim = damageInfo.GetVictim()->GetGUID();
absorbLog.Caster = absorbAurEff->GetBase()->GetCasterGUID();
absorbLog.AbsorbedSpellID = damageInfo.GetSpellInfo() ? damageInfo.GetSpellInfo()->Id : 0;
@@ -1887,14 +1900,14 @@ void Unit::CalcAbsorbResist(DamageInfo& damageInfo)
absorbLog.Absorbed = currentAbsorb;
absorbLog.OriginalDamage = damageInfo.GetOriginalDamage();
absorbLog.LogData.Initialize(damageInfo.GetVictim());
- SendCombatLogMessage(&absorbLog);
+ damageInfo.GetVictim()->SendCombatLogMessage(&absorbLog);
}
}
damageInfo.ModifyDamage(absorbIgnoringDamage);
// split damage auras - only when not damaging self
- if (damageInfo.GetVictim() != this)
+ if (damageInfo.GetVictim() != damageInfo.GetAttacker())
{
// We're going to call functions which can modify content of the list during iteration over it's elements
// Let's copy the list so we can prevent iterator invalidation
@@ -1932,23 +1945,23 @@ void Unit::CalcAbsorbResist(DamageInfo& damageInfo)
}
uint32 split_absorb = 0;
- DealDamageMods(caster, splitDamage, &split_absorb);
+ Unit::DealDamageMods(damageInfo.GetAttacker(), caster, splitDamage, &split_absorb);
- SpellNonMeleeDamage log(this, caster, (*itr)->GetSpellInfo(), (*itr)->GetBase()->GetSpellVisual(), damageInfo.GetSchoolMask(), (*itr)->GetBase()->GetCastGUID());
+ SpellNonMeleeDamage log(damageInfo.GetAttacker(), caster, (*itr)->GetSpellInfo(), (*itr)->GetBase()->GetSpellVisual(), damageInfo.GetSchoolMask(), (*itr)->GetBase()->GetCastGUID());
CleanDamage cleanDamage = CleanDamage(splitDamage, 0, BASE_ATTACK, MELEE_HIT_NORMAL);
- DealDamage(caster, splitDamage, &cleanDamage, DIRECT_DAMAGE, damageInfo.GetSchoolMask(), (*itr)->GetSpellInfo(), false);
+ Unit::DealDamage(damageInfo.GetAttacker(), caster, splitDamage, &cleanDamage, DIRECT_DAMAGE, damageInfo.GetSchoolMask(), (*itr)->GetSpellInfo(), false);
log.damage = splitDamage;
log.originalDamage = splitDamage;
log.absorb = split_absorb;
- SendSpellNonMeleeDamageLog(&log);
+ caster->SendSpellNonMeleeDamageLog(&log);
// break 'Fear' and similar auras
- ProcSkillsAndAuras(caster, PROC_FLAG_NONE, PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG, PROC_SPELL_TYPE_DAMAGE, PROC_SPELL_PHASE_HIT, PROC_HIT_NONE, nullptr, &damageInfo, nullptr);
+ Unit::ProcSkillsAndAuras(damageInfo.GetAttacker(), caster, PROC_FLAG_NONE, PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG, PROC_SPELL_TYPE_DAMAGE, PROC_SPELL_PHASE_HIT, PROC_HIT_NONE, nullptr, &damageInfo, nullptr);
}
}
}
-void Unit::CalcHealAbsorb(HealInfo& healInfo) const
+/*static*/ void Unit::CalcHealAbsorb(HealInfo& healInfo)
{
if (!healInfo.GetHeal())
return;
@@ -2061,13 +2074,13 @@ void Unit::AttackerStateUpdate(Unit* victim, WeaponAttackType attType, bool extr
CalcDamageInfo damageInfo;
CalculateMeleeDamage(victim, 0, &damageInfo, attType);
// Send log damage message to client
- DealDamageMods(victim, damageInfo.damage, &damageInfo.absorb);
+ Unit::DealDamageMods(damageInfo.attacker, victim, damageInfo.damage, &damageInfo.absorb);
SendAttackStateUpdate(&damageInfo);
DealMeleeDamage(&damageInfo, true);
DamageInfo dmgInfo(damageInfo);
- ProcSkillsAndAuras(damageInfo.target, damageInfo.procAttacker, damageInfo.procVictim, PROC_SPELL_TYPE_NONE, PROC_SPELL_PHASE_NONE, dmgInfo.GetHitMask(), nullptr, &dmgInfo, nullptr);
+ Unit::ProcSkillsAndAuras(damageInfo.attacker, damageInfo.target, damageInfo.procAttacker, damageInfo.procVictim, PROC_SPELL_TYPE_NONE, PROC_SPELL_PHASE_NONE, dmgInfo.GetHitMask(), nullptr, &dmgInfo, nullptr);
TC_LOG_DEBUG("entities.unit", "AttackerStateUpdate: %s attacked %s for %u dmg, absorbed %u, blocked %u, resisted %u.",
GetGUID().ToString().c_str(), victim->GetGUID().ToString().c_str(), damageInfo.damage, damageInfo.absorb, damageInfo.blocked_amount, damageInfo.resist);
@@ -2150,7 +2163,7 @@ MeleeHitOutcome Unit::RollMeleeOutcomeAgainst(Unit const* victim, WeaponAttackTy
int32 miss_chance = int32(MeleeSpellMissChance(victim, attType, nullptr) * 100.0f);
// Critical hit chance
- int32 crit_chance = int32(GetUnitCriticalChance(attType, victim) + GetTotalAuraModifier(SPELL_AURA_MOD_AUTOATTACK_CRIT_CHANCE) * 100.0f);
+ int32 crit_chance = int32((GetUnitCriticalChanceAgainst(attType, victim) + GetTotalAuraModifier(SPELL_AURA_MOD_AUTOATTACK_CRIT_CHANCE)) * 100.0f);
int32 dodge_chance = int32(GetUnitDodgeChance(attType, victim) * 100.0f);
int32 block_chance = int32(GetUnitBlockChance(attType, victim) * 100.0f);
@@ -2781,7 +2794,7 @@ float Unit::GetUnitBlockChance(WeaponAttackType /*attType*/, Unit const* victim)
return std::max(chance, 0.0f);
}
-float Unit::GetUnitCriticalChance(WeaponAttackType attackType, Unit const* victim) const
+float Unit::GetUnitCriticalChanceDone(WeaponAttackType attackType) const
{
float chance = 0.0f;
if (Player const* thisPlayer = ToPlayer())
@@ -2813,35 +2826,48 @@ float Unit::GetUnitCriticalChance(WeaponAttackType attackType, Unit const* victi
}
}
+ return chance;
+}
+
+float Unit::GetUnitCriticalChanceTaken(Unit const* attacker, WeaponAttackType attackType, float critDone) const
+{
+ float chance = critDone;
+
// flat aura mods
if (attackType == RANGED_ATTACK)
- chance += victim->GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_RANGED_CRIT_CHANCE);
+ chance += GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_RANGED_CRIT_CHANCE);
else
- chance += victim->GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_CHANCE);
+ chance += GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_CHANCE);
- chance += GetTotalAuraModifier(SPELL_AURA_MOD_CRIT_CHANCE_VERSUS_TARGET_HEALTH, [victim](AuraEffect const* aurEff)
+ chance += GetTotalAuraModifier(SPELL_AURA_MOD_CRIT_CHANCE_VERSUS_TARGET_HEALTH, [this](AuraEffect const* aurEff)
{
- return !victim->HealthBelowPct(aurEff->GetMiscValueB());
+ return !HealthBelowPct(aurEff->GetMiscValueB());
});
- chance += victim->GetTotalAuraModifier(SPELL_AURA_MOD_CRIT_CHANCE_FOR_CASTER, [this](AuraEffect const* aurEff) -> bool
+ chance += GetTotalAuraModifier(SPELL_AURA_MOD_CRIT_CHANCE_FOR_CASTER, [attacker](AuraEffect const* aurEff) -> bool
{
- return aurEff->GetCasterGUID() == GetGUID();
+ return aurEff->GetCasterGUID() == attacker->GetGUID();
});
- if (TempSummon const* tempSummon = ToTempSummon())
+ if (TempSummon const* tempSummon = attacker->ToTempSummon())
{
- chance += victim->GetTotalAuraModifier(SPELL_AURA_MOD_CRIT_CHANCE_FOR_CASTER_PET, [tempSummon](AuraEffect const* aurEff) -> bool
+ chance += GetTotalAuraModifier(SPELL_AURA_MOD_CRIT_CHANCE_FOR_CASTER_PET, [tempSummon](AuraEffect const* aurEff) -> bool
{
return aurEff->GetCasterGUID() == tempSummon->GetSummonerGUID();
});
}
- chance += victim->GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_SPELL_AND_WEAPON_CRIT_CHANCE);
+ chance += GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_SPELL_AND_WEAPON_CRIT_CHANCE);
return std::max(chance, 0.0f);
}
+float Unit::GetUnitCriticalChanceAgainst(WeaponAttackType attackType, Unit const* victim) const
+{
+ float chance = GetUnitCriticalChanceDone(attackType);
+ return victim->GetUnitCriticalChanceTaken(this, attackType, chance);
+}
+
void Unit::_DeleteRemovedAuras()
{
while (!m_removedAuras.empty())
@@ -3416,7 +3442,6 @@ void Unit::_ApplyAura(AuraApplication * aurApp, uint32 effMask)
if (aurApp->GetRemoveMode())
return;
- aura->HandleAuraSpecificPeriodics(aurApp, caster);
aura->HandleAuraSpecificMods(aurApp, caster, true, false);
// apply effects of the aura
@@ -5312,16 +5337,17 @@ void Unit::SendSpellNonMeleeDamageLog(SpellNonMeleeDamage const* log)
SendCombatLogMessage(&packet);
}
-void Unit::ProcSkillsAndAuras(Unit* actionTarget, uint32 typeMaskActor, uint32 typeMaskActionTarget, uint32 spellTypeMask, uint32 spellPhaseMask, uint32 hitMask, Spell* spell, DamageInfo* damageInfo, HealInfo* healInfo)
+/*static*/ void Unit::ProcSkillsAndAuras(Unit* actor, Unit* actionTarget, uint32 typeMaskActor, uint32 typeMaskActionTarget, uint32 spellTypeMask, uint32 spellPhaseMask, uint32 hitMask, Spell* spell, DamageInfo* damageInfo, HealInfo* healInfo)
{
WeaponAttackType attType = damageInfo ? damageInfo->GetAttackType() : BASE_ATTACK;
- if (typeMaskActor)
- ProcSkillsAndReactives(false, actionTarget, typeMaskActor, hitMask, attType);
+ if (typeMaskActor && actor)
+ actor->ProcSkillsAndReactives(false, actionTarget, typeMaskActor, hitMask, attType);
if (typeMaskActionTarget && actionTarget)
- actionTarget->ProcSkillsAndReactives(true, this, typeMaskActionTarget, hitMask, attType);
+ actionTarget->ProcSkillsAndReactives(true, actor, typeMaskActionTarget, hitMask, attType);
- TriggerAurasProcOnEvent(nullptr, nullptr, actionTarget, typeMaskActor, typeMaskActionTarget, spellTypeMask, spellPhaseMask, hitMask, spell, damageInfo, healInfo);
+ if (actor)
+ actor->TriggerAurasProcOnEvent(nullptr, nullptr, actionTarget, typeMaskActor, typeMaskActionTarget, spellTypeMask, spellPhaseMask, hitMask, spell, damageInfo, healInfo);
}
void Unit::SendPeriodicAuraLog(SpellPeriodicAuraLogInfo* info)
@@ -6431,39 +6457,45 @@ void Unit::SetCharm(Unit* charm, bool apply)
UpdatePetCombatState();
}
-void Unit::DealHeal(HealInfo& healInfo)
+/*static*/ void Unit::DealHeal(HealInfo& healInfo)
{
int32 gain = 0;
+ Unit* healer = healInfo.GetHealer();
Unit* victim = healInfo.GetTarget();
uint32 addhealth = healInfo.GetHeal();
- if (victim->IsAIEnabled)
- victim->GetAI()->HealReceived(this, addhealth);
+ if (healer)
+ {
+ if (victim->IsAIEnabled)
+ victim->GetAI()->HealReceived(healer, addhealth);
- if (IsAIEnabled)
- GetAI()->HealDone(victim, addhealth);
+ if (healer->IsAIEnabled)
+ healer->GetAI()->HealDone(victim, addhealth);
+ }
if (addhealth)
gain = victim->ModifyHealth(int32(addhealth));
// Hook for OnHeal Event
- sScriptMgr->OnHeal(this, victim, (uint32&)gain);
-
- Unit* unit = this;
+ sScriptMgr->OnHeal(healer, victim, (uint32&)gain);
- if (GetTypeId() == TYPEID_UNIT && IsTotem())
- unit = GetOwner();
+ Unit* unit = healer;
+ if (healer && healer->GetTypeId() == TYPEID_UNIT && healer->IsTotem())
+ unit = healer->GetOwner();
- if (Player* player = unit->ToPlayer())
+ if (unit)
{
- if (Battleground* bg = player->GetBattleground())
- bg->UpdatePlayerScore(player, SCORE_HEALING_DONE, gain);
+ if (Player* player = unit->ToPlayer())
+ {
+ if (Battleground* bg = player->GetBattleground())
+ bg->UpdatePlayerScore(player, SCORE_HEALING_DONE, gain);
- // use the actual gain, as the overheal shall not be counted, skip gain 0 (it ignored anyway in to criteria)
- if (gain)
- player->UpdateCriteria(CRITERIA_TYPE_HEALING_DONE, gain, 0, 0, victim);
+ // use the actual gain, as the overheal shall not be counted, skip gain 0 (it ignored anyway in to criteria)
+ if (gain)
+ player->UpdateCriteria(CRITERIA_TYPE_HEALING_DONE, gain, 0, 0, victim);
- player->UpdateCriteria(CRITERIA_TYPE_HIGHEST_HEAL_CAST, addhealth);
+ player->UpdateCriteria(CRITERIA_TYPE_HIGHEST_HEAL_CAST, addhealth);
+ }
}
if (Player* player = victim->ToPlayer())
@@ -6718,9 +6750,8 @@ void Unit::SendHealSpellLog(HealInfo& healInfo, bool critical /*= false*/)
int32 Unit::HealBySpell(HealInfo& healInfo, bool critical /*= false*/)
{
// calculate heal absorb and reduce healing
- CalcHealAbsorb(healInfo);
-
- DealHeal(healInfo);
+ Unit::CalcHealAbsorb(healInfo);
+ Unit::DealHeal(healInfo);
SendHealSpellLog(healInfo, critical);
return healInfo.GetEffectiveHeal();
}
@@ -6746,7 +6777,7 @@ void Unit::EnergizeBySpell(Unit* victim, SpellInfo const* spellInfo, int32 damag
SendEnergizeSpellLog(victim, spellInfo->Id, gain, overEnergize, powerType);
}
-uint32 Unit::SpellDamageBonusDone(Unit* victim, SpellInfo const* spellProto, uint32 pdamage, DamageEffectType damagetype, SpellEffectInfo const* effect, uint32 stack) const
+uint32 Unit::SpellDamageBonusDone(Unit* victim, SpellInfo const* spellProto, uint32 pdamage, DamageEffectType damagetype, SpellEffectInfo const* effect, uint32 stack /*= 1*/) const
{
if (!spellProto || !victim || damagetype == DIRECT_DAMAGE)
return pdamage;
@@ -6761,6 +6792,7 @@ uint32 Unit::SpellDamageBonusDone(Unit* victim, SpellInfo const* spellProto, uin
return owner->SpellDamageBonusDone(victim, spellProto, pdamage, damagetype, effect, stack);
int32 DoneTotal = 0;
+ float DoneTotalMod = SpellDamagePctDone(victim, spellProto, damagetype);
// Done fixed damage bonus auras
int32 DoneAdvertisedBenefit = SpellBaseDamageBonusDone(spellProto->GetSchoolMask());
@@ -6808,16 +6840,11 @@ uint32 Unit::SpellDamageBonusDone(Unit* victim, SpellInfo const* spellProto, uin
DoneTotal += int32(DoneAdvertisedBenefit * coeff * stack);
}
- // Done Percentage for DOT is already calculated, no need to do it again. The percentage mod is applied in Aura::HandleAuraSpecificMods.
- float tmpDamage = (int32(pdamage) + DoneTotal) * (damagetype == DOT ? 1.0f : SpellDamagePctDone(victim, spellProto, damagetype));
+ float tmpDamage = float(int32(pdamage) + DoneTotal) * DoneTotalMod;
+
// apply spellmod to Done damage (flat and pct)
if (Player* modOwner = GetSpellModOwner())
- {
- if (damagetype == DOT)
- modOwner->ApplySpellMod(spellProto, SpellModOp::PeriodicHealingAndDamage, tmpDamage);
- else
- modOwner->ApplySpellMod(spellProto, SpellModOp::HealingAndDamage, tmpDamage);
- }
+ modOwner->ApplySpellMod(spellProto, damagetype == DOT ? SpellModOp::PeriodicHealingAndDamage : SpellModOp::HealingAndDamage, tmpDamage);
return uint32(std::max(tmpDamage, 0.0f));
}
@@ -6827,13 +6854,18 @@ float Unit::SpellDamagePctDone(Unit* victim, SpellInfo const* spellProto, Damage
if (!spellProto || !victim || damagetype == DIRECT_DAMAGE)
return 1.0f;
+ // Some spells don't benefit from done mods
+ if (spellProto->HasAttribute(SPELL_ATTR3_NO_DONE_BONUS))
+ return 1.0f;
+
// Some spells don't benefit from pct done mods
if (spellProto->HasAttribute(SPELL_ATTR6_IGNORE_CASTER_DAMAGE_MODIFIERS))
return 1.0f;
- // For totems pct done mods are calculated when its calculation is run on the player in SpellDamageBonusDone.
+ // For totems get damage bonus from owner
if (GetTypeId() == TYPEID_UNIT && IsTotem())
- return 1.0f;
+ if (Unit* owner = GetOwner())
+ return owner->SpellDamagePctDone(victim, spellProto, damagetype);
// Done total percent damage auras
float DoneTotalMod = 1.0f;
@@ -7040,41 +7072,19 @@ int32 Unit::SpellBaseDamageBonusTaken(SpellSchoolMask schoolMask) const
return GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_DAMAGE_TAKEN, schoolMask);
}
-bool Unit::IsSpellCrit(Unit* victim, Spell* spell, AuraEffect const* aurEff, SpellSchoolMask schoolMask, WeaponAttackType attackType /*= BASE_ATTACK*/) const
-{
- return roll_chance_f(GetUnitSpellCriticalChance(victim, spell, aurEff, schoolMask, attackType));
-}
-
-float Unit::GetUnitSpellCriticalChance(Unit* victim, Spell* spell, AuraEffect const* aurEff, SpellSchoolMask schoolMask, WeaponAttackType attackType /*= BASE_ATTACK*/) const
+float Unit::SpellCritChanceDone(SpellInfo const* spellInfo, SpellSchoolMask schoolMask, WeaponAttackType attackType /*= BASE_ATTACK*/) const
{
- SpellInfo const* spellProto = spell ? spell->GetSpellInfo() : aurEff->GetSpellInfo();
- //! Mobs can't crit with spells. Player Totems can
- //! Fire Elemental (from totem) can too - but this part is a hack and needs more research
- if (GetGUID().IsCreatureOrVehicle() && !(IsTotem() && GetOwnerGUID().IsPlayer()) && GetEntry() != 15438)
+ //! Mobs can't crit with spells. (Except player controlled)
+ if (GetTypeId() == TYPEID_UNIT && !GetSpellModOwner())
return 0.0f;
// not critting spell
- if ((spellProto->HasAttribute(SPELL_ATTR2_CANT_CRIT)))
+ if (spellInfo->HasAttribute(SPELL_ATTR2_CANT_CRIT))
return 0.0f;
float crit_chance = 0.0f;
- switch (spellProto->DmgClass)
+ switch (spellInfo->DmgClass)
{
- case SPELL_DAMAGE_CLASS_NONE:
- // We need more spells to find a general way (if there is any)
- switch (spellProto->Id)
- {
- case 379: // Earth Shield
- case 33778: // Lifebloom Final Bloom
- case 64844: // Divine Hymn
- case 71607: // Item - Bauble of True Blood 10m
- case 71646: // Item - Bauble of True Blood 25m
- break;
- default:
- return 0.0f;
- }
- // Do not add a break here, case fallthrough is intentional! Adding a break will make above spells unable to crit.
- /* fallthrough */
case SPELL_DAMAGE_CLASS_MAGIC:
{
if (schoolMask & SPELL_SCHOOL_MASK_NORMAL)
@@ -7084,25 +7094,58 @@ float Unit::GetUnitSpellCriticalChance(Unit* victim, Spell* spell, AuraEffect co
crit_chance = thisPlayer->m_activePlayerData->SpellCritPercentage;
else
crit_chance = (float)m_baseSpellCritChance;
+ break;
+ }
+ case SPELL_DAMAGE_CLASS_MELEE:
+ case SPELL_DAMAGE_CLASS_RANGED:
+ {
+ crit_chance += GetUnitCriticalChanceDone(attackType);
+ break;
+ }
+ case SPELL_DAMAGE_CLASS_NONE:
+ default:
+ return 0.0f;
+ }
+ // percent done
+ // only players use intelligence for critical chance computations
+ if (Player* modOwner = GetSpellModOwner())
+ modOwner->ApplySpellMod(spellInfo, SpellModOp::CritChance, crit_chance);
+
+ return std::max(crit_chance, 0.0f);
+}
+
+float Unit::SpellCritChanceTaken(Unit const* caster, Spell* spell, AuraEffect const* aurEff, SpellSchoolMask /*schoolMask*/, float doneChance, WeaponAttackType attackType /*= BASE_ATTACK*/) const
+{
+ SpellInfo const* spellInfo = spell ? spell->GetSpellInfo() : aurEff->GetSpellInfo();
+ // not critting spell
+ if (spellInfo->HasAttribute(SPELL_ATTR2_CANT_CRIT))
+ return 0.0f;
+
+ float crit_chance = doneChance;
+ switch (spellInfo->DmgClass)
+ {
+ case SPELL_DAMAGE_CLASS_MAGIC:
+ {
// taken
- if (victim)
+ if (!spellInfo->IsPositive())
+ {
+ // Modify critical chance by victim SPELL_AURA_MOD_ATTACKER_SPELL_AND_WEAPON_CRIT_CHANCE
+ crit_chance += GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_SPELL_AND_WEAPON_CRIT_CHANCE);
+ }
+
+ if (caster)
{
- if (!spellProto->IsPositive())
- {
- // Modify critical chance by victim SPELL_AURA_MOD_ATTACKER_SPELL_AND_WEAPON_CRIT_CHANCE
- crit_chance += victim->GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_SPELL_AND_WEAPON_CRIT_CHANCE);
- }
// scripted (increase crit chance ... against ... target by x%
- AuraEffectList const& mOverrideClassScript = GetAuraEffectsByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
+ AuraEffectList const& mOverrideClassScript = caster->GetAuraEffectsByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
for (AuraEffect const* aurEff : mOverrideClassScript)
{
- if (!aurEff->IsAffectingSpell(spellProto))
+ if (!aurEff->IsAffectingSpell(spellInfo))
continue;
switch (aurEff->GetMiscValue())
{
case 911: // Shatter
- if (victim->HasAuraState(AURA_STATE_FROZEN, spellProto, this))
+ if (HasAuraState(AURA_STATE_FROZEN, spellInfo, caster))
{
crit_chance *= 1.5f;
if (AuraEffect const* eff = aurEff->GetBase()->GetEffect(EFFECT_1))
@@ -7114,19 +7157,19 @@ float Unit::GetUnitSpellCriticalChance(Unit* victim, Spell* spell, AuraEffect co
}
}
// Custom crit by class
- switch (spellProto->SpellFamilyName)
+ switch (spellInfo->SpellFamilyName)
{
case SPELLFAMILY_ROGUE:
// Shiv-applied poisons can't crit
- if (FindCurrentSpellBySpellId(5938))
+ if (caster->FindCurrentSpellBySpellId(5938))
crit_chance = 0.0f;
break;
case SPELLFAMILY_SHAMAN:
// Lava Burst
- if (spellProto->SpellFamilyFlags[1] & 0x00001000)
+ if (spellInfo->SpellFamilyFlags[1] & 0x00001000)
{
- if (victim->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_SHAMAN, flag128(0x10000000, 0, 0), GetGUID()))
- if (victim->GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_SPELL_AND_WEAPON_CRIT_CHANCE) > -100)
+ if (GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_SHAMAN, flag128(0x10000000, 0, 0), caster->GetGUID()))
+ if (GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_SPELL_AND_WEAPON_CRIT_CHANCE) > -100)
return 100.0f;
break;
}
@@ -7134,48 +7177,44 @@ float Unit::GetUnitSpellCriticalChance(Unit* victim, Spell* spell, AuraEffect co
}
// Spell crit suppression
- if (victim->GetTypeId() == TYPEID_UNIT)
+ if (GetTypeId() == TYPEID_UNIT)
{
- int32 const levelDiff = static_cast<int32>(victim->GetLevelForTarget(this)) - getLevel();
+ int32 const levelDiff = static_cast<int32>(GetLevelForTarget(caster)) - caster->getLevel();
crit_chance -= levelDiff * 1.0f;
}
}
break;
}
case SPELL_DAMAGE_CLASS_MELEE:
+
/// Intentional fallback. Calculate critical strike chance for both Ranged and Melee spells
case SPELL_DAMAGE_CLASS_RANGED:
- {
- if (victim)
- crit_chance += GetUnitCriticalChance(attackType, victim);
+ if (caster)
+ crit_chance = GetUnitCriticalChanceTaken(caster, attackType, crit_chance);
break;
- }
+ case SPELL_DAMAGE_CLASS_NONE:
default:
- return 0.0f;
+ return 0.f;
}
- // percent done
- // only players use intelligence for critical chance computations
- if (Player* modOwner = GetSpellModOwner())
- modOwner->ApplySpellMod(spellProto, SpellModOp::CritChance, crit_chance);
// for this types the bonus was already added in GetUnitCriticalChance, do not add twice
- if (spellProto->DmgClass != SPELL_DAMAGE_CLASS_MELEE && spellProto->DmgClass != SPELL_DAMAGE_CLASS_RANGED)
+ if (caster && spellInfo->DmgClass != SPELL_DAMAGE_CLASS_MELEE && spellInfo->DmgClass != SPELL_DAMAGE_CLASS_RANGED)
{
- crit_chance += victim->GetTotalAuraModifier(SPELL_AURA_MOD_CRIT_CHANCE_FOR_CASTER_WITH_ABILITIES, [this, spellProto](AuraEffect const* aurEff) -> bool
+ crit_chance += GetTotalAuraModifier(SPELL_AURA_MOD_CRIT_CHANCE_FOR_CASTER_WITH_ABILITIES, [caster, spellInfo](AuraEffect const* aurEff) -> bool
{
- return aurEff->GetCasterGUID() == GetGUID() && aurEff->IsAffectingSpell(spellProto);
+ return aurEff->GetCasterGUID() == caster->GetGUID() && aurEff->IsAffectingSpell(spellInfo);
});
- crit_chance += victim->GetTotalAuraModifier(SPELL_AURA_MOD_CRIT_CHANCE_FOR_CASTER, [this](AuraEffect const* aurEff) -> bool
+ crit_chance += GetTotalAuraModifier(SPELL_AURA_MOD_CRIT_CHANCE_FOR_CASTER, [caster](AuraEffect const* aurEff) -> bool
{
- return aurEff->GetCasterGUID() != GetGUID();
+ return aurEff->GetCasterGUID() == caster->GetGUID();
});
- crit_chance += GetTotalAuraModifier(SPELL_AURA_MOD_CRIT_CHANCE_VERSUS_TARGET_HEALTH, [victim](AuraEffect const* aurEff)
+ crit_chance += caster->GetTotalAuraModifier(SPELL_AURA_MOD_CRIT_CHANCE_VERSUS_TARGET_HEALTH, [this](AuraEffect const* aurEff)
{
- return !victim->HealthBelowPct(aurEff->GetMiscValueB());
+ return !HealthBelowPct(aurEff->GetMiscValueB());
});
- if (TempSummon const* tempSummon = ToTempSummon())
+ if (TempSummon const* tempSummon = caster->ToTempSummon())
{
- crit_chance += victim->GetTotalAuraModifier(SPELL_AURA_MOD_CRIT_CHANCE_FOR_CASTER_PET, [tempSummon](AuraEffect const* aurEff) -> bool
+ crit_chance += GetTotalAuraModifier(SPELL_AURA_MOD_CRIT_CHANCE_FOR_CASTER_PET, [tempSummon](AuraEffect const* aurEff) -> bool
{
return aurEff->GetCasterGUID() == tempSummon->GetSummonerGUID();
});
@@ -7184,57 +7223,62 @@ float Unit::GetUnitSpellCriticalChance(Unit* victim, Spell* spell, AuraEffect co
// call script handlers
if (spell)
- spell->CallScriptCalcCritChanceHandlers(victim, crit_chance);
+ spell->CallScriptCalcCritChanceHandlers(this, crit_chance);
else
- aurEff->GetBase()->CallScriptEffectCalcCritChanceHandlers(aurEff, aurEff->GetBase()->GetApplicationOfTarget(victim->GetGUID()), victim, crit_chance);
+ aurEff->GetBase()->CallScriptEffectCalcCritChanceHandlers(aurEff, aurEff->GetBase()->GetApplicationOfTarget(GetGUID()), this, crit_chance);
return std::max(crit_chance, 0.0f);
}
-uint32 Unit::SpellCriticalDamageBonus(SpellInfo const* spellProto, uint32 damage, Unit* victim)
+/*static*/ uint32 Unit::SpellCriticalDamageBonus(Unit const* caster, SpellInfo const* spellProto, uint32 damage, Unit* victim)
{
// Calculate critical bonus
int32 crit_bonus = damage * 2;
float crit_mod = 0.0f;
- crit_mod += (GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_CRIT_DAMAGE_BONUS, spellProto->GetSchoolMask()) - 1.0f) * 100;
+ if (caster)
+ {
+ crit_mod += (caster->GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_CRIT_DAMAGE_BONUS, spellProto->GetSchoolMask()) - 1.0f) * 100;
- if (crit_bonus != 0)
- AddPct(crit_bonus, crit_mod);
+ if (crit_bonus != 0)
+ AddPct(crit_bonus, crit_mod);
- AddPct(crit_bonus, victim->GetTotalAuraModifier(SPELL_AURA_MOD_CRITICAL_DAMAGE_TAKEN_FROM_CASTER, [&](AuraEffect const* aurEff)
- {
- return aurEff->GetCasterGUID() == GetGUID();
- }));
+ AddPct(crit_bonus, victim->GetTotalAuraModifier(SPELL_AURA_MOD_CRITICAL_DAMAGE_TAKEN_FROM_CASTER, [&](AuraEffect const* aurEff)
+ {
+ return aurEff->GetCasterGUID() == caster->GetGUID();
+ }));
- crit_bonus -= damage;
+ crit_bonus -= damage;
- // adds additional damage to critBonus (from talents)
- if (Player* modOwner = GetSpellModOwner())
- modOwner->ApplySpellMod(spellProto, SpellModOp::CritDamageAndHealing, crit_bonus);
+ // adds additional damage to critBonus (from talents)
+ if (Player* modOwner = caster->GetSpellModOwner())
+ modOwner->ApplySpellMod(spellProto, SpellModOp::CritDamageAndHealing, crit_bonus);
- crit_bonus += damage;
+ crit_bonus += damage;
+ }
return crit_bonus;
}
-uint32 Unit::SpellCriticalHealingBonus(SpellInfo const* spellProto, uint32 damage, Unit* /*victim*/)
+/*static*/ uint32 Unit::SpellCriticalHealingBonus(Unit const* caster, SpellInfo const* spellProto, uint32 damage, Unit* /*victim*/)
{
// Calculate critical bonus
int32 crit_bonus = damage;
// adds additional damage to critBonus (from talents)
- if (Player* modOwner = GetSpellModOwner())
- modOwner->ApplySpellMod(spellProto, SpellModOp::CritDamageAndHealing, crit_bonus);
+ if (caster)
+ if (Player* modOwner = caster->GetSpellModOwner())
+ modOwner->ApplySpellMod(spellProto, SpellModOp::CritDamageAndHealing, crit_bonus);
damage += crit_bonus;
- damage = int32(float(damage) * GetTotalAuraMultiplier(SPELL_AURA_MOD_CRITICAL_HEALING_AMOUNT));
+ if (caster)
+ damage = int32(float(damage) * caster->GetTotalAuraMultiplier(SPELL_AURA_MOD_CRITICAL_HEALING_AMOUNT));
return damage;
}
-uint32 Unit::SpellHealingBonusDone(Unit* victim, SpellInfo const* spellProto, uint32 healamount, DamageEffectType damagetype, SpellEffectInfo const* spellEffect, uint32 stack) const
+uint32 Unit::SpellHealingBonusDone(Unit* victim, SpellInfo const* spellProto, uint32 healamount, DamageEffectType damagetype, SpellEffectInfo const* spellEffect, uint32 stack /*= 1*/) const
{
// For totems get healing bonus from owner (statue isn't totem in fact)
if (GetTypeId() == TYPEID_UNIT && IsTotem())
@@ -7246,18 +7290,20 @@ uint32 Unit::SpellHealingBonusDone(Unit* victim, SpellInfo const* spellProto, ui
return healamount;
int32 DoneTotal = 0;
+ float DoneTotalMod = SpellHealingPctDone(victim, spellProto);
// done scripted mod (take it from owner)
Unit const* owner = GetOwner() ? GetOwner() : this;
AuraEffectList const& mOverrideClassScript= owner->GetAuraEffectsByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
- for (AuraEffectList::const_iterator i = mOverrideClassScript.begin(); i != mOverrideClassScript.end(); ++i)
+ for (AuraEffect const* aurEff : mOverrideClassScript)
{
- if (!(*i)->IsAffectingSpell(spellProto))
+ if (!aurEff->IsAffectingSpell(spellProto))
continue;
- switch ((*i)->GetMiscValue())
+
+ switch (aurEff->GetMiscValue())
{
case 3736: // Hateful Totem of the Third Wind / Increased Lesser Healing Wave / LK Arena (4/5/6) Totem of the Third Wind / Savage Totem of the Third Wind
- DoneTotal += (*i)->GetAmount();
+ DoneTotal += aurEff->GetAmount();
break;
default:
break;
@@ -7310,24 +7356,28 @@ uint32 Unit::SpellHealingBonusDone(Unit* victim, SpellInfo const* spellProto, ui
DoneTotal = 0;
}
- // Done Percentage for DOT is already calculated, no need to do it again. The percentage mod is applied in Aura::HandleAuraSpecificMods.
- float heal = float(int32(healamount) + DoneTotal) * (damagetype == DOT ? 1.0f : SpellHealingPctDone(victim, spellProto));
+ float heal = float(int32(healamount) + DoneTotal) * DoneTotalMod;
+
// apply spellmod to Done amount
if (Player* modOwner = GetSpellModOwner())
- {
- if (damagetype == DOT)
- modOwner->ApplySpellMod(spellProto, SpellModOp::PeriodicHealingAndDamage, heal);
- else
- modOwner->ApplySpellMod(spellProto, SpellModOp::HealingAndDamage, heal);
- }
+ modOwner->ApplySpellMod(spellProto, damagetype == DOT ? SpellModOp::PeriodicHealingAndDamage : SpellModOp::HealingAndDamage, heal);
return uint32(std::max(heal, 0.0f));
}
float Unit::SpellHealingPctDone(Unit* victim, SpellInfo const* spellProto) const
{
- // For totems pct done mods are calculated when its calculation is run on the player in SpellHealingBonusDone.
+ // For totems get healing bonus from owner
if (GetTypeId() == TYPEID_UNIT && IsTotem())
+ if (Unit* owner = GetOwner())
+ return owner->SpellHealingPctDone(victim, spellProto);
+
+ // Some spells don't benefit from done mods
+ if (spellProto->HasAttribute(SPELL_ATTR3_NO_DONE_BONUS))
+ return 1.0f;
+
+ // Some spells don't benefit from done mods
+ if (spellProto->HasAttribute(SPELL_ATTR6_IGNORE_HEALING_MODIFIERS))
return 1.0f;
// No bonus healing for potion spells
@@ -8947,7 +8997,7 @@ void Unit::AtEnterCombat()
InterruptNonMeleeSpells(false);
RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags::EnteringCombat);
- ProcSkillsAndAuras(nullptr, PROC_FLAG_ENTER_COMBAT, PROC_FLAG_NONE, PROC_SPELL_TYPE_MASK_ALL, PROC_SPELL_PHASE_NONE, PROC_HIT_NONE, nullptr, nullptr, nullptr);
+ Unit::ProcSkillsAndAuras(this, nullptr, PROC_FLAG_ENTER_COMBAT, PROC_FLAG_NONE, PROC_SPELL_TYPE_MASK_ALL, PROC_SPELL_PHASE_NONE, PROC_HIT_NONE, nullptr, nullptr, nullptr);
}
void Unit::AtExitCombat()
@@ -11307,14 +11357,20 @@ void Unit::SetMeleeAnimKitId(uint16 animKitId)
SendMessageToSet(data.Write(), true);
}
-void Unit::Kill(Unit* victim, bool durabilityLoss /*= true*/, bool skipSettingDeathState /*= false*/)
+/*static*/ void Unit::Kill(Unit* attacker, Unit* victim, bool durabilityLoss /*= true*/, bool skipSettingDeathState /*= false*/)
{
// Prevent killing unit twice (and giving reward from kill twice)
if (!victim->GetHealth())
return;
+ if (attacker && !attacker->IsInMap(victim))
+ attacker = nullptr;
+
// find player: owner of controlled `this` or `this` itself maybe
- Player* player = GetCharmerOrOwnerPlayerOrPlayerItself();
+ Player* player = nullptr;
+ if (attacker)
+ player = attacker->GetCharmerOrOwnerPlayerOrPlayerItself();
+
Creature* creature = victim->ToCreature();
bool isRewardAllowed = true;
@@ -11382,7 +11438,7 @@ void Unit::Kill(Unit* victim, bool durabilityLoss /*= true*/, bool skipSettingDe
Loot* loot = &creature->loot;
loot->clear();
if (uint32 lootid = creature->GetCreatureTemplate()->lootid)
- loot->FillLoot(lootid, LootTemplates_Creature, looter, false, false, creature->GetLootMode(), GetMap()->GetDifficultyLootItemContext());
+ loot->FillLoot(lootid, LootTemplates_Creature, looter, false, false, creature->GetLootMode(), creature->GetMap()->GetDifficultyLootItemContext());
if (creature->GetLootMode() > 0)
loot->generateMoneyLoot(creature->GetCreatureTemplate()->mingold, creature->GetCreatureTemplate()->maxgold);
@@ -11404,23 +11460,24 @@ void Unit::Kill(Unit* victim, bool durabilityLoss /*= true*/, bool skipSettingDe
}
// Do KILL and KILLED procs. KILL proc is called only for the unit who landed the killing blow (and its owner - for pets and totems) regardless of who tapped the victim
- if (IsPet() || IsTotem())
+ if (attacker && (attacker->IsPet() || attacker->IsTotem()))
{
// proc only once for victim
- if (Unit* owner = GetOwner())
- owner->ProcSkillsAndAuras(victim, PROC_FLAG_KILL, PROC_FLAG_NONE, PROC_SPELL_TYPE_MASK_ALL, PROC_SPELL_PHASE_NONE, PROC_HIT_NONE, nullptr, nullptr, nullptr);
+ if (Unit* owner = attacker->GetOwner())
+ Unit::ProcSkillsAndAuras(owner, victim, PROC_FLAG_KILL, PROC_FLAG_NONE, PROC_SPELL_TYPE_MASK_ALL, PROC_SPELL_PHASE_NONE, PROC_HIT_NONE, nullptr, nullptr, nullptr);
}
if (!victim->IsCritter())
- ProcSkillsAndAuras(victim, PROC_FLAG_KILL, PROC_FLAG_KILLED, PROC_SPELL_TYPE_MASK_ALL, PROC_SPELL_PHASE_NONE, PROC_HIT_NONE, nullptr, nullptr, nullptr);
+ Unit::ProcSkillsAndAuras(attacker, victim, PROC_FLAG_KILL, PROC_FLAG_KILLED, PROC_SPELL_TYPE_MASK_ALL, PROC_SPELL_PHASE_NONE, PROC_HIT_NONE, nullptr, nullptr, nullptr);
// Proc auras on death - must be before aura/combat remove
- victim->ProcSkillsAndAuras(victim, PROC_FLAG_NONE, PROC_FLAG_DEATH, PROC_SPELL_TYPE_MASK_ALL, PROC_SPELL_PHASE_NONE, PROC_HIT_NONE, nullptr, nullptr, nullptr);
+ Unit::ProcSkillsAndAuras(victim, victim, PROC_FLAG_NONE, PROC_FLAG_DEATH, PROC_SPELL_TYPE_MASK_ALL, PROC_SPELL_PHASE_NONE, PROC_HIT_NONE, nullptr, nullptr, nullptr);
// update get killing blow achievements, must be done before setDeathState to be able to require auras on target
// and before Spirit of Redemption as it also removes auras
- if (Player* killerPlayer = GetCharmerOrOwnerPlayerOrPlayerItself())
- killerPlayer->UpdateCriteria(CRITERIA_TYPE_GET_KILLING_BLOWS, 1, 0, 0, victim);
+ if (attacker)
+ if (Player* killerPlayer = attacker->GetCharmerOrOwnerPlayerOrPlayerItself())
+ killerPlayer->UpdateCriteria(CRITERIA_TYPE_GET_KILLING_BLOWS, 1, 0, 0, victim);
if (!skipSettingDeathState)
{
@@ -11454,11 +11511,11 @@ void Unit::Kill(Unit* victim, bool durabilityLoss /*= true*/, bool skipSettingDe
// Durability loss is calculated more accurately again for each item in Player::DurabilityLoss
plrVictim->DurabilityLossAll(baseLoss, false);
// durability lost message
- SendDurabilityLoss(plrVictim, loss);
+ plrVictim->SendDurabilityLoss(plrVictim, loss);
}
// Call KilledUnit for creatures
- if (GetTypeId() == TYPEID_UNIT && IsAIEnabled)
- ToCreature()->AI()->KilledUnit(victim);
+ if (attacker && attacker->GetTypeId() == TYPEID_UNIT && attacker->IsAIEnabled)
+ attacker->ToCreature()->AI()->KilledUnit(victim);
// last damage from non duel opponent or opponent controlled creature
if (plrVictim->duel)
@@ -11484,31 +11541,30 @@ void Unit::Kill(Unit* victim, bool durabilityLoss /*= true*/, bool skipSettingDe
}
// Call KilledUnit for creatures, this needs to be called after the lootable flag is set
- if (GetTypeId() == TYPEID_UNIT && IsAIEnabled)
- ToCreature()->AI()->KilledUnit(victim);
+ if (attacker && attacker->GetTypeId() == TYPEID_UNIT && attacker->IsAIEnabled)
+ attacker->ToCreature()->AI()->KilledUnit(victim);
// Call creature just died function
if (creature->IsAIEnabled)
- creature->AI()->JustDied(this);
+ creature->AI()->JustDied(attacker);
if (TempSummon* summon = creature->ToTempSummon())
if (Unit* summoner = summon->GetSummoner())
if (summoner->ToCreature() && summoner->IsAIEnabled)
- summoner->ToCreature()->AI()->SummonedCreatureDies(creature, this);
+ summoner->ToCreature()->AI()->SummonedCreatureDies(creature, attacker);
// Dungeon specific stuff, only applies to players killing creatures
if (creature->GetInstanceId())
{
Map* instanceMap = creature->GetMap();
- Player* creditedPlayer = GetCharmerOrOwnerPlayerOrPlayerItself();
- /// @todo do instance binding anyway if the charmer/owner is offline
- if (instanceMap->IsDungeon() && (creditedPlayer || this == victim))
+ /// @todo do instance binding anyway if the charmer/owner is offline
+ if (instanceMap->IsDungeon() && ((attacker && attacker->GetCharmerOrOwnerPlayerOrPlayerItself()) || attacker == victim))
{
if (instanceMap->IsRaidOrHeroicDungeon())
{
if (creature->GetCreatureTemplate()->flags_extra & CREATURE_FLAG_EXTRA_INSTANCE_BIND)
- ((InstanceMap*)instanceMap)->PermBindAllPlayers();
+ instanceMap->ToInstanceMap()->PermBindAllPlayers();
}
else
{
@@ -11525,7 +11581,7 @@ void Unit::Kill(Unit* victim, bool durabilityLoss /*= true*/, bool skipSettingDe
// outdoor pvp things, do these after setting the death state, else the player activity notify won't work... doh...
// handle player kill only if not suicide (spirit of redemption for example)
- if (player && this != victim)
+ if (player && attacker != victim)
{
if (OutdoorPvP* pvp = player->GetOutdoorPvP())
pvp->HandleKill(player, victim);
@@ -11551,26 +11607,29 @@ void Unit::Kill(Unit* victim, bool durabilityLoss /*= true*/, bool skipSettingDe
}
// achievement stuff
- if (victim->GetTypeId() == TYPEID_PLAYER)
+ if (attacker && victim->GetTypeId() == TYPEID_PLAYER)
{
- if (GetTypeId() == TYPEID_UNIT)
- victim->ToPlayer()->UpdateCriteria(CRITERIA_TYPE_KILLED_BY_CREATURE, GetEntry());
- else if (GetTypeId() == TYPEID_PLAYER && victim != this)
- victim->ToPlayer()->UpdateCriteria(CRITERIA_TYPE_KILLED_BY_PLAYER, 1, ToPlayer()->GetTeam());
+ if (attacker->GetTypeId() == TYPEID_UNIT)
+ victim->ToPlayer()->UpdateCriteria(CRITERIA_TYPE_KILLED_BY_CREATURE, attacker->GetEntry());
+ else if (attacker->GetTypeId() == TYPEID_PLAYER && victim != attacker)
+ victim->ToPlayer()->UpdateCriteria(CRITERIA_TYPE_KILLED_BY_PLAYER, 1, attacker->ToPlayer()->GetTeam());
}
// Hook for OnPVPKill Event
- if (Player* killerPlr = ToPlayer())
- {
- if (Player* killedPlr = victim->ToPlayer())
- sScriptMgr->OnPVPKill(killerPlr, killedPlr);
- else if (Creature* killedCre = victim->ToCreature())
- sScriptMgr->OnCreatureKill(killerPlr, killedCre);
- }
- else if (Creature* killerCre = ToCreature())
+ if (attacker)
{
- if (Player* killed = victim->ToPlayer())
- sScriptMgr->OnPlayerKilledByCreature(killerCre, killed);
+ if (Player* killerPlr = attacker->ToPlayer())
+ {
+ if (Player* killedPlr = victim->ToPlayer())
+ sScriptMgr->OnPVPKill(killerPlr, killedPlr);
+ else if (Creature* killedCre = victim->ToCreature())
+ sScriptMgr->OnCreatureKill(killerPlr, killedCre);
+ }
+ else if (Creature* killerCre = attacker->ToCreature())
+ {
+ if (Player* killed = victim->ToPlayer())
+ sScriptMgr->OnPlayerKilledByCreature(killerCre, killed);
+ }
}
}
@@ -12422,21 +12481,26 @@ void Unit::CancelSpellMissiles(uint32 spellId, bool reverseMissile /*= false*/)
}
}
-void Unit::ApplyResilience(Unit const* victim, int32* damage) const
+bool Unit::CanApplyResilience() const
{
- // player mounted on multi-passenger mount is also classified as vehicle
- if (IsVehicle() || (victim->IsVehicle() && victim->GetTypeId() != TYPEID_PLAYER))
- return;
+ return !IsVehicle() && GetOwnerGUID().IsPlayer();
+}
- // Don't consider resilience if not in PvP - player or pet
- if (!GetCharmerOrOwnerPlayerOrPlayerItself())
+/*static*/ void Unit::ApplyResilience(Unit const* victim, int32* damage)
+{
+ // player mounted on multi-passenger mount is also classified as vehicle
+ if (victim->IsVehicle() && victim->GetTypeId() != TYPEID_PLAYER)
return;
Unit const* target = nullptr;
if (victim->GetTypeId() == TYPEID_PLAYER)
target = victim;
- else if (victim->GetTypeId() == TYPEID_UNIT && victim->GetOwner() && victim->GetOwner()->GetTypeId() == TYPEID_PLAYER)
- target = victim->GetOwner();
+ else // victim->GetTypeId() == TYPEID_UNIT
+ {
+ if (Unit* owner = victim->GetOwner())
+ if (owner->GetTypeId() == TYPEID_PLAYER)
+ target = owner;
+ }
if (!target)
return;
@@ -12444,6 +12508,15 @@ void Unit::ApplyResilience(Unit const* victim, int32* damage) const
*damage -= target->GetDamageReduction(*damage);
}
+int32 Unit::CalculateAOEAvoidance(int32 damage, uint32 schoolMask, Unit* caster) const
+{
+ damage = int32(float(damage) * GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_AOE_DAMAGE_AVOIDANCE, schoolMask));
+ if (caster->GetTypeId() == TYPEID_UNIT)
+ damage = int32(float(damage) * GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_CREATURE_AOE_DAMAGE_AVOIDANCE, schoolMask));
+
+ return damage;
+}
+
// Melee based spells can be miss, parry or dodge on this step
// Crit or block - determined on damage calculation phase! (and can be both in some time)
float Unit::MeleeSpellMissChance(Unit const* victim, WeaponAttackType attType, SpellInfo const* spellInfo) const
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
index dda4b56ab43..af2557b4f99 100644
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -879,7 +879,7 @@ class TC_GAME_API Unit : public WorldObject
int32 GetResistance(SpellSchoolMask mask) const;
void SetResistance(SpellSchools school, int32 val) { SetUpdateFieldValue(m_values.ModifyValue(&Unit::m_unitData).ModifyValue(&UF::UnitData::Resistances, school), val); }
void SetBonusResistanceMod(SpellSchools school, int32 val) { SetUpdateFieldValue(m_values.ModifyValue(&Unit::m_unitData).ModifyValue(&UF::UnitData::BonusResistanceMods, school), val); }
- float CalculateAverageResistReduction(SpellSchoolMask schoolMask, Unit const* victim, SpellInfo const* spellInfo = nullptr) const;
+ static float CalculateAverageResistReduction(Unit const* attacker, SpellSchoolMask schoolMask, Unit const* victim, SpellInfo const* spellInfo = nullptr);
uint64 GetHealth() const { return m_unitData->Health; }
uint64 GetMaxHealth() const { return m_unitData->MaxHealth; }
@@ -1019,13 +1019,13 @@ class TC_GAME_API Unit : public WorldObject
uint16 GetMeleeAnimKitId() const override { return _meleeAnimKitId; }
uint16 GetMaxSkillValueForLevel(Unit const* target = nullptr) const { return (target ? GetLevelForTarget(target) : getLevel()) * 5; }
- void DealDamageMods(Unit const* victim, uint32 &damage, uint32* absorb) const;
- uint32 DealDamage(Unit* victim, uint32 damage, CleanDamage const* cleanDamage = nullptr, DamageEffectType damagetype = DIRECT_DAMAGE, SpellSchoolMask damageSchoolMask = SPELL_SCHOOL_MASK_NORMAL, SpellInfo const* spellProto = nullptr, bool durabilityLoss = true);
- void Kill(Unit* victim, bool durabilityLoss = true, bool skipSettingDeathState = false);
- void KillSelf(bool durabilityLoss = true, bool skipSettingDeathState = false) { Kill(this, durabilityLoss, skipSettingDeathState); }
- void DealHeal(HealInfo& healInfo);
+ static void DealDamageMods(Unit const* attacker, Unit const* victim, uint32& damage, uint32* absorb);
+ static uint32 DealDamage(Unit* attacker, Unit* victim, uint32 damage, CleanDamage const* cleanDamage = nullptr, DamageEffectType damagetype = DIRECT_DAMAGE, SpellSchoolMask damageSchoolMask = SPELL_SCHOOL_MASK_NORMAL, SpellInfo const* spellProto = nullptr, bool durabilityLoss = true);
+ static void Kill(Unit* attacker, Unit* victim, bool durabilityLoss = true, bool skipSettingDeathState = false);
+ void KillSelf(bool durabilityLoss = true, bool skipSettingDeathState = false) { Unit::Kill(this, this, durabilityLoss, skipSettingDeathState); }
+ static void DealHeal(HealInfo& healInfo);
- void ProcSkillsAndAuras(Unit* actionTarget, uint32 typeMaskActor, uint32 typeMaskActionTarget,
+ static void ProcSkillsAndAuras(Unit* actor, Unit* actionTarget, uint32 typeMaskActor, uint32 typeMaskActionTarget,
uint32 spellTypeMask, uint32 spellPhaseMask, uint32 hitMask, Spell* spell,
DamageInfo* damageInfo, HealInfo* healInfo);
@@ -1051,7 +1051,10 @@ class TC_GAME_API Unit : public WorldObject
// player or player's pet resilience (-1%)
uint32 GetDamageReduction(uint32 damage) const { return GetCombatRatingDamageReduction(CR_RESILIENCE_PLAYER_DAMAGE, 1.0f, 100.0f, damage); }
- void ApplyResilience(Unit const* victim, int32* damage) const;
+ virtual bool CanApplyResilience() const;
+ static void ApplyResilience(Unit const* victim, int32* damage);
+
+ int32 CalculateAOEAvoidance(int32 damage, uint32 schoolMask, Unit* caster) const;
float MeleeSpellMissChance(Unit const* victim, WeaponAttackType attType, SpellInfo const* spellInfo) const;
SpellMissInfo MeleeSpellHitResult(Unit* victim, SpellInfo const* spellInfo) const;
@@ -1062,7 +1065,9 @@ class TC_GAME_API Unit : public WorldObject
float GetUnitParryChance(WeaponAttackType attType, Unit const* victim) const;
float GetUnitBlockChance(WeaponAttackType attType, Unit const* victim) const;
float GetUnitMissChance(WeaponAttackType attType) const;
- float GetUnitCriticalChance(WeaponAttackType attackType, Unit const* victim) const;
+ float GetUnitCriticalChanceDone(WeaponAttackType attackType) const;
+ float GetUnitCriticalChanceTaken(Unit const* attacker, WeaponAttackType attackType, float critDone) const;
+ float GetUnitCriticalChanceAgainst(WeaponAttackType attackType, Unit const* victim) const;
int32 GetMechanicResistChance(SpellInfo const* spellInfo) const;
bool CanUseAttackType(uint8 attacktype) const;
@@ -1701,10 +1706,10 @@ class TC_GAME_API Unit : public WorldObject
bool isSpellBlocked(Unit* victim, SpellInfo const* spellProto, WeaponAttackType attackType = BASE_ATTACK);
bool isBlockCritical();
- bool IsSpellCrit(Unit* victim, Spell* spell, AuraEffect const* aurEff, SpellSchoolMask schoolMask, WeaponAttackType attackType = BASE_ATTACK) const;
- float GetUnitSpellCriticalChance(Unit* victim, Spell* spell, AuraEffect const* aurEff, SpellSchoolMask schoolMask, WeaponAttackType attackType = BASE_ATTACK) const;
- uint32 SpellCriticalDamageBonus(SpellInfo const* spellProto, uint32 damage, Unit* victim);
- uint32 SpellCriticalHealingBonus(SpellInfo const* spellProto, uint32 damage, Unit* victim);
+ float SpellCritChanceDone(SpellInfo const* spellInfo, SpellSchoolMask schoolMask, WeaponAttackType attackType = BASE_ATTACK) const;
+ float SpellCritChanceTaken(Unit const* caster, Spell* spell, AuraEffect const* aurEff, SpellSchoolMask schoolMask, float doneChance, WeaponAttackType attackType = BASE_ATTACK) const;
+ static uint32 SpellCriticalDamageBonus(Unit const* caster, SpellInfo const* spellProto, uint32 damage, Unit* victim);
+ static uint32 SpellCriticalHealingBonus(Unit const* caster, SpellInfo const* spellProto, uint32 damage, Unit* victim);
uint32 GetCastingTimeForBonus(SpellInfo const* spellProto, DamageEffectType damagetype, uint32 CastingTime) const;
float CalculateDefaultCoefficient(SpellInfo const* spellInfo, DamageEffectType damagetype) const;
@@ -1721,11 +1726,11 @@ class TC_GAME_API Unit : public WorldObject
bool IsImmunedToDamage(SpellInfo const* spellInfo) const;
virtual bool IsImmunedToSpellEffect(SpellInfo const* spellInfo, uint32 index, Unit* caster) const; // redefined in Creature
- bool IsDamageReducedByArmor(SpellSchoolMask damageSchoolMask, SpellInfo const* spellInfo = nullptr, int8 effIndex = -1);
- uint32 CalcArmorReducedDamage(Unit* attacker, Unit* victim, const uint32 damage, SpellInfo const* spellInfo, WeaponAttackType attackType = MAX_ATTACK) const;
- uint32 CalcSpellResistedDamage(Unit* attacker, Unit* victim, uint32 damage, SpellSchoolMask schoolMask, SpellInfo const* spellInfo);
- void CalcAbsorbResist(DamageInfo& damageInfo);
- void CalcHealAbsorb(HealInfo& healInfo) const;
+ static bool IsDamageReducedByArmor(SpellSchoolMask damageSchoolMask, SpellInfo const* spellInfo = nullptr, int8 effIndex = -1);
+ static uint32 CalcArmorReducedDamage(Unit const* attacker, Unit* victim, uint32 damage, SpellInfo const* spellInfo, uint8 attackerLevel = 0, WeaponAttackType attackType = MAX_ATTACK);
+ static uint32 CalcSpellResistedDamage(Unit const* attacker, Unit* victim, uint32 damage, SpellSchoolMask schoolMask, SpellInfo const* spellInfo);
+ static void CalcAbsorbResist(DamageInfo& damageInfo);
+ static void CalcHealAbsorb(HealInfo& healInfo);
void UpdateSpeed(UnitMoveType mtype);
float GetSpeed(UnitMoveType mtype) const;
diff --git a/src/server/game/Handlers/MovementHandler.cpp b/src/server/game/Handlers/MovementHandler.cpp
index d8dd7070786..9fe6808defb 100644
--- a/src/server/game/Handlers/MovementHandler.cpp
+++ b/src/server/game/Handlers/MovementHandler.cpp
@@ -454,7 +454,7 @@ void WorldSession::HandleMovementOpcode(OpcodeClient opcode, MovementInfo& movem
if (opcode == CMSG_MOVE_JUMP)
{
plrMover->RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags2::Jump);
- plrMover->ProcSkillsAndAuras(nullptr, PROC_FLAG_JUMP, PROC_FLAG_NONE, PROC_SPELL_TYPE_MASK_ALL, PROC_SPELL_PHASE_NONE, PROC_HIT_NONE, nullptr, nullptr, nullptr);
+ Unit::ProcSkillsAndAuras(plrMover, nullptr, PROC_FLAG_JUMP, PROC_FLAG_NONE, PROC_SPELL_TYPE_MASK_ALL, PROC_SPELL_PHASE_NONE, PROC_HIT_NONE, nullptr, nullptr, nullptr);
}
}
}
diff --git a/src/server/game/Instances/InstanceScript.cpp b/src/server/game/Instances/InstanceScript.cpp
index 228e59b4fc8..32d219fa03a 100644
--- a/src/server/game/Instances/InstanceScript.cpp
+++ b/src/server/game/Instances/InstanceScript.cpp
@@ -382,7 +382,7 @@ bool InstanceScript::SetBossState(uint32 id, EncounterState state)
for (Map::PlayerList::const_iterator i = playerList.begin(); i != playerList.end(); ++i)
if (Player* player = i->GetSource())
if (player->IsAlive())
- player->ProcSkillsAndAuras(nullptr, PROC_FLAG_ENCOUNTER_START, PROC_FLAG_NONE, PROC_SPELL_TYPE_MASK_ALL, PROC_SPELL_PHASE_NONE, PROC_HIT_NONE, nullptr, nullptr, nullptr);
+ Unit::ProcSkillsAndAuras(player, nullptr, PROC_FLAG_ENCOUNTER_START, PROC_FLAG_NONE, PROC_SPELL_TYPE_MASK_ALL, PROC_SPELL_PHASE_NONE, PROC_HIT_NONE, nullptr, nullptr, nullptr);
break;
}
case FAIL:
diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
index 1a6100e1ce8..6373a39c3b4 100644
--- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp
+++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
@@ -576,13 +576,12 @@ NonDefaultConstructible<pAuraEffectHandler> AuraEffectHandler[TOTAL_AURAS]=
AuraEffect::AuraEffect(Aura* base, SpellEffectInfo const* spellEfffectInfo, int32 *baseAmount, Unit* caster) :
m_base(base), m_spellInfo(base->GetSpellInfo()), m_effectInfo(spellEfffectInfo), m_spellmod(nullptr),
m_baseAmount(baseAmount ? *baseAmount : spellEfffectInfo->CalcBaseValue(caster, base->GetType() == UNIT_AURA_TYPE ? base->GetOwner()->ToUnit() : nullptr, base->GetCastItemId(), base->GetCastItemLevel())),
-m_damage(0), m_critChance(0.0f), m_donePct(1.0f),
-_periodicTimer(0), _period(0), _ticksDone(0),
+_amount(), _periodicTimer(0), _period(0), _ticksDone(0),
m_canBeRecalculated(true), m_isPeriodic(false)
{
CalculatePeriodic(caster, true, false);
- m_amount = CalculateAmount(caster);
+ _amount = CalculateAmount(caster);
CalculateSpellMod();
}
@@ -815,7 +814,7 @@ void AuraEffect::ChangeAmount(int32 newAmount, bool mark, bool onStackOrReapply,
if (handleMask & AURA_EFFECT_HANDLE_CHANGE_AMOUNT)
{
if (!mark)
- m_amount = newAmount;
+ _amount = newAmount;
else
SetAmount(newAmount);
CalculateSpellMod();
@@ -975,6 +974,11 @@ void AuraEffect::Update(uint32 diff, Unit* caster)
}
}
+float AuraEffect::GetCritChanceFor(Unit const* caster, Unit const* target) const
+{
+ return target->SpellCritChanceTaken(caster, nullptr, this, GetSpellInfo()->GetSchoolMask(), GetBase()->CalcPeriodicCritChance(caster), GetSpellInfo()->GetAttackType());
+}
+
bool AuraEffect::IsAffectingSpell(SpellInfo const* spell) const
{
if (!spell)
@@ -2920,7 +2924,7 @@ void AuraEffect::HandleAuraControlVehicle(AuraApplication const* aurApp, uint8 m
// so this break such spells or most of them.
// Current formula about m_amount: effect base points + dieside - 1
// TO DO: Reasearch more about 0/0 and fix it.
- caster->_EnterVehicle(target->GetVehicleKit(), m_amount - 1, aurApp);
+ caster->_EnterVehicle(target->GetVehicleKit(), GetAmount() - 1, aurApp);
}
else
{
@@ -2929,7 +2933,7 @@ void AuraEffect::HandleAuraControlVehicle(AuraApplication const* aurApp, uint8 m
if (GetId() == 53111) // Devour Humanoid
{
- target->Kill(caster);
+ Unit::Kill(target, caster);
if (caster->GetTypeId() == TYPEID_UNIT)
caster->ToCreature()->DespawnOrUnsummon();
}
@@ -3357,7 +3361,7 @@ void AuraEffect::HandleModPercentStat(AuraApplication const* aurApp, uint8 mode,
if (GetMiscValue() == i || GetMiscValue() == -1)
{
if (apply)
- target->ApplyStatPctModifier(UnitMods(UNIT_MOD_STAT_START + i), BASE_PCT, float(m_amount));
+ target->ApplyStatPctModifier(UnitMods(UNIT_MOD_STAT_START + i), BASE_PCT, float(GetAmount()));
else
{
float amount = target->GetTotalAuraMultiplier(SPELL_AURA_MOD_PERCENT_STAT, [i](AuraEffect const* aurEff) -> bool
@@ -3517,7 +3521,7 @@ void AuraEffect::HandleModStatBonusPercent(AuraApplication const* aurApp, uint8
{
if (GetMiscValue() == i || GetMiscValue() == -1)
{
- target->HandleStatFlatModifier(UnitMods(UNIT_MOD_STAT_START + i), BASE_PCT_EXCLUDE_CREATE, float(m_amount), apply);
+ target->HandleStatFlatModifier(UnitMods(UNIT_MOD_STAT_START + i), BASE_PCT_EXCLUDE_CREATE, float(GetAmount()), apply);
target->UpdateStatBuffMod(Stats(i));
}
}
@@ -3532,7 +3536,7 @@ void AuraEffect::HandleOverrideSpellPowerByAttackPower(AuraApplication const* au
if (!target)
return;
- target->ApplyModOverrideSpellPowerByAPPercent(float(m_amount), apply);
+ target->ApplyModOverrideSpellPowerByAPPercent(float(GetAmount()), apply);
target->UpdateSpellDamageAndHealingBonus();
}
@@ -3545,7 +3549,7 @@ void AuraEffect::HandleOverrideAttackPowerBySpellPower(AuraApplication const* au
if (!target)
return;
- target->ApplyModOverrideAPBySpellPowerPercent(float(m_amount), apply);
+ target->ApplyModOverrideAPBySpellPowerPercent(float(GetAmount()), apply);
target->UpdateAttackPowerAndDamage();
target->UpdateAttackPowerAndDamage(true);
}
@@ -4060,7 +4064,7 @@ void AuraEffect::HandleModCombatSpeedPct(AuraApplication const* aurApp, uint8 mo
target->ApplyAttackTimePercentMod(OFF_ATTACK, float(spellGroupVal), !apply);
target->ApplyAttackTimePercentMod(RANGED_ATTACK, float(spellGroupVal), !apply);
}
- target->ApplyCastTimePercentMod(float(m_amount), apply);
+ target->ApplyCastTimePercentMod(float(GetAmount()), apply);
target->ApplyAttackTimePercentMod(BASE_ATTACK, float(GetAmount()), apply);
target->ApplyAttackTimePercentMod(OFF_ATTACK, float(GetAmount()), apply);
target->ApplyAttackTimePercentMod(RANGED_ATTACK, float(GetAmount()), apply);
@@ -4736,7 +4740,7 @@ void AuraEffect::HandleChannelDeathItem(AuraApplication const* aurApp, uint8 mod
//Adding items
uint32 noSpaceForCount = 0;
- uint32 count = m_amount;
+ uint32 count = GetAmount();
ItemPosCountVec dest;
InventoryResult msg = plCaster->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, GetSpellEffectInfo()->ItemType, count, &noSpaceForCount);
@@ -4784,7 +4788,7 @@ void AuraEffect::HandleForceReaction(AuraApplication const* aurApp, uint8 mode,
return;
uint32 factionId = GetMiscValue();
- ReputationRank factionRank = ReputationRank(m_amount);
+ ReputationRank factionRank = ReputationRank(GetAmount());
player->GetReputationMgr().ApplyForceReaction(factionId, factionRank, apply);
player->GetReputationMgr().SendForceReactions();
@@ -5138,7 +5142,10 @@ void AuraEffect::HandlePeriodicTriggerSpellWithValueAuraTick(Unit* target, Unit*
void AuraEffect::HandlePeriodicDamageAurasTick(Unit* target, Unit* caster) const
{
- if (!caster || !target->IsAlive())
+ // dynobj auras must always have a caster
+ ASSERT(GetSpellEffectInfo()->Effect != SPELL_EFFECT_PERSISTENT_AREA_AURA || caster);
+
+ if (!target->IsAlive())
return;
if (target->HasUnitState(UNIT_STATE_ISOLATED) || target->IsImmunedToDamage(GetSpellInfo()))
@@ -5154,38 +5161,27 @@ void AuraEffect::HandlePeriodicDamageAurasTick(Unit* target, Unit* caster) const
CleanDamage cleanDamage = CleanDamage(0, 0, BASE_ATTACK, MELEE_HIT_NORMAL);
- // AOE spells are not affected by the new periodic system.
- bool isAreaAura = GetSpellEffectInfo()->IsAreaAuraEffect() || GetSpellEffectInfo()->IsEffect(SPELL_EFFECT_PERSISTENT_AREA_AURA);
// ignore negative values (can be result apply spellmods to aura damage
- uint32 damage = isAreaAura ? std::max(GetAmount(), 0) : m_damage;
+ uint32 damage = std::max(GetAmount(), 0);
// Script Hook For HandlePeriodicDamageAurasTick -- Allow scripts to change the Damage pre class mitigation calculations
- if (isAreaAura)
- sScriptMgr->ModifyPeriodicDamageAurasTick(target, caster, damage);
+ sScriptMgr->ModifyPeriodicDamageAurasTick(target, caster, damage);
switch (GetAuraType())
{
case SPELL_AURA_PERIODIC_DAMAGE:
{
- if (isAreaAura)
- damage = caster->SpellDamageBonusDone(target, GetSpellInfo(), damage, DOT, GetSpellEffectInfo(), GetBase()->GetStackAmount()) * caster->SpellDamagePctDone(target, m_spellInfo, DOT);
+ if (caster)
+ damage = caster->SpellDamageBonusDone(target, GetSpellInfo(), damage, DOT, GetSpellEffectInfo(), GetBase()->GetStackAmount());
damage = target->SpellDamageBonusTaken(caster, GetSpellInfo(), damage, DOT, GetSpellEffectInfo(), GetBase()->GetStackAmount());
- // Calculate armor mitigation
- if (caster->IsDamageReducedByArmor(GetSpellInfo()->GetSchoolMask(), GetSpellInfo(), GetEffIndex()))
- {
- uint32 damageReductedArmor = caster->CalcArmorReducedDamage(caster, target, damage, GetSpellInfo());
- cleanDamage.mitigated_damage += damage - damageReductedArmor;
- damage = damageReductedArmor;
- }
-
// There is a Chance to make a Soul Shard when Drain soul does damage
- if (GetSpellInfo()->SpellFamilyName == SPELLFAMILY_WARLOCK && (GetSpellInfo()->SpellFamilyFlags[0] & 0x00004000))
+ if (caster && GetSpellInfo()->SpellFamilyName == SPELLFAMILY_WARLOCK && (GetSpellInfo()->SpellFamilyFlags[0] & 0x00004000))
{
if (caster->GetTypeId() == TYPEID_PLAYER && caster->ToPlayer()->isHonorOrXPTarget(target))
caster->CastSpell(caster, 95810, this);
}
- if (GetSpellInfo()->SpellFamilyName == SPELLFAMILY_GENERIC)
+ else if (GetSpellInfo()->SpellFamilyName == SPELLFAMILY_GENERIC)
{
switch (GetId())
{
@@ -5205,44 +5201,49 @@ void AuraEffect::HandlePeriodicDamageAurasTick(Unit* target, Unit* caster) const
{
WeaponAttackType attackType = GetSpellInfo()->GetAttackType();
- int32 weaponDamage = CalculatePct(caster->CalculateDamage(attackType, false, true), GetAmount());
+ damage = CalculatePct(caster->CalculateDamage(attackType, false, true), GetAmount());
// Add melee damage bonuses (also check for negative)
- uint32 damageBonusDone = caster->MeleeDamageBonusDone(target, std::max(weaponDamage, 0), attackType, DOT, GetSpellInfo());
+ if (caster)
+ damage = caster->MeleeDamageBonusDone(target, damage, attackType, DOT, GetSpellInfo());
- damage = target->MeleeDamageBonusTaken(caster, damageBonusDone, attackType, DOT, GetSpellInfo());
+ damage = target->MeleeDamageBonusTaken(caster, damage, attackType, DOT, GetSpellInfo());
break;
}
case SPELL_AURA_PERIODIC_DAMAGE_PERCENT:
// ceil obtained value, it may happen that 10 ticks for 10% damage may not kill owner
damage = uint32(ceil(CalculatePct<float, float>(target->GetMaxHealth(), damage)));
+ damage = target->SpellDamageBonusTaken(caster, GetSpellInfo(), damage, DOT, GetSpellEffectInfo(), GetBase()->GetStackAmount());
break;
default:
break;
}
- if (!m_spellInfo->HasAttribute(SPELL_ATTR4_FIXED_DAMAGE))
+ bool crit = roll_chance_f(GetCritChanceFor(caster, target));
+ if (crit)
+ damage = Unit::SpellCriticalDamageBonus(caster, m_spellInfo, damage, target);
+
+ // Calculate armor mitigation
+ if (Unit::IsDamageReducedByArmor(GetSpellInfo()->GetSchoolMask(), GetSpellInfo(), GetEffIndex()))
{
- if (GetSpellEffectInfo()->IsTargetingArea() || isAreaAura)
- {
- damage = int32(float(damage) * target->GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_AOE_DAMAGE_AVOIDANCE, m_spellInfo->SchoolMask));
- if (caster->GetTypeId() != TYPEID_PLAYER)
- damage = int32(float(damage) * target->GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_CREATURE_AOE_DAMAGE_AVOIDANCE, m_spellInfo->SchoolMask));
- }
+ uint32 damageReductedArmor = Unit::CalcArmorReducedDamage(caster, target, damage, GetSpellInfo(), GetBase()->GetCasterLevel());
+ cleanDamage.mitigated_damage += damage - damageReductedArmor;
+ damage = damageReductedArmor;
}
- bool crit = roll_chance_f(isAreaAura ? caster->GetUnitSpellCriticalChance(target, nullptr, this, m_spellInfo->GetSchoolMask()) : m_critChance);
-
- if (crit)
- damage = caster->SpellCriticalDamageBonus(m_spellInfo, damage, target);
+ if (!GetSpellInfo()->HasAttribute(SPELL_ATTR4_FIXED_DAMAGE))
+ {
+ if (GetSpellEffectInfo()->IsTargetingArea() || GetSpellEffectInfo()->IsAreaAuraEffect() || GetSpellEffectInfo()->Effect == SPELL_EFFECT_PERSISTENT_AREA_AURA)
+ damage = target->CalculateAOEAvoidance(damage, m_spellInfo->SchoolMask, caster);
+ }
int32 dmg = damage;
- if (!GetSpellInfo()->HasAttribute(SPELL_ATTR4_FIXED_DAMAGE))
- caster->ApplyResilience(target, &dmg);
+ if (!GetSpellInfo()->HasAttribute(SPELL_ATTR4_FIXED_DAMAGE) && caster && caster->CanApplyResilience())
+ Unit::ApplyResilience(target, &dmg);
damage = dmg;
DamageInfo damageInfo(caster, target, damage, GetSpellInfo(), GetSpellInfo()->GetSchoolMask(), DOT, BASE_ATTACK);
- caster->CalcAbsorbResist(damageInfo);
+ Unit::CalcAbsorbResist(damageInfo);
damage = damageInfo.GetDamage();
uint32 absorb = damageInfo.GetAbsorb();
@@ -5250,7 +5251,7 @@ void AuraEffect::HandlePeriodicDamageAurasTick(Unit* target, Unit* caster) const
TC_LOG_DEBUG("spells.periodic", "PeriodicTick: %s attacked %s for %u dmg inflicted by %u absorb is %u",
GetCasterGUID().ToString().c_str(), target->GetGUID().ToString().c_str(), damage, GetId(), absorb);
- caster->DealDamageMods(target, damage, &absorb);
+ Unit::DealDamageMods(caster, target, damage, &absorb);
// Set trigger flag
uint32 procAttacker = PROC_FLAG_DONE_PERIODIC;
@@ -5268,9 +5269,9 @@ void AuraEffect::HandlePeriodicDamageAurasTick(Unit* target, Unit* caster) const
SpellPeriodicAuraLogInfo pInfo(this, damage, dmg, overkill, absorb, resist, 0.0f, crit);
- caster->DealDamage(target, damage, &cleanDamage, DOT, GetSpellInfo()->GetSchoolMask(), GetSpellInfo(), true);
+ Unit::DealDamage(caster, target, damage, &cleanDamage, DOT, GetSpellInfo()->GetSchoolMask(), GetSpellInfo(), true);
- caster->ProcSkillsAndAuras(target, procAttacker, procVictim, PROC_SPELL_TYPE_DAMAGE, PROC_SPELL_PHASE_NONE, hitMask, nullptr, &damageInfo, nullptr);
+ Unit::ProcSkillsAndAuras(caster, target, procAttacker, procVictim, PROC_SPELL_TYPE_DAMAGE, PROC_SPELL_PHASE_NONE, hitMask, nullptr, &damageInfo, nullptr);
target->SendPeriodicAuraLog(&pInfo);
}
@@ -5282,7 +5283,10 @@ bool AuraEffect::IsAreaAuraEffect() const
void AuraEffect::HandlePeriodicHealthLeechAuraTick(Unit* target, Unit* caster) const
{
- if (!caster || !target->IsAlive())
+ // dynobj auras must always have a caster
+ ASSERT(GetSpellEffectInfo()->Effect != SPELL_EFFECT_PERSISTENT_AREA_AURA || caster);
+
+ if (!target->IsAlive())
return;
if (target->HasUnitState(UNIT_STATE_ISOLATED) || target->IsImmunedToDamage(GetSpellInfo()))
@@ -5297,46 +5301,38 @@ void AuraEffect::HandlePeriodicHealthLeechAuraTick(Unit* target, Unit* caster) c
CleanDamage cleanDamage = CleanDamage(0, 0, BASE_ATTACK, MELEE_HIT_NORMAL);
- bool isAreaAura = GetSpellEffectInfo()->IsAreaAuraEffect() || GetSpellEffectInfo()->IsEffect(SPELL_EFFECT_PERSISTENT_AREA_AURA);
// ignore negative values (can be result apply spellmods to aura damage
- uint32 damage = isAreaAura ? std::max(GetAmount(), 0) : m_damage;
+ uint32 damage = std::max(GetAmount(), 0);
- if (isAreaAura)
- {
- // Script Hook For HandlePeriodicDamageAurasTick -- Allow scripts to change the Damage pre class mitigation calculations
- sScriptMgr->ModifyPeriodicDamageAurasTick(target, caster, damage);
- damage = caster->SpellDamageBonusDone(target, GetSpellInfo(), damage, DOT, GetSpellEffectInfo(), GetBase()->GetStackAmount()) * caster->SpellDamagePctDone(target, m_spellInfo, DOT);
- }
+ if (caster)
+ damage = caster->SpellDamageBonusDone(target, GetSpellInfo(), damage, DOT, GetSpellEffectInfo(), GetBase()->GetStackAmount());
damage = target->SpellDamageBonusTaken(caster, GetSpellInfo(), damage, DOT, GetSpellEffectInfo(), GetBase()->GetStackAmount());
+ bool crit = roll_chance_f(GetCritChanceFor(caster, target));
+ if (crit)
+ damage = Unit::SpellCriticalDamageBonus(caster, m_spellInfo, damage, target);
+
// Calculate armor mitigation
- if (caster->IsDamageReducedByArmor(GetSpellInfo()->GetSchoolMask(), GetSpellInfo(), GetEffIndex()))
+ if (Unit::IsDamageReducedByArmor(GetSpellInfo()->GetSchoolMask(), GetSpellInfo(), GetEffIndex()))
{
- uint32 damageReductedArmor = caster->CalcArmorReducedDamage(caster, target, damage, GetSpellInfo());
+ uint32 damageReductedArmor = Unit::CalcArmorReducedDamage(caster, target, damage, GetSpellInfo(), GetBase()->GetCasterLevel());
cleanDamage.mitigated_damage += damage - damageReductedArmor;
damage = damageReductedArmor;
}
- if (!m_spellInfo->HasAttribute(SPELL_ATTR4_FIXED_DAMAGE))
- if (GetSpellEffectInfo()->IsTargetingArea() || isAreaAura)
- {
- damage = int32(float(damage) * target->GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_AOE_DAMAGE_AVOIDANCE, m_spellInfo->SchoolMask));
- if (caster->GetTypeId() != TYPEID_PLAYER)
- damage = int32(float(damage) * target->GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_CREATURE_AOE_DAMAGE_AVOIDANCE, m_spellInfo->SchoolMask));
- }
-
- bool crit = roll_chance_f(isAreaAura ? caster->GetUnitSpellCriticalChance(target, nullptr, this, m_spellInfo->GetSchoolMask()) : m_critChance);
-
- if (crit)
- damage = caster->SpellCriticalDamageBonus(m_spellInfo, damage, target);
+ if (!GetSpellInfo()->HasAttribute(SPELL_ATTR4_FIXED_DAMAGE))
+ {
+ if (GetSpellEffectInfo()->IsTargetingArea() || GetSpellEffectInfo()->IsAreaAuraEffect() || GetSpellEffectInfo()->Effect == SPELL_EFFECT_PERSISTENT_AREA_AURA)
+ damage = target->CalculateAOEAvoidance(damage, m_spellInfo->SchoolMask, caster);
+ }
int32 dmg = damage;
- if (!GetSpellInfo()->HasAttribute(SPELL_ATTR4_FIXED_DAMAGE))
- caster->ApplyResilience(target, &dmg);
+ if (!GetSpellInfo()->HasAttribute(SPELL_ATTR4_FIXED_DAMAGE) && caster && caster->CanApplyResilience())
+ Unit::ApplyResilience(target, &dmg);
damage = dmg;
DamageInfo damageInfo(caster, target, damage, GetSpellInfo(), GetSpellInfo()->GetSchoolMask(), DOT, BASE_ATTACK);
- caster->CalcAbsorbResist(damageInfo);
+ Unit::CalcAbsorbResist(damageInfo);
uint32 absorb = damageInfo.GetAbsorb();
uint32 resist = damageInfo.GetResist();
@@ -5363,22 +5359,22 @@ void AuraEffect::HandlePeriodicHealthLeechAuraTick(Unit* target, Unit* caster) c
procVictim |= PROC_FLAG_TAKEN_DAMAGE;
}
- int32 new_damage = caster->DealDamage(target, damage, &cleanDamage, DOT, GetSpellInfo()->GetSchoolMask(), GetSpellInfo(), false);
- if (caster->IsAlive())
- {
- caster->ProcSkillsAndAuras(target, procAttacker, procVictim, PROC_SPELL_TYPE_DAMAGE, PROC_SPELL_PHASE_NONE, hitMask, nullptr, &damageInfo, nullptr);
+ int32 new_damage = Unit::DealDamage(caster, target, damage, &cleanDamage, DOT, GetSpellInfo()->GetSchoolMask(), GetSpellInfo(), false);
+ if (!caster || !caster->IsAlive())
+ return;
- float gainMultiplier = GetSpellEffectInfo()->CalcValueMultiplier(caster);
+ Unit::ProcSkillsAndAuras(caster, target, procAttacker, procVictim, PROC_SPELL_TYPE_DAMAGE, PROC_SPELL_PHASE_NONE, hitMask, nullptr, &damageInfo, nullptr);
- uint32 heal = uint32(caster->SpellHealingBonusDone(caster, GetSpellInfo(), uint32(new_damage * gainMultiplier), DOT, GetSpellEffectInfo(), GetBase()->GetStackAmount()));
- heal = uint32(caster->SpellHealingBonusTaken(caster, GetSpellInfo(), heal, DOT, GetSpellEffectInfo(), GetBase()->GetStackAmount()));
+ float gainMultiplier = GetSpellEffectInfo()->CalcValueMultiplier(caster);
- HealInfo healInfo(caster, caster, heal, GetSpellInfo(), GetSpellInfo()->GetSchoolMask());
- caster->HealBySpell(healInfo);
+ uint32 heal = caster->SpellHealingBonusDone(caster, GetSpellInfo(), uint32(new_damage * gainMultiplier), DOT, GetSpellEffectInfo(), GetBase()->GetStackAmount());
+ heal = caster->SpellHealingBonusTaken(caster, GetSpellInfo(), heal, DOT, GetSpellEffectInfo(), GetBase()->GetStackAmount());
- caster->GetThreatManager().ForwardThreatForAssistingMe(caster, healInfo.GetEffectiveHeal()*0.5f, GetSpellInfo());
- caster->ProcSkillsAndAuras(caster, PROC_FLAG_DONE_PERIODIC, PROC_FLAG_TAKEN_PERIODIC, PROC_SPELL_TYPE_HEAL, PROC_SPELL_PHASE_NONE, hitMask, nullptr, nullptr, &healInfo);
- }
+ HealInfo healInfo(caster, caster, heal, GetSpellInfo(), GetSpellInfo()->GetSchoolMask());
+ caster->HealBySpell(healInfo);
+
+ caster->GetThreatManager().ForwardThreatForAssistingMe(caster, healInfo.GetEffectiveHeal() * 0.5f, GetSpellInfo());
+ Unit::ProcSkillsAndAuras(caster, caster, PROC_FLAG_DONE_PERIODIC, PROC_FLAG_TAKEN_PERIODIC, PROC_SPELL_TYPE_HEAL, PROC_SPELL_PHASE_NONE, hitMask, nullptr, nullptr, &healInfo);
caster->SendSpellNonMeleeDamageLog(&log);
}
@@ -5410,12 +5406,15 @@ void AuraEffect::HandlePeriodicHealthFunnelAuraTick(Unit* target, Unit* caster)
HealInfo healInfo(caster, target, damage, GetSpellInfo(), GetSpellInfo()->GetSchoolMask());
caster->HealBySpell(healInfo);
- caster->ProcSkillsAndAuras(target, PROC_FLAG_DONE_PERIODIC, PROC_FLAG_TAKEN_PERIODIC, PROC_SPELL_TYPE_HEAL, PROC_SPELL_PHASE_NONE, PROC_HIT_NORMAL, nullptr, nullptr, &healInfo);
+ Unit::ProcSkillsAndAuras(caster, target, PROC_FLAG_DONE_PERIODIC, PROC_FLAG_TAKEN_PERIODIC, PROC_SPELL_TYPE_HEAL, PROC_SPELL_PHASE_NONE, PROC_HIT_NORMAL, nullptr, nullptr, &healInfo);
}
void AuraEffect::HandlePeriodicHealAurasTick(Unit* target, Unit* caster) const
{
- if (!caster || !target->IsAlive())
+ // dynobj auras must always have a caster
+ ASSERT(GetSpellEffectInfo()->Effect != SPELL_EFFECT_PERSISTENT_AREA_AURA || caster);
+
+ if (!target->IsAlive())
return;
if (target->HasUnitState(UNIT_STATE_ISOLATED))
@@ -5425,51 +5424,26 @@ void AuraEffect::HandlePeriodicHealAurasTick(Unit* target, Unit* caster) const
}
// heal for caster damage (must be alive)
- if (target != caster && GetSpellInfo()->HasAttribute(SPELL_ATTR2_HEALTH_FUNNEL) && !caster->IsAlive())
+ if (target != caster && GetSpellInfo()->HasAttribute(SPELL_ATTR2_HEALTH_FUNNEL) && (!caster || !caster->IsAlive()))
return;
// don't regen when permanent aura target has full power
if (GetBase()->IsPermanent() && target->IsFullHealth())
return;
- bool isAreaAura = GetSpellEffectInfo()->IsAreaAuraEffect() || GetSpellEffectInfo()->IsEffect(SPELL_EFFECT_PERSISTENT_AREA_AURA);
// ignore negative values (can be result apply spellmods to aura damage
- int32 damage = isAreaAura ? std::max(GetAmount(), 0) : m_damage;
+ uint32 damage = std::max(GetAmount(), 0);
if (GetAuraType() == SPELL_AURA_OBS_MOD_HEALTH)
- {
- // Taken mods
- float TakenTotalMod = 1.0f;
-
- // Tenacity increase healing % taken
- if (AuraEffect const* Tenacity = target->GetAuraEffect(58549, 0))
- AddPct(TakenTotalMod, Tenacity->GetAmount());
-
- // Healing taken percent
- float minval = (float)target->GetMaxNegativeAuraModifier(SPELL_AURA_MOD_HEALING_PCT);
- if (minval)
- AddPct(TakenTotalMod, minval);
-
- float maxval = (float)target->GetMaxPositiveAuraModifier(SPELL_AURA_MOD_HEALING_PCT);
- if (maxval)
- AddPct(TakenTotalMod, maxval);
-
- TakenTotalMod = std::max(TakenTotalMod, 0.0f);
-
damage = uint32(target->CountPctFromMaxHealth(damage));
- damage = uint32(damage * TakenTotalMod);
- }
- else
- {
- if (isAreaAura)
- damage = caster->SpellHealingBonusDone(target, GetSpellInfo(), damage, DOT, GetSpellEffectInfo(), GetBase()->GetStackAmount()) * caster->SpellHealingPctDone(target, m_spellInfo);
- damage = target->SpellHealingBonusTaken(caster, GetSpellInfo(), damage, DOT, GetSpellEffectInfo(), GetBase()->GetStackAmount());
- }
+ else if (caster)
+ damage = caster->SpellHealingBonusDone(target, GetSpellInfo(), damage, DOT, GetSpellEffectInfo(), GetBase()->GetStackAmount());
- bool crit = roll_chance_f(isAreaAura ? caster->GetUnitSpellCriticalChance(target, nullptr, this, m_spellInfo->GetSchoolMask()) : m_critChance);
+ damage = target->SpellHealingBonusTaken(caster, GetSpellInfo(), damage, DOT, GetSpellEffectInfo(), GetBase()->GetStackAmount());
+ bool crit = roll_chance_f(GetCritChanceFor(caster, target));
if (crit)
- damage = caster->SpellCriticalHealingBonus(m_spellInfo, damage, target);
+ damage = Unit::SpellCriticalHealingBonus(caster, m_spellInfo, damage, target);
TC_LOG_DEBUG("spells.periodic", "PeriodicTick: %s heal of %s for %u health inflicted by %u",
GetCasterGUID().ToString().c_str(), target->GetGUID().ToString().c_str(), damage, GetId());
@@ -5477,13 +5451,14 @@ void AuraEffect::HandlePeriodicHealAurasTick(Unit* target, Unit* caster) const
uint32 heal = damage;
HealInfo healInfo(caster, target, damage, GetSpellInfo(), GetSpellInfo()->GetSchoolMask());
- caster->CalcHealAbsorb(healInfo);
- caster->DealHeal(healInfo);
+ Unit::CalcHealAbsorb(healInfo);
+ Unit::DealHeal(healInfo);
SpellPeriodicAuraLogInfo pInfo(this, heal, damage, heal - healInfo.GetEffectiveHeal(), healInfo.GetAbsorb(), 0, 0.0f, crit);
target->SendPeriodicAuraLog(&pInfo);
- target->GetThreatManager().ForwardThreatForAssistingMe(caster, float(healInfo.GetEffectiveHeal())*0.5f, GetSpellInfo());
+ if (caster)
+ target->GetThreatManager().ForwardThreatForAssistingMe(caster, healInfo.GetEffectiveHeal() * 0.5f, GetSpellInfo());
// %-based heal - does not proc auras
if (GetAuraType() == SPELL_AURA_OBS_MOD_HEALTH)
@@ -5494,7 +5469,7 @@ void AuraEffect::HandlePeriodicHealAurasTick(Unit* target, Unit* caster) const
uint32 hitMask = crit ? PROC_HIT_CRITICAL : PROC_HIT_NORMAL;
// ignore item heals
if (GetBase()->GetCastItemGUID().IsEmpty())
- caster->ProcSkillsAndAuras(target, procAttacker, procVictim, PROC_SPELL_TYPE_HEAL, PROC_SPELL_PHASE_NONE, hitMask, nullptr, nullptr, &healInfo);
+ Unit::ProcSkillsAndAuras(caster, target, procAttacker, procVictim, PROC_SPELL_TYPE_HEAL, PROC_SPELL_PHASE_NONE, hitMask, nullptr, nullptr, &healInfo);
}
void AuraEffect::HandlePeriodicManaLeechAuraTick(Unit* target, Unit* caster) const
@@ -5515,7 +5490,7 @@ void AuraEffect::HandlePeriodicManaLeechAuraTick(Unit* target, Unit* caster) con
return;
// ignore negative values (can be result apply spellmods to aura damage
- int32 drainAmount = std::max(m_amount, 0);
+ int32 drainAmount = std::max(GetAmount(), 0);
TC_LOG_DEBUG("spells.periodic", "PeriodicTick: %s power leech of %s for %u dmg inflicted by %u",
GetCasterGUID().ToString().c_str(), target->GetGUID().ToString().c_str(), drainAmount, GetId());
@@ -5578,7 +5553,7 @@ void AuraEffect::HandleObsModPowerAuraTick(Unit* target, Unit* caster) const
return;
// ignore negative values (can be result apply spellmods to aura damage
- uint32 amount = std::max(m_amount, 0) * target->GetMaxPower(powerType) /100;
+ uint32 amount = std::max(GetAmount(), 0) * target->GetMaxPower(powerType) /100;
TC_LOG_DEBUG("spells.periodic", "PeriodicTick: %s energize %s for %u dmg inflicted by %u",
GetCasterGUID().ToString().c_str(), target->GetGUID().ToString().c_str(), amount, GetId());
@@ -5608,7 +5583,7 @@ void AuraEffect::HandlePeriodicEnergizeAuraTick(Unit* target, Unit* caster) cons
return;
// ignore negative values (can be result apply spellmods to aura damage
- int32 amount = std::max(m_amount, 0);
+ int32 amount = std::max(GetAmount(), 0);
SpellPeriodicAuraLogInfo pInfo(this, amount, amount, 0, 0, 0, 0.0f, false);
@@ -5636,7 +5611,7 @@ void AuraEffect::HandlePeriodicPowerBurnAuraTick(Unit* target, Unit* caster) con
}
// ignore negative values (can be result apply spellmods to aura damage
- int32 damage = std::max(m_amount, 0);
+ int32 damage = std::max(GetAmount(), 0);
uint32 gain = uint32(-target->ModifyPower(powerType, -damage));
@@ -5648,7 +5623,7 @@ void AuraEffect::HandlePeriodicPowerBurnAuraTick(Unit* target, Unit* caster) con
// no SpellDamageBonus for burn mana
caster->CalculateSpellDamageTaken(&damageInfo, int32(gain * dmgMultiplier), spellProto);
- caster->DealDamageMods(damageInfo.target, damageInfo.damage, &damageInfo.absorb);
+ Unit::DealDamageMods(damageInfo.attacker, damageInfo.target, damageInfo.damage, &damageInfo.absorb);
// Set trigger flag
uint32 procAttacker = PROC_FLAG_DONE_PERIODIC;
@@ -5664,7 +5639,7 @@ void AuraEffect::HandlePeriodicPowerBurnAuraTick(Unit* target, Unit* caster) con
caster->DealSpellDamage(&damageInfo, true);
DamageInfo dotDamageInfo(damageInfo, DOT, BASE_ATTACK, hitMask);
- caster->ProcSkillsAndAuras(target, procAttacker, procVictim, spellTypeMask, PROC_SPELL_PHASE_NONE, hitMask, nullptr, &dotDamageInfo, nullptr);
+ Unit::ProcSkillsAndAuras(caster, target, procAttacker, procVictim, spellTypeMask, PROC_SPELL_PHASE_NONE, hitMask, nullptr, &dotDamageInfo, nullptr);
caster->SendSpellNonMeleeDamageLog(&damageInfo);
}
@@ -5725,7 +5700,7 @@ void AuraEffect::HandleProcTriggerDamageAuraProc(AuraApplication* aurApp, ProcEv
uint32 damage = target->SpellDamageBonusDone(triggerTarget, GetSpellInfo(), GetAmount(), SPELL_DIRECT_DAMAGE, GetSpellEffectInfo());
damage = triggerTarget->SpellDamageBonusTaken(target, GetSpellInfo(), damage, SPELL_DIRECT_DAMAGE, GetSpellEffectInfo());
target->CalculateSpellDamageTaken(&damageInfo, damage, GetSpellInfo());
- target->DealDamageMods(damageInfo.target, damageInfo.damage, &damageInfo.absorb);
+ Unit::DealDamageMods(damageInfo.attacker, damageInfo.target, damageInfo.damage, &damageInfo.absorb);
TC_LOG_DEBUG("spells", "AuraEffect::HandleProcTriggerDamageAuraProc: Triggering %u spell damage from aura %u proc", damage, GetId());
target->DealSpellDamage(&damageInfo, true);
target->SendSpellNonMeleeDamageLog(&damageInfo);
diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.h b/src/server/game/Spells/Auras/SpellAuraEffects.h
index ff6cba63688..51e8d738cff 100644
--- a/src/server/game/Spells/Auras/SpellAuraEffects.h
+++ b/src/server/game/Spells/Auras/SpellAuraEffects.h
@@ -54,8 +54,8 @@ class TC_GAME_API AuraEffect
int32 GetMiscValueB() const { return GetSpellEffectInfo()->MiscValueB; }
int32 GetMiscValue() const { return GetSpellEffectInfo()->MiscValue; }
AuraType GetAuraType() const { return (AuraType)GetSpellEffectInfo()->ApplyAuraName; }
- int32 GetAmount() const { return m_amount; }
- void SetAmount(int32 amount) { m_amount = amount; m_canBeRecalculated = false;}
+ int32 GetAmount() const { return _amount; }
+ void SetAmount(int32 amount) { _amount = amount; m_canBeRecalculated = false; }
int32 GetPeriodicTimer() const { return _periodicTimer; }
void SetPeriodicTimer(int32 periodicTimer) { _periodicTimer = periodicTimer; }
@@ -72,13 +72,6 @@ class TC_GAME_API AuraEffect
void HandleEffect(Unit* target, uint8 mode, bool apply, AuraEffect const* triggeredBy = nullptr);
void ApplySpellMod(Unit* target, bool apply, AuraEffect const* triggeredBy = nullptr);
- void SetDamage(int32 val) { m_damage = val; }
- int32 GetDamage() const { return m_damage; }
- void SetCritChance(float val) { m_critChance = val; }
- float GetCritChance() const { return m_critChance; }
- void SetDonePct(float val) { m_donePct = val; }
- float GetDonePct() const { return m_donePct; }
-
void Update(uint32 diff, Unit* caster);
uint32 GetTickNumber() const { return _ticksDone; }
@@ -116,10 +109,7 @@ class TC_GAME_API AuraEffect
SpellModifier* m_spellmod;
int32 const m_baseAmount;
- int32 m_amount;
- int32 m_damage;
- float m_critChance;
- float m_donePct;
+ int32 _amount;
// periodic stuff
int32 _periodicTimer;
@@ -129,6 +119,8 @@ class TC_GAME_API AuraEffect
bool m_canBeRecalculated;
bool m_isPeriodic;
+ float GetCritChanceFor(Unit const* caster, Unit const* target) const;
+
public:
// aura effect apply/remove handlers
void HandleNULL(AuraApplication const* /*aurApp*/, uint8 /*mode*/, bool /*apply*/) const
diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp
index aaba2370cc4..fe1ed0caefe 100644
--- a/src/server/game/Spells/Auras/SpellAuras.cpp
+++ b/src/server/game/Spells/Auras/SpellAuras.cpp
@@ -386,6 +386,19 @@ void Aura::_InitEffects(uint32 effMask, Unit* caster, int32 *baseAmount)
_effects[effect->EffectIndex] = new AuraEffect(this, effect, baseAmount ? baseAmount + effect->EffectIndex : nullptr, caster);
}
+float Aura::CalcPeriodicCritChance(Unit const* caster) const
+{
+ if (!caster)
+ return 0.0f;
+
+ Player* modOwner = caster->GetSpellModOwner();
+ if (!modOwner)
+ return 0.0f;
+
+ float critChance = modOwner->SpellCritChanceDone(GetSpellInfo(), GetSpellInfo()->GetSchoolMask(), GetSpellInfo()->GetAttackType());
+ return std::max(0.0f, critChance);
+}
+
Aura::~Aura()
{
// unload scripts
@@ -916,13 +929,8 @@ void Aura::SetStackAmount(uint8 stackAmount)
effect->ChangeAmount(effect->CalculateAmount(caster), false, true);
for (std::list<AuraApplication*>::const_iterator apptItr = applications.begin(); apptItr != applications.end(); ++apptItr)
- {
if (!(*apptItr)->GetRemoveMode())
- {
- HandleAuraSpecificPeriodics(*apptItr, caster);
HandleAuraSpecificMods(*apptItr, caster, true, true);
- }
- }
SetNeedClientUpdateForTargets();
}
@@ -1419,55 +1427,6 @@ void Aura::HandleAuraSpecificMods(AuraApplication const* aurApp, Unit* caster, b
}
}
-void Aura::HandleAuraSpecificPeriodics(AuraApplication const* aurApp, Unit* caster)
-{
- Unit* target = aurApp->GetTarget();
-
- if (!caster || aurApp->GetRemoveMode())
- return;
-
- for (AuraEffect* effect : GetAuraEffects())
- {
- if (!effect || effect->IsAreaAuraEffect() || effect->IsEffect(SPELL_EFFECT_PERSISTENT_AREA_AURA))
- continue;
-
- switch (effect->GetSpellEffectInfo()->ApplyAuraName)
- {
- case SPELL_AURA_PERIODIC_DAMAGE:
- case SPELL_AURA_PERIODIC_DAMAGE_PERCENT:
- case SPELL_AURA_PERIODIC_LEECH:
- {
- // ignore non positive values (can be result apply spellmods to aura damage
- uint32 damage = std::max(effect->GetAmount(), 0);
-
- // Script Hook For HandlePeriodicDamageAurasTick -- Allow scripts to change the Damage pre class mitigation calculations
- sScriptMgr->ModifyPeriodicDamageAurasTick(target, caster, damage);
-
- effect->SetDonePct(caster->SpellDamagePctDone(target, m_spellInfo, DOT)); // Calculate done percentage first!
- effect->SetDamage(caster->SpellDamageBonusDone(target, m_spellInfo, damage, DOT, effect->GetSpellEffectInfo(), GetStackAmount()) * effect->GetDonePct());
- effect->SetCritChance(caster->GetUnitSpellCriticalChance(target, nullptr, effect, m_spellInfo->GetSchoolMask()));
- break;
- }
- case SPELL_AURA_PERIODIC_HEAL:
- case SPELL_AURA_OBS_MOD_HEALTH:
- {
- // ignore non positive values (can be result apply spellmods to aura damage
- uint32 damage = std::max(effect->GetAmount(), 0);
-
- // Script Hook For HandlePeriodicDamageAurasTick -- Allow scripts to change the Damage pre class mitigation calculations
- sScriptMgr->ModifyPeriodicDamageAurasTick(target, caster, damage);
-
- effect->SetDonePct(caster->SpellHealingPctDone(target, m_spellInfo)); // Calculate done percentage first!
- effect->SetDamage(caster->SpellHealingBonusDone(target, m_spellInfo, damage, DOT, effect->GetSpellEffectInfo(), GetStackAmount()) * effect->GetDonePct());
- effect->SetCritChance(caster->GetUnitSpellCriticalChance(target, nullptr, effect, m_spellInfo->GetSchoolMask()));
- break;
- }
- default:
- break;
- }
- }
-}
-
bool Aura::CanBeAppliedOn(Unit* target)
{
// unit not in world or during remove from world
@@ -1853,7 +1812,7 @@ float Aura::CalcPPMProcChance(Unit* actor) const
using FSeconds = std::chrono::duration<float, Seconds::period>;
// Formula see http://us.battle.net/wow/en/forum/topic/8197741003#1
- float ppm = m_spellInfo->CalcProcPPM(actor, m_castItemLevel);
+ float ppm = m_spellInfo->CalcProcPPM(actor, GetCastItemLevel());
float averageProcInterval = 60.0f / ppm;
std::chrono::steady_clock::time_point currentTime = GameTime::GetGameTimeSteadyPoint();
@@ -2068,7 +2027,7 @@ void Aura::CallScriptEffectCalcSpellModHandlers(AuraEffect const* aurEff, SpellM
}
}
-void Aura::CallScriptEffectCalcCritChanceHandlers(AuraEffect const* aurEff, AuraApplication const* aurApp, Unit* victim, float& critChance)
+void Aura::CallScriptEffectCalcCritChanceHandlers(AuraEffect const* aurEff, AuraApplication const* aurApp, Unit const* victim, float& critChance)
{
for (AuraScript* loadedScript : m_loadedScripts)
{
diff --git a/src/server/game/Spells/Auras/SpellAuras.h b/src/server/game/Spells/Auras/SpellAuras.h
index acb1ff5bf3f..7f55bc70fb1 100644
--- a/src/server/game/Spells/Auras/SpellAuras.h
+++ b/src/server/game/Spells/Auras/SpellAuras.h
@@ -90,7 +90,6 @@ class TC_GAME_API AuraApplication
void ClientUpdate(bool remove = false);
};
-#pragma pack(push, 1)
// Structure representing database aura primary key fields
struct AuraKey
{
@@ -101,7 +100,9 @@ struct AuraKey
bool operator<(AuraKey const& right) const
{
- return memcmp(this, &right, sizeof(*this)) < 0;
+ auto comparisonTuple = [](AuraKey const& k) { return std::tie(k.Caster, k.Item, k.SpellId, k.EffectMask); };
+
+ return comparisonTuple(*this) < comparisonTuple(right);
}
};
@@ -110,7 +111,6 @@ struct AuraLoadEffectInfo
std::array<int32, MAX_SPELL_EFFECTS> Amounts;
std::array<int32, MAX_SPELL_EFFECTS> BaseAmounts;
};
-#pragma pack(pop)
class TC_GAME_API Aura
{
@@ -182,7 +182,6 @@ class TC_GAME_API Aura
uint8 GetStackAmount() const { return m_stackAmount; }
void SetStackAmount(uint8 num);
bool ModStackAmount(int32 num, AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT, bool resetPeriodicTimer = true);
-
uint32 CalcMaxStackAmount() const;
bool IsUsingStacks() const;
@@ -223,6 +222,8 @@ class TC_GAME_API Aura
void SetLoadedState(int32 maxDuration, int32 duration, int32 charges, uint8 stackAmount, uint32 recalculateMask, int32* amount);
// helpers for aura effects
+ float CalcPeriodicCritChance(Unit const* caster) const;
+
bool HasEffect(uint8 effIndex) const { return GetEffect(effIndex) != nullptr; }
bool HasEffectType(AuraType type) const;
static bool EffectTypeNeedsSendingAmount(AuraType type);
@@ -240,7 +241,6 @@ class TC_GAME_API Aura
void SetNeedClientUpdateForTargets() const;
void HandleAuraSpecificMods(AuraApplication const* aurApp, Unit* caster, bool apply, bool onReapply);
- void HandleAuraSpecificPeriodics(AuraApplication const* aurApp, Unit* caster);
bool CanBeAppliedOn(Unit* target);
bool CheckAreaTarget(Unit* target);
bool CanStackWith(Aura const* existingAura) const;
@@ -271,7 +271,7 @@ class TC_GAME_API Aura
void CallScriptEffectCalcAmountHandlers(AuraEffect const* aurEff, int32 & amount, bool & canBeRecalculated);
void CallScriptEffectCalcPeriodicHandlers(AuraEffect const* aurEff, bool & isPeriodic, int32 & amplitude);
void CallScriptEffectCalcSpellModHandlers(AuraEffect const* aurEff, SpellModifier* & spellMod);
- void CallScriptEffectCalcCritChanceHandlers(AuraEffect const* aurEff, AuraApplication const* aurApp, Unit* victim, float& critChance);
+ void CallScriptEffectCalcCritChanceHandlers(AuraEffect const* aurEff, AuraApplication const* aurApp, Unit const* victim, float& critChance);
void CallScriptEffectAbsorbHandlers(AuraEffect* aurEff, AuraApplication const* aurApp, DamageInfo & dmgInfo, uint32 & absorbAmount, bool & defaultPrevented);
void CallScriptEffectAfterAbsorbHandlers(AuraEffect* aurEff, AuraApplication const* aurApp, DamageInfo & dmgInfo, uint32 & absorbAmount);
void CallScriptEffectManaShieldHandlers(AuraEffect* aurEff, AuraApplication const* aurApp, DamageInfo & dmgInfo, uint32 & absorbAmount, bool & defaultPrevented);
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index f9d166338c0..e66482430fc 100644
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -2074,7 +2074,7 @@ class ProcReflectDelayed : public BasicEvent
uint32 const spellPhaseMask = PROC_SPELL_PHASE_NONE;
uint32 const hitMask = PROC_HIT_REFLECT;
- caster->ProcSkillsAndAuras(_victim, typeMaskActor, typeMaskActionTarget, spellTypeMask, spellPhaseMask, hitMask, nullptr, nullptr, nullptr);
+ Unit::ProcSkillsAndAuras(caster, _victim, typeMaskActor, typeMaskActionTarget, spellTypeMask, spellPhaseMask, hitMask, nullptr, nullptr, nullptr);
return true;
}
@@ -2473,7 +2473,7 @@ void Spell::DoAllEffectOnTarget(TargetInfo* target)
if (crit)
{
hitMask |= PROC_HIT_CRITICAL;
- addhealth = caster->SpellCriticalHealingBonus(m_spellInfo, addhealth, nullptr);
+ addhealth = Unit::SpellCriticalHealingBonus(caster, m_spellInfo, addhealth, nullptr);
}
else
hitMask |= PROC_HIT_NORMAL;
@@ -2485,7 +2485,7 @@ void Spell::DoAllEffectOnTarget(TargetInfo* target)
// Do triggers for unit
if (canEffectTrigger)
- caster->ProcSkillsAndAuras(unitTarget, procAttacker, procVictim, PROC_SPELL_TYPE_HEAL, PROC_SPELL_PHASE_HIT, hitMask, this, nullptr, &healInfo);
+ Unit::ProcSkillsAndAuras(caster, unitTarget, procAttacker, procVictim, PROC_SPELL_TYPE_HEAL, PROC_SPELL_PHASE_HIT, hitMask, this, nullptr, &healInfo);
}
// Do damage and triggers
else if (m_damage > 0)
@@ -2505,7 +2505,7 @@ void Spell::DoAllEffectOnTarget(TargetInfo* target)
{
// Add bonuses and fill damageInfo struct
caster->CalculateSpellDamageTaken(&damageInfo, m_damage, m_spellInfo, m_attackType, target->crit);
- caster->DealDamageMods(damageInfo.target, damageInfo.damage, &damageInfo.absorb);
+ Unit::DealDamageMods(damageInfo.attacker, damageInfo.target, damageInfo.damage, &damageInfo.absorb);
hitMask |= createProcHitMask(&damageInfo, missInfo);
procVictim |= PROC_FLAG_TAKEN_DAMAGE;
@@ -2522,7 +2522,7 @@ void Spell::DoAllEffectOnTarget(TargetInfo* target)
if (canEffectTrigger)
{
DamageInfo spellDamageInfo(damageInfo, SPELL_DIRECT_DAMAGE, m_attackType, hitMask);
- caster->ProcSkillsAndAuras(unitTarget, procAttacker, procVictim, PROC_SPELL_TYPE_DAMAGE, PROC_SPELL_PHASE_HIT, hitMask, this, &spellDamageInfo, nullptr);
+ Unit::ProcSkillsAndAuras(caster, unitTarget, procAttacker, procVictim, PROC_SPELL_TYPE_DAMAGE, PROC_SPELL_PHASE_HIT, hitMask, this, &spellDamageInfo, nullptr);
if (caster->GetTypeId() == TYPEID_PLAYER && !m_spellInfo->HasAttribute(SPELL_ATTR0_STOP_ATTACK_TARGET) && !m_spellInfo->HasAttribute(SPELL_ATTR4_SUPPRESS_WEAPON_PROCS) &&
(m_spellInfo->DmgClass == SPELL_DAMAGE_CLASS_MELEE || m_spellInfo->DmgClass == SPELL_DAMAGE_CLASS_RANGED))
@@ -2539,7 +2539,7 @@ void Spell::DoAllEffectOnTarget(TargetInfo* target)
if (canEffectTrigger)
{
DamageInfo spellNoDamageInfo(damageInfo, NODAMAGE, m_attackType, hitMask);
- caster->ProcSkillsAndAuras(unitTarget, procAttacker, procVictim, PROC_SPELL_TYPE_NO_DMG_HEAL, PROC_SPELL_PHASE_HIT, hitMask, this, &spellNoDamageInfo, nullptr);
+ Unit::ProcSkillsAndAuras(caster, unitTarget, procAttacker, procVictim, PROC_SPELL_TYPE_NO_DMG_HEAL, PROC_SPELL_PHASE_HIT, hitMask, this, &spellNoDamageInfo, nullptr);
if (caster->GetTypeId() == TYPEID_PLAYER && !m_spellInfo->HasAttribute(SPELL_ATTR0_STOP_ATTACK_TARGET) && !m_spellInfo->HasAttribute(SPELL_ATTR4_SUPPRESS_WEAPON_PROCS) &&
(m_spellInfo->DmgClass == SPELL_DAMAGE_CLASS_MELEE || m_spellInfo->DmgClass == SPELL_DAMAGE_CLASS_RANGED))
@@ -3442,7 +3442,7 @@ void Spell::_cast(bool skipCheck)
if (!(_triggeredCastFlags & TRIGGERED_IGNORE_AURA_INTERRUPT_FLAGS) && !m_spellInfo->HasAttribute(SPELL_ATTR2_IGNORE_ACTION_AURA_INTERRUPT_FLAGS))
m_originalCaster->RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags::ActionDelayed);
- m_originalCaster->ProcSkillsAndAuras(nullptr, procAttacker, PROC_FLAG_NONE, PROC_SPELL_TYPE_MASK_ALL, PROC_SPELL_PHASE_CAST, hitMask, this, nullptr, nullptr);
+ Unit::ProcSkillsAndAuras(m_originalCaster, nullptr, procAttacker, PROC_FLAG_NONE, PROC_SPELL_TYPE_MASK_ALL, PROC_SPELL_PHASE_CAST, hitMask, this, nullptr, nullptr);
// Call CreatureAI hook OnSuccessfulSpellCast
if (Creature* caster = m_originalCaster->ToCreature())
@@ -3667,7 +3667,7 @@ void Spell::_handle_finish_phase()
procAttacker = IsPositive() ? PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS : PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_NEG;
}
- m_originalCaster->ProcSkillsAndAuras(nullptr, procAttacker, PROC_FLAG_NONE, PROC_SPELL_TYPE_MASK_ALL, PROC_SPELL_PHASE_FINISH, m_hitMask, this, nullptr, nullptr);
+ Unit::ProcSkillsAndAuras(m_originalCaster, nullptr, procAttacker, PROC_FLAG_NONE, PROC_SPELL_TYPE_MASK_ALL, PROC_SPELL_PHASE_FINISH, m_hitMask, this, nullptr, nullptr);
}
void Spell::SendSpellCooldown()
@@ -7477,9 +7477,7 @@ void Spell::DoAllEffectOnLaunchTarget(TargetInfo& targetInfo, float* multiplier)
{
if (effect->IsTargetingArea() || effect->IsAreaAuraEffect() || effect->IsEffect(SPELL_EFFECT_PERSISTENT_AREA_AURA))
{
- m_damage = int32(float(m_damage) * unit->GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_AOE_DAMAGE_AVOIDANCE, m_spellInfo->SchoolMask));
- if (m_caster->GetTypeId() != TYPEID_PLAYER)
- m_damage = int32(float(m_damage) * unit->GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_CREATURE_AOE_DAMAGE_AVOIDANCE, m_spellInfo->SchoolMask));
+ m_damage = unit->CalculateAOEAvoidance(m_damage, m_spellInfo->SchoolMask, m_caster);
if (m_caster->GetTypeId() == TYPEID_PLAYER)
{
@@ -7499,7 +7497,8 @@ void Spell::DoAllEffectOnLaunchTarget(TargetInfo& targetInfo, float* multiplier)
}
}
- targetInfo.crit = m_caster->IsSpellCrit(unit, this, nullptr, m_spellSchoolMask, m_attackType);
+ float critChance = m_caster->SpellCritChanceDone(m_spellInfo, m_spellSchoolMask, m_attackType);
+ targetInfo.crit = roll_chance_f(unit->SpellCritChanceTaken(m_caster, this, nullptr, m_spellSchoolMask, critChance, m_attackType));
}
SpellCastResult Spell::CanOpenLock(uint32 effIndex, uint32 lockId, SkillType& skillId, int32& reqSkillValue, int32& skillValue)
@@ -7782,7 +7781,7 @@ void Spell::CallScriptAfterHitHandlers()
}
}
-void Spell::CallScriptCalcCritChanceHandlers(Unit* victim, float& critChance)
+void Spell::CallScriptCalcCritChanceHandlers(Unit const* victim, float& critChance)
{
for (SpellScript* loadedScript : m_loadedScripts)
{
diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h
index a817e1dfc17..5966a8b1193 100644
--- a/src/server/game/Spells/Spell.h
+++ b/src/server/game/Spells/Spell.h
@@ -852,7 +852,7 @@ class TC_GAME_API Spell
void CallScriptOnHitHandlers();
void CallScriptAfterHitHandlers();
public:
- void CallScriptCalcCritChanceHandlers(Unit* victim, float& chance);
+ void CallScriptCalcCritChanceHandlers(Unit const* victim, float& chance);
protected:
void CallScriptObjectAreaTargetSelectHandlers(std::list<WorldObject*>& targets, SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType);
void CallScriptObjectTargetSelectHandlers(WorldObject*& target, SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType);
diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp
index e544e0ebfb2..a5620b9293c 100644
--- a/src/server/game/Spells/SpellEffects.cpp
+++ b/src/server/game/Spells/SpellEffects.cpp
@@ -420,10 +420,9 @@ void Spell::EffectInstaKill(SpellEffIndex /*effIndex*/)
data.Target = unitTarget->GetGUID();
data.Caster = m_caster->GetGUID();
data.SpellID = m_spellInfo->Id;
-
m_caster->SendMessageToSet(data.Write(), true);
- m_caster->DealDamage(unitTarget, unitTarget->GetHealth(), nullptr, NODAMAGE, SPELL_SCHOOL_MASK_NORMAL, nullptr, false);
+ Unit::DealDamage(m_caster, unitTarget, unitTarget->GetHealth(), nullptr, NODAMAGE, SPELL_SCHOOL_MASK_NORMAL, nullptr, false);
}
void Spell::EffectEnvironmentalDMG(SpellEffIndex /*effIndex*/)
@@ -440,7 +439,7 @@ void Spell::EffectEnvironmentalDMG(SpellEffIndex /*effIndex*/)
else
{
DamageInfo damageInfo(m_caster, unitTarget, damage, m_spellInfo, m_spellInfo->GetSchoolMask(), SPELL_DIRECT_DAMAGE, BASE_ATTACK);
- m_caster->CalcAbsorbResist(damageInfo);
+ Unit::CalcAbsorbResist(damageInfo);
SpellNonMeleeDamage log(m_caster, unitTarget, m_spellInfo, m_SpellVisual, m_spellInfo->GetSchoolMask(), m_castId);
log.damage = damageInfo.GetDamage();
@@ -1075,7 +1074,7 @@ void Spell::EffectPowerDrain(SpellEffIndex effIndex)
return;
// add spell damage bonus
- uint32 bonus = m_caster->SpellDamageBonusDone(unitTarget, m_spellInfo, (uint32)damage, SPELL_DIRECT_DAMAGE, effectInfo);
+ uint32 bonus = m_caster->SpellDamageBonusDone(unitTarget, m_spellInfo, uint32(damage), SPELL_DIRECT_DAMAGE, effectInfo);
damage = bonus + uint32(bonus * variance);
damage = unitTarget->SpellDamageBonusTaken(m_caster, m_spellInfo, uint32(damage), SPELL_DIRECT_DAMAGE, effectInfo);
@@ -1203,9 +1202,8 @@ void Spell::EffectHeal(SpellEffIndex /*effIndex*/)
addhealth = caster->SpellHealingBonusDone(unitTarget, m_spellInfo, int32(caster->CountPctFromMaxHealth(damage)), HEAL, effectInfo);
else
{
- addhealth = caster->SpellHealingBonusDone(unitTarget, m_spellInfo, addhealth, HEAL, effectInfo);
uint32 bonus = caster->SpellHealingBonusDone(unitTarget, m_spellInfo, addhealth, HEAL, effectInfo);
- damage = bonus + uint32(bonus * variance);
+ addhealth = bonus + uint32(bonus * variance);
}
addhealth = unitTarget->SpellHealingBonusTaken(caster, m_spellInfo, addhealth, HEAL, effectInfo);
@@ -1231,9 +1229,7 @@ void Spell::EffectHealPct(SpellEffIndex /*effIndex*/)
return;
uint32 heal = m_originalCaster->SpellHealingBonusDone(unitTarget, m_spellInfo, unitTarget->CountPctFromMaxHealth(damage), HEAL, effectInfo);
- heal = unitTarget->SpellHealingBonusTaken(m_originalCaster, m_spellInfo, heal, HEAL, effectInfo);
-
- m_healing += heal;
+ m_healing += unitTarget->SpellHealingBonusTaken(m_originalCaster, m_spellInfo, heal, HEAL, effectInfo);
}
void Spell::EffectHealMechanical(SpellEffIndex /*effIndex*/)
@@ -2969,10 +2965,10 @@ void Spell::EffectInterruptCast(SpellEffIndex effIndex)
int32 duration = m_spellInfo->GetDuration();
unitTarget->GetSpellHistory()->LockSpellSchool(curSpellInfo->GetSchoolMask(), unitTarget->ModSpellDuration(m_spellInfo, unitTarget, duration, false, 1 << effIndex));
if (m_spellInfo->DmgClass == SPELL_DAMAGE_CLASS_MAGIC)
- m_originalCaster->ProcSkillsAndAuras(unitTarget, PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG, PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG,
+ Unit::ProcSkillsAndAuras(m_originalCaster, unitTarget, PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG, PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG,
PROC_SPELL_TYPE_MASK_ALL, PROC_SPELL_PHASE_HIT, PROC_HIT_INTERRUPT, nullptr, nullptr, nullptr);
else if (m_spellInfo->DmgClass == SPELL_DAMAGE_CLASS_MELEE)
- m_originalCaster->ProcSkillsAndAuras(unitTarget, PROC_FLAG_DONE_SPELL_MELEE_DMG_CLASS, PROC_FLAG_TAKEN_SPELL_MELEE_DMG_CLASS,
+ Unit::ProcSkillsAndAuras(m_originalCaster, unitTarget, PROC_FLAG_DONE_SPELL_MELEE_DMG_CLASS, PROC_FLAG_TAKEN_SPELL_MELEE_DMG_CLASS,
PROC_SPELL_TYPE_MASK_ALL, PROC_SPELL_PHASE_HIT, PROC_HIT_INTERRUPT, nullptr, nullptr, nullptr);
}
ExecuteLogEffectInterruptCast(effIndex, unitTarget, curSpellInfo->Id);
@@ -3589,7 +3585,7 @@ void Spell::EffectStuck(SpellEffIndex /*effIndex*/)
// the player dies if hearthstone is in cooldown, else the player is teleported to home
if (player->GetSpellHistory()->HasCooldown(8690))
{
- player->Kill(player);
+ player->KillSelf();
return;
}
diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp
index be712095f14..be77f4af514 100644
--- a/src/server/game/Spells/SpellMgr.cpp
+++ b/src/server/game/Spells/SpellMgr.cpp
@@ -3341,6 +3341,19 @@ void SpellMgr::LoadSpellInfoCorrections()
});
}
+ // Allows those to crit
+ ApplySpellFix({
+ 379, // Earth Shield
+ 71607, // Item - Bauble of True Blood 10m
+ 71646, // Item - Bauble of True Blood 25m
+ 71610, // Item - Althor's Abacus trigger 10m
+ 71641 // Item - Althor's Abacus trigger 25m
+ }, [](SpellInfo* spellInfo)
+ {
+ // We need more spells to find a general way (if there is any)
+ spellInfo->DmgClass = SPELL_DAMAGE_CLASS_MAGIC;
+ });
+
ApplySpellFix({
63026, // Summon Aspirant Test NPC (HACK: Target shouldn't be changed)
63137 // Summon Valiant Test (HACK: Target shouldn't be changed; summon position should be untied from spell destination)
diff --git a/src/server/game/Spells/SpellScript.cpp b/src/server/game/Spells/SpellScript.cpp
index 294028d8882..d437790b48b 100644
--- a/src/server/game/Spells/SpellScript.cpp
+++ b/src/server/game/Spells/SpellScript.cpp
@@ -249,7 +249,7 @@ SpellScript::OnCalcCritChanceHandler::OnCalcCritChanceHandler(SpellOnCalcCritCha
_onCalcCritChanceHandlerScript = onCalcCritChanceHandlerScript;
}
-void SpellScript::OnCalcCritChanceHandler::Call(SpellScript* spellScript, Unit* victim, float& critChance) const
+void SpellScript::OnCalcCritChanceHandler::Call(SpellScript* spellScript, Unit const* victim, float& critChance) const
{
(spellScript->*_onCalcCritChanceHandlerScript)(victim, critChance);
}
@@ -952,7 +952,7 @@ AuraScript::EffectCalcCritChanceHandler::EffectCalcCritChanceHandler(AuraEffectC
_effectHandlerScript = effectHandlerScript;
}
-void AuraScript::EffectCalcCritChanceHandler::Call(AuraScript* auraScript, AuraEffect const* aurEff, Unit* victim, float& critChance) const
+void AuraScript::EffectCalcCritChanceHandler::Call(AuraScript* auraScript, AuraEffect const* aurEff, Unit const* victim, float& critChance) const
{
(auraScript->*_effectHandlerScript)(aurEff, victim, critChance);
}
diff --git a/src/server/game/Spells/SpellScript.h b/src/server/game/Spells/SpellScript.h
index fc665f0947a..2a52b953266 100644
--- a/src/server/game/Spells/SpellScript.h
+++ b/src/server/game/Spells/SpellScript.h
@@ -193,7 +193,7 @@ class TC_GAME_API SpellScript : public _SpellScript
typedef void(CLASSNAME::*SpellBeforeHitFnType)(SpellMissInfo missInfo); \
typedef void(CLASSNAME::*SpellHitFnType)(); \
typedef void(CLASSNAME::*SpellCastFnType)(); \
- typedef void(CLASSNAME::*SpellOnCalcCritChanceFnType)(Unit* victim, float& chance); \
+ typedef void(CLASSNAME::*SpellOnCalcCritChanceFnType)(Unit const* victim, float& chance); \
typedef void(CLASSNAME::*SpellObjectAreaTargetSelectFnType)(std::list<WorldObject*>&); \
typedef void(CLASSNAME::*SpellObjectTargetSelectFnType)(WorldObject*&); \
typedef void(CLASSNAME::*SpellDestinationTargetSelectFnType)(SpellDestination&);
@@ -251,7 +251,7 @@ class TC_GAME_API SpellScript : public _SpellScript
{
public:
OnCalcCritChanceHandler(SpellOnCalcCritChanceFnType onCalcCritChanceHandlerScript);
- void Call(SpellScript* spellScript, Unit* victim, float& critChance) const;
+ void Call(SpellScript* spellScript, Unit const* victim, float& critChance) const;
private:
SpellOnCalcCritChanceFnType _onCalcCritChanceHandlerScript;
};
@@ -563,7 +563,7 @@ class TC_GAME_API AuraScript : public _SpellScript
typedef void(CLASSNAME::*AuraEffectCalcAmountFnType)(AuraEffect const*, int32 &, bool &); \
typedef void(CLASSNAME::*AuraEffectCalcPeriodicFnType)(AuraEffect const*, bool &, int32 &); \
typedef void(CLASSNAME::*AuraEffectCalcSpellModFnType)(AuraEffect const*, SpellModifier* &); \
- typedef void(CLASSNAME::*AuraEffectCalcCritChanceFnType)(AuraEffect const*, Unit*, float&); \
+ typedef void(CLASSNAME::*AuraEffectCalcCritChanceFnType)(AuraEffect const*, Unit const*, float&); \
typedef void(CLASSNAME::*AuraEffectAbsorbFnType)(AuraEffect*, DamageInfo &, uint32 &); \
typedef void(CLASSNAME::*AuraEffectSplitFnType)(AuraEffect*, DamageInfo &, uint32 &); \
typedef bool(CLASSNAME::*AuraCheckProcFnType)(ProcEventInfo&); \
@@ -641,7 +641,7 @@ class TC_GAME_API AuraScript : public _SpellScript
{
public:
EffectCalcCritChanceHandler(AuraEffectCalcCritChanceFnType effectHandlerScript, uint8 effIndex, uint16 effName);
- void Call(AuraScript* auraScript, AuraEffect const* aurEff, Unit* victim, float& critChance) const;
+ void Call(AuraScript* auraScript, AuraEffect const* aurEff, Unit const* victim, float& critChance) const;
private:
AuraEffectCalcCritChanceFnType _effectHandlerScript;
};
diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp
index 4cc34449eb0..7f534f71b9f 100644
--- a/src/server/scripts/Commands/cs_misc.cpp
+++ b/src/server/scripts/Commands/cs_misc.cpp
@@ -648,9 +648,9 @@ public:
if (target->IsAlive())
{
if (sWorld->getBoolConfig(CONFIG_DIE_COMMAND_MODE))
- handler->GetSession()->GetPlayer()->Kill(target);
+ Unit::Kill(handler->GetSession()->GetPlayer(), target);
else
- handler->GetSession()->GetPlayer()->DealDamage(target, target->GetHealth(), nullptr, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, nullptr, false);
+ Unit::DealDamage(handler->GetSession()->GetPlayer(), target, target->GetHealth(), nullptr, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, nullptr, false);
}
return true;
@@ -2408,7 +2408,7 @@ public:
// flat melee damage without resistence/etc reduction
if (!schoolStr)
{
- handler->GetSession()->GetPlayer()->DealDamage(target, damage, nullptr, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, nullptr, false);
+ Unit::DealDamage(handler->GetSession()->GetPlayer(), target, damage, nullptr, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, nullptr, false);
if (target != handler->GetSession()->GetPlayer())
handler->GetSession()->GetPlayer()->SendAttackStateUpdate (HITINFO_AFFECTS_VICTIM, target, 1, SPELL_SCHOOL_MASK_NORMAL, damage, 0, 0, VICTIMSTATE_HIT, 0);
return true;
@@ -2420,8 +2420,8 @@ public:
SpellSchoolMask schoolmask = SpellSchoolMask(1 << school);
- if (handler->GetSession()->GetPlayer()->IsDamageReducedByArmor(schoolmask))
- damage = handler->GetSession()->GetPlayer()->CalcArmorReducedDamage(handler->GetSession()->GetPlayer(), target, damage, nullptr, BASE_ATTACK);
+ if (Unit::IsDamageReducedByArmor(schoolmask))
+ damage = Unit::CalcArmorReducedDamage(handler->GetSession()->GetPlayer(), target, damage, nullptr, BASE_ATTACK);
char* spellStr = strtok((char*)nullptr, " ");
@@ -2431,7 +2431,7 @@ public:
if (!spellStr)
{
DamageInfo dmgInfo(attacker, target, damage, nullptr, schoolmask, SPELL_DIRECT_DAMAGE, BASE_ATTACK);
- attacker->CalcAbsorbResist(dmgInfo);
+ Unit::CalcAbsorbResist(dmgInfo);
if (!dmgInfo.GetDamage())
return true;
@@ -2440,8 +2440,8 @@ public:
uint32 absorb = dmgInfo.GetAbsorb();
uint32 resist = dmgInfo.GetResist();
- attacker->DealDamageMods(target, damage, &absorb);
- attacker->DealDamage(target, damage, nullptr, DIRECT_DAMAGE, schoolmask, nullptr, false);
+ Unit::DealDamageMods(attacker, target, damage, &absorb);
+ Unit::DealDamage(attacker, target, damage, nullptr, DIRECT_DAMAGE, schoolmask, nullptr, false);
attacker->SendAttackStateUpdate(HITINFO_AFFECTS_VICTIM, target, 0, schoolmask, damage, absorb, resist, VICTIMSTATE_HIT, 0);
return true;
}
@@ -2457,9 +2457,9 @@ public:
if (!spellInfo)
return false;
- SpellNonMeleeDamage damageInfo(attacker, target, spellInfo, { spellInfo->GetSpellXSpellVisualId(handler->GetSession()->GetPlayer()),0 }, spellInfo->SchoolMask);
+ SpellNonMeleeDamage damageInfo(attacker, target, spellInfo, { spellInfo->GetSpellXSpellVisualId(handler->GetSession()->GetPlayer()), 0 }, spellInfo->SchoolMask);
damageInfo.damage = damage;
- attacker->DealDamageMods(damageInfo.target, damageInfo.damage, &damageInfo.absorb);
+ Unit::DealDamageMods(damageInfo.attacker, damageInfo.target, damageInfo.damage, &damageInfo.absorb);
target->DealSpellDamage(&damageInfo, true);
target->SendSpellNonMeleeDamageLog(&damageInfo);
return true;
diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_ragnaros.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_ragnaros.cpp
index d2bd0d01504..0a4392d8ef2 100644
--- a/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_ragnaros.cpp
+++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_ragnaros.cpp
@@ -157,7 +157,7 @@ class boss_ragnaros : public CreatureScript
case EVENT_INTRO_4:
Talk(SAY_ARRIVAL5_RAG);
if (Creature* executus = ObjectAccessor::GetCreature(*me, instance->GetGuidData(BOSS_MAJORDOMO_EXECUTUS)))
- me->Kill(executus);
+ Unit::Kill(me, executus);
break;
case EVENT_INTRO_5:
me->SetReactState(REACT_AGGRESSIVE);
diff --git a/src/server/scripts/EasternKingdoms/Karazhan/karazhan.cpp b/src/server/scripts/EasternKingdoms/Karazhan/karazhan.cpp
index 66efdc34ede..8c8ab02a9dd 100644
--- a/src/server/scripts/EasternKingdoms/Karazhan/karazhan.cpp
+++ b/src/server/scripts/EasternKingdoms/Karazhan/karazhan.cpp
@@ -579,7 +579,7 @@ public:
}
case 15:
if (Creature* arca = ObjectAccessor::GetCreature(*me, ArcanagosGUID))
- arca->DealDamage(arca, arca->GetHealth(), nullptr, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, nullptr, false);
+ arca->KillSelf();
return 5000;
default:
return 9999999;
diff --git a/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp b/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp
index 6e0d047514e..b41a3d78c81 100644
--- a/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp
+++ b/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp
@@ -570,7 +570,7 @@ public:
{
//spell Burn should possible do this, but it doesn't, so do this for now.
uint16 dmg = urand(1650, 2050);
- me->DealDamage(me, dmg, nullptr, DOT, SPELL_SCHOOL_MASK_FIRE, nullptr, false);
+ Unit::DealDamage(me, me, dmg, nullptr, DOT, SPELL_SCHOOL_MASK_FIRE, nullptr, false);
BurnTimer += 2000;
} BurnTimer -= diff;
diff --git a/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter2.cpp b/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter2.cpp
index aa2cf832825..f9c2d609406 100644
--- a/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter2.cpp
+++ b/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter2.cpp
@@ -142,7 +142,7 @@ public:
case 6:
Talk(SAY_PERSUADED6);
- player->Kill(me);
+ Unit::Kill(player, me);
speechCounter = 0;
player->GroupEventHappens(QUEST_HOW_TO_WIN_FRIENDS, me);
return;
diff --git a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_brutallus.cpp b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_brutallus.cpp
index d21be4f569f..cb899bd4e3d 100644
--- a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_brutallus.cpp
+++ b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_brutallus.cpp
@@ -233,7 +233,7 @@ public:
++IntroPhase;
break;
case 7:
- me->Kill(Madrigosa);
+ Unit::Kill(me, Madrigosa);
Madrigosa->AI()->Talk(YELL_MADR_DEATH);
me->SetFullHealth();
me->AttackStop();
diff --git a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_felmyst.cpp b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_felmyst.cpp
index 2336a3d4177..cb38c495583 100644
--- a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_felmyst.cpp
+++ b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_felmyst.cpp
@@ -217,7 +217,7 @@ public:
summon->CastSpell(summon, SPELL_FOG_CHARM, true);
summon->CastSpell(summon, SPELL_FOG_CHARM2, true);
}
- me->DealDamage(caster, caster->GetHealth(), nullptr, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, nullptr, false);
+ Unit::DealDamage(me, caster, caster->GetHealth(), nullptr, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, nullptr, false);
}
}
diff --git a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kalecgos.cpp b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kalecgos.cpp
index da24c72d8dd..c971dbf1dcb 100644
--- a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kalecgos.cpp
+++ b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kalecgos.cpp
@@ -477,7 +477,7 @@ struct boss_sathrovarr : public BossAI
if (spell->Id == SPELL_TAP_CHECK_DAMAGE)
{
DoCastSelf(SPELL_TELEPORT_BACK, true);
- caster->Kill(me);
+ Unit::Kill(caster, me);
}
}
diff --git a/src/server/scripts/EasternKingdoms/zone_western_plaguelands.cpp b/src/server/scripts/EasternKingdoms/zone_western_plaguelands.cpp
index 7ab80813107..6a2c7f188d8 100644
--- a/src/server/scripts/EasternKingdoms/zone_western_plaguelands.cpp
+++ b/src/server/scripts/EasternKingdoms/zone_western_plaguelands.cpp
@@ -58,7 +58,7 @@ public:
void DoDie()
{
//summoner dies here
- me->DealDamage(me, me->GetHealth(), nullptr, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, nullptr, false);
+ me->KillSelf();
//override any database `spawntimesecs` to prevent duplicated summons
uint32 rTime = me->GetRespawnDelay();
if (rTime < 600)
diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_archimonde.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_archimonde.cpp
index 6e5bccf0b22..87e7d87458d 100644
--- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_archimonde.cpp
+++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_archimonde.cpp
@@ -390,7 +390,7 @@ public:
DoSpawnCreature(NPC_ANCIENT_WISP, float(rand32() % 40), float(rand32() % 40), 0, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
++WispCount;
if (WispCount >= 30)
- me->DealDamage(me, me->GetHealth(), nullptr, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, nullptr, false);
+ me->KillSelf();
events.ScheduleEvent(EVENT_SUMMON_WHISP, 1500);
break;
default:
diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/instance_culling_of_stratholme.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/instance_culling_of_stratholme.cpp
index 5a7ff84108f..ca6ae33eeaa 100644
--- a/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/instance_culling_of_stratholme.cpp
+++ b/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/instance_culling_of_stratholme.cpp
@@ -296,7 +296,7 @@ class instance_culling_of_stratholme : public InstanceMapScript
if (Creature* infinite = instance->GetCreature(_infiniteGUID))
{
if (Creature* guardian = infinite->FindNearestCreature(NPC_GUARDIAN_OF_TIME, 100.0f))
- infinite->Kill(guardian);
+ Unit::Kill(infinite, guardian);
if (Creature* rift = infinite->FindNearestCreature(NPC_TIME_RIFT, 100.0f))
{
diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/boss_aeonus.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/boss_aeonus.cpp
index c9fb3b273d9..e62b3ad2372 100644
--- a/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/boss_aeonus.cpp
+++ b/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/boss_aeonus.cpp
@@ -79,7 +79,7 @@ public:
if (me->IsWithinDistInMap(who, 20.0f))
{
Talk(SAY_BANISH);
- me->DealDamage(who, who->GetHealth(), nullptr, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, nullptr, false);
+ Unit::DealDamage(me, who, who->GetHealth(), nullptr, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, nullptr, false);
}
}
diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/boss_chrono_lord_deja.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/boss_chrono_lord_deja.cpp
index 2e2a6f321b4..6f0aeba2bd2 100644
--- a/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/boss_chrono_lord_deja.cpp
+++ b/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/boss_chrono_lord_deja.cpp
@@ -82,7 +82,7 @@ public:
if (me->IsWithinDistInMap(who, 20.0f))
{
Talk(SAY_BANISH);
- me->DealDamage(who, who->GetHealth(), nullptr, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, nullptr, false);
+ Unit::DealDamage(me, who, who->GetHealth(), nullptr, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, nullptr, false);
}
}
diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/boss_temporus.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/boss_temporus.cpp
index 9463a72ef51..eb768a27d88 100644
--- a/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/boss_temporus.cpp
+++ b/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/boss_temporus.cpp
@@ -93,7 +93,7 @@ public:
{
Talk(SAY_BANISH);
- me->DealDamage(who, who->GetHealth(), nullptr, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, nullptr, false);
+ Unit::DealDamage(me, who, who->GetHealth(), nullptr, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, nullptr, false);
}
}
diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/instance_the_black_morass.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/instance_the_black_morass.cpp
index bf355e9b5d1..054d3928748 100644
--- a/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/instance_the_black_morass.cpp
+++ b/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/instance_the_black_morass.cpp
@@ -181,7 +181,7 @@ public:
{
if (medivh->IsAlive())
{
- medivh->DealDamage(medivh, medivh->GetHealth(), nullptr, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, nullptr, false);
+ medivh->KillSelf();
m_auiEncounter[0] = FAIL;
m_auiEncounter[1] = NOT_STARTED;
}
diff --git a/src/server/scripts/Kalimdor/OnyxiasLair/boss_onyxia.cpp b/src/server/scripts/Kalimdor/OnyxiasLair/boss_onyxia.cpp
index b084f7cf2bc..3da118111cf 100644
--- a/src/server/scripts/Kalimdor/OnyxiasLair/boss_onyxia.cpp
+++ b/src/server/scripts/Kalimdor/OnyxiasLair/boss_onyxia.cpp
@@ -231,7 +231,7 @@ public:
me->SetDisableGravity(false);
me->SetAnimTier(UNIT_BYTE1_FLAG_NONE, false);
if (Creature* trigger = ObjectAccessor::GetCreature(*me, triggerGUID))
- me->Kill(trigger);
+ Unit::Kill(me, trigger);
me->SetReactState(REACT_AGGRESSIVE);
// tank selection based on phase one. If tank is not there i take nearest one
if (Unit* tank = ObjectAccessor::GetUnit(*me, tankGUID))
diff --git a/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/boss_buru.cpp b/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/boss_buru.cpp
index 9defa281c0d..62c20793c97 100644
--- a/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/boss_buru.cpp
+++ b/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/boss_buru.cpp
@@ -101,7 +101,7 @@ class boss_buru : public CreatureScript
{
if (action == ACTION_EXPLODE)
if (_phase == PHASE_EGG)
- me->DealDamage(me, 45000);
+ Unit::DealDamage(me, me, 45000);
}
void KilledUnit(Unit* victim) override
diff --git a/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_viscidus.cpp b/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_viscidus.cpp
index 49392be4ee4..6fa10647d47 100644
--- a/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_viscidus.cpp
+++ b/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_viscidus.cpp
@@ -284,7 +284,7 @@ class npc_glob_of_viscidus : public CreatureScript
{
Viscidus->SetVisible(true);
if (Viscidus->GetVictim())
- Viscidus->EnsureVictim()->Kill(Viscidus);
+ Unit::Kill(Viscidus->EnsureVictim(), Viscidus);
}
else
{
diff --git a/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/obsidian_sanctum.cpp b/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/obsidian_sanctum.cpp
index 190034b6228..b67d6df83a3 100644
--- a/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/obsidian_sanctum.cpp
+++ b/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/obsidian_sanctum.cpp
@@ -815,7 +815,7 @@ public:
me->SummonCreature(NPC_TWILIGHT_WHELP, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 60000);
else
me->SummonCreature(NPC_SARTHARION_TWILIGHT_WHELP, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 60000);
- me->DealDamage(me, me->GetHealth());
+ me->KillSelf();
}
void JustSummoned(Creature* who) override
diff --git a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_baltharus_the_warborn.cpp b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_baltharus_the_warborn.cpp
index 3934e636e1a..cbe62f4f6cc 100644
--- a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_baltharus_the_warborn.cpp
+++ b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_baltharus_the_warborn.cpp
@@ -273,7 +273,7 @@ class npc_baltharus_the_warborn_clone : public CreatureScript
{
// This is here because DamageTaken wont trigger if the damage is deadly.
if (Creature* baltharus = instance->GetCreature(DATA_BALTHARUS_THE_WARBORN))
- killer->Kill(baltharus);
+ Unit::Kill(killer, baltharus);
}
void UpdateAI(uint32 diff) override
diff --git a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp
index 7f7ed99314a..2251d623f4d 100644
--- a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp
+++ b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp
@@ -452,7 +452,7 @@ class boss_twilight_halion : public CreatureScript
halion->LowerPlayerDamageReq(halion->GetMaxHealth());
if (halion->IsAlive())
- killer->Kill(halion);
+ Unit::Kill(killer, halion);
}
if (Creature* controller = instance->GetCreature(DATA_HALION_CONTROLLER))
diff --git a/src/server/scripts/Northrend/Gundrak/boss_drakkari_colossus.cpp b/src/server/scripts/Northrend/Gundrak/boss_drakkari_colossus.cpp
index b6cebf1c172..f6835e0dbea 100644
--- a/src/server/scripts/Northrend/Gundrak/boss_drakkari_colossus.cpp
+++ b/src/server/scripts/Northrend/Gundrak/boss_drakkari_colossus.cpp
@@ -265,7 +265,7 @@ class boss_drakkari_elemental : public CreatureScript
Talk(EMOTE_ACTIVATE_ALTAR);
if (Creature* colossus = instance->GetCreature(DATA_DRAKKARI_COLOSSUS))
- killer->Kill(colossus);
+ Unit::Kill(killer, colossus);
}
void UpdateAI(uint32 diff) override
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_prince_council.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_prince_council.cpp
index c9790455396..024ed6b8731 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_prince_council.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_prince_council.cpp
@@ -330,7 +330,7 @@ class boss_blood_council_controller : public CreatureScript
// Make sure looting is allowed
if (me->IsDamageEnoughForLootingAndReward())
prince->LowerPlayerDamageReq(prince->GetMaxHealth());
- killer->Kill(prince);
+ Unit::Kill(killer, prince);
}
}
}
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp
index 3030f3145a6..a05607623cb 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp
@@ -373,7 +373,7 @@ class boss_valithria_dreamwalker : public CreatureScript
lichKing->CastSpell(lichKing, SPELL_SPAWN_CHEST, false);
if (Creature* trigger = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_VALITHRIA_TRIGGER)))
- me->Kill(trigger);
+ Unit::Kill(me, trigger);
}
}
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp
index 0fae791b82e..75f71b16024 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp
@@ -881,7 +881,7 @@ class boss_sister_svalna : public CreatureScript
switch (spell->Id)
{
case SPELL_IMPALING_SPEAR_KILL:
- me->Kill(target);
+ Unit::Kill(me, target);
break;
case SPELL_IMPALING_SPEAR:
if (TempSummon* summon = target->SummonCreature(NPC_IMPALING_SPEAR, *target))
diff --git a/src/server/scripts/Northrend/IsleOfConquest/boss_ioc_horde_alliance.cpp b/src/server/scripts/Northrend/IsleOfConquest/boss_ioc_horde_alliance.cpp
index 9434f49803e..570f21b0d34 100644
--- a/src/server/scripts/Northrend/IsleOfConquest/boss_ioc_horde_alliance.cpp
+++ b/src/server/scripts/Northrend/IsleOfConquest/boss_ioc_horde_alliance.cpp
@@ -71,7 +71,7 @@ public:
void SpellHit(Unit* caster, SpellInfo const* /*spell*/) override
{
if (caster->IsVehicle())
- me->Kill(caster);
+ Unit::Kill(me, caster);
}
void UpdateAI(uint32 diff) override
diff --git a/src/server/scripts/Northrend/Naxxramas/boss_faerlina.cpp b/src/server/scripts/Northrend/Naxxramas/boss_faerlina.cpp
index 00aecb3312c..2f1d0566a0f 100644
--- a/src/server/scripts/Northrend/Naxxramas/boss_faerlina.cpp
+++ b/src/server/scripts/Northrend/Naxxramas/boss_faerlina.cpp
@@ -130,7 +130,7 @@ class boss_faerlina : public CreatureScript
{
++_frenzyDispels;
Talk(EMOTE_WIDOW_EMBRACE, caster);
- me->Kill(caster);
+ Unit::Kill(me, caster);
}
}
diff --git a/src/server/scripts/Northrend/Ulduar/HallsOfStone/halls_of_stone.cpp b/src/server/scripts/Northrend/Ulduar/HallsOfStone/halls_of_stone.cpp
index f17ed5148f5..4d5113b1d1e 100644
--- a/src/server/scripts/Northrend/Ulduar/HallsOfStone/halls_of_stone.cpp
+++ b/src/server/scripts/Northrend/Ulduar/HallsOfStone/halls_of_stone.cpp
@@ -555,7 +555,7 @@ public:
me->SetStandState(UNIT_STAND_STATE_STAND);
instance->HandleGameObject(instance->GetGuidData(DATA_GO_SKY_FLOOR), true);
if (Creature* temp = ObjectAccessor::GetCreature(*me, uiControllerGUID))
- temp->DealDamage(temp, temp->GetHealth(), nullptr, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, nullptr, false);
+ temp->KillSelf();
bIsBattle = true;
SetEscortPaused(false);
JumpToNextStep(6500);
diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp
index 567a365efd9..7940d0b25e2 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp
@@ -1196,7 +1196,7 @@ class spell_algalon_collapse : public SpellScriptLoader
void HandlePeriodic(AuraEffect const* /*aurEff*/)
{
PreventDefaultAction();
- GetTarget()->DealDamage(GetTarget(), GetTarget()->CountPctFromMaxHealth(1), nullptr, NODAMAGE);
+ Unit::DealDamage(GetTarget(), GetTarget(), GetTarget()->CountPctFromMaxHealth(1), nullptr, NODAMAGE);
}
void Register() override
diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp
index 2076946b2ba..2e9fa68bc89 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp
@@ -366,9 +366,9 @@ static bool IsEncounterFinished(Unit* who)
vx001->GetStandState() == UNIT_STAND_STATE_DEAD &&
aerial->GetStandState() == UNIT_STAND_STATE_DEAD)
{
- who->Kill(mkii);
- who->Kill(vx001);
- who->Kill(aerial);
+ Unit::Kill(who, mkii);
+ Unit::Kill(who, vx001);
+ Unit::Kill(who, aerial);
mkii->DespawnOrUnsummon(120000);
vx001->DespawnOrUnsummon(120000);
aerial->DespawnOrUnsummon(120000);
diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_xt002.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_xt002.cpp
index ebf04754986..236353877e2 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_xt002.cpp
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_xt002.cpp
@@ -695,7 +695,7 @@ class npc_boombot : public CreatureScript
instakill.SpellID = SPELL_BOOM;
me->SendMessageToSet(instakill.Write(), false);
- me->DealDamage(me, me->GetHealth(), nullptr, NODAMAGE, SPELL_SCHOOL_MASK_NORMAL, nullptr, false);
+ me->KillSelf();
damage = 0;
diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_yogg_saron.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_yogg_saron.cpp
index d6ea96a1ec8..9a8399068e2 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_yogg_saron.cpp
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_yogg_saron.cpp
@@ -948,7 +948,7 @@ class boss_yogg_saron : public CreatureScript
Talk(SAY_YOGG_SARON_DEATH);
if (Creature* creature = _instance->GetCreature(DATA_VOICE_OF_YOGG_SARON))
- me->Kill(creature);
+ Unit::Kill(me, creature);
for (uint8 i = DATA_SARA; i <= DATA_BRAIN_OF_YOGG_SARON; ++i)
if (Creature* creature = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(i)))
@@ -3104,7 +3104,7 @@ class spell_yogg_saron_titanic_storm : public SpellScriptLoader // 64172
void HandleScript(SpellEffIndex /*effIndex*/)
{
if (Unit* target = GetHitUnit())
- GetCaster()->Kill(target);
+ Unit::Kill(GetCaster(), target);
}
void Register() override
diff --git a/src/server/scripts/Northrend/zone_borean_tundra.cpp b/src/server/scripts/Northrend/zone_borean_tundra.cpp
index ad80e29881c..2f41372df6d 100644
--- a/src/server/scripts/Northrend/zone_borean_tundra.cpp
+++ b/src/server/scripts/Northrend/zone_borean_tundra.cpp
@@ -149,7 +149,7 @@ public:
DoCast(me, SPELL_EXPLODE_CART, true);
if (Unit* worm = me->FindNearestCreature(NPC_SCOURGED_BURROWER, 3.0f))
{
- me->Kill(worm);
+ Unit::Kill(me, worm);
worm->RemoveDynamicFlag(UNIT_DYNFLAG_LOOTABLE);
}
phaseTimer = 2000;
diff --git a/src/server/scripts/Northrend/zone_grizzly_hills.cpp b/src/server/scripts/Northrend/zone_grizzly_hills.cpp
index 9fd63359db2..021fb8e7701 100644
--- a/src/server/scripts/Northrend/zone_grizzly_hills.cpp
+++ b/src/server/scripts/Northrend/zone_grizzly_hills.cpp
@@ -134,7 +134,7 @@ public:
{
if (Creature* RWORG = ObjectAccessor::GetCreature(*me, _RavenousworgGUID))
{
- RWORG->Kill(Mrfloppy);
+ Unit::Kill(RWORG, Mrfloppy);
Mrfloppy->ExitVehicle();
RWORG->SetFaction(FACTION_MONSTER);
RWORG->GetMotionMaster()->MovePoint(0, RWORG->GetPositionX()+10, RWORG->GetPositionY()+80, RWORG->GetPositionZ());
diff --git a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_fathomlord_karathress.cpp b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_fathomlord_karathress.cpp
index 85fa9eb3f90..5406c35e176 100644
--- a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_fathomlord_karathress.cpp
+++ b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_fathomlord_karathress.cpp
@@ -348,7 +348,7 @@ public:
Creature* Pet = ObjectAccessor::GetCreature(*me, SummonedPet);
if (Pet && Pet->IsAlive())
- Pet->DealDamage(Pet, Pet->GetHealth(), nullptr, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, nullptr, false);
+ Pet->KillSelf();
SummonedPet.Clear();
diff --git a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_leotheras_the_blind.cpp b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_leotheras_the_blind.cpp
index 97888f62955..57bd9af5500 100644
--- a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_leotheras_the_blind.cpp
+++ b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_leotheras_the_blind.cpp
@@ -157,7 +157,7 @@ public:
AttackStart(owner);
} else if (owner && owner->isDead())
{
- me->DealDamage(me, me->GetHealth(), nullptr, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, nullptr, false);
+ me->KillSelf();
return;
}
}
diff --git a/src/server/scripts/Outland/CoilfangReservoir/TheSlavePens/boss_ahune.cpp b/src/server/scripts/Outland/CoilfangReservoir/TheSlavePens/boss_ahune.cpp
index fe6268da9e8..e4f54514d94 100644
--- a/src/server/scripts/Outland/CoilfangReservoir/TheSlavePens/boss_ahune.cpp
+++ b/src/server/scripts/Outland/CoilfangReservoir/TheSlavePens/boss_ahune.cpp
@@ -202,9 +202,9 @@ public:
instance->DoCastSpellOnPlayers(SPELL_AHUNE_ACHIEVEMENT);
if (Creature* ahuneBunny = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_AHUNE_BUNNY)))
- me->Kill(ahuneBunny);
+ Unit::Kill(me, ahuneBunny);
if (Creature* frozenCore = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_FROZEN_CORE)))
- me->Kill(frozenCore);
+ Unit::Kill(me, frozenCore);
Map::PlayerList const& players = me->GetMap()->GetPlayers();
if (!players.isEmpty())
@@ -317,7 +317,7 @@ public:
void JustDied(Unit* /*killer*/) override
{
if (Creature* ahune = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_AHUNE)))
- me->Kill(ahune);
+ Unit::Kill(me, ahune);
DoCast(SPELL_SUMMON_LOOT_MISSILE);
DoCast(SPELL_MINION_DESPAWNER);
diff --git a/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/shattered_halls.cpp b/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/shattered_halls.cpp
index 63503c6bbe6..4cceca72229 100644
--- a/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/shattered_halls.cpp
+++ b/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/shattered_halls.cpp
@@ -125,7 +125,7 @@ class boss_shattered_executioner : public CreatureScript
if (type == DATA_PRISONERS_EXECUTED && data <= 3)
{
if (Creature* victim = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_FIRST_PRISONER + data - 1)))
- me->Kill(victim);
+ Unit::Kill(me, victim);
if (data == 1)
{
diff --git a/src/server/scripts/Outland/TempestKeep/Eye/boss_alar.cpp b/src/server/scripts/Outland/TempestKeep/Eye/boss_alar.cpp
index 07ce00a4a63..366de0b1ad1 100644
--- a/src/server/scripts/Outland/TempestKeep/Eye/boss_alar.cpp
+++ b/src/server/scripts/Outland/TempestKeep/Eye/boss_alar.cpp
@@ -550,7 +550,7 @@ class npc_ember_of_alar : public CreatureScript
if (toDie)
{
- me->DealDamage(me, me->GetHealth(), nullptr, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, nullptr, false);
+ me->KillSelf();
//me->SetVisibility(VISIBILITY_OFF);
}
diff --git a/src/server/scripts/Outland/TempestKeep/botanica/boss_warp_splinter.cpp b/src/server/scripts/Outland/TempestKeep/botanica/boss_warp_splinter.cpp
index 455360570ca..c630d2f37e8 100644
--- a/src/server/scripts/Outland/TempestKeep/botanica/boss_warp_splinter.cpp
+++ b/src/server/scripts/Outland/TempestKeep/botanica/boss_warp_splinter.cpp
@@ -108,7 +108,7 @@ class npc_warp_splinter_treant : public CreatureScript
{
int32 CurrentHP_Treant = (int32)me->GetHealth();
Warp->CastSpell(Warp, SPELL_HEAL_FATHER, CastSpellExtraArgs(me->GetGUID()).AddSpellBP0(CurrentHP_Treant));
- me->DealDamage(me, me->GetHealth(), nullptr, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, nullptr, false);
+ me->KillSelf();
return;
}
me->GetMotionMaster()->MoveFollow(Warp, 0, 0);
diff --git a/src/server/scripts/Outland/zone_shadowmoon_valley.cpp b/src/server/scripts/Outland/zone_shadowmoon_valley.cpp
index 6cced21f333..d9e5e030a86 100644
--- a/src/server/scripts/Outland/zone_shadowmoon_valley.cpp
+++ b/src/server/scripts/Outland/zone_shadowmoon_valley.cpp
@@ -552,7 +552,7 @@ public:
player->KilledMonsterCredit(23209);
}
PoisonTimer = 0;
- me->DealDamage(me, me->GetHealth(), nullptr, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, nullptr, false);
+ me->KillSelf();
} else PoisonTimer -= diff;
}
if (!UpdateVictim())
diff --git a/src/server/scripts/Spells/spell_dk.cpp b/src/server/scripts/Spells/spell_dk.cpp
index 0f59df198c1..12ff19eb64c 100644
--- a/src/server/scripts/Spells/spell_dk.cpp
+++ b/src/server/scripts/Spells/spell_dk.cpp
@@ -286,7 +286,7 @@ class spell_dk_dancing_rune_weapon : public AuraScript
int32 amount = static_cast<int32>(damageInfo->GetDamage()) / 2;
SpellNonMeleeDamage log(drw, drw->GetVictim(), spellInfo, { spellInfo->GetSpellXSpellVisualId(drw), 0 }, spellInfo->GetSchoolMask());
log.damage = amount;
- drw->DealDamage(drw->GetVictim(), amount, nullptr, SPELL_DIRECT_DAMAGE, spellInfo->GetSchoolMask(), spellInfo, true);
+ Unit::DealDamage(drw, drw->GetVictim(), amount, nullptr, SPELL_DIRECT_DAMAGE, spellInfo->GetSchoolMask(), spellInfo, true);
drw->SendSpellNonMeleeDamageLog(&log);
}
diff --git a/src/server/scripts/Spells/spell_monk.cpp b/src/server/scripts/Spells/spell_monk.cpp
index b12aa458e68..721ca1f829e 100644
--- a/src/server/scripts/Spells/spell_monk.cpp
+++ b/src/server/scripts/Spells/spell_monk.cpp
@@ -309,7 +309,7 @@ class spell_monk_stagger_damage_aura : public AuraScript
if (AuraEffect* auraEff = auraStagger->GetEffect(AuraStaggerEffectTotal))
{
float total = float(auraEff->GetAmount());
- float tickDamage = float(aurEff->GetDamage());
+ float tickDamage = float(aurEff->GetAmount());
auraEff->ChangeAmount(total - tickDamage);
}
}
@@ -382,7 +382,7 @@ private:
if (auraDamage)
if (AuraEffect* eff = auraDamage->GetEffect(AuraStaggerEffectTick))
- eff->SetDamage(tickDamage);
+ eff->ChangeAmount(tickDamage);
}
};