Core/Unit: Big cleanup in Unit::CalcAbsorbResist
Core/AuraScript: Fix compile time check for AuraScript functions Remove AuraApplication from hook functions parameter list, use GetTarget() and GetTargetApplication() instead Add OnEffectAbsorb hook Scripts: move handlers of Spell Deflection, Savage Defense, Primal Tenacity, Nerves of Steel, Astral shift from core to scripts. --HG-- branch : trunk
This commit is contained in:
@@ -1548,6 +1548,8 @@ void Unit::CalcAbsorbResist(Unit *pVictim, SpellSchoolMask schoolMask, DamageEff
|
||||
if (!pVictim || !pVictim->isAlive() || !damage)
|
||||
return;
|
||||
|
||||
DamageInfo dmgInfo = DamageInfo(this, pVictim, damage, spellInfo, schoolMask, damagetype);
|
||||
|
||||
// Magic damage, check for resists
|
||||
if ((schoolMask & SPELL_SCHOOL_MASK_NORMAL) == 0)
|
||||
{
|
||||
@@ -1591,32 +1593,25 @@ void Unit::CalcAbsorbResist(Unit *pVictim, SpellSchoolMask schoolMask, DamageEff
|
||||
probabilitySum += discreteResistProbability[i];
|
||||
}
|
||||
|
||||
uint32 damageResisted = damage * i / 10;
|
||||
|
||||
*resist += damageResisted;
|
||||
float damageResisted = damage * i / 10;
|
||||
|
||||
AuraEffectList const &ResIgnoreAurasAb = GetAuraEffectsByType(SPELL_AURA_MOD_ABILITY_IGNORE_TARGET_RESIST);
|
||||
for (AuraEffectList::const_iterator j = ResIgnoreAurasAb.begin(); j != ResIgnoreAurasAb.end(); ++j)
|
||||
{
|
||||
if ((*j)->GetMiscValue() & schoolMask
|
||||
&& (*j)->IsAffectedOnSpell(spellInfo))
|
||||
AddPctN(*resist, -(*j)->GetAmount());
|
||||
AddPctN(damageResisted, -(*j)->GetAmount());
|
||||
}
|
||||
|
||||
AuraEffectList const &ResIgnoreAuras = GetAuraEffectsByType(SPELL_AURA_MOD_IGNORE_TARGET_RESIST);
|
||||
for (AuraEffectList::const_iterator j = ResIgnoreAuras.begin(); j != ResIgnoreAuras.end(); ++j)
|
||||
{
|
||||
if ((*j)->GetMiscValue() & schoolMask)
|
||||
AddPctN(*resist, -(*j)->GetAmount());
|
||||
AddPctN(damageResisted, -(*j)->GetAmount());
|
||||
}
|
||||
dmgInfo.ResistDamage(damageResisted);
|
||||
}
|
||||
else
|
||||
*resist = 0;
|
||||
|
||||
int32 RemainingDamage = damage - *resist;
|
||||
int32 TotalAbsorb = RemainingDamage;
|
||||
// Get unit state (need for some absorb check)
|
||||
uint32 unitflag = pVictim->GetUInt32Value(UNIT_FIELD_FLAGS);
|
||||
// Death Prevention Aura
|
||||
SpellEntry const* preventDeathSpell = NULL;
|
||||
int32 preventDeathAmount = 0;
|
||||
@@ -1625,7 +1620,7 @@ void Unit::CalcAbsorbResist(Unit *pVictim, SpellSchoolMask schoolMask, DamageEff
|
||||
int32 incanterAbsorption = 0;
|
||||
|
||||
// Ignore Absorption Auras
|
||||
int32 auraAbsorbMod = 0;
|
||||
float auraAbsorbMod = 0;
|
||||
AuraEffectList const & AbsIgnoreAurasA = GetAuraEffectsByType(SPELL_AURA_MOD_TARGET_ABSORB_SCHOOL);
|
||||
for (AuraEffectList::const_iterator itr = AbsIgnoreAurasA.begin(); itr != AbsIgnoreAurasA.end(); ++itr)
|
||||
{
|
||||
@@ -1645,6 +1640,7 @@ void Unit::CalcAbsorbResist(Unit *pVictim, SpellSchoolMask schoolMask, DamageEff
|
||||
if (((*itr)->GetAmount() > auraAbsorbMod) && (*itr)->IsAffectedOnSpell(spellInfo))
|
||||
auraAbsorbMod = (*itr)->GetAmount();
|
||||
}
|
||||
RoundToInterval(auraAbsorbMod, 0.0f, 100.0f);
|
||||
|
||||
// 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
|
||||
@@ -1652,80 +1648,39 @@ void Unit::CalcAbsorbResist(Unit *pVictim, SpellSchoolMask schoolMask, DamageEff
|
||||
vSchoolAbsorbCopy.sort(Trinity::AbsorbAuraOrderPred());
|
||||
|
||||
// absorb without mana cost
|
||||
for (AuraEffectList::iterator itr = vSchoolAbsorbCopy.begin(); (itr != vSchoolAbsorbCopy.end()) && (RemainingDamage > 0); ++itr)
|
||||
for (AuraEffectList::iterator itr = vSchoolAbsorbCopy.begin(); (itr != vSchoolAbsorbCopy.end()) && (dmgInfo.GetDamage() > 0); ++itr)
|
||||
{
|
||||
AuraEffect * absorbAurEff = (*itr);
|
||||
// Check if aura was removed during iteration - we don't need to work on such auras
|
||||
if (!(absorbAurEff->GetBase()->IsAppliedOnTarget(pVictim->GetGUID())))
|
||||
AuraApplication const * aurApp = absorbAurEff->GetBase()->GetApplicationOfTarget(pVictim->GetGUID());
|
||||
if (!aurApp)
|
||||
continue;
|
||||
if (!(absorbAurEff->GetMiscValue() & schoolMask))
|
||||
continue;
|
||||
|
||||
SpellEntry const * spellProto = absorbAurEff->GetSpellProto();
|
||||
|
||||
// Frost Warding
|
||||
// Chaos Bolt ignore the absorption but still proc Frost Warding mana return
|
||||
if ((spellProto->SpellFamilyName == SPELLFAMILY_MAGE) && (spellProto->Category == 56))
|
||||
if (AuraEffect * aurEff = pVictim->GetAuraEffect(SPELL_AURA_ADD_PCT_MODIFIER, SPELLFAMILY_MAGE, 501, EFFECT_0))
|
||||
{
|
||||
int32 chance = SpellMgr::CalculateSpellEffectAmount(aurEff->GetSpellProto(), EFFECT_1);
|
||||
|
||||
if (roll_chance_i(chance))
|
||||
{
|
||||
pVictim->CastCustomSpell(pVictim, 57776, &RemainingDamage, NULL, NULL, true, NULL, absorbAurEff);
|
||||
RemainingDamage = RemainingDamage * auraAbsorbMod / 100;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (auraAbsorbMod >= 100) // Do nothing if 100% absorb ignore
|
||||
continue;
|
||||
|
||||
// Max Amount can be absorbed by this aura
|
||||
// get amount which can be still absorbed by the aura
|
||||
int32 currentAbsorb = absorbAurEff->GetAmount();
|
||||
// Found empty aura
|
||||
if (currentAbsorb <= 0)
|
||||
{
|
||||
absorbAurEff->GetBase()->Remove(AURA_REMOVE_BY_ENEMY_SPELL);
|
||||
continue;
|
||||
}
|
||||
// aura with infinite absorb amount - let the scripts handle absorbtion amount, set here to 0 for safety
|
||||
if (currentAbsorb < 0)
|
||||
currentAbsorb = 0;
|
||||
|
||||
currentAbsorb = (100 - auraAbsorbMod) * currentAbsorb / 100;
|
||||
uint32 absorb = currentAbsorb;
|
||||
|
||||
// Handle custom absorb auras
|
||||
// TODO: try find better way
|
||||
bool defaultPrevented = false;
|
||||
|
||||
absorbAurEff->GetBase()->CallScriptEffectAbsorbHandlers(absorbAurEff, aurApp, dmgInfo, absorb, defaultPrevented);
|
||||
|
||||
currentAbsorb = absorb;
|
||||
switch (spellProto->SpellFamilyName)
|
||||
{
|
||||
case SPELLFAMILY_GENERIC:
|
||||
{
|
||||
// Astral Shift
|
||||
if (spellProto->SpellIconID == 3066)
|
||||
{
|
||||
//reduces all damage taken while stun, fear or silence
|
||||
if (unitflag & (UNIT_FLAG_STUNNED | UNIT_FLAG_FLEEING | UNIT_FLAG_SILENCED))
|
||||
AddPctN(RemainingDamage, -currentAbsorb);
|
||||
continue;
|
||||
}
|
||||
// Nerves of Steel
|
||||
if (spellProto->SpellIconID == 2115)
|
||||
{
|
||||
// while affected by Stun and Fear
|
||||
if (unitflag & (UNIT_FLAG_STUNNED | UNIT_FLAG_FLEEING))
|
||||
AddPctN(RemainingDamage, -currentAbsorb);
|
||||
continue;
|
||||
}
|
||||
// Spell Deflection
|
||||
if (spellProto->SpellIconID == 3006)
|
||||
{
|
||||
// You have a chance equal to your Parry chance
|
||||
if ((damagetype == DIRECT_DAMAGE) && roll_chance_f(pVictim->GetUnitParryChance()))
|
||||
AddPctN(RemainingDamage, -currentAbsorb);
|
||||
continue;
|
||||
}
|
||||
// Reflective Shield (Lady Malande boss)
|
||||
if (spellProto->Id == 41475)
|
||||
{
|
||||
int32 bp = std::min(RemainingDamage, currentAbsorb) / 2;
|
||||
int32 bp = std::min(int32(dmgInfo.GetDamage()), currentAbsorb) / 2;
|
||||
pVictim->CastCustomSpell(this, 33619, &bp, NULL, NULL, true, NULL, *itr);
|
||||
break;
|
||||
}
|
||||
@@ -1740,34 +1695,25 @@ void Unit::CalcAbsorbResist(Unit *pVictim, SpellSchoolMask schoolMask, DamageEff
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SPELLFAMILY_DRUID:
|
||||
case SPELLFAMILY_MAGE:
|
||||
{
|
||||
// Primal Tenacity
|
||||
if (spellProto->SpellIconID == 2253)
|
||||
// possibly create BeforeEffectAbsorb for this?
|
||||
// Frost ward and Fire Ward
|
||||
if (spellProto->Category == 56)
|
||||
{
|
||||
//reduces all damage taken while Stunned
|
||||
if ((pVictim->GetShapeshiftForm() == FORM_CAT) && (unitflag & UNIT_FLAG_STUNNED))
|
||||
AddPctN(RemainingDamage, -currentAbsorb);
|
||||
continue;
|
||||
}
|
||||
// Savage Defense
|
||||
if (spellProto->SpellIconID == 146)
|
||||
{
|
||||
if (RemainingDamage < currentAbsorb)
|
||||
currentAbsorb = RemainingDamage;
|
||||
// Frost Warding
|
||||
if (AuraEffect * aurEff = pVictim->GetAuraEffect(SPELL_AURA_ADD_PCT_MODIFIER, SPELLFAMILY_MAGE, 501, EFFECT_0))
|
||||
{
|
||||
int32 chance = SpellMgr::CalculateSpellEffectAmount(aurEff->GetSpellProto(), EFFECT_1);
|
||||
|
||||
RemainingDamage -= currentAbsorb;
|
||||
|
||||
absorbAurEff->GetBase()->Remove(AURA_REMOVE_BY_ENEMY_SPELL); // guarantee removal
|
||||
continue;
|
||||
}
|
||||
// Moonkin Form passive
|
||||
if (spellProto->Id == 69366)
|
||||
{
|
||||
//reduces all damage taken while Stunned
|
||||
if (unitflag & UNIT_FLAG_STUNNED)
|
||||
AddPctN(RemainingDamage, -currentAbsorb);
|
||||
continue;
|
||||
if (roll_chance_i(chance))
|
||||
{
|
||||
int32 bp = dmgInfo.GetDamage();
|
||||
pVictim->CastCustomSpell(pVictim, 57776, &bp, NULL, NULL, true, NULL, absorbAurEff);
|
||||
dmgInfo.AbsorbDamage(dmgInfo.GetDamage());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -1809,7 +1755,7 @@ void Unit::CalcAbsorbResist(Unit *pVictim, SpellSchoolMask schoolMask, DamageEff
|
||||
case 5065: // Rank 1
|
||||
case 5064: // Rank 2
|
||||
{
|
||||
int32 bp = CalculatePctN(std::min(RemainingDamage, currentAbsorb), aurEff->GetAmount());
|
||||
int32 bp = CalculatePctN(std::min(int32(dmgInfo.GetDamage()), currentAbsorb), aurEff->GetAmount());
|
||||
pVictim->CastCustomSpell(this, 33619, &bp, NULL, NULL, true, NULL, *itr);
|
||||
break;
|
||||
}
|
||||
@@ -1828,13 +1774,13 @@ void Unit::CalcAbsorbResist(Unit *pVictim, SpellSchoolMask schoolMask, DamageEff
|
||||
if (!pVictim->ToPlayer())
|
||||
continue;
|
||||
|
||||
int32 remainingHealth = pVictim->GetHealth() - RemainingDamage;
|
||||
int32 remainingHealth = pVictim->GetHealth() - dmgInfo.GetDamage();
|
||||
uint32 allowedHealth = pVictim->CountPctFromMaxHealth(35);
|
||||
// If damage kills us
|
||||
if (remainingHealth <= 0 && !pVictim->ToPlayer()->HasSpellCooldown(66235))
|
||||
{
|
||||
// Cast healing spell, completely avoid damage
|
||||
RemainingDamage = 0;
|
||||
dmgInfo.AbsorbDamage(dmgInfo.GetDamage());
|
||||
|
||||
uint32 defenseSkillValue = pVictim->GetDefenseSkillValue();
|
||||
// Max heal when defense skill denies critical hits from raid bosses
|
||||
@@ -1852,26 +1798,14 @@ void Unit::CalcAbsorbResist(Unit *pVictim, SpellSchoolMask schoolMask, DamageEff
|
||||
{
|
||||
// Reduce damage that brings us under 35% (or full damage if we are already under 35%) by x%
|
||||
uint32 damageToReduce = (pVictim->GetHealth() < allowedHealth)
|
||||
? RemainingDamage
|
||||
? dmgInfo.GetDamage()
|
||||
: allowedHealth - remainingHealth;
|
||||
RemainingDamage -= CalculatePctN(damageToReduce, currentAbsorb);
|
||||
dmgInfo.AbsorbDamage(CalculatePctN(damageToReduce, currentAbsorb));
|
||||
}
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SPELLFAMILY_SHAMAN:
|
||||
{
|
||||
// Astral Shift
|
||||
if (spellProto->SpellIconID == 3066)
|
||||
{
|
||||
//reduces all damage taken while stun, fear or silence
|
||||
if (unitflag & (UNIT_FLAG_STUNNED | UNIT_FLAG_FLEEING | UNIT_FLAG_SILENCED))
|
||||
AddPctN(RemainingDamage, -currentAbsorb);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SPELLFAMILY_DEATHKNIGHT:
|
||||
{
|
||||
switch (spellProto->Id)
|
||||
@@ -1885,14 +1819,14 @@ void Unit::CalcAbsorbResist(Unit *pVictim, SpellSchoolMask schoolMask, DamageEff
|
||||
if (AuraEffect const * aurEff = caster->GetAuraEffect(58635, 0))
|
||||
AddPctN(absorbed, aurEff->GetAmount());
|
||||
|
||||
RemainingDamage -= absorbed;
|
||||
dmgInfo.AbsorbDamage(absorbed);
|
||||
}
|
||||
continue;
|
||||
case 52284: // Will of the Necropolis
|
||||
case 52285:
|
||||
case 52286:
|
||||
{
|
||||
int32 remainingHp = int32(pVictim->GetHealth() - RemainingDamage);
|
||||
int32 remainingHp = int32(pVictim->GetHealth() - dmgInfo.GetDamage());
|
||||
|
||||
// min pct of hp is stored in effect 0 of talent spell
|
||||
uint32 rank = sSpellMgr->GetSpellRank(spellProto->Id);
|
||||
@@ -1902,8 +1836,8 @@ void Unit::CalcAbsorbResist(Unit *pVictim, SpellSchoolMask schoolMask, DamageEff
|
||||
// Damage that would take you below [effect0] health or taken while you are at [effect0]
|
||||
if (remainingHp < minHp)
|
||||
{
|
||||
uint32 absorbed = uint32(currentAbsorb * RemainingDamage * 0.01f);
|
||||
RemainingDamage -= absorbed;
|
||||
uint32 absorbed = uint32(currentAbsorb * dmgInfo.GetDamage() * 0.01f);
|
||||
dmgInfo.AbsorbDamage(absorbed);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
@@ -1911,24 +1845,24 @@ void Unit::CalcAbsorbResist(Unit *pVictim, SpellSchoolMask schoolMask, DamageEff
|
||||
{
|
||||
// damage absorbed by Anti-Magic Shell energizes the DK with additional runic power.
|
||||
// This, if I'm not mistaken, shows that we get back ~2% of the absorbed damage as runic power.
|
||||
int32 absorbed = CalculatePctN(RemainingDamage, currentAbsorb);
|
||||
RemainingDamage -= absorbed;
|
||||
int32 absorbed = CalculatePctN(dmgInfo.GetDamage(), currentAbsorb);
|
||||
dmgInfo.AbsorbDamage(absorbed);
|
||||
int32 bp = absorbed * 2 / 10;
|
||||
pVictim->CastCustomSpell(pVictim, 49088, &bp, NULL, NULL, true, NULL, *itr);
|
||||
continue;
|
||||
}
|
||||
case 50462: // Anti-Magic Shell (on single party/raid member)
|
||||
AddPctN(RemainingDamage, -currentAbsorb);
|
||||
dmgInfo.AbsorbDamage(CalculatePctN(dmgInfo.GetDamage(), currentAbsorb));
|
||||
continue;
|
||||
case 50461: // Anti-Magic Zone
|
||||
if (Unit * caster = absorbAurEff->GetCaster())
|
||||
{
|
||||
int32 absorbed = CalculatePctN(RemainingDamage, currentAbsorb);
|
||||
int32 absorbed = CalculatePctN(dmgInfo.GetDamage(), currentAbsorb);
|
||||
int32 canabsorb = caster->GetHealth();
|
||||
if (canabsorb < absorbed)
|
||||
absorbed = canabsorb;
|
||||
|
||||
RemainingDamage -= absorbed;
|
||||
dmgInfo.AbsorbDamage(absorbed);
|
||||
}
|
||||
continue;
|
||||
default:
|
||||
@@ -1940,163 +1874,154 @@ void Unit::CalcAbsorbResist(Unit *pVictim, SpellSchoolMask schoolMask, DamageEff
|
||||
break;
|
||||
}
|
||||
|
||||
// currentAbsorb - damage can be absorbed by shield
|
||||
// If need absorb less damage
|
||||
if (RemainingDamage < currentAbsorb)
|
||||
currentAbsorb = RemainingDamage;
|
||||
if (defaultPrevented)
|
||||
continue;
|
||||
|
||||
RemainingDamage -= currentAbsorb;
|
||||
// Apply absorb mod auras
|
||||
AddPctF(currentAbsorb, -auraAbsorbMod);
|
||||
|
||||
// absorb must be smaller than the damage itself
|
||||
currentAbsorb = RoundToInterval(currentAbsorb, 0, int32(dmgInfo.GetDamage()));
|
||||
|
||||
dmgInfo.AbsorbDamage(currentAbsorb);
|
||||
|
||||
// Fire Ward or Frost Ward or Ice Barrier (or Mana Shield)
|
||||
// for Incanter's Absorption converting to spell power
|
||||
if (spellProto->SpellFamilyName == SPELLFAMILY_MAGE && spellProto->SpellFamilyFlags[EFFECT_2] & 0x8)
|
||||
if (spellProto->SpellFamilyName == SPELLFAMILY_MAGE && spellProto->SpellFamilyFlags[2] & 0x8)
|
||||
incanterAbsorption += currentAbsorb;
|
||||
|
||||
// Reduce shield amount
|
||||
absorbAurEff->SetAmount(absorbAurEff->GetAmount() - currentAbsorb);
|
||||
// Need remove it later
|
||||
if (absorbAurEff->GetAmount() <= 0)
|
||||
absorbAurEff->GetBase()->Remove(AURA_REMOVE_BY_ENEMY_SPELL);
|
||||
// Check if our aura is using amount to count damage
|
||||
if (absorbAurEff->GetAmount() >= 0)
|
||||
{
|
||||
// Reduce shield amount
|
||||
absorbAurEff->SetAmount(absorbAurEff->GetAmount() - currentAbsorb);
|
||||
// Aura cannot absorb anything more - remove it
|
||||
if (absorbAurEff->GetAmount() <= 0)
|
||||
absorbAurEff->GetBase()->Remove(AURA_REMOVE_BY_ENEMY_SPELL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (auraAbsorbMod < 100) // Do nothing if 100% absorb ignore
|
||||
{
|
||||
bool existExpired = false;
|
||||
|
||||
// absorb by mana cost
|
||||
AuraEffectList const & vManaShield = pVictim->GetAuraEffectsByType(SPELL_AURA_MANA_SHIELD);
|
||||
|
||||
for (AuraEffectList::const_iterator itr = vManaShield.begin(); (itr != vManaShield.end()) && (RemainingDamage > 0); ++itr)
|
||||
AuraEffectList vManaShieldCopy(pVictim->GetAuraEffectsByType(SPELL_AURA_MANA_SHIELD));
|
||||
for (AuraEffectList::const_iterator itr = vManaShieldCopy.begin(); (itr != vManaShieldCopy.end()) && (dmgInfo.GetDamage() > 0); ++itr)
|
||||
{
|
||||
AuraEffect * absorbAurEff = *itr;
|
||||
// Check if aura was removed during iteration - we don't need to work on such auras
|
||||
if (!(absorbAurEff->GetBase()->IsAppliedOnTarget(pVictim->GetGUID())))
|
||||
continue;
|
||||
// check damage school mask
|
||||
if (!(absorbAurEff->GetMiscValue() & schoolMask))
|
||||
continue;
|
||||
|
||||
// get amount which can be still absorbed by the aura
|
||||
int32 currentAbsorb = absorbAurEff->GetAmount();
|
||||
|
||||
AddPctF(currentAbsorb, -auraAbsorbMod);
|
||||
|
||||
// absorb must be smaller than the damage itself
|
||||
currentAbsorb = RoundToInterval(currentAbsorb, 0, int32(dmgInfo.GetDamage()));
|
||||
|
||||
int32 manaReduction = currentAbsorb;
|
||||
|
||||
// lower absorb amount by talents
|
||||
if (float manaMultiplier = SpellMgr::CalculateSpellEffectValueMultiplier(absorbAurEff->GetSpellProto(), absorbAurEff->GetEffIndex(), absorbAurEff->GetCaster()))
|
||||
manaReduction = float(manaReduction) * manaMultiplier;
|
||||
|
||||
int32 manaTaken = -pVictim->ModifyPower(POWER_MANA, -manaReduction);
|
||||
|
||||
// take case when mana has ended up into account
|
||||
currentAbsorb = float(currentAbsorb)*(float(manaTaken) / float(manaReduction));
|
||||
|
||||
// Mana Shield (or Fire Ward or Frost Ward or Ice Barrier)
|
||||
// for Incanter's Absorption converting to spell power
|
||||
if (absorbAurEff->GetSpellProto()->SpellFamilyName == SPELLFAMILY_MAGE && absorbAurEff->GetSpellProto()->SpellFamilyFlags[2] & 0x8)
|
||||
incanterAbsorption += currentAbsorb;
|
||||
|
||||
dmgInfo.AbsorbDamage(currentAbsorb);
|
||||
|
||||
absorbAurEff->SetAmount(absorbAurEff->GetAmount() - currentAbsorb);
|
||||
if ((absorbAurEff->GetAmount() <= 0))
|
||||
absorbAurEff->GetBase()->Remove(AURA_REMOVE_BY_ENEMY_SPELL);
|
||||
}
|
||||
}
|
||||
|
||||
// split damage auras - only when not damaging self
|
||||
if (pVictim != this)
|
||||
{
|
||||
// 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(pVictim->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(pVictim->GetGUID())))
|
||||
continue;
|
||||
// check damage school mask
|
||||
if (!((*itr)->GetMiscValue() & schoolMask))
|
||||
continue;
|
||||
|
||||
int32 currentAbsorb;
|
||||
// Damage can be splitted only if aura has an alive caster
|
||||
Unit * caster = (*itr)->GetCaster();
|
||||
if (!caster || (caster == pVictim) || !caster->IsInWorld() || !caster->isAlive())
|
||||
continue;
|
||||
|
||||
if (RemainingDamage >= (*itr)->GetAmount())
|
||||
currentAbsorb = (*itr)->GetAmount();
|
||||
else
|
||||
currentAbsorb = RemainingDamage;
|
||||
int32 splitDamage = (*itr)->GetAmount();
|
||||
|
||||
currentAbsorb = (100 - auraAbsorbMod) * currentAbsorb / 100;
|
||||
// absorb must be smaller than the damage itself
|
||||
splitDamage = RoundToInterval(splitDamage, 0, int32(dmgInfo.GetDamage()));
|
||||
|
||||
if (float manaMultiplier = SpellMgr::CalculateSpellEffectValueMultiplier((*itr)->GetSpellProto(), (*itr)->GetEffIndex(), (*itr)->GetCaster()))
|
||||
{
|
||||
int32 maxAbsorb = int32(pVictim->GetPower(POWER_MANA) / manaMultiplier);
|
||||
if (currentAbsorb > maxAbsorb)
|
||||
currentAbsorb = maxAbsorb;
|
||||
dmgInfo.ModifyDamage(-splitDamage);
|
||||
|
||||
int32 manaReduction = int32(currentAbsorb * manaMultiplier);
|
||||
pVictim->ApplyPowerMod(POWER_MANA, manaReduction, false);
|
||||
}
|
||||
uint32 splitted = splitDamage;
|
||||
uint32 splitted_absorb = 0;
|
||||
DealDamageMods(caster, splitted, &splitted_absorb);
|
||||
|
||||
// Mana Shield (or Fire Ward or Frost Ward or Ice Barrier)
|
||||
// for Incanter's Absorption converting to spell power
|
||||
if ((*itr)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_MAGE && (*itr)->GetSpellProto()->SpellFamilyFlags[EFFECT_2] & 0x8)
|
||||
incanterAbsorption += currentAbsorb;
|
||||
SendSpellNonMeleeDamageLog(caster, (*itr)->GetSpellProto()->Id, splitted, schoolMask, splitted_absorb, 0, false, 0, false);
|
||||
|
||||
(*itr)->SetAmount((*itr)->GetAmount() - currentAbsorb);
|
||||
if (((*itr)->GetAmount() <= 0) || (pVictim->GetPower(POWER_MANA) <= 1))
|
||||
existExpired = true;
|
||||
|
||||
RemainingDamage -= currentAbsorb;
|
||||
CleanDamage cleanDamage = CleanDamage(splitted, 0, BASE_ATTACK, MELEE_HIT_NORMAL);
|
||||
DealDamage(caster, splitted, &cleanDamage, DIRECT_DAMAGE, schoolMask, (*itr)->GetSpellProto(), false);
|
||||
}
|
||||
|
||||
if (existExpired)
|
||||
for (AuraEffectList::const_iterator itr = vManaShield.begin(); itr != vManaShield.end();)
|
||||
{
|
||||
AuraEffect * auraEff = (*itr);
|
||||
++itr;
|
||||
|
||||
if ((auraEff->GetAmount() <= 0) || (pVictim->GetPower(POWER_MANA) <= 1))
|
||||
{
|
||||
uint32 removedAuras = pVictim->m_removedAurasCount;
|
||||
auraEff->GetBase()->Remove(AURA_REMOVE_BY_ENEMY_SPELL);
|
||||
if (removedAuras + 1 < pVictim->m_removedAurasCount)
|
||||
itr = vManaShield.begin();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Do nothing if 100% absorb ignore
|
||||
if (auraAbsorbMod < 100)
|
||||
if (pVictim != this) // only split damage if not damaging yourself
|
||||
// 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(pVictim->GetAuraEffectsByType(SPELL_AURA_SPLIT_DAMAGE_PCT));
|
||||
for (AuraEffectList::iterator itr = vSplitDamagePctCopy.begin(), next; (itr != vSplitDamagePctCopy.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(pVictim->GetAuraEffectsByType(SPELL_AURA_SPLIT_DAMAGE_FLAT));
|
||||
for (AuraEffectList::iterator itr = vSplitDamageFlatCopy.begin(); (itr != vSplitDamageFlatCopy.end()) && (RemainingDamage >= 0); ++itr)
|
||||
{
|
||||
// Check if aura was removed during iteration - we don't need to work on such auras
|
||||
if (!((*itr)->GetBase()->IsAppliedOnTarget(pVictim->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(pVictim->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 == pVictim) || !caster->IsInWorld() || !caster->isAlive())
|
||||
continue;
|
||||
// Damage can be splitted only if aura has an alive caster
|
||||
Unit * caster = (*itr)->GetCaster();
|
||||
if (!caster || (caster == pVictim) || !caster->IsInWorld() || !caster->isAlive())
|
||||
continue;
|
||||
|
||||
int32 currentAbsorb;
|
||||
if (RemainingDamage >= (*itr)->GetAmount())
|
||||
currentAbsorb = (*itr)->GetAmount();
|
||||
else
|
||||
currentAbsorb = RemainingDamage;
|
||||
currentAbsorb = (100 - auraAbsorbMod) * currentAbsorb / 100;
|
||||
int32 splitDamage = CalculatePctN(dmgInfo.GetDamage(), (*itr)->GetAmount());
|
||||
|
||||
RemainingDamage -= currentAbsorb;
|
||||
// absorb must be smaller than the damage itself
|
||||
splitDamage = RoundToInterval(splitDamage, 0, int32(dmgInfo.GetDamage()));
|
||||
|
||||
uint32 splitted = currentAbsorb;
|
||||
uint32 splitted_absorb = 0;
|
||||
DealDamageMods(caster, splitted, &splitted_absorb);
|
||||
dmgInfo.ModifyDamage(-splitDamage);
|
||||
|
||||
SendSpellNonMeleeDamageLog(caster, (*itr)->GetSpellProto()->Id, splitted, schoolMask, splitted_absorb, 0, false, 0, false);
|
||||
uint32 splitted = splitDamage;
|
||||
uint32 split_absorb = 0;
|
||||
DealDamageMods(caster, splitted, &split_absorb);
|
||||
|
||||
CleanDamage cleanDamage = CleanDamage(splitted, 0, BASE_ATTACK, MELEE_HIT_NORMAL);
|
||||
DealDamage(caster, splitted, &cleanDamage, DIRECT_DAMAGE, schoolMask, (*itr)->GetSpellProto(), false);
|
||||
}
|
||||
SendSpellNonMeleeDamageLog(caster, (*itr)->GetSpellProto()->Id, splitted, schoolMask, split_absorb, 0, false, 0, 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(pVictim->GetAuraEffectsByType(SPELL_AURA_SPLIT_DAMAGE_PCT));
|
||||
for (AuraEffectList::iterator itr = vSplitDamagePctCopy.begin(), next; (itr != vSplitDamagePctCopy.end()) && (RemainingDamage >= 0); ++itr)
|
||||
{
|
||||
// Check if aura was removed during iteration - we don't need to work on such auras
|
||||
if (!((*itr)->GetBase()->IsAppliedOnTarget(pVictim->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 == pVictim) || !caster->IsInWorld() || !caster->isAlive())
|
||||
continue;
|
||||
|
||||
uint32 splitted = CalculatePctN(RemainingDamage, (*itr)->GetAmount());
|
||||
AddPctN(splitted, -auraAbsorbMod);
|
||||
|
||||
RemainingDamage -= int32(splitted);
|
||||
|
||||
uint32 split_absorb = 0;
|
||||
DealDamageMods(caster, splitted, &split_absorb);
|
||||
|
||||
SendSpellNonMeleeDamageLog(caster, (*itr)->GetSpellProto()->Id, splitted, schoolMask, split_absorb, 0, false, 0, false);
|
||||
|
||||
CleanDamage cleanDamage = CleanDamage(splitted, 0, BASE_ATTACK, MELEE_HIT_NORMAL);
|
||||
DealDamage(caster, splitted, &cleanDamage, DIRECT_DAMAGE, schoolMask, (*itr)->GetSpellProto(), false);
|
||||
}
|
||||
CleanDamage cleanDamage = CleanDamage(splitted, 0, BASE_ATTACK, MELEE_HIT_NORMAL);
|
||||
DealDamage(caster, splitted, &cleanDamage, DIRECT_DAMAGE, schoolMask, (*itr)->GetSpellProto(), false);
|
||||
}
|
||||
|
||||
TotalAbsorb = (TotalAbsorb - RemainingDamage > 0) ? TotalAbsorb - RemainingDamage : 0;
|
||||
}
|
||||
|
||||
// Apply death prevention spells effects
|
||||
if (auraAbsorbMod < 100) // Do nothing if 100% absorb ignore
|
||||
if (preventDeathSpell && (RemainingDamage >= int32(pVictim->GetHealth())))
|
||||
if (preventDeathSpell && (dmgInfo.GetDamage() >= int32(pVictim->GetHealth())))
|
||||
{
|
||||
switch(preventDeathSpell->SpellFamilyName)
|
||||
{
|
||||
@@ -2108,9 +2033,14 @@ void Unit::CalcAbsorbResist(Unit *pVictim, SpellSchoolMask schoolMask, DamageEff
|
||||
pVictim->CastSpell(pVictim, 31231, true);
|
||||
pVictim->ToPlayer()->AddSpellCooldown(31231, 0, time(NULL) + 60);
|
||||
|
||||
// with health > 10% lost health until health == 10%, in other case no losses
|
||||
uint32 health10 = pVictim->CountPctFromMaxHealth(10);
|
||||
RemainingDamage = pVictim->GetHealth() > health10 ? pVictim->GetHealth() - health10 : 0;
|
||||
|
||||
// hp > 10% - absorb hp till 10%
|
||||
if (pVictim->GetHealth() > health10)
|
||||
dmgInfo.AbsorbDamage(dmgInfo.GetDamage() - pVictim->GetHealth() + health10);
|
||||
// hp lower than 10% - absorb everything
|
||||
else
|
||||
dmgInfo.AbsorbDamage(dmgInfo.GetDamage());
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -2122,14 +2052,15 @@ void Unit::CalcAbsorbResist(Unit *pVictim, SpellSchoolMask schoolMask, DamageEff
|
||||
int32 healAmount = int32(pVictim->CountPctFromMaxHealth(preventDeathAmount));
|
||||
pVictim->RemoveAurasDueToSpell(preventDeathSpell->Id);
|
||||
pVictim->CastCustomSpell(pVictim, 48153, &healAmount, NULL, NULL, true);
|
||||
RemainingDamage = 0;
|
||||
dmgInfo.AbsorbDamage(dmgInfo.GetDamage());
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*absorb = RemainingDamage > 0 ? (damage - RemainingDamage - *resist) : (damage - *resist);
|
||||
*resist = dmgInfo.GetResist();
|
||||
*absorb = dmgInfo.GetAbsorb();
|
||||
|
||||
// Incanter's Absorption, if have affective absorbing
|
||||
if (incanterAbsorption)
|
||||
@@ -13550,50 +13481,6 @@ void Unit::SetMaxPower(Powers power, uint32 val)
|
||||
SetPower(power, val);
|
||||
}
|
||||
|
||||
void Unit::ApplyPowerMod(Powers power, uint32 val, bool apply)
|
||||
{
|
||||
ApplyModUInt32Value(UNIT_FIELD_POWER1+power, val, apply);
|
||||
|
||||
// group update
|
||||
if (GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
if (this->ToPlayer()->GetGroup())
|
||||
this->ToPlayer()->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_CUR_POWER);
|
||||
}
|
||||
else if (this->ToCreature()->isPet())
|
||||
{
|
||||
Pet *pet = ((Pet*)this);
|
||||
if (pet->isControlled())
|
||||
{
|
||||
Unit *owner = GetOwner();
|
||||
if (owner && (owner->GetTypeId() == TYPEID_PLAYER) && owner->ToPlayer()->GetGroup())
|
||||
owner->ToPlayer()->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_CUR_POWER);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Unit::ApplyMaxPowerMod(Powers power, uint32 val, bool apply)
|
||||
{
|
||||
ApplyModUInt32Value(UNIT_FIELD_MAXPOWER1+power, val, apply);
|
||||
|
||||
// group update
|
||||
if (GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
if (this->ToPlayer()->GetGroup())
|
||||
this->ToPlayer()->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_MAX_POWER);
|
||||
}
|
||||
else if (this->ToCreature()->isPet())
|
||||
{
|
||||
Pet *pet = ((Pet*)this);
|
||||
if (pet->isControlled())
|
||||
{
|
||||
Unit *owner = GetOwner();
|
||||
if (owner && (owner->GetTypeId() == TYPEID_PLAYER) && owner->ToPlayer()->GetGroup())
|
||||
owner->ToPlayer()->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_MAX_POWER);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint32 Unit::GetCreatePowers(Powers power) const
|
||||
{
|
||||
// POWER_FOCUS and POWER_HAPPINESS only have hunter pet
|
||||
|
||||
@@ -806,6 +806,60 @@ struct CleanDamage
|
||||
MeleeHitOutcome hitOutCome;
|
||||
};
|
||||
|
||||
class DamageInfo
|
||||
{
|
||||
private:
|
||||
Unit * const m_attacker;
|
||||
Unit * const m_victim;
|
||||
DamageEffectType const m_damageType;
|
||||
SpellEntry const * const m_spellInfo;
|
||||
SpellSchoolMask const m_schoolMask;
|
||||
uint32 m_damage;
|
||||
uint32 m_absorb;
|
||||
uint32 m_resist;
|
||||
uint32 m_block;
|
||||
public:
|
||||
explicit DamageInfo(Unit * _attacker, Unit * _victim, uint32 _damage, SpellEntry const * _spellInfo, SpellSchoolMask _schoolMask, DamageEffectType _damageType)
|
||||
: m_attacker(_attacker), m_victim(_victim), m_damage(_damage), m_spellInfo(_spellInfo), m_schoolMask(_schoolMask), m_damageType(_damageType)
|
||||
{
|
||||
m_absorb = 0;
|
||||
m_resist = 0;
|
||||
m_block = 0;
|
||||
}
|
||||
void ModifyDamage(int32 amount)
|
||||
{
|
||||
amount = std::min(amount, int32(GetDamage()));
|
||||
m_damage += amount;
|
||||
}
|
||||
void AbsorbDamage(uint32 amount)
|
||||
{
|
||||
amount = std::min(amount, GetDamage());
|
||||
m_absorb += amount;
|
||||
m_damage -= amount;
|
||||
}
|
||||
void ResistDamage(uint32 amount)
|
||||
{
|
||||
amount = std::min(amount, GetDamage());
|
||||
m_resist += amount;
|
||||
m_damage -= amount;
|
||||
}
|
||||
void BlockDamage(uint32 amount)
|
||||
{
|
||||
amount = std::min(amount, GetDamage());
|
||||
m_block += amount;
|
||||
m_damage -= amount;
|
||||
}
|
||||
Unit * GetAttacker() const { return m_attacker; };
|
||||
Unit * GetVictim() const { return m_victim; };
|
||||
DamageEffectType const GetDamageType() const { return m_damageType; };
|
||||
SpellEntry const * GetSpellInfo() const { return m_spellInfo; };
|
||||
SpellSchoolMask const GetSchoolMask() const { return m_schoolMask; };
|
||||
uint32 GetDamage() const { return m_damage; };
|
||||
uint32 GetAbsorb() const { return m_absorb; };
|
||||
uint32 GetResist() const { return m_resist; };
|
||||
uint32 GetBlock() const { return m_block; };
|
||||
};
|
||||
|
||||
// Struct for use in Unit::CalculateMeleeDamage
|
||||
// Need create structure like in SMSG_ATTACKERSTATEUPDATE opcode
|
||||
struct CalcDamageInfo
|
||||
@@ -1214,9 +1268,8 @@ class Unit : public WorldObject
|
||||
uint32 GetMaxPower(Powers power) const { return GetUInt32Value(UNIT_FIELD_MAXPOWER1+power); }
|
||||
void SetPower(Powers power, uint32 val);
|
||||
void SetMaxPower(Powers power, uint32 val);
|
||||
// returns the change in power
|
||||
int32 ModifyPower(Powers power, int32 val);
|
||||
void ApplyPowerMod(Powers power, uint32 val, bool apply);
|
||||
void ApplyMaxPowerMod(Powers power, uint32 val, bool apply);
|
||||
|
||||
uint32 GetAttackTime(WeaponAttackType att) const
|
||||
{
|
||||
|
||||
@@ -60,6 +60,7 @@ class AuraEffect
|
||||
void ResetPeriodic(bool resetPeriodicTimer = false) { if (resetPeriodicTimer) m_periodicTimer = m_amplitude; m_tickNumber = 0;}
|
||||
|
||||
bool IsPeriodic() const { return m_isPeriodic; }
|
||||
void SetPeriodic(bool isPeriodic) { m_isPeriodic = isPeriodic; }
|
||||
bool IsAffectedOnSpell(SpellEntry const *spell) const;
|
||||
|
||||
void SendTickImmune(Unit * target, Unit *caster) const;
|
||||
@@ -72,7 +73,6 @@ class AuraEffect
|
||||
|
||||
void CleanupTriggeredSpells(Unit * target);
|
||||
|
||||
static bool IsPeriodicAuraType(uint32 type);
|
||||
// add/remove SPELL_AURA_MOD_SHAPESHIFT (36) linked auras
|
||||
void HandleShapeshiftBoosts(Unit * target, bool apply) const;
|
||||
private:
|
||||
|
||||
@@ -1656,12 +1656,12 @@ bool Aura::CallScriptEffectApplyHandlers(AuraEffect const * aurEff, AuraApplicat
|
||||
bool preventDefault = false;
|
||||
for(std::list<AuraScript *>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end() ; ++scritr)
|
||||
{
|
||||
(*scritr)->_PrepareScriptCall(AURA_SCRIPT_HOOK_EFFECT_APPLY);
|
||||
(*scritr)->_PrepareScriptCall(AURA_SCRIPT_HOOK_EFFECT_APPLY, aurApp);
|
||||
std::list<AuraScript::EffectApplyHandler>::iterator effEndItr = (*scritr)->OnEffectApply.end(), effItr = (*scritr)->OnEffectApply.begin();
|
||||
for(; effItr != effEndItr ; ++effItr)
|
||||
{
|
||||
if ((*effItr).IsEffectAffected(m_spellProto, aurEff->GetEffIndex()))
|
||||
(*effItr).Call(*scritr, aurEff, aurApp, mode);
|
||||
(*effItr).Call(*scritr, aurEff, mode);
|
||||
}
|
||||
if (!preventDefault)
|
||||
preventDefault = (*scritr)->_IsDefaultActionPrevented();
|
||||
@@ -1675,12 +1675,12 @@ bool Aura::CallScriptEffectRemoveHandlers(AuraEffect const * aurEff, AuraApplica
|
||||
bool preventDefault = false;
|
||||
for(std::list<AuraScript *>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end() ; ++scritr)
|
||||
{
|
||||
(*scritr)->_PrepareScriptCall(AURA_SCRIPT_HOOK_EFFECT_REMOVE);
|
||||
(*scritr)->_PrepareScriptCall(AURA_SCRIPT_HOOK_EFFECT_REMOVE, aurApp);
|
||||
std::list<AuraScript::EffectApplyHandler>::iterator effEndItr = (*scritr)->OnEffectRemove.end(), effItr = (*scritr)->OnEffectRemove.begin();
|
||||
for(; effItr != effEndItr ; ++effItr)
|
||||
{
|
||||
if ((*effItr).IsEffectAffected(m_spellProto, aurEff->GetEffIndex()))
|
||||
(*effItr).Call(*scritr, aurEff, aurApp, mode);
|
||||
(*effItr).Call(*scritr, aurEff, mode);
|
||||
}
|
||||
if (!preventDefault)
|
||||
preventDefault = (*scritr)->_IsDefaultActionPrevented();
|
||||
@@ -1694,12 +1694,12 @@ bool Aura::CallScriptEffectPeriodicHandlers(AuraEffect const * aurEff, AuraAppli
|
||||
bool preventDefault = false;
|
||||
for(std::list<AuraScript *>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end() ; ++scritr)
|
||||
{
|
||||
(*scritr)->_PrepareScriptCall(AURA_SCRIPT_HOOK_EFFECT_PERIODIC);
|
||||
(*scritr)->_PrepareScriptCall(AURA_SCRIPT_HOOK_EFFECT_PERIODIC, aurApp);
|
||||
std::list<AuraScript::EffectPeriodicHandler>::iterator effEndItr = (*scritr)->OnEffectPeriodic.end(), effItr = (*scritr)->OnEffectPeriodic.begin();
|
||||
for(; effItr != effEndItr ; ++effItr)
|
||||
{
|
||||
if ((*effItr).IsEffectAffected(m_spellProto, aurEff->GetEffIndex()))
|
||||
(*effItr).Call(*scritr, aurEff, aurApp);
|
||||
(*effItr).Call(*scritr, aurEff);
|
||||
}
|
||||
if (!preventDefault)
|
||||
preventDefault = (*scritr)->_IsDefaultActionPrevented();
|
||||
@@ -1728,7 +1728,7 @@ void Aura::CallScriptEffectCalcAmountHandlers(AuraEffect const * aurEff, int32 &
|
||||
for(std::list<AuraScript *>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end() ; ++scritr)
|
||||
{
|
||||
(*scritr)->_PrepareScriptCall(AURA_SCRIPT_HOOK_EFFECT_CALC_AMOUNT);
|
||||
std::list<AuraScript::EffectCalcAmountHandler>::iterator effEndItr = (*scritr)->OnEffectCalcAmount.end(), effItr = (*scritr)->OnEffectCalcAmount.begin();
|
||||
std::list<AuraScript::EffectCalcAmountHandler>::iterator effEndItr = (*scritr)->DoEffectCalcAmount.end(), effItr = (*scritr)->DoEffectCalcAmount.begin();
|
||||
for(; effItr != effEndItr ; ++effItr)
|
||||
{
|
||||
if ((*effItr).IsEffectAffected(m_spellProto, aurEff->GetEffIndex()))
|
||||
@@ -1743,7 +1743,7 @@ void Aura::CallScriptEffectCalcPeriodicHandlers(AuraEffect const * aurEff, bool
|
||||
for(std::list<AuraScript *>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end() ; ++scritr)
|
||||
{
|
||||
(*scritr)->_PrepareScriptCall(AURA_SCRIPT_HOOK_EFFECT_CALC_PERIODIC);
|
||||
std::list<AuraScript::EffectCalcPeriodicHandler>::iterator effEndItr = (*scritr)->OnEffectCalcPeriodic.end(), effItr = (*scritr)->OnEffectCalcPeriodic.begin();
|
||||
std::list<AuraScript::EffectCalcPeriodicHandler>::iterator effEndItr = (*scritr)->DoEffectCalcPeriodic.end(), effItr = (*scritr)->DoEffectCalcPeriodic.begin();
|
||||
for(; effItr != effEndItr ; ++effItr)
|
||||
{
|
||||
if ((*effItr).IsEffectAffected(m_spellProto, aurEff->GetEffIndex()))
|
||||
@@ -1758,7 +1758,7 @@ void Aura::CallScriptEffectCalcSpellModHandlers(AuraEffect const * aurEff, Spell
|
||||
for(std::list<AuraScript *>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end() ; ++scritr)
|
||||
{
|
||||
(*scritr)->_PrepareScriptCall(AURA_SCRIPT_HOOK_EFFECT_CALC_SPELLMOD);
|
||||
std::list<AuraScript::EffectCalcSpellModHandler>::iterator effEndItr = (*scritr)->OnEffectCalcSpellMod.end(), effItr = (*scritr)->OnEffectCalcSpellMod.begin();
|
||||
std::list<AuraScript::EffectCalcSpellModHandler>::iterator effEndItr = (*scritr)->DoEffectCalcSpellMod.end(), effItr = (*scritr)->DoEffectCalcSpellMod.begin();
|
||||
for(; effItr != effEndItr ; ++effItr)
|
||||
{
|
||||
if ((*effItr).IsEffectAffected(m_spellProto, aurEff->GetEffIndex()))
|
||||
@@ -1768,6 +1768,23 @@ void Aura::CallScriptEffectCalcSpellModHandlers(AuraEffect const * aurEff, Spell
|
||||
}
|
||||
}
|
||||
|
||||
void Aura::CallScriptEffectAbsorbHandlers(AuraEffect * aurEff, AuraApplication const * aurApp, DamageInfo & dmgInfo, uint32 & absorbAmount, bool & defaultPrevented)
|
||||
{
|
||||
for(std::list<AuraScript *>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end() ; ++scritr)
|
||||
{
|
||||
(*scritr)->_PrepareScriptCall(AURA_SCRIPT_HOOK_EFFECT_ABSORB, aurApp);
|
||||
std::list<AuraScript::EffectAbsorbHandler>::iterator effEndItr = (*scritr)->OnEffectAbsorb.end(), effItr = (*scritr)->OnEffectAbsorb.begin();
|
||||
for(; effItr != effEndItr ; ++effItr)
|
||||
{
|
||||
if ((*effItr).IsEffectAffected(m_spellProto, aurEff->GetEffIndex()))
|
||||
(*effItr).Call(*scritr, aurEff, dmgInfo, absorbAmount);
|
||||
}
|
||||
if (!defaultPrevented)
|
||||
defaultPrevented = (*scritr)->_IsDefaultActionPrevented();
|
||||
(*scritr)->_FinishScriptCall();
|
||||
}
|
||||
}
|
||||
|
||||
UnitAura::UnitAura(SpellEntry const* spellproto, uint8 effMask, WorldObject * owner, Unit * caster, int32 *baseAmount, Item * castItem, uint64 casterGUID)
|
||||
: Aura(spellproto, effMask, owner, caster, baseAmount, castItem, casterGUID)
|
||||
{
|
||||
|
||||
@@ -174,6 +174,7 @@ class 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 CallScriptEffectAbsorbHandlers(AuraEffect * aurEff, AuraApplication const * aurApp, DamageInfo & dmgInfo, uint32 & absorbAmount, bool & defaultPrevented);
|
||||
std::list<AuraScript *> m_loadedScripts;
|
||||
private:
|
||||
void _DeleteRemovedApplications();
|
||||
|
||||
@@ -431,15 +431,19 @@ bool AuraScript::_Validate(SpellEntry const * entry)
|
||||
if (!(*itr).GetAffectedEffectsMask(entry))
|
||||
sLog->outError("TSCR: Spell `%u` Effect `%s` of script`%s` did not match dbc effect data - bound handler won't be executed", entry->Id, (*itr).ToString().c_str(), m_scriptName->c_str());
|
||||
|
||||
for (std::list<EffectCalcAmountHandler>::iterator itr = OnEffectCalcAmount.begin(); itr != OnEffectCalcAmount.end(); ++itr)
|
||||
for (std::list<EffectCalcAmountHandler>::iterator itr = DoEffectCalcAmount.begin(); itr != DoEffectCalcAmount.end(); ++itr)
|
||||
if (!(*itr).GetAffectedEffectsMask(entry))
|
||||
sLog->outError("TSCR: Spell `%u` Effect `%s` of script`%s` did not match dbc effect data - bound handler won't be executed", entry->Id, (*itr).ToString().c_str(), m_scriptName->c_str());
|
||||
|
||||
for (std::list<EffectCalcPeriodicHandler>::iterator itr = OnEffectCalcPeriodic.begin(); itr != OnEffectCalcPeriodic.end(); ++itr)
|
||||
for (std::list<EffectCalcPeriodicHandler>::iterator itr = DoEffectCalcPeriodic.begin(); itr != DoEffectCalcPeriodic.end(); ++itr)
|
||||
if (!(*itr).GetAffectedEffectsMask(entry))
|
||||
sLog->outError("TSCR: Spell `%u` Effect `%s` of script`%s` did not match dbc effect data - bound handler won't be executed", entry->Id, (*itr).ToString().c_str(), m_scriptName->c_str());
|
||||
|
||||
for (std::list<EffectCalcSpellModHandler>::iterator itr = OnEffectCalcSpellMod.begin(); itr != OnEffectCalcSpellMod.end(); ++itr)
|
||||
for (std::list<EffectCalcSpellModHandler>::iterator itr = DoEffectCalcSpellMod.begin(); itr != DoEffectCalcSpellMod.end(); ++itr)
|
||||
if (!(*itr).GetAffectedEffectsMask(entry))
|
||||
sLog->outError("TSCR: Spell `%u` Effect `%s` of script`%s` did not match dbc effect data - bound handler won't be executed", entry->Id, (*itr).ToString().c_str(), m_scriptName->c_str());
|
||||
|
||||
for (std::list<EffectAbsorbHandler>::iterator itr = OnEffectAbsorb.begin(); itr != OnEffectAbsorb.end(); ++itr)
|
||||
if (!(*itr).GetAffectedEffectsMask(entry))
|
||||
sLog->outError("TSCR: Spell `%u` Effect `%s` of script`%s` did not match dbc effect data - bound handler won't be executed", entry->Id, (*itr).ToString().c_str(), m_scriptName->c_str());
|
||||
|
||||
@@ -467,9 +471,9 @@ AuraScript::EffectPeriodicHandler::EffectPeriodicHandler(AuraEffectPeriodicFnTyp
|
||||
pEffectHandlerScript = _pEffectHandlerScript;
|
||||
}
|
||||
|
||||
void AuraScript::EffectPeriodicHandler::Call(AuraScript * auraScript, AuraEffect const * _aurEff, AuraApplication const * _aurApp)
|
||||
void AuraScript::EffectPeriodicHandler::Call(AuraScript * auraScript, AuraEffect const * _aurEff)
|
||||
{
|
||||
(auraScript->*pEffectHandlerScript)(_aurEff, _aurApp);
|
||||
(auraScript->*pEffectHandlerScript)(_aurEff);
|
||||
}
|
||||
|
||||
AuraScript::EffectUpdatePeriodicHandler::EffectUpdatePeriodicHandler(AuraEffectUpdatePeriodicFnType _pEffectHandlerScript,uint8 _effIndex, uint16 _effName)
|
||||
@@ -523,10 +527,21 @@ AuraScript::EffectApplyHandler::EffectApplyHandler(AuraEffectApplicationModeFnTy
|
||||
mode = _mode;
|
||||
}
|
||||
|
||||
void AuraScript::EffectApplyHandler::Call(AuraScript * auraScript, AuraEffect const * _aurEff, AuraApplication const * _aurApp, AuraEffectHandleModes _mode)
|
||||
void AuraScript::EffectApplyHandler::Call(AuraScript * auraScript, AuraEffect const * _aurEff, AuraEffectHandleModes _mode)
|
||||
{
|
||||
if (_mode & mode)
|
||||
(auraScript->*pEffectHandlerScript)(_aurEff, _aurApp, _mode);
|
||||
(auraScript->*pEffectHandlerScript)(_aurEff, _mode);
|
||||
}
|
||||
|
||||
AuraScript::EffectAbsorbHandler::EffectAbsorbHandler(AuraEffectAbsorbFnType _pEffectHandlerScript,uint8 _effIndex)
|
||||
: AuraScript::EffectBase(_effIndex, SPELL_AURA_SCHOOL_ABSORB)
|
||||
{
|
||||
pEffectHandlerScript = _pEffectHandlerScript;
|
||||
}
|
||||
|
||||
void AuraScript::EffectAbsorbHandler::Call(AuraScript * auraScript, AuraEffect * aurEff, DamageInfo & dmgInfo, uint32 & absorbAmount)
|
||||
{
|
||||
(auraScript->*pEffectHandlerScript)(aurEff, dmgInfo, absorbAmount);
|
||||
}
|
||||
|
||||
bool AuraScript::_Load(Aura * aura)
|
||||
@@ -538,7 +553,7 @@ bool AuraScript::_Load(Aura * aura)
|
||||
return load;
|
||||
}
|
||||
|
||||
void AuraScript::_PrepareScriptCall(AuraScriptHookType hookType)
|
||||
void AuraScript::_PrepareScriptCall(AuraScriptHookType hookType, AuraApplication const * aurApp)
|
||||
{
|
||||
m_currentScriptState = hookType;
|
||||
switch (m_currentScriptState)
|
||||
@@ -546,16 +561,19 @@ void AuraScript::_PrepareScriptCall(AuraScriptHookType hookType)
|
||||
case AURA_SCRIPT_HOOK_EFFECT_APPLY:
|
||||
case AURA_SCRIPT_HOOK_EFFECT_REMOVE:
|
||||
case AURA_SCRIPT_HOOK_EFFECT_PERIODIC:
|
||||
case AURA_SCRIPT_HOOK_EFFECT_ABSORB:
|
||||
m_defaultActionPrevented = false;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
m_auraApplication = aurApp;
|
||||
}
|
||||
|
||||
void AuraScript::_FinishScriptCall()
|
||||
{
|
||||
m_currentScriptState = SPELL_SCRIPT_STATE_NONE;
|
||||
m_auraApplication = NULL;
|
||||
}
|
||||
|
||||
bool AuraScript::_IsDefaultActionPrevented()
|
||||
@@ -733,3 +751,13 @@ bool AuraScript::HasEffectType(AuraType type) const
|
||||
return m_aura->HasEffectType(type);
|
||||
}
|
||||
|
||||
Unit * AuraScript::GetTarget() const
|
||||
{
|
||||
return m_auraApplication->GetTarget();
|
||||
}
|
||||
|
||||
AuraApplication const * AuraScript::GetTargetApplication() const
|
||||
{
|
||||
return m_auraApplication;
|
||||
}
|
||||
|
||||
|
||||
@@ -282,6 +282,7 @@ enum AuraScriptHookType
|
||||
AURA_SCRIPT_HOOK_EFFECT_CALC_AMOUNT,
|
||||
AURA_SCRIPT_HOOK_EFFECT_CALC_PERIODIC,
|
||||
AURA_SCRIPT_HOOK_EFFECT_CALC_SPELLMOD,
|
||||
AURA_SCRIPT_HOOK_EFFECT_ABSORB,
|
||||
/*AURA_SCRIPT_HOOK_APPLY,
|
||||
AURA_SCRIPT_HOOK_REMOVE,*/
|
||||
};
|
||||
@@ -296,12 +297,14 @@ class AuraScript : public _SpellScript
|
||||
public:
|
||||
|
||||
#define AURASCRIPT_FUNCTION_TYPE_DEFINES(CLASSNAME) \
|
||||
typedef void(CLASSNAME::*AuraEffectApplicationModeFnType)(AuraEffect const *, AuraApplication const *, AuraEffectHandleModes mode); \
|
||||
typedef void(CLASSNAME::*AuraEffectPeriodicFnType)(AuraEffect const *, AuraApplication const *); \
|
||||
typedef void(CLASSNAME::*AuraEffectApplicationModeFnType)(AuraEffect const *, AuraEffectHandleModes); \
|
||||
typedef void(CLASSNAME::*AuraEffectPeriodicFnType)(AuraEffect const *); \
|
||||
typedef void(CLASSNAME::*AuraEffectUpdatePeriodicFnType)(AuraEffect *); \
|
||||
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::*AuraEffectAbsorbFnType)(AuraEffect *, DamageInfo &, uint32 &); \
|
||||
//typedef void(CLASSNAME::*AuraAbsorbFnType)(AuraEffect *, DamageInfo &); \
|
||||
|
||||
AURASCRIPT_FUNCTION_TYPE_DEFINES(AuraScript)
|
||||
|
||||
@@ -316,7 +319,7 @@ class AuraScript : public _SpellScript
|
||||
{
|
||||
public:
|
||||
EffectPeriodicHandler(AuraEffectPeriodicFnType _pEffectHandlerScript,uint8 _effIndex, uint16 _effName);
|
||||
void Call(AuraScript * auraScript, AuraEffect const * _aurEff, AuraApplication const * _aurApp);
|
||||
void Call(AuraScript * auraScript, AuraEffect const * _aurEff);
|
||||
private:
|
||||
AuraEffectPeriodicFnType pEffectHandlerScript;
|
||||
};
|
||||
@@ -356,11 +359,19 @@ class AuraScript : public _SpellScript
|
||||
{
|
||||
public:
|
||||
EffectApplyHandler(AuraEffectApplicationModeFnType _pEffectHandlerScript,uint8 _effIndex, uint16 _effName, AuraEffectHandleModes _mode);
|
||||
void Call(AuraScript * auraScript, AuraEffect const * _aurEff, AuraApplication const * _aurApp, AuraEffectHandleModes _mode);
|
||||
void Call(AuraScript * auraScript, AuraEffect const * _aurEff, AuraEffectHandleModes _mode);
|
||||
private:
|
||||
AuraEffectApplicationModeFnType pEffectHandlerScript;
|
||||
AuraEffectHandleModes mode;
|
||||
};
|
||||
class EffectAbsorbHandler : public EffectBase
|
||||
{
|
||||
public:
|
||||
EffectAbsorbHandler(AuraEffectAbsorbFnType _pEffectHandlerScript, uint8 _effIndex);
|
||||
void Call(AuraScript * auraScript, AuraEffect * aurEff, DamageInfo & dmgInfo, uint32 & absorbAmount);
|
||||
private:
|
||||
AuraEffectAbsorbFnType pEffectHandlerScript;
|
||||
};
|
||||
|
||||
#define AURASCRIPT_FUNCTION_CAST_DEFINES(CLASSNAME) \
|
||||
class EffectPeriodicHandlerFunction : public AuraScript::EffectPeriodicHandler { public: EffectPeriodicHandlerFunction(AuraEffectPeriodicFnType _pEffectHandlerScript,uint8 _effIndex, uint16 _effName) : AuraScript::EffectPeriodicHandler((AuraScript::AuraEffectPeriodicFnType)_pEffectHandlerScript, _effIndex, _effName) {} }; \
|
||||
@@ -369,17 +380,19 @@ class AuraScript : public _SpellScript
|
||||
class EffectCalcPeriodicHandlerFunction : public AuraScript::EffectCalcPeriodicHandler { public: EffectCalcPeriodicHandlerFunction(AuraEffectCalcPeriodicFnType _pEffectHandlerScript,uint8 _effIndex, uint16 _effName) : AuraScript::EffectCalcPeriodicHandler((AuraScript::AuraEffectCalcPeriodicFnType)_pEffectHandlerScript, _effIndex, _effName) {} }; \
|
||||
class EffectCalcSpellModHandlerFunction : public AuraScript::EffectCalcSpellModHandler { public: EffectCalcSpellModHandlerFunction(AuraEffectCalcSpellModFnType _pEffectHandlerScript,uint8 _effIndex, uint16 _effName) : AuraScript::EffectCalcSpellModHandler((AuraScript::AuraEffectCalcSpellModFnType)_pEffectHandlerScript, _effIndex, _effName) {} }; \
|
||||
class EffectApplyHandlerFunction : public AuraScript::EffectApplyHandler { public: EffectApplyHandlerFunction(AuraEffectApplicationModeFnType _pEffectHandlerScript,uint8 _effIndex, uint16 _effName, AuraEffectHandleModes _mode) : AuraScript::EffectApplyHandler((AuraScript::AuraEffectApplicationModeFnType)_pEffectHandlerScript, _effIndex, _effName, _mode) {} }; \
|
||||
class EffectAbsorbFunction : public AuraScript::EffectAbsorbHandler { public: EffectAbsorbFunction(AuraEffectAbsorbFnType _pEffectHandlerScript,uint8 _effIndex) : AuraScript::EffectAbsorbHandler((AuraScript::AuraEffectAbsorbFnType)_pEffectHandlerScript, _effIndex) {} }; \
|
||||
|
||||
#define PrepareAuraScript(CLASSNAME) AURASCRIPT_FUNCTION_TYPE_DEFINES(CLASSNAME) AURASCRIPT_FUNCTION_CAST_DEFINES(CLASSNAME)
|
||||
|
||||
public:
|
||||
bool _Validate(SpellEntry const * entry);
|
||||
bool _Load(Aura * aura);
|
||||
void _PrepareScriptCall(AuraScriptHookType hookType);
|
||||
void _PrepareScriptCall(AuraScriptHookType hookType, AuraApplication const * aurApp = NULL);
|
||||
void _FinishScriptCall();
|
||||
bool _IsDefaultActionPrevented();
|
||||
private:
|
||||
Aura * m_aura;
|
||||
AuraApplication const * m_auraApplication;
|
||||
bool m_defaultActionPrevented;
|
||||
public:
|
||||
//
|
||||
@@ -388,44 +401,57 @@ class AuraScript : public _SpellScript
|
||||
//
|
||||
// executed when periodic aura effect is applied with specified mode to target
|
||||
// example: OnEffectApply += AuraEffectApplyFn(class::function, EffectIndexSpecifier, EffectAuraNameSpecifier, AuraEffectHandleModes);
|
||||
// where function is: void function (AuraEffect const * aurEff, AuraEffectHandleModes mode);
|
||||
HookList<EffectApplyHandler> OnEffectApply;
|
||||
#define AuraEffectApplyFn(F, I, N, M) EffectApplyHandlerFunction((AuraEffectApplicationModeFnType)&F, I, N, M)
|
||||
#define AuraEffectApplyFn(F, I, N, M) EffectApplyHandlerFunction(&F, I, N, M)
|
||||
|
||||
// executed when periodic aura effect is removed with specified mode from target
|
||||
// example: OnEffectRemove += AuraEffectRemoveFn(class::function, EffectIndexSpecifier, EffectAuraNameSpecifier, AuraEffectHandleModes);
|
||||
// where function is: void function (AuraEffect const * aurEff, AuraApplication const * aurApp, AuraEffectHandleModes mode);
|
||||
// where function is: void function (AuraEffect const * aurEff, AuraEffectHandleModes mode);
|
||||
HookList<EffectApplyHandler> OnEffectRemove;
|
||||
#define AuraEffectRemoveFn(F, I, N, M) EffectApplyHandlerFunction((AuraEffectApplicationModeFnType)&F, I, N, M)
|
||||
#define AuraEffectRemoveFn(F, I, N, M) EffectApplyHandlerFunction(&F, I, N, M)
|
||||
|
||||
// executed when periodic aura effect ticks on target
|
||||
// example: OnEffectPeriodic += AuraEffectPeriodicFn(class::function, EffectIndexSpecifier, EffectAuraNameSpecifier);
|
||||
// where function is: void function (AuraEffect const * aurEff, AuraApplication const * aurApp, AuraEffectHandleModes mode);
|
||||
// where function is: void function (AuraEffect const * aurEff, AuraEffectHandleModes mode);
|
||||
HookList<EffectPeriodicHandler> OnEffectPeriodic;
|
||||
#define AuraEffectPeriodicFn(F, I, N) EffectPeriodicHandlerFunction((AuraEffectPeriodicFnType)&F, I, N)
|
||||
#define AuraEffectPeriodicFn(F, I, N) EffectPeriodicHandlerFunction(&F, I, N)
|
||||
|
||||
// executed when periodic aura effect is updated
|
||||
// example: OnEffectUpdatePeriodic += AuraEffectUpdatePeriodicFn(class::function, EffectIndexSpecifier, EffectAuraNameSpecifier);
|
||||
// where function is: void function (AuraEffect const * aurEff, AuraApplication const * aurApp);
|
||||
// where function is: void function (AuraEffect const * aurEff);
|
||||
HookList<EffectUpdatePeriodicHandler> OnEffectUpdatePeriodic;
|
||||
#define AuraEffectUpdatePeriodicFn(F, I, N) EffectUpdatePeriodicHandlerFunction((AuraEffectUpdatePeriodicFnType)&F, I, N)
|
||||
#define AuraEffectUpdatePeriodicFn(F, I, N) EffectUpdatePeriodicHandlerFunction(&F, I, N)
|
||||
|
||||
// executed when aura effect calculates amount
|
||||
// example: OnEffectCalcAmount += AuraEffectCalcAmounFn(class::function, EffectIndexSpecifier, EffectAuraNameSpecifier);
|
||||
// example: DoEffectCalcAmount += AuraEffectCalcAmounFn(class::function, EffectIndexSpecifier, EffectAuraNameSpecifier);
|
||||
// where function is: void function (AuraEffect * aurEff, int32 & amount, bool & canBeRecalculated);
|
||||
HookList<EffectCalcAmountHandler> OnEffectCalcAmount;
|
||||
#define AuraEffectCalcAmountFn(F, I, N) EffectCalcAmountHandlerFunction((AuraEffectCalcAmountFnType)&F, I, N)
|
||||
HookList<EffectCalcAmountHandler> DoEffectCalcAmount;
|
||||
#define AuraEffectCalcAmountFn(F, I, N) EffectCalcAmountHandlerFunction(&F, I, N)
|
||||
|
||||
// executed when aura effect calculates periodic data
|
||||
// example: OnEffectCalcPeriodic += AuraEffectCalcPeriodicFn(class::function, EffectIndexSpecifier, EffectAuraNameSpecifier);
|
||||
// example: DoEffectCalcPeriodic += AuraEffectCalcPeriodicFn(class::function, EffectIndexSpecifier, EffectAuraNameSpecifier);
|
||||
// where function is: void function (AuraEffect const * aurEff, bool & isPeriodic, int32 & amplitude);
|
||||
HookList<EffectCalcPeriodicHandler> OnEffectCalcPeriodic;
|
||||
#define AuraEffectCalcPeriodicFn(F, I, N) EffectCalcPeriodicHandlerFunction((AuraEffectCalcPeriodicFnType)&F, I, N)
|
||||
HookList<EffectCalcPeriodicHandler> DoEffectCalcPeriodic;
|
||||
#define AuraEffectCalcPeriodicFn(F, I, N) EffectCalcPeriodicHandlerFunction(&F, I, N)
|
||||
|
||||
// executed when aura effect calculates spellmod
|
||||
// example: OnEffectCalcSpellMod += AuraEffectCalcSpellModFn(class::function, EffectIndexSpecifier, EffectAuraNameSpecifier);
|
||||
// example: DoEffectCalcSpellMod += AuraEffectCalcSpellModFn(class::function, EffectIndexSpecifier, EffectAuraNameSpecifier);
|
||||
// where function is: void function (AuraEffect const * aurEff, SpellModifier *& spellMod);
|
||||
HookList<EffectCalcSpellModHandler> OnEffectCalcSpellMod;
|
||||
#define AuraEffectCalcSpellModFn(F, I, N) EffectCalcSpellModHandlerFunction((AuraEffectCalcSpellModFnType)&F, I, N)
|
||||
HookList<EffectCalcSpellModHandler> DoEffectCalcSpellMod;
|
||||
#define AuraEffectCalcSpellModFn(F, I, N) EffectCalcSpellModHandlerFunction(&F, I, N)
|
||||
|
||||
// executed when absorb aura effect is going to reduce damage
|
||||
// example: OnEffectAbsorb += AuraEffectAbsorbFn(class::function, EffectIndexSpecifier);
|
||||
// where function is: void function (AuraEffect * aurEff, DamageInfo & dmgInfo, uint32 & absorbAmount);
|
||||
HookList<EffectAbsorbHandler> OnEffectAbsorb;
|
||||
#define AuraEffectAbsorbFn(F, I) EffectAbsorbFunction(&F, I)
|
||||
|
||||
// executed after aura absorbtions reduced damage
|
||||
// example: AfterAbsorb += AuraAbsorbFn(class::function);
|
||||
// where function is: void function (AuraEffect * aurEff, DamageInfo & dmgInfo);
|
||||
//HookList<AbsorbHandler> AfterAbsorb;
|
||||
//#define AuraAbsorbFn(F) EffectAbsorbFunction(&F)
|
||||
|
||||
// AuraScript interface - hook/effect execution manipulators
|
||||
|
||||
@@ -494,6 +520,14 @@ class AuraScript : public _SpellScript
|
||||
|
||||
// check if aura has effect of given aura type
|
||||
bool HasEffectType(AuraType type) const;
|
||||
|
||||
// AuraScript interface - functions which are redirecting to AuraApplication class
|
||||
// Do not call these in hooks in which AuraApplication is not avalible, otherwise result will differ from expected (the functions will return NULL)
|
||||
|
||||
// returns currently processed target of an aura
|
||||
Unit * GetTarget() const;
|
||||
// returns AuraApplication object of currently processed target
|
||||
AuraApplication const * GetTargetApplication() const;
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
Reference in New Issue
Block a user