Created
October 24, 2015 20:05
-
-
Save robinsch/13218e5f672db9b09096 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp | |
index 9ced65b..12ee925 100644 | |
--- a/src/server/game/Entities/Unit/Unit.cpp | |
+++ b/src/server/game/Entities/Unit/Unit.cpp | |
@@ -1784,97 +1784,125 @@ void Unit::CalcAbsorbResist(Unit* victim, SpellSchoolMask schoolMask, DamageEffe | |
// split damage auras - only when not damaging self | |
if (victim != this) | |
+ SplitDamage(victim, schoolMask, dmgInfo); | |
+ | |
+ *resist = dmgInfo.GetResist(); | |
+ *absorb = dmgInfo.GetAbsorb(); | |
+} | |
+ | |
+void Unit::SplitDamage(Unit* victim, SpellSchoolMask schoolMask, DamageInfo dmgInfo) | |
+{ | |
+ // 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 | |
+ AuraEffectList vSplitDamageFlatCopy(victim->GetAuraEffectsByType(SPELL_AURA_SPLIT_DAMAGE_FLAT)); | |
+ for (AuraEffectList::iterator itr = vSplitDamageFlatCopy.begin(); (itr != vSplitDamageFlatCopy.end()) && (dmgInfo.GetDamage() > 0); ++itr) | |
{ | |
- // 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 | |
- AuraEffectList vSplitDamageFlatCopy(victim->GetAuraEffectsByType(SPELL_AURA_SPLIT_DAMAGE_FLAT)); | |
- for (AuraEffectList::iterator itr = vSplitDamageFlatCopy.begin(); (itr != vSplitDamageFlatCopy.end()) && (dmgInfo.GetDamage() > 0); ++itr) | |
- { | |
- // Check if aura was removed during iteration - we don't need to work on such auras | |
- if (!((*itr)->GetBase()->IsAppliedOnTarget(victim->GetGUID()))) | |
- continue; | |
- // check damage school mask | |
- if (!((*itr)->GetMiscValue() & schoolMask)) | |
- continue; | |
+ // Check if aura was removed during iteration - we don't need to work on such auras | |
+ if (!((*itr)->GetBase()->IsAppliedOnTarget(victim->GetGUID()))) | |
+ continue; | |
+ // check damage school mask | |
+ if (!((*itr)->GetMiscValue() & schoolMask)) | |
+ continue; | |
- // Damage can be splitted only if aura has an alive caster | |
- Unit* caster = (*itr)->GetCaster(); | |
- if (!caster || (caster == victim) || !caster->IsInWorld() || !caster->IsAlive()) | |
- continue; | |
+ // Damage can be splitted only if aura has an alive caster | |
+ Unit* caster = (*itr)->GetCaster(); | |
+ if (!caster || (caster == victim) || !caster->IsInWorld() || !caster->IsAlive()) | |
+ continue; | |
- int32 splitDamage = (*itr)->GetAmount(); | |
+ int32 splitDamage = (*itr)->GetAmount(); | |
- // absorb must be smaller than the damage itself | |
- splitDamage = RoundToInterval(splitDamage, 0, int32(dmgInfo.GetDamage())); | |
+ // absorb must be smaller than the damage itself | |
+ splitDamage = RoundToInterval(splitDamage, 0, int32(dmgInfo.GetDamage())); | |
- dmgInfo.AbsorbDamage(splitDamage); | |
+ dmgInfo.AbsorbDamage(splitDamage); | |
- // check if caster is immune to damage | |
- if (caster->IsImmunedToDamage(schoolMask)) | |
- { | |
- victim->SendSpellMiss(caster, (*itr)->GetSpellInfo()->Id, SPELL_MISS_IMMUNE); | |
- continue; | |
- } | |
+ // check if caster is immune to damage | |
+ if (caster->IsImmunedToDamage(schoolMask)) | |
+ { | |
+ victim->SendSpellMiss(caster, (*itr)->GetSpellInfo()->Id, SPELL_MISS_IMMUNE); | |
+ continue; | |
+ } | |
- uint32 splitted = splitDamage; | |
- uint32 splitted_absorb = 0; | |
- DealDamageMods(caster, splitted, &splitted_absorb); | |
+ uint32 splitted = splitDamage; | |
+ uint32 splitted_absorb = 0; | |
+ DealDamageMods(caster, splitted, &splitted_absorb); | |
- SendSpellNonMeleeDamageLog(caster, (*itr)->GetSpellInfo()->Id, splitted, schoolMask, splitted_absorb, 0, false, 0, false); | |
+ SendSpellNonMeleeDamageLog(caster, (*itr)->GetSpellInfo()->Id, splitted, schoolMask, splitted_absorb, 0, false, 0, false); | |
- CleanDamage cleanDamage = CleanDamage(splitted, 0, BASE_ATTACK, MELEE_HIT_NORMAL); | |
- DealDamage(caster, splitted, &cleanDamage, DIRECT_DAMAGE, schoolMask, (*itr)->GetSpellInfo(), false); | |
- } | |
+ CleanDamage cleanDamage = CleanDamage(splitted, 0, BASE_ATTACK, MELEE_HIT_NORMAL); | |
+ DealDamage(caster, splitted, &cleanDamage, DIRECT_DAMAGE, schoolMask, (*itr)->GetSpellInfo(), false); | |
+ } | |
- // 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 | |
- AuraEffectList vSplitDamagePctCopy(victim->GetAuraEffectsByType(SPELL_AURA_SPLIT_DAMAGE_PCT)); | |
- for (AuraEffectList::iterator itr = vSplitDamagePctCopy.begin(); itr != vSplitDamagePctCopy.end() && dmgInfo.GetDamage() > 0; ++itr) | |
- { | |
- // Check if aura was removed during iteration - we don't need to work on such auras | |
- AuraApplication const* aurApp = (*itr)->GetBase()->GetApplicationOfTarget(victim->GetGUID()); | |
- if (!aurApp) | |
- continue; | |
+ // 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 | |
+ AuraEffectList vSplitDamagePctCopy(victim->GetAuraEffectsByType(SPELL_AURA_SPLIT_DAMAGE_PCT)); | |
+ for (AuraEffectList::iterator itr = vSplitDamagePctCopy.begin(); itr != vSplitDamagePctCopy.end() && dmgInfo.GetDamage() > 0; ++itr) | |
+ { | |
+ // Check if aura was removed during iteration - we don't need to work on such auras | |
+ AuraApplication const* aurApp = (*itr)->GetBase()->GetApplicationOfTarget(victim->GetGUID()); | |
+ if (!aurApp) | |
+ continue; | |
- // check damage school mask | |
- if (!((*itr)->GetMiscValue() & schoolMask)) | |
- continue; | |
+ // check damage school mask | |
+ if (!((*itr)->GetMiscValue() & schoolMask)) | |
+ continue; | |
- // Damage can be splitted only if aura has an alive caster | |
- Unit* caster = (*itr)->GetCaster(); | |
- if (!caster || (caster == victim) || !caster->IsInWorld() || !caster->IsAlive()) | |
- continue; | |
+ // Damage can be splitted only if aura has an alive caster | |
+ Unit* caster = (*itr)->GetCaster(); | |
+ if (!caster || (caster == victim) || !caster->IsInWorld() || !caster->IsAlive()) | |
+ continue; | |
- uint32 splitDamage = CalculatePct(dmgInfo.GetDamage(), (*itr)->GetAmount()); | |
+ uint32 splitDamage = CalculatePct(dmgInfo.GetDamage(), (*itr)->GetAmount()); | |
- (*itr)->GetBase()->CallScriptEffectSplitHandlers((*itr), aurApp, dmgInfo, splitDamage); | |
+ (*itr)->GetBase()->CallScriptEffectSplitHandlers((*itr), aurApp, dmgInfo, splitDamage); | |
- // absorb must be smaller than the damage itself | |
- splitDamage = RoundToInterval(splitDamage, uint32(0), uint32(dmgInfo.GetDamage())); | |
+ // absorb must be smaller than the damage itself | |
+ splitDamage = RoundToInterval(splitDamage, uint32(0), uint32(dmgInfo.GetDamage())); | |
- dmgInfo.AbsorbDamage(splitDamage); | |
+ dmgInfo.AbsorbDamage(splitDamage); | |
- // check if caster is immune to damage | |
- if (caster->IsImmunedToDamage(schoolMask)) | |
+ // check if caster is immune to damage | |
+ if (caster->IsImmunedToDamage(schoolMask)) | |
+ { | |
+ victim->SendSpellMiss(caster, (*itr)->GetSpellInfo()->Id, SPELL_MISS_IMMUNE); | |
+ continue; | |
+ } | |
+ | |
+ uint32 split_absorb = 0; | |
+ DealDamageMods(caster, splitDamage, &split_absorb); | |
+ | |
+ SendSpellNonMeleeDamageLog(caster, (*itr)->GetSpellInfo()->Id, splitDamage, schoolMask, split_absorb, 0, false, 0, false); | |
+ | |
+ CleanDamage cleanDamage = CleanDamage(splitDamage, 0, BASE_ATTACK, MELEE_HIT_NORMAL); | |
+ DealDamage(caster, splitDamage, &cleanDamage, DIRECT_DAMAGE, schoolMask, (*itr)->GetSpellInfo(), false); | |
+ // break 'Fear' and similar auras | |
+ caster->ProcDamageAndSpellFor(true, this, PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG, PROC_EX_NORMAL_HIT, BASE_ATTACK, (*itr)->GetSpellInfo(), splitDamage); | |
+ } | |
+ | |
+ // special case for Roar of Sacrifice | |
+ if (Aura* aura = victim->GetAura(53179)) | |
+ { | |
+ if (Unit* auraCaster = aura->GetCaster()) | |
+ { | |
+ if (auraCaster->IsHunterPet()) | |
{ | |
- victim->SendSpellMiss(caster, (*itr)->GetSpellInfo()->Id, SPELL_MISS_IMMUNE); | |
- continue; | |
- } | |
+ if (!auraCaster || (auraCaster == victim) || !auraCaster->IsInWorld() || !auraCaster->IsAlive()) | |
+ return; | |
- uint32 split_absorb = 0; | |
- DealDamageMods(caster, splitDamage, &split_absorb); | |
+ // check if caster is immune to damage | |
+ if (auraCaster->IsImmunedToDamage(schoolMask)) | |
+ { | |
+ victim->SendSpellMiss(auraCaster, aura->GetSpellInfo()->Id, SPELL_MISS_IMMUNE); | |
+ return; | |
+ } | |
- SendSpellNonMeleeDamageLog(caster, (*itr)->GetSpellInfo()->Id, splitDamage, schoolMask, split_absorb, 0, false, 0, false); | |
+ uint32 transferDamage = CalculatePct(dmgInfo.GetDamage(), 20); | |
- CleanDamage cleanDamage = CleanDamage(splitDamage, 0, BASE_ATTACK, MELEE_HIT_NORMAL); | |
- DealDamage(caster, splitDamage, &cleanDamage, DIRECT_DAMAGE, schoolMask, (*itr)->GetSpellInfo(), false); | |
- // break 'Fear' and similar auras | |
- caster->ProcDamageAndSpellFor(true, this, PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG, PROC_EX_NORMAL_HIT, BASE_ATTACK, (*itr)->GetSpellInfo(), splitDamage); | |
+ CleanDamage cleanDamage = CleanDamage(transferDamage, 0, BASE_ATTACK, MELEE_HIT_NORMAL); | |
+ DealDamage(auraCaster, transferDamage, &cleanDamage, DIRECT_DAMAGE, schoolMask, aura->GetSpellInfo()->Id, false); | |
+ } | |
} | |
} | |
- | |
- *resist = dmgInfo.GetResist(); | |
- *absorb = dmgInfo.GetAbsorb(); | |
} | |
void Unit::CalcHealAbsorb(Unit* victim, SpellInfo const* healSpell, uint32 &healAmount, uint32 &absorb) | |
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h | |
index 39b1c34..bc6b951 100644 | |
--- a/src/server/game/Entities/Unit/Unit.h | |
+++ b/src/server/game/Entities/Unit/Unit.h | |
@@ -1972,6 +1972,8 @@ class Unit : public WorldObject | |
void CalcAbsorbResist(Unit* victim, SpellSchoolMask schoolMask, DamageEffectType damagetype, uint32 const damage, uint32* absorb, uint32* resist, SpellInfo const* spellInfo = NULL); | |
void CalcHealAbsorb(Unit* victim, SpellInfo const* spellInfo, uint32& healAmount, uint32& absorb); | |
+ void SplitDamage(Unit* victim, SpellSchoolMask schoolMask, DamageInfo dmgInfo); | |
+ | |
void UpdateSpeed(UnitMoveType mtype, bool forced); | |
float GetSpeed(UnitMoveType mtype) const; | |
float GetSpeedRate(UnitMoveType mtype) const { return m_speed_rate[mtype]; } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment