mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-14 17:49:10 +00:00
feat(Core/Spells): add helper to get clean and unmitigated damage for pro… (#7244)
This commit is contained in:
@@ -109,21 +109,28 @@ static bool isAlwaysTriggeredAura[TOTAL_AURAS];
|
||||
// Prepare lists
|
||||
static bool procPrepared = InitTriggerAuraData();
|
||||
|
||||
DamageInfo::DamageInfo(Unit* _attacker, Unit* _victim, uint32 _damage, SpellInfo const* _spellInfo, SpellSchoolMask _schoolMask, DamageEffectType _damageType)
|
||||
DamageInfo::DamageInfo(Unit* _attacker, Unit* _victim, uint32 _damage, SpellInfo const* _spellInfo, SpellSchoolMask _schoolMask, DamageEffectType _damageType, uint32 cleanDamage)
|
||||
: m_attacker(_attacker), m_victim(_victim), m_damage(_damage), m_spellInfo(_spellInfo), m_schoolMask(_schoolMask),
|
||||
m_damageType(_damageType), m_attackType(BASE_ATTACK)
|
||||
m_damageType(_damageType), m_attackType(BASE_ATTACK), m_cleanDamage(cleanDamage)
|
||||
{
|
||||
m_absorb = 0;
|
||||
m_resist = 0;
|
||||
m_block = 0;
|
||||
}
|
||||
|
||||
DamageInfo::DamageInfo(CalcDamageInfo& dmgInfo)
|
||||
: m_attacker(dmgInfo.attacker), m_victim(dmgInfo.target), m_damage(dmgInfo.damage), m_spellInfo(nullptr), m_schoolMask(SpellSchoolMask(dmgInfo.damageSchoolMask)),
|
||||
m_damageType(DIRECT_DAMAGE), m_attackType(dmgInfo.attackType)
|
||||
m_damageType(DIRECT_DAMAGE), m_attackType(dmgInfo.attackType), m_absorb(dmgInfo.absorb), m_resist(dmgInfo.resist), m_block(dmgInfo.blocked_amount),
|
||||
m_cleanDamage(dmgInfo.cleanDamage)
|
||||
{
|
||||
}
|
||||
|
||||
DamageInfo::DamageInfo(SpellNonMeleeDamage const& spellNonMeleeDamage, DamageEffectType damageType)
|
||||
: m_attacker(spellNonMeleeDamage.attacker), m_victim(spellNonMeleeDamage.target), m_damage(spellNonMeleeDamage.damage),
|
||||
m_spellInfo(spellNonMeleeDamage.spellInfo), m_schoolMask(SpellSchoolMask(spellNonMeleeDamage.schoolMask)), m_damageType(damageType),
|
||||
m_absorb(spellNonMeleeDamage.absorb), m_resist(spellNonMeleeDamage.resist), m_block(spellNonMeleeDamage.blocked),
|
||||
m_cleanDamage(spellNonMeleeDamage.cleanDamage)
|
||||
{
|
||||
m_absorb = 0;
|
||||
m_resist = 0;
|
||||
m_block = 0;
|
||||
}
|
||||
|
||||
void DamageInfo::ModifyDamage(int32 amount)
|
||||
@@ -153,6 +160,11 @@ void DamageInfo::BlockDamage(uint32 amount)
|
||||
m_damage -= amount;
|
||||
}
|
||||
|
||||
uint32 DamageInfo::GetUnmitigatedDamage() const
|
||||
{
|
||||
return m_damage + m_cleanDamage + m_absorb + m_resist;
|
||||
}
|
||||
|
||||
ProcEventInfo::ProcEventInfo(Unit* actor, Unit* actionTarget, Unit* procTarget, uint32 typeMask, uint32 spellTypeMask, uint32 spellPhaseMask, uint32 hitMask, Spell const* spell, DamageInfo* damageInfo, HealInfo* healInfo, SpellInfo const* triggeredByAuraSpell, int8 procAuraEffectIndex)
|
||||
: _actor(actor), _actionTarget(actionTarget), _procTarget(procTarget), _typeMask(typeMask), _spellTypeMask(spellTypeMask), _spellPhaseMask(spellPhaseMask),
|
||||
_hitMask(hitMask), _spell(spell), _damageInfo(damageInfo), _healInfo(healInfo), _triggeredByAuraSpell(triggeredByAuraSpell), _procAuraEffectIndex(procAuraEffectIndex)
|
||||
@@ -810,13 +822,16 @@ uint32 Unit::DealDamage(Unit* attacker, Unit* victim, uint32 damage, CleanDamage
|
||||
}
|
||||
else
|
||||
{
|
||||
DamageInfo sharedDamageInfo(attacker, shareDamageTarget, shareDamage, spellProto, damageSchoolMask, damagetype);
|
||||
Unit::CalcAbsorbResist(sharedDamageInfo, true);
|
||||
shareAbsorb = sharedDamageInfo.GetAbsorb();
|
||||
shareResist = sharedDamageInfo.GetResist();
|
||||
shareDamage = sharedDamageInfo.GetDamage();
|
||||
Unit::DealDamageMods(shareDamageTarget, shareDamage, &shareAbsorb);
|
||||
Unit::CalcAbsorbResist(attacker, shareDamageTarget, damageSchoolMask, damagetype, shareDamage, &shareAbsorb, &shareResist, spellProto, true);
|
||||
shareDamage -= std::min(shareAbsorb, shareDamage);
|
||||
}
|
||||
|
||||
if (attacker && shareDamageTarget->GetTypeId() == TYPEID_PLAYER)
|
||||
attacker->SendSpellNonMeleeDamageLog(shareDamageTarget, spell->Id, shareDamage + shareAbsorb + shareResist, damageSchoolMask, shareAbsorb, shareResist, damagetype == DIRECT_DAMAGE, 0, false);
|
||||
attacker->SendSpellNonMeleeDamageLog(shareDamageTarget, spell, shareDamage, damageSchoolMask, shareAbsorb, shareResist, damagetype == DIRECT_DAMAGE, 0, false);
|
||||
|
||||
Unit::DealDamage(attacker, shareDamageTarget, shareDamage, cleanDamage, NODAMAGE, damageSchoolMask, spellProto, false);
|
||||
}
|
||||
@@ -1180,8 +1195,16 @@ void Unit::CalculateSpellDamageTaken(SpellNonMeleeDamage* damageInfo, int32 dama
|
||||
SpellSchoolMask damageSchoolMask = SpellSchoolMask(damageInfo->schoolMask);
|
||||
uint32 crTypeMask = victim->GetCreatureTypeMask();
|
||||
|
||||
// Script Hook For CalculateSpellDamageTaken -- Allow scripts to change the Damage post class mitigation calculations
|
||||
sScriptMgr->ModifySpellDamageTaken(damageInfo->target, damageInfo->attacker, damage);
|
||||
|
||||
if (Unit::IsDamageReducedByArmor(damageSchoolMask, spellInfo))
|
||||
damage = Unit::CalcArmorReducedDamage(this, victim, damage, spellInfo, 0, attackType);
|
||||
{
|
||||
damageInfo->damage = Unit::CalcArmorReducedDamage(this, victim, damage, spellInfo, 0, attackType);
|
||||
damageInfo->cleanDamage += damage - damageInfo->damage;
|
||||
}
|
||||
else
|
||||
damageInfo->damage = damage;
|
||||
|
||||
bool blocked = false;
|
||||
// Per-school calc
|
||||
@@ -1203,11 +1226,11 @@ void Unit::CalculateSpellDamageTaken(SpellNonMeleeDamage* damageInfo, int32 dama
|
||||
damageInfo->HitInfo |= SPELL_HIT_TYPE_CRIT;
|
||||
|
||||
// Calculate crit bonus
|
||||
uint32 crit_bonus = damage;
|
||||
uint32 crit_bonus = damageInfo->damage;
|
||||
// Apply crit_damage bonus for melee spells
|
||||
if (Player* modOwner = GetSpellModOwner())
|
||||
modOwner->ApplySpellMod(spellInfo->Id, SPELLMOD_CRIT_DAMAGE_BONUS, crit_bonus);
|
||||
damage += crit_bonus;
|
||||
damageInfo->damage += crit_bonus;
|
||||
|
||||
// Apply SPELL_AURA_MOD_ATTACKER_RANGED_CRIT_DAMAGE or SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_DAMAGE
|
||||
float critPctDamageMod = 0.0f;
|
||||
@@ -1223,7 +1246,7 @@ void Unit::CalculateSpellDamageTaken(SpellNonMeleeDamage* damageInfo, int32 dama
|
||||
critPctDamageMod += GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_CRIT_PERCENT_VERSUS, crTypeMask);
|
||||
|
||||
if (critPctDamageMod != 0)
|
||||
AddPct(damage, critPctDamageMod);
|
||||
AddPct(damageInfo->damage, critPctDamageMod);
|
||||
}
|
||||
|
||||
// Spell weapon based damage CAN BE crit & blocked at same time
|
||||
@@ -1232,19 +1255,26 @@ void Unit::CalculateSpellDamageTaken(SpellNonMeleeDamage* damageInfo, int32 dama
|
||||
damageInfo->blocked = victim->GetShieldBlockValue();
|
||||
// double blocked amount if block is critical
|
||||
if (victim->isBlockCritical())
|
||||
damageInfo->blocked += damageInfo->blocked;
|
||||
damageInfo->blocked *= 2;
|
||||
if (damage < int32(damageInfo->blocked))
|
||||
damageInfo->blocked = uint32(damage);
|
||||
damage -= damageInfo->blocked;
|
||||
|
||||
damageInfo->damage -= damageInfo->blocked;
|
||||
damageInfo->cleanDamage += damageInfo->blocked;
|
||||
}
|
||||
|
||||
int32 resilienceReduction = damageInfo->damage;
|
||||
if (CanApplyResilience())
|
||||
{
|
||||
if (attackType != RANGED_ATTACK)
|
||||
Unit::ApplyResilience(victim, nullptr, &damage, crit, CR_CRIT_TAKEN_MELEE);
|
||||
Unit::ApplyResilience(victim, nullptr, &resilienceReduction, crit, CR_CRIT_TAKEN_MELEE);
|
||||
else
|
||||
Unit::ApplyResilience(victim, nullptr, &damage, crit, CR_CRIT_TAKEN_RANGED);
|
||||
Unit::ApplyResilience(victim, nullptr, &resilienceReduction, crit, CR_CRIT_TAKEN_RANGED);
|
||||
}
|
||||
|
||||
resilienceReduction = damageInfo->damage - resilienceReduction;
|
||||
damageInfo->damage -= resilienceReduction;
|
||||
damageInfo->cleanDamage += resilienceReduction;
|
||||
break;
|
||||
}
|
||||
// Magical Attacks
|
||||
@@ -1255,30 +1285,33 @@ void Unit::CalculateSpellDamageTaken(SpellNonMeleeDamage* damageInfo, int32 dama
|
||||
if (crit)
|
||||
{
|
||||
damageInfo->HitInfo |= SPELL_HIT_TYPE_CRIT;
|
||||
damage = Unit::SpellCriticalDamageBonus(this, spellInfo, damage, victim);
|
||||
damageInfo->damage = Unit::SpellCriticalDamageBonus(this, spellInfo, damageInfo->damage, victim);
|
||||
}
|
||||
|
||||
int32 resilienceReduction = damageInfo->damage;
|
||||
if (CanApplyResilience())
|
||||
Unit::ApplyResilience(victim, nullptr, &damage, crit, CR_CRIT_TAKEN_SPELL);
|
||||
Unit::ApplyResilience(victim, nullptr, &resilienceReduction, crit, CR_CRIT_TAKEN_SPELL);
|
||||
|
||||
resilienceReduction = damageInfo->damage - resilienceReduction;
|
||||
damageInfo->damage -= resilienceReduction;
|
||||
damageInfo->cleanDamage += resilienceReduction;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Script Hook For CalculateSpellDamageTaken -- Allow scripts to change the Damage post class mitigation calculations
|
||||
sScriptMgr->ModifySpellDamageTaken(damageInfo->target, damageInfo->attacker, damage);
|
||||
|
||||
// Calculate absorb resist
|
||||
if (damage > 0)
|
||||
if (int32(damageInfo->damage) > 0)
|
||||
{
|
||||
Unit::CalcAbsorbResist(this, victim, damageSchoolMask, SPELL_DIRECT_DAMAGE, damage, &damageInfo->absorb, &damageInfo->resist, spellInfo);
|
||||
damage -= damageInfo->absorb + damageInfo->resist;
|
||||
DamageInfo dmgInfo(*damageInfo, SPELL_DIRECT_DAMAGE);
|
||||
Unit::CalcAbsorbResist(dmgInfo);
|
||||
damageInfo->absorb = dmgInfo.GetAbsorb();
|
||||
damageInfo->resist = dmgInfo.GetResist();
|
||||
damage = dmgInfo.GetDamage();
|
||||
}
|
||||
else
|
||||
damage = 0;
|
||||
|
||||
damageInfo->damage = std::max(damage, 0);
|
||||
damageInfo->damage = 0;
|
||||
}
|
||||
|
||||
void Unit::DealSpellDamage(SpellNonMeleeDamage* damageInfo, bool durabilityLoss)
|
||||
@@ -1294,10 +1327,10 @@ void Unit::DealSpellDamage(SpellNonMeleeDamage* damageInfo, bool durabilityLoss)
|
||||
if (!victim->IsAlive() || victim->IsInFlight() || (victim->GetTypeId() == TYPEID_UNIT && victim->ToCreature()->IsEvadingAttacks()))
|
||||
return;
|
||||
|
||||
SpellInfo const* spellProto = sSpellMgr->GetSpellInfo(damageInfo->SpellID);
|
||||
if (spellProto == nullptr)
|
||||
SpellInfo const* spellProto = damageInfo->spellInfo;
|
||||
if (!spellProto)
|
||||
{
|
||||
LOG_DEBUG("entities.unit", "Unit::DealSpellDamage has wrong damageInfo->SpellID: %u", damageInfo->SpellID);
|
||||
LOG_DEBUG("entities.unit", "Unit::DealSpellDamage has wrong damageInfo");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1504,7 +1537,11 @@ void Unit::CalculateMeleeDamage(Unit* victim, uint32 damage, CalcDamageInfo* dam
|
||||
{
|
||||
damageInfo->procVictim |= PROC_FLAG_TAKEN_DAMAGE;
|
||||
// Calculate absorb & resists
|
||||
Unit::CalcAbsorbResist(this, damageInfo->target, SpellSchoolMask(damageInfo->damageSchoolMask), DIRECT_DAMAGE, damageInfo->damage, &damageInfo->absorb, &damageInfo->resist);
|
||||
|
||||
DamageInfo dmgInfo(*damageInfo);
|
||||
Unit::CalcAbsorbResist(dmgInfo);
|
||||
damageInfo->absorb = dmgInfo.GetAbsorb();
|
||||
damageInfo->resist = dmgInfo.GetResist();
|
||||
|
||||
if (damageInfo->absorb)
|
||||
{
|
||||
@@ -1515,7 +1552,7 @@ void Unit::CalculateMeleeDamage(Unit* victim, uint32 damage, CalcDamageInfo* dam
|
||||
if (damageInfo->resist)
|
||||
damageInfo->HitInfo |= (damageInfo->damage - damageInfo->resist == 0 ? HITINFO_FULL_RESIST : HITINFO_PARTIAL_RESIST);
|
||||
|
||||
damageInfo->damage -= damageInfo->absorb + damageInfo->resist;
|
||||
damageInfo->damage = dmgInfo.GetDamage();
|
||||
}
|
||||
else // Impossible get negative result but....
|
||||
damageInfo->damage = 0;
|
||||
@@ -1628,9 +1665,11 @@ void Unit::DealMeleeDamage(CalcDamageInfo* damageInfo, bool durabilityLoss)
|
||||
damage = this->SpellDamageBonusTaken(caster, i_spellProto, damage, SPELL_DIRECT_DAMAGE);
|
||||
|
||||
uint32 absorb = 0;
|
||||
uint32 resist = 0;
|
||||
Unit::CalcAbsorbResist(victim, this, i_spellProto->GetSchoolMask(), SPELL_DIRECT_DAMAGE, damage, &absorb, &resist, i_spellProto);
|
||||
damage -= absorb + resist;
|
||||
|
||||
DamageInfo dmgInfo(victim, this, damage, i_spellProto, i_spellProto->GetSchoolMask(), SPELL_DIRECT_DAMAGE);
|
||||
Unit::CalcAbsorbResist(dmgInfo);
|
||||
absorb = dmgInfo.GetAbsorb();
|
||||
damage = dmgInfo.GetDamage();
|
||||
|
||||
Unit::DealDamageMods(this, damage, &absorb);
|
||||
|
||||
@@ -1804,13 +1843,17 @@ float Unit::GetEffectiveResistChance(Unit const* owner, SpellSchoolMask schoolMa
|
||||
return victimResistance / (victimResistance + resistanceConstant);
|
||||
}
|
||||
|
||||
void Unit::CalcAbsorbResist(Unit* attacker, Unit* victim, SpellSchoolMask schoolMask, DamageEffectType damagetype, const uint32 damage, uint32* absorb, uint32* resist, SpellInfo const* spellInfo, bool Splited)
|
||||
void Unit::CalcAbsorbResist(DamageInfo& dmgInfo, bool Splited)
|
||||
{
|
||||
Unit* victim = dmgInfo.GetVictim();
|
||||
Unit* attacker = dmgInfo.GetAttacker();
|
||||
uint32 damage = dmgInfo.GetDamage();
|
||||
SpellSchoolMask schoolMask = dmgInfo.GetSchoolMask();
|
||||
SpellInfo const* spellInfo = dmgInfo.GetSpellInfo();
|
||||
|
||||
if (!victim || !victim->IsAlive() || !damage)
|
||||
return;
|
||||
|
||||
DamageInfo dmgInfo = DamageInfo(attacker, victim, damage, spellInfo, schoolMask, damagetype);
|
||||
|
||||
// Magic damage, check for resists
|
||||
// Ignore spells that cant be resisted
|
||||
// Xinef: holy resistance exists for npcs
|
||||
@@ -2043,25 +2086,28 @@ void Unit::CalcAbsorbResist(Unit* attacker, Unit* victim, SpellSchoolMask school
|
||||
uint32 splitted_resist = 0;
|
||||
|
||||
uint32 procAttacker = 0, procVictim = 0, procEx = PROC_EX_NORMAL_HIT;
|
||||
DamageInfo splittedDmgInfo(attacker, caster, splitted, spellInfo, schoolMask, dmgInfo.GetDamageType());
|
||||
if (caster->IsImmunedToDamageOrSchool(schoolMask))
|
||||
{
|
||||
procEx |= PROC_EX_IMMUNE;
|
||||
splitted_absorb = splitted;
|
||||
splitted = 0;
|
||||
splittedDmgInfo.AbsorbDamage(splitted);
|
||||
}
|
||||
else
|
||||
{
|
||||
Unit::CalcAbsorbResist(splittedDmgInfo, true);
|
||||
Unit::DealDamageMods(caster, splitted, &splitted_absorb);
|
||||
Unit::CalcAbsorbResist(attacker, caster, schoolMask, damagetype, splitted, &splitted_absorb, &splitted_resist, spellInfo, true);
|
||||
splitted -= std::min(splitted_absorb, splitted);
|
||||
}
|
||||
|
||||
splitted_absorb = splittedDmgInfo.GetAbsorb();
|
||||
splitted_resist = splittedDmgInfo.GetResist();
|
||||
splitted = splittedDmgInfo.GetDamage();
|
||||
|
||||
// create procs
|
||||
createProcFlags(spellInfo, BASE_ATTACK, false, procAttacker, procVictim);
|
||||
caster->ProcDamageAndSpellFor(true, attacker, procVictim, procEx, BASE_ATTACK, spellInfo, splitted);
|
||||
caster->ProcDamageAndSpellFor(true, attacker, procVictim, procEx, BASE_ATTACK, spellInfo, splitted, nullptr, -1, nullptr, &splittedDmgInfo);
|
||||
|
||||
if (attacker)
|
||||
attacker->SendSpellNonMeleeDamageLog(caster, (*itr)->GetSpellInfo()->Id, splitted + splitted_absorb, schoolMask, splitted_absorb, 0, false, 0, false);
|
||||
attacker->SendSpellNonMeleeDamageLog(caster, (*itr)->GetSpellInfo(), splitted, schoolMask, splitted_absorb, splitted_resist, false, 0, false);
|
||||
|
||||
CleanDamage cleanDamage = CleanDamage(splitted, 0, BASE_ATTACK, MELEE_HIT_NORMAL);
|
||||
Unit::DealDamage(attacker, caster, splitted, &cleanDamage, DIRECT_DAMAGE, schoolMask, (*itr)->GetSpellInfo(), false);
|
||||
@@ -2111,50 +2157,51 @@ void Unit::CalcAbsorbResist(Unit* attacker, Unit* victim, SpellSchoolMask school
|
||||
uint32 splitted_resist = 0;
|
||||
|
||||
uint32 procAttacker = 0, procVictim = 0, procEx = PROC_EX_NORMAL_HIT;
|
||||
DamageInfo splittedDmgInfo(attacker, caster, splitted, spellInfo, splitSchoolMask, dmgInfo.GetDamageType());
|
||||
if (caster->IsImmunedToDamageOrSchool(schoolMask))
|
||||
{
|
||||
procEx |= PROC_EX_IMMUNE;
|
||||
splitted_absorb = splitted;
|
||||
splitted = 0;
|
||||
splittedDmgInfo.AbsorbDamage(splitted);
|
||||
}
|
||||
else
|
||||
{
|
||||
Unit::CalcAbsorbResist(splittedDmgInfo, true);
|
||||
Unit::DealDamageMods(caster, splitted, &splitted_absorb);
|
||||
Unit::CalcAbsorbResist(attacker, caster, splitSchoolMask, damagetype, splitted, &splitted_absorb, &splitted_resist, spellInfo, true);
|
||||
splitted -= std::min(splitted_absorb, splitted);
|
||||
}
|
||||
|
||||
splitted_absorb = splittedDmgInfo.GetAbsorb();
|
||||
splitted_resist = splittedDmgInfo.GetResist();
|
||||
splitted = splittedDmgInfo.GetDamage();
|
||||
|
||||
// create procs
|
||||
createProcFlags(spellInfo, BASE_ATTACK, false, procAttacker, procVictim);
|
||||
caster->ProcDamageAndSpellFor(true, attacker, procVictim, procEx, BASE_ATTACK, spellInfo, splitted);
|
||||
|
||||
if (attacker)
|
||||
attacker->SendSpellNonMeleeDamageLog(caster, splitSpellInfo->Id, splitted + splitted_absorb, splitSchoolMask, splitted_absorb, 0, false, 0, false);
|
||||
attacker->SendSpellNonMeleeDamageLog(caster, splitSpellInfo, splitted, splitSchoolMask, splitted_absorb, splitted_resist, false, 0, false);
|
||||
|
||||
CleanDamage cleanDamage = CleanDamage(splitted, 0, BASE_ATTACK, MELEE_HIT_NORMAL);
|
||||
Unit::DealDamage(attacker, caster, splitted, &cleanDamage, DIRECT_DAMAGE, splitSchoolMask, splitSpellInfo, false);
|
||||
}
|
||||
}
|
||||
|
||||
*resist = dmgInfo.GetResist();
|
||||
*absorb = dmgInfo.GetAbsorb();
|
||||
}
|
||||
|
||||
void Unit::CalcHealAbsorb(Unit const* victim, const SpellInfo* healSpell, uint32& healAmount, uint32& absorb)
|
||||
void Unit::CalcHealAbsorb(HealInfo& healInfo)
|
||||
{
|
||||
if (!healAmount)
|
||||
if (!healInfo.GetHeal())
|
||||
return;
|
||||
|
||||
int32 RemainingHeal = healAmount;
|
||||
int32 const healing = static_cast<int32>(healInfo.GetHeal());
|
||||
int32 absorbAmount = 0;
|
||||
|
||||
// Need remove expired auras after
|
||||
bool existExpired = false;
|
||||
|
||||
// absorb without mana cost
|
||||
AuraEffectList const& vHealAbsorb = victim->GetAuraEffectsByType(SPELL_AURA_SCHOOL_HEAL_ABSORB);
|
||||
for (AuraEffectList::const_iterator i = vHealAbsorb.begin(); i != vHealAbsorb.end() && RemainingHeal > 0; ++i)
|
||||
AuraEffectList const& vHealAbsorb = healInfo.GetTarget()->GetAuraEffectsByType(SPELL_AURA_SCHOOL_HEAL_ABSORB);
|
||||
for (AuraEffectList::const_iterator i = vHealAbsorb.begin(); i != vHealAbsorb.end() && absorbAmount <= healing; ++i)
|
||||
{
|
||||
if (!((*i)->GetMiscValue() & healSpell->SchoolMask))
|
||||
if (!((*i)->GetMiscValue() & healInfo.GetSpellInfo()->SchoolMask))
|
||||
continue;
|
||||
|
||||
// Max Amount can be absorbed by this aura
|
||||
@@ -2169,10 +2216,10 @@ void Unit::CalcHealAbsorb(Unit const* victim, const SpellInfo* healSpell, uint32
|
||||
|
||||
// currentAbsorb - damage can be absorbed by shield
|
||||
// If need absorb less damage
|
||||
if (RemainingHeal < currentAbsorb)
|
||||
currentAbsorb = RemainingHeal;
|
||||
if (healing < currentAbsorb + absorbAmount)
|
||||
currentAbsorb = healing - absorbAmount;
|
||||
|
||||
RemainingHeal -= currentAbsorb;
|
||||
absorbAmount += currentAbsorb;
|
||||
|
||||
// Reduce shield amount
|
||||
(*i)->SetAmount((*i)->GetAmount() - currentAbsorb);
|
||||
@@ -2190,16 +2237,16 @@ void Unit::CalcHealAbsorb(Unit const* victim, const SpellInfo* healSpell, uint32
|
||||
++i;
|
||||
if (auraEff->GetAmount() <= 0)
|
||||
{
|
||||
uint32 removedAuras = victim->m_removedAurasCount;
|
||||
uint32 removedAuras = healInfo.GetTarget()->m_removedAurasCount;
|
||||
auraEff->GetBase()->Remove(AURA_REMOVE_BY_ENEMY_SPELL);
|
||||
if (removedAuras + 1 < victim->m_removedAurasCount)
|
||||
if (removedAuras + 1 < healInfo.GetTarget()->m_removedAurasCount)
|
||||
i = vHealAbsorb.begin();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
absorb = RemainingHeal > 0 ? (healAmount - RemainingHeal) : healAmount;
|
||||
healAmount = RemainingHeal;
|
||||
if (absorbAmount > 0)
|
||||
healInfo.AbsorbHeal(absorbAmount);
|
||||
}
|
||||
|
||||
void Unit::AttackerStateUpdate(Unit* victim, WeaponAttackType attType, bool extra)
|
||||
@@ -2239,7 +2286,10 @@ void Unit::AttackerStateUpdate(Unit* victim, WeaponAttackType attType, bool extr
|
||||
//TriggerAurasProcOnEvent(damageInfo);
|
||||
|
||||
DealMeleeDamage(&damageInfo, true);
|
||||
ProcDamageAndSpell(damageInfo.target, damageInfo.procAttacker, damageInfo.procVictim, damageInfo.procEx, damageInfo.damage, damageInfo.attackType);
|
||||
|
||||
DamageInfo dmgInfo(damageInfo);
|
||||
ProcDamageAndSpell(damageInfo.target, damageInfo.procAttacker, damageInfo.procVictim, damageInfo.procEx, damageInfo.damage,
|
||||
damageInfo.attackType, nullptr, nullptr, -1, nullptr, &dmgInfo);
|
||||
|
||||
if (GetTypeId() == TYPEID_PLAYER)
|
||||
LOG_DEBUG("entities.unit", "AttackerStateUpdate: (Player) %s attacked %s for %u dmg, absorbed %u, blocked %u, resisted %u.",
|
||||
@@ -5627,7 +5677,7 @@ void Unit::SendSpellNonMeleeReflectLog(SpellNonMeleeDamage* log, Unit* attacker)
|
||||
}
|
||||
data << log->target->GetPackGUID();
|
||||
data << attacker->GetPackGUID();
|
||||
data << uint32(log->SpellID);
|
||||
data << uint32(log->spellInfo->Id);
|
||||
data << uint32(damage); // damage amount
|
||||
int32 overkill = damage - log->target->GetHealth();
|
||||
data << uint32(overkill > 0 ? overkill : 0); // overkill
|
||||
@@ -5655,7 +5705,7 @@ void Unit::SendSpellNonMeleeDamageLog(SpellNonMeleeDamage* log)
|
||||
}
|
||||
data << log->target->GetPackGUID();
|
||||
data << log->attacker->GetPackGUID();
|
||||
data << uint32(log->SpellID);
|
||||
data << uint32(log->spellInfo->Id);
|
||||
data << uint32(damage); // damage amount
|
||||
int32 overkill = damage - log->target->GetHealth();
|
||||
data << uint32(overkill > 0 ? overkill : 0); // overkill
|
||||
@@ -5670,10 +5720,10 @@ void Unit::SendSpellNonMeleeDamageLog(SpellNonMeleeDamage* log)
|
||||
SendMessageToSet(&data, true);
|
||||
}
|
||||
|
||||
void Unit::SendSpellNonMeleeDamageLog(Unit* target, uint32 SpellID, uint32 Damage, SpellSchoolMask damageSchoolMask, uint32 AbsorbedDamage, uint32 Resist, bool PhysicalDamage, uint32 Blocked, bool CriticalHit)
|
||||
void Unit::SendSpellNonMeleeDamageLog(Unit* target, SpellInfo const* spellInfo, uint32 Damage, SpellSchoolMask damageSchoolMask, uint32 AbsorbedDamage, uint32 Resist, bool PhysicalDamage, uint32 Blocked, bool CriticalHit)
|
||||
{
|
||||
SpellNonMeleeDamage log(this, target, SpellID, damageSchoolMask);
|
||||
log.damage = Damage - AbsorbedDamage - Resist - Blocked;
|
||||
SpellNonMeleeDamage log(this, target, spellInfo, damageSchoolMask);
|
||||
log.damage = Damage;
|
||||
log.absorb = AbsorbedDamage;
|
||||
log.resist = Resist;
|
||||
log.physicalLog = PhysicalDamage;
|
||||
@@ -5684,15 +5734,15 @@ void Unit::SendSpellNonMeleeDamageLog(Unit* target, uint32 SpellID, uint32 Damag
|
||||
SendSpellNonMeleeDamageLog(&log);
|
||||
}
|
||||
|
||||
void Unit::ProcDamageAndSpell(Unit* victim, uint32 procAttacker, uint32 procVictim, uint32 procExtra, uint32 amount, WeaponAttackType attType, SpellInfo const* procSpellInfo, SpellInfo const* procAura, int8 procAuraEffectIndex, Spell const* procSpell)
|
||||
void Unit::ProcDamageAndSpell(Unit* victim, uint32 procAttacker, uint32 procVictim, uint32 procExtra, uint32 amount, WeaponAttackType attType, SpellInfo const* procSpellInfo, SpellInfo const* procAura, int8 procAuraEffectIndex, Spell const* procSpell, DamageInfo* damageInfo, HealInfo* healInfo)
|
||||
{
|
||||
// Not much to do if no flags are set.
|
||||
if (procAttacker)
|
||||
ProcDamageAndSpellFor(false, victim, procAttacker, procExtra, attType, procSpellInfo, amount, procAura, procAuraEffectIndex, procSpell);
|
||||
ProcDamageAndSpellFor(false, victim, procAttacker, procExtra, attType, procSpellInfo, amount, procAura, procAuraEffectIndex, procSpell, damageInfo, healInfo);
|
||||
// Now go on with a victim's events'n'auras
|
||||
// Not much to do if no flags are set or there is no victim
|
||||
if (victim && victim->IsAlive() && procVictim)
|
||||
victim->ProcDamageAndSpellFor(true, this, procVictim, procExtra, attType, procSpellInfo, amount, procAura, procAuraEffectIndex, procSpell);
|
||||
victim->ProcDamageAndSpellFor(true, this, procVictim, procExtra, attType, procSpellInfo, amount, procAura, procAuraEffectIndex, procSpell, damageInfo, healInfo);
|
||||
}
|
||||
|
||||
void Unit::SendPeriodicAuraLog(SpellPeriodicAuraLogInfo* pInfo)
|
||||
@@ -10508,16 +10558,17 @@ void Unit::SendHealSpellLog(Unit* victim, uint32 SpellID, uint32 Damage, uint32
|
||||
SendMessageToSet(&data, true);
|
||||
}
|
||||
|
||||
int32 Unit::HealBySpell(Unit* victim, SpellInfo const* spellInfo, uint32 addHealth, bool critical)
|
||||
int32 Unit::HealBySpell(HealInfo& healInfo, bool critical)
|
||||
{
|
||||
uint32 absorb = 0;
|
||||
uint32 heal = healInfo.GetHeal();
|
||||
sScriptMgr->ModifyHealRecieved(this, healInfo.GetTarget(), heal);
|
||||
healInfo.SetHeal(heal);
|
||||
|
||||
// calculate heal absorb and reduce healing
|
||||
CalcHealAbsorb(victim, spellInfo, addHealth, absorb);
|
||||
CalcHealAbsorb(healInfo);
|
||||
|
||||
sScriptMgr->ModifyHealRecieved(this, victim, addHealth);
|
||||
|
||||
int32 gain = Unit::DealHeal(this, victim, addHealth);
|
||||
SendHealSpellLog(victim, spellInfo->Id, addHealth, uint32(addHealth - gain), absorb, critical);
|
||||
int32 gain = Unit::DealHeal(healInfo.GetHealer(), healInfo.GetTarget(), healInfo.GetHeal());
|
||||
SendHealSpellLog(healInfo.GetTarget(), healInfo.GetSpellInfo()->Id, healInfo.GetHeal(), uint32(healInfo.GetHeal() - gain), healInfo.GetAbsorb(), critical);
|
||||
return gain;
|
||||
}
|
||||
|
||||
@@ -15302,7 +15353,7 @@ uint32 createProcExtendMask(SpellNonMeleeDamage* damageInfo, SpellMissInfo missC
|
||||
return procEx;
|
||||
}
|
||||
|
||||
void Unit::ProcDamageAndSpellFor(bool isVictim, Unit* target, uint32 procFlag, uint32 procExtra, WeaponAttackType attType, SpellInfo const* procSpellInfo, uint32 damage, SpellInfo const* procAura, int8 procAuraEffectIndex, Spell const* procSpell)
|
||||
void Unit::ProcDamageAndSpellFor(bool isVictim, Unit* target, uint32 procFlag, uint32 procExtra, WeaponAttackType attType, SpellInfo const* procSpellInfo, uint32 damage, SpellInfo const* procAura, int8 procAuraEffectIndex, Spell const* procSpell, DamageInfo* damageInfo, HealInfo* healInfo)
|
||||
{
|
||||
// Player is loaded now - do not allow passive spell casts to proc
|
||||
if (GetTypeId() == TYPEID_PLAYER && ToPlayer()->GetSession()->PlayerLoading())
|
||||
@@ -15397,9 +15448,7 @@ void Unit::ProcDamageAndSpellFor(bool isVictim, Unit* target, uint32 procFlag, u
|
||||
Unit* actor = isVictim ? target : this;
|
||||
Unit* actionTarget = !isVictim ? target : this;
|
||||
|
||||
DamageInfo damageInfo = DamageInfo(actor, actionTarget, damage, procSpellInfo, procSpellInfo ? SpellSchoolMask(procSpellInfo->SchoolMask) : SPELL_SCHOOL_MASK_NORMAL, SPELL_DIRECT_DAMAGE);
|
||||
HealInfo healInfo = HealInfo(actor, actionTarget, damage, procSpellInfo, procSpellInfo ? SpellSchoolMask(procSpellInfo->SchoolMask) : SPELL_SCHOOL_MASK_NORMAL);
|
||||
ProcEventInfo eventInfo = ProcEventInfo(actor, actionTarget, target, procFlag, 0, 0, procExtra, procSpell, &damageInfo, &healInfo, procAura, procAuraEffectIndex);
|
||||
ProcEventInfo eventInfo = ProcEventInfo(actor, actionTarget, target, procFlag, 0, 0, procExtra, procSpell, damageInfo, healInfo, procAura, procAuraEffectIndex);
|
||||
|
||||
ProcTriggeredList procTriggered;
|
||||
// Fill procTriggered list
|
||||
|
||||
Reference in New Issue
Block a user