diff options
author | QAston <none@none> | 2010-12-27 20:14:54 +0100 |
---|---|---|
committer | QAston <none@none> | 2010-12-27 20:14:54 +0100 |
commit | ef968f4b1552c2f1673a2ec79d8cd6b1ec9c2d11 (patch) | |
tree | d9909a464e9131ffdbe3a6577f0c907560e5f799 | |
parent | da8d794f4bd6765c45847d93626057e272f7358e (diff) |
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
30 files changed, 780 insertions, 427 deletions
diff --git a/sql/base/world_database.sql b/sql/base/world_database.sql index aca1a4b2c5f..ea7b427c7c2 100644 --- a/sql/base/world_database.sql +++ b/sql/base/world_database.sql @@ -26929,6 +26929,7 @@ INSERT INTO `spell_script_names` (`spell_id`,`ScriptName`) VALUES ( 55709, 'spell_hun_pet_heart_of_the_phoenix'), ( 54044, 'spell_hun_pet_carrion_feeder'), -- rogue +(-31130, 'spell_rog_nerves_of_steel'), ( 5938, 'spell_rog_shiv'), ( 14185, 'spell_rog_preparation'), (-51685, 'spell_rog_prey_on_the_weak'), @@ -26940,7 +26941,9 @@ INSERT INTO `spell_script_names` (`spell_id`,`ScriptName`) VALUES (-49158, 'spell_dk_corpse_explosion'), ( 50524, 'spell_dk_runic_power_feed'), (-55090, 'spell_dk_scourge_strike'), +(-49145, 'spell_dk_spell_deflection'), -- shaman +(-51474, 'spell_sha_astral_shift'), ( 39610, 'spell_sha_mana_tide_totem'), ( -1535, 'spell_sha_fire_nova'), ( 6474, 'spell_sha_earthbind_totem'), @@ -26955,9 +26958,14 @@ INSERT INTO `spell_script_names` (`spell_id`,`ScriptName`) VALUES ( 47422, 'spell_warl_everlasting_affliction'), -- druid ( 54846, 'spell_dru_glyph_of_starfire'), +(69366, 'spell_dru_moonkin_form_passive'), +(-33851, 'spell_dru_primal_tenacity'), +(62606, 'spell_dru_savage_defense'), -- example ( 66244, 'spell_ex_66244'), -( 5581, 'spell_ex_5581'); +( 5581, 'spell_ex_5581'), +(47299, 'spell_ex_absorb_aura'); + /*!40000 ALTER TABLE `spell_script_names` ENABLE KEYS */; UNLOCK TABLES; diff --git a/sql/updates/10853_world_spell_script_names.sql b/sql/updates/10853_world_spell_script_names.sql new file mode 100644 index 00000000000..e58c4c9c57d --- /dev/null +++ b/sql/updates/10853_world_spell_script_names.sql @@ -0,0 +1,15 @@ +DELETE FROM `spell_script_names` WHERE `spell_id`=-51474 AND `ScriptName`='spell_sha_astral_shift'; +DELETE FROM `spell_script_names` WHERE `spell_id`=-49145 AND `ScriptName`='spell_dk_spell_deflection'; +DELETE FROM `spell_script_names` WHERE `spell_id`=-31130 AND `ScriptName`='spell_rog_nerves_of_steel'; +DELETE FROM `spell_script_names` WHERE `spell_id`=62606 AND `ScriptName`='spell_dru_savage_defense'; +DELETE FROM `spell_script_names` WHERE `spell_id`=69366 AND `ScriptName`='spell_dru_moonkin_form_passive'; +DELETE FROM `spell_script_names` WHERE `spell_id`=-33851 AND `ScriptName`='spell_dru_primal_tenacity'; +DELETE FROM `spell_script_names` WHERE `spell_id`=47299 AND `ScriptName`='spell_ex_absorb_aura'; +INSERT INTO `spell_script_names` (`spell_id`,`ScriptName`) VALUES +(-51474, 'spell_sha_astral_shift'), +(-49145, 'spell_dk_spell_deflection'), +(-31130, 'spell_rog_nerves_of_steel'), +(62606, 'spell_dru_savage_defense'), +(69366, 'spell_dru_moonkin_form_passive'), +(-33851, 'spell_dru_primal_tenacity'), +(47299, 'spell_ex_absorb_aura');
\ No newline at end of file diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 44659254e7c..ab0eb074506 100755 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -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); + // get amount which can be still absorbed by the aura + int32 currentAbsorb = absorbAurEff->GetAmount(); + // aura with infinite absorb amount - let the scripts handle absorbtion amount, set here to 0 for safety + if (currentAbsorb < 0) + currentAbsorb = 0; - if (roll_chance_i(chance)) - { - pVictim->CastCustomSpell(pVictim, 57776, &RemainingDamage, NULL, NULL, true, NULL, absorbAurEff); - RemainingDamage = RemainingDamage * auraAbsorbMod / 100; - continue; - } - } + uint32 absorb = currentAbsorb; - if (auraAbsorbMod >= 100) // Do nothing if 100% absorb ignore - continue; + bool defaultPrevented = false; - // Max Amount can be absorbed by this aura - int32 currentAbsorb = absorbAurEff->GetAmount(); - // Found empty aura - if (currentAbsorb <= 0) - { - absorbAurEff->GetBase()->Remove(AURA_REMOVE_BY_ENEMY_SPELL); - continue; - } - - currentAbsorb = (100 - auraAbsorbMod) * currentAbsorb / 100; + absorbAurEff->GetBase()->CallScriptEffectAbsorbHandlers(absorbAurEff, aurApp, dmgInfo, absorb, defaultPrevented); - // Handle custom absorb auras - // TODO: try find better way + 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; - - RemainingDamage -= currentAbsorb; + // 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); - 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; + + // Apply absorb mod auras + AddPctF(currentAbsorb, -auraAbsorbMod); + + // absorb must be smaller than the damage itself + currentAbsorb = RoundToInterval(currentAbsorb, 0, int32(dmgInfo.GetDamage())); - RemainingDamage -= currentAbsorb; + 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 (!((*itr)->GetMiscValue() & schoolMask)) + if (!(absorbAurEff->GetMiscValue() & schoolMask)) continue; - int32 currentAbsorb; + // get amount which can be still absorbed by the aura + int32 currentAbsorb = absorbAurEff->GetAmount(); - if (RemainingDamage >= (*itr)->GetAmount()) - currentAbsorb = (*itr)->GetAmount(); - else - currentAbsorb = RemainingDamage; + AddPctF(currentAbsorb, -auraAbsorbMod); - currentAbsorb = (100 - auraAbsorbMod) * currentAbsorb / 100; + // absorb must be smaller than the damage itself + currentAbsorb = RoundToInterval(currentAbsorb, 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; + int32 manaReduction = currentAbsorb; - int32 manaReduction = int32(currentAbsorb * manaMultiplier); - pVictim->ApplyPowerMod(POWER_MANA, manaReduction, false); - } + // 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 ((*itr)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_MAGE && (*itr)->GetSpellProto()->SpellFamilyFlags[EFFECT_2] & 0x8) + if (absorbAurEff->GetSpellProto()->SpellFamilyName == SPELLFAMILY_MAGE && absorbAurEff->GetSpellProto()->SpellFamilyFlags[2] & 0x8) incanterAbsorption += currentAbsorb; - (*itr)->SetAmount((*itr)->GetAmount() - currentAbsorb); - if (((*itr)->GetAmount() <= 0) || (pVictim->GetPower(POWER_MANA) <= 1)) - existExpired = true; + dmgInfo.AbsorbDamage(currentAbsorb); - RemainingDamage -= currentAbsorb; + absorbAurEff->SetAmount(absorbAurEff->GetAmount() - currentAbsorb); + if ((absorbAurEff->GetAmount() <= 0)) + absorbAurEff->GetBase()->Remove(AURA_REMOVE_BY_ENEMY_SPELL); } - - 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 + // 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) { - // 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 = (*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 splitted_absorb = 0; + DealDamageMods(caster, splitted, &splitted_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, splitted_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; + CleanDamage cleanDamage = CleanDamage(splitted, 0, BASE_ATTACK, MELEE_HIT_NORMAL); + DealDamage(caster, splitted, &cleanDamage, DIRECT_DAMAGE, schoolMask, (*itr)->GetSpellProto(), false); + } - // Damage can be splitted only if aura has an alive caster - Unit * caster = (*itr)->GetCaster(); - if (!caster || (caster == pVictim) || !caster->IsInWorld() || !caster->isAlive()) - 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(pVictim->GetAuraEffectsByType(SPELL_AURA_SPLIT_DAMAGE_PCT)); + for (AuraEffectList::iterator itr = vSplitDamagePctCopy.begin(), next; (itr != vSplitDamagePctCopy.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; - uint32 splitted = CalculatePctN(RemainingDamage, (*itr)->GetAmount()); - AddPctN(splitted, -auraAbsorbMod); + // Damage can be splitted only if aura has an alive caster + Unit * caster = (*itr)->GetCaster(); + if (!caster || (caster == pVictim) || !caster->IsInWorld() || !caster->isAlive()) + continue; - RemainingDamage -= int32(splitted); + int32 splitDamage = CalculatePctN(dmgInfo.GetDamage(), (*itr)->GetAmount()); - uint32 split_absorb = 0; - DealDamageMods(caster, splitted, &split_absorb); + // absorb must be smaller than the damage itself + splitDamage = RoundToInterval(splitDamage, 0, int32(dmgInfo.GetDamage())); - SendSpellNonMeleeDamageLog(caster, (*itr)->GetSpellProto()->Id, splitted, schoolMask, split_absorb, 0, false, 0, false); + dmgInfo.ModifyDamage(-splitDamage); - CleanDamage cleanDamage = CleanDamage(splitted, 0, BASE_ATTACK, MELEE_HIT_NORMAL); - DealDamage(caster, splitted, &cleanDamage, DIRECT_DAMAGE, schoolMask, (*itr)->GetSpellProto(), false); - } - } + uint32 splitted = splitDamage; + uint32 split_absorb = 0; + DealDamageMods(caster, splitted, &split_absorb); - TotalAbsorb = (TotalAbsorb - RemainingDamage > 0) ? TotalAbsorb - RemainingDamage : 0; + 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); + } + } // 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 diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index 15b248a5fff..465ab7aa729 100755 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -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 { diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.h b/src/server/game/Spells/Auras/SpellAuraEffects.h index 80809c9d0bb..02b5825d5ec 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.h +++ b/src/server/game/Spells/Auras/SpellAuraEffects.h @@ -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: diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp index 4a7ec595f28..5068de484af 100755 --- a/src/server/game/Spells/Auras/SpellAuras.cpp +++ b/src/server/game/Spells/Auras/SpellAuras.cpp @@ -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) { diff --git a/src/server/game/Spells/Auras/SpellAuras.h b/src/server/game/Spells/Auras/SpellAuras.h index 6b619ef2e9a..ab9a56be7fc 100755 --- a/src/server/game/Spells/Auras/SpellAuras.h +++ b/src/server/game/Spells/Auras/SpellAuras.h @@ -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(); diff --git a/src/server/game/Spells/SpellScript.cpp b/src/server/game/Spells/SpellScript.cpp index ade0c63b2b8..482a185f590 100755 --- a/src/server/game/Spells/SpellScript.cpp +++ b/src/server/game/Spells/SpellScript.cpp @@ -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; +} + diff --git a/src/server/game/Spells/SpellScript.h b/src/server/game/Spells/SpellScript.h index 48971ffa64a..972f6794436 100755 --- a/src/server/game/Spells/SpellScript.h +++ b/src/server/game/Spells/SpellScript.h @@ -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; }; // diff --git a/src/server/scripts/Examples/example_spell.cpp b/src/server/scripts/Examples/example_spell.cpp index 42f10329afd..8d44cb92a4d 100644 --- a/src/server/scripts/Examples/example_spell.cpp +++ b/src/server/scripts/Examples/example_spell.cpp @@ -144,7 +144,7 @@ class spell_ex_66244 : public SpellScriptLoader // checks if script has data required for it to work bool Validate(SpellEntry const * /*spellEntry*/) { - // check if spellid 70522 exists in dbc, we will trigger it later + // check if spellid exists in dbc, we will trigger it later if (!sSpellStore.LookupEntry(SPELL_TRIGGERED)) return false; return true; @@ -161,18 +161,18 @@ class spell_ex_66244 : public SpellScriptLoader return false; } - void HandleEffectApply(AuraEffect const * /*aurEff*/, AuraApplication const * aurApp, AuraEffectHandleModes /*mode*/) + void HandleEffectApply(AuraEffect const * /*aurEff*/, AuraEffectHandleModes /*mode*/) { sLog->outString("Aura Effect is about to be applied on target!"); - Unit * target = aurApp->GetTarget(); + Unit * target = GetTarget(); // cast spell on target on aura apply target->CastSpell(target, SPELL_TRIGGERED, true); } - void HandleEffectRemove(AuraEffect const * /*aurEff*/, AuraApplication const * aurApp, AuraEffectHandleModes /*mode*/) + void HandleEffectRemove(AuraEffect const * /*aurEff*/, AuraEffectHandleModes /*mode*/) { sLog->outString("Aura Effect is just removed on target!"); - Unit * target = aurApp->GetTarget(); + Unit * target = GetTarget(); Unit * caster = GetCaster(); // caster may be not avalible (logged out for example) if (!caster) @@ -181,10 +181,10 @@ class spell_ex_66244 : public SpellScriptLoader target->CastSpell(caster, SPELL_TRIGGERED, true); } - void HandleEffectPeriodic(AuraEffect const * /*aurEff*/, AuraApplication const * aurApp) + void HandleEffectPeriodic(AuraEffect const * /*aurEff*/) { sLog->outString("Perioidic Aura Effect is does a tick on target!"); - Unit * target = aurApp->GetTarget(); + Unit * target = GetTarget(); // aura targets damage self on tick target->DealDamage(target, 100); } @@ -199,7 +199,7 @@ class spell_ex_66244 : public SpellScriptLoader void HandleEffectCalcAmount(AuraEffect const * /*aurEff*/, int32 & amount, bool & canBeRecalculated) { sLog->outString("Amount of Aura Effect is being calculated now!"); - // we're setting amount to 0 + // we're setting amount to 100 amount = 100; // amount will be never recalculated due to applying passive aura canBeRecalculated = false; @@ -213,7 +213,7 @@ class spell_ex_66244 : public SpellScriptLoader amplitude = 2 * IN_MILLISECONDS; } - void HandleEffectCalcSpellMod(AuraEffect * const /*aurEff*/, SpellModifier *& spellMod) + void HandleEffectCalcSpellMod(AuraEffect const * /*aurEff*/, SpellModifier *& spellMod) { sLog->outString("SpellMod data of Aura Effect is being calculated now!"); // we don't want spellmod for example @@ -242,10 +242,25 @@ class spell_ex_66244 : public SpellScriptLoader OnEffectRemove += AuraEffectRemoveFn(spell_ex_66244AuraScript::HandleEffectRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); OnEffectPeriodic += AuraEffectPeriodicFn(spell_ex_66244AuraScript::HandleEffectPeriodic,EFFECT_0, SPELL_AURA_DUMMY); OnEffectUpdatePeriodic += AuraEffectUpdatePeriodicFn(spell_ex_66244AuraScript::HandleEffectPeriodicUpdate, EFFECT_0, SPELL_AURA_DUMMY); - OnEffectCalcAmount += AuraEffectCalcAmountFn(spell_ex_66244AuraScript::HandleEffectCalcAmount, EFFECT_0, SPELL_AURA_DUMMY); - OnEffectCalcPeriodic += AuraEffectCalcPeriodicFn(spell_ex_66244AuraScript::HandleEffectCalcPeriodic, EFFECT_0, SPELL_AURA_DUMMY); - OnEffectCalcSpellMod += AuraEffectCalcSpellModFn(spell_ex_66244AuraScript::HandleEffectCalcSpellMod, EFFECT_0, SPELL_AURA_DUMMY); + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_ex_66244AuraScript::HandleEffectCalcAmount, EFFECT_0, SPELL_AURA_DUMMY); + DoEffectCalcPeriodic += AuraEffectCalcPeriodicFn(spell_ex_66244AuraScript::HandleEffectCalcPeriodic, EFFECT_0, SPELL_AURA_DUMMY); + DoEffectCalcSpellMod += AuraEffectCalcSpellModFn(spell_ex_66244AuraScript::HandleEffectCalcSpellMod, EFFECT_0, SPELL_AURA_DUMMY); + /*OnApply += AuraEffectApplyFn(); + OnRemove += AuraEffectRemoveFn(); + DoCheckAreaTarget += AuraCheckAreaTargetFn();*/ + } + /* + void OnApply() + { + } + + void OnRemove() + { } + + bool DoCheckAreaTarget(Unit * proposedTarget) + { + }*/ }; // function which creates AuraScript @@ -253,6 +268,56 @@ class spell_ex_66244 : public SpellScriptLoader { return new spell_ex_66244AuraScript(); } + + +}; + +class spell_ex_absorb_aura : public SpellScriptLoader +{ + public: + spell_ex_absorb_aura() : SpellScriptLoader("spell_ex_absorb_aura") { } + + class spell_ex_absorb_auraAuraScript : public AuraScript + { + PrepareAuraScript(spell_ex_absorb_auraAuraScript) + enum Spells + { + SPELL_TRIGGERED = 18282 + }; + + bool Validate(SpellEntry const * /*spellEntry*/) + { + // check if spellid exists in dbc, we will trigger it later + if (!sSpellStore.LookupEntry(SPELL_TRIGGERED)) + return false; + return true; + } + + void HandleOnEffectAbsorb(AuraEffect * aurEff, DamageInfo & dmgInfo, uint32 & absorbAmount) + { + sLog->outString("Our aura is now absorbing damage done to us!"); + // absorb whole damage done to us + absorbAmount = dmgInfo.GetDamage(); + } + + /*void HandleAfterAbsorb(DamageInfo & dmgInfo) + { + sLog->outString("Our auras have just absorbed damage done to us!"); + }*/ + + // function registering + void Register() + { + OnEffectAbsorb += AuraEffectAbsorbFn(spell_ex_absorb_auraAuraScript::HandleOnEffectAbsorb, EFFECT_0); + //AfterAbsorb += AuraAbsorbFn(spell_ex_absorb_auraAuraScript::HandleAfterAbsorb); + } + }; + + // function which creates AuraScript + AuraScript *GetAuraScript() const + { + return new spell_ex_absorb_auraAuraScript(); + } }; @@ -261,6 +326,7 @@ void AddSC_example_spell_scripts() { new spell_ex_5581; new spell_ex_66244; + new spell_ex_absorb_aura; } /* empty script for copypasting @@ -303,13 +369,13 @@ class spell_ex : public SpellScriptLoader //bool Load(){return true;} //void Unload(){} - //void spell_ex_SpellScript::Function(AuraEffect const * aurEff, AuraApplication const * aurApp, AuraEffectHandleModes mode) //OnEffectApply += AuraEffectApplyFn(spell_ex_SpellScript::Function, EFFECT_ANY, SPELL_AURA_ANY, AURA_EFFECT_HANDLE_REAL); - //void spell_ex_SpellScript::Function(AuraEffect const * aurEff, AuraApplication const * aurApp, AuraEffectHandleModes mode) //OnEffectRemove += AuraEffectRemoveFn(spell_ex_SpellScript::Function, EFFECT_ANY, SPELL_AURA_ANY, AURA_EFFECT_HANDLE_REAL); - //void spell_ex_SpellScript::Function(AuraEffect const * aurEff, AuraApplication const * aurApp) //OnEffectPeriodic += AuraEffectPeriodicFn(spell_ex_SpellScript::Function, EFFECT_ANY, SPELL_AURA_ANY); + //void spell_ex_SpellScript::Function(AuraEffect const * aurEff, AuraEffectHandleModes mode) //OnEffectApply += AuraEffectApplyFn(spell_ex_SpellScript::Function, EFFECT_ANY, SPELL_AURA_ANY, AURA_EFFECT_HANDLE_REAL); + //void spell_ex_SpellScript::Function(AuraEffect const * aurEff, AuraEffectHandleModes mode) //OnEffectRemove += AuraEffectRemoveFn(spell_ex_SpellScript::Function, EFFECT_ANY, SPELL_AURA_ANY, AURA_EFFECT_HANDLE_REAL); + //void spell_ex_SpellScript::Function(AuraEffect const * aurEff) //OnEffectPeriodic += AuraEffectPeriodicFn(spell_ex_SpellScript::Function, EFFECT_ANY, SPELL_AURA_ANY); //void spell_ex_SpellScript::Function(AuraEffect * aurEff) //OnEffectUpdatePeriodic += AuraEffectUpdatePeriodicFn(spell_ex_SpellScript::Function, EFFECT_ANY, SPELL_AURA_ANY); - //void spell_ex_SpellScript::Function(AuraEffect const * aurEff, int32 & amount, bool & canBeRecalculated) //OnEffectCalcAmount += AuraEffectCalcAmountFn(spell_ex_SpellScript::Function, EFFECT_ANY, SPELL_AURA_ANY); + //void spell_ex_SpellScript::Function(AuraEffect const * aurEff, int32 & amount, bool & canBeRecalculated) //DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_ex_SpellScript::Function, EFFECT_ANY, SPELL_AURA_ANY); //void spell_ex_SpellScript::Function(AuraEffect const * aurEff, bool & isPeriodic, int32 & amplitude) //OnEffectCalcPeriodic += AuraEffectCalcPeriodicFn(spell_ex_SpellScript::Function, EFFECT_ANY, SPELL_AURA_ANY); - //void spell_ex_SpellScript::Function(AuraEffect * const aurEff, SpellModifier *& spellMod) //OnEffectCalcSpellMod += AuraEffectCalcSpellModFn(spell_ex_SpellScript::Function, EFFECT_ANY, SPELL_AURA_ANY); + //void spell_ex_SpellScript::Function(AuraEffect const * aurEff, SpellModifier *& spellMod) //OnEffectCalcSpellMod += AuraEffectCalcSpellModFn(spell_ex_SpellScript::Function, EFFECT_ANY, SPELL_AURA_ANY); void Register() { } diff --git a/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_bronjahm.cpp b/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_bronjahm.cpp index 511f2350670..4daa0a354df 100644 --- a/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_bronjahm.cpp +++ b/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_bronjahm.cpp @@ -302,11 +302,11 @@ class spell_bronjahm_soulstorm_channel : public SpellScriptLoader { PrepareAuraScript(spell_bronjahm_soulstorm_channel_AuraScript); - void HandlePeriodicTick(AuraEffect const* /*aurEff*/, AuraApplication const* aurApp) + void HandlePeriodicTick(AuraEffect const* /*aurEff*/) { PreventDefaultAction(); for (uint32 i = 68904; i <= 68907; ++i) - aurApp->GetTarget()->CastSpell(aurApp->GetTarget(), i, true); + GetTarget()->CastSpell(GetTarget(), i, true); } void Register() @@ -330,14 +330,14 @@ class spell_bronjahm_soulstorm_visual : public SpellScriptLoader { PrepareAuraScript(spell_bronjahm_soulstorm_visual_AuraScript); - void HandlePeriodicTick(AuraEffect const* aurEff, AuraApplication const* aurApp) + void HandlePeriodicTick(AuraEffect const* aurEff) { PreventDefaultAction(); if (aurEff->GetTickNumber()%5) return; - aurApp->GetTarget()->CastSpell(aurApp->GetTarget(), 68886, true); + GetTarget()->CastSpell(GetTarget(), 68886, true); for (uint32 i = 68896; i <= 68898; ++i) - aurApp->GetTarget()->CastSpell(aurApp->GetTarget(), i, true); + GetTarget()->CastSpell(GetTarget(), i, true); } void Register() diff --git a/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_scourgelord_tyrannus.cpp b/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_scourgelord_tyrannus.cpp index dc838462f7f..6a7e49bdad8 100644 --- a/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_scourgelord_tyrannus.cpp +++ b/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_scourgelord_tyrannus.cpp @@ -314,26 +314,26 @@ class spell_tyrannus_overlord_brand : public SpellScriptLoader { PrepareAuraScript(spell_tyrannus_overlord_brand_AuraScript); - void OnApply(AuraEffect const* /*aurEff*/, AuraApplication const* aurApp, AuraEffectHandleModes /*mode*/) + void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) { - if (aurApp->GetTarget()->GetTypeId() != TYPEID_PLAYER) + if (GetTarget()->GetTypeId() != TYPEID_PLAYER) return; - oldAI = aurApp->GetTarget()->GetAI(); - aurApp->GetTarget()->SetAI(new player_overlord_brandAI(aurApp->GetTarget()->ToPlayer())); - aurApp->GetTarget()->GetAI()->SetGUID(GetCasterGUID()); - oldAIState = aurApp->GetTarget()->IsAIEnabled; - aurApp->GetTarget()->IsAIEnabled = true; + oldAI = GetTarget()->GetAI(); + GetTarget()->SetAI(new player_overlord_brandAI(GetTarget()->ToPlayer())); + GetTarget()->GetAI()->SetGUID(GetCasterGUID()); + oldAIState = GetTarget()->IsAIEnabled; + GetTarget()->IsAIEnabled = true; } - void OnRemove(AuraEffect const* /*aurEff*/, AuraApplication const* aurApp, AuraEffectHandleModes /*mode*/) + void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) { - if (aurApp->GetTarget()->GetTypeId() != TYPEID_PLAYER) + if (GetTarget()->GetTypeId() != TYPEID_PLAYER) return; - delete aurApp->GetTarget()->GetAI(); - aurApp->GetTarget()->SetAI(oldAI); - aurApp->GetTarget()->IsAIEnabled = oldAIState; + delete GetTarget()->GetAI(); + GetTarget()->SetAI(oldAI); + GetTarget()->IsAIEnabled = oldAIState; } void Register() diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_prince_council.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_prince_council.cpp index 7e679f0a0ca..6ec53f412f1 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_prince_council.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_prince_council.cpp @@ -1353,9 +1353,9 @@ class spell_taldaram_flame_ball_visual : public SpellScriptLoader return false; } - void OnRemove(AuraEffect const* /*aurEff*/, AuraApplication const* aurApp, AuraEffectHandleModes /*mode*/) + void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) { - Creature* target = aurApp->GetTarget()->ToCreature(); + Creature* target = GetTarget()->ToCreature(); if (!target) return; @@ -1439,9 +1439,9 @@ class spell_valanar_kinetic_bomb : public SpellScriptLoader { PrepareAuraScript(spell_valanar_kinetic_bomb_AuraScript); - void HandleDummyTick(AuraEffect const* /*aurEff*/, AuraApplication const* aurApp) + void HandleDummyTick(AuraEffect const* /*aurEff*/) { - Unit* target = aurApp->GetTarget(); + Unit* target = GetTarget(); if (target->GetTypeId() != TYPEID_UNIT) return; @@ -1449,7 +1449,7 @@ class spell_valanar_kinetic_bomb : public SpellScriptLoader { bomb->CastSpell(bomb, SPELL_KINETIC_BOMB_EXPLOSION, true); bomb->RemoveAurasDueToSpell(SPELL_KINETIC_BOMB_VISUAL); - target->RemoveAura(const_cast<AuraApplication*>(aurApp)); + target->RemoveAura(GetAura()); bomb->AI()->DoAction(SPELL_KINETIC_BOMB_EXPLOSION); } } @@ -1507,10 +1507,10 @@ class spell_blood_council_shadow_prison : public SpellScriptLoader { PrepareAuraScript(spell_blood_council_shadow_prison_AuraScript); - void HandleDummyTick(AuraEffect const* aurEff, AuraApplication const* aurApp) + void HandleDummyTick(AuraEffect const* aurEff) { - if (aurApp->GetTarget()->isMoving()) - aurApp->GetTarget()->CastSpell(aurApp->GetTarget(), SPELL_SHADOW_PRISON_DAMAGE, true, NULL, aurEff); + if (GetTarget()->isMoving()) + GetTarget()->CastSpell(GetTarget(), SPELL_SHADOW_PRISON_DAMAGE, true, NULL, aurEff); } void Register() diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp index 6c032d58bc2..60cd356a9ee 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp @@ -479,17 +479,17 @@ class spell_blood_queen_frenzied_bloodthirst : public SpellScriptLoader { PrepareAuraScript(spell_blood_queen_frenzied_bloodthirst_AuraScript); - void OnApply(AuraEffect const* /*aurEff*/, AuraApplication const* aurApp, AuraEffectHandleModes /*mode*/) + void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) { - if (InstanceScript* instance = aurApp->GetTarget()->GetInstanceScript()) - if (Creature* bloodQueen = ObjectAccessor::GetCreature(*aurApp->GetTarget(), instance->GetData64(DATA_BLOOD_QUEEN_LANA_THEL))) + if (InstanceScript* instance = GetTarget()->GetInstanceScript()) + if (Creature* bloodQueen = ObjectAccessor::GetCreature(*GetTarget(), instance->GetData64(DATA_BLOOD_QUEEN_LANA_THEL))) bloodQueen->AI()->Talk(EMOTE_BLOODTHIRST); } - void OnRemove(AuraEffect const* /*aurEff*/, AuraApplication const* aurApp, AuraEffectHandleModes /*mode*/) + void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) { - Unit* target = aurApp->GetTarget(); - if (aurApp->GetRemoveMode() == AURA_REMOVE_BY_EXPIRE) + Unit* target = GetTarget(); + if (GetTargetApplication()->GetRemoveMode() == AURA_REMOVE_BY_EXPIRE) if (InstanceScript* instance = target->GetInstanceScript()) if (Creature* bloodQueen = ObjectAccessor::GetCreature(*target, instance->GetData64(DATA_BLOOD_QUEEN_LANA_THEL))) { diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp index b922c95c511..67b5d3ccd14 100755 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp @@ -969,7 +969,7 @@ class spell_deathbringer_blood_link_aura : public SpellScriptLoader return true; } - void HandlePeriodicTick(AuraEffect const* /*aurEff*/, AuraApplication const* /*aurApp*/) + void HandlePeriodicTick(AuraEffect const* /*aurEff*/) { PreventDefaultAction(); if (GetUnitOwner()->getPowerType() == POWER_ENERGY && GetUnitOwner()->GetPower(POWER_ENERGY) == GetUnitOwner()->GetMaxPower(POWER_ENERGY)) @@ -1022,8 +1022,8 @@ class spell_deathbringer_blood_power : public SpellScriptLoader void Register() { - OnEffectCalcAmount += AuraEffectCalcAmountFn(spell_deathbringer_blood_power_AuraScript::RecalculateHook, EFFECT_0, SPELL_AURA_MOD_SCALE); - OnEffectCalcAmount += AuraEffectCalcAmountFn(spell_deathbringer_blood_power_AuraScript::RecalculateHook, EFFECT_1, SPELL_AURA_MOD_DAMAGE_PERCENT_DONE); + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_deathbringer_blood_power_AuraScript::RecalculateHook, EFFECT_0, SPELL_AURA_MOD_SCALE); + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_deathbringer_blood_power_AuraScript::RecalculateHook, EFFECT_1, SPELL_AURA_MOD_DAMAGE_PERCENT_DONE); } bool Load() diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_festergut.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_festergut.cpp index a8fc9405285..f221d8d2495 100755 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_festergut.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_festergut.cpp @@ -430,17 +430,17 @@ class spell_festergut_blighted_spores : public SpellScriptLoader { PrepareAuraScript(spell_festergut_blighted_spores_AuraScript); - void ExtraEffect(AuraEffect const* /*aurEff*/, AuraApplication const* aurApp, AuraEffectHandleModes /*mode*/) + void ExtraEffect(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) { if (!GetCaster()->IsAIEnabled || GetCaster()->GetTypeId() != TYPEID_UNIT) return; uint32 inoculateId = CAST_AI(ScriptedAI, GetCaster()->ToCreature()->AI())->INOCULATED_HELPER; uint32 currStack = 0; - if (Aura const* inoculate = aurApp->GetTarget()->GetAura(inoculateId)) + if (Aura const* inoculate = GetTarget()->GetAura(inoculateId)) currStack = inoculate->GetStackAmount(); - aurApp->GetTarget()->CastSpell(aurApp->GetTarget(), SPELL_INOCULATED, true); + GetTarget()->CastSpell(GetTarget(), SPELL_INOCULATED, true); ++currStack; GetCaster()->ToCreature()->AI()->SetData(DATA_INOCULATED_STACK, currStack); } diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp index 29c772f9a10..cb0f61c79a7 100755 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp @@ -766,7 +766,7 @@ class spell_deathwhisper_mana_barrier : public SpellScriptLoader { PrepareAuraScript(spell_deathwhisper_mana_barrier_AuraScript); - void HandlePeriodicTick(AuraEffect const* /*aurEff*/, AuraApplication const* /*aurApp*/) + void HandlePeriodicTick(AuraEffect const* /*aurEff*/) { PreventDefaultAction(); Unit* caster = GetCaster(); diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp index 28d6a58b935..09513b98603 100755 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp @@ -755,9 +755,9 @@ class spell_putricide_gaseous_bloat : public SpellScriptLoader { PrepareAuraScript(spell_putricide_gaseous_bloat_AuraScript); - void HandleExtraEffect(AuraEffect const* /*aurEff*/, AuraApplication const* aurApp) + void HandleExtraEffect(AuraEffect const* /*aurEff*/) { - aurApp->GetTarget()->RemoveAuraFromStack(GetSpellProto()->Id, aurApp->GetBase()->GetCasterGUID()); + GetTarget()->RemoveAuraFromStack(GetSpellProto()->Id, GetCasterGUID()); } void Register() @@ -837,10 +837,10 @@ class spell_putricide_slime_puddle : public SpellScriptLoader { PrepareAuraScript(spell_putricide_slime_puddle_AuraScript); - void HandleTriggerSpell(AuraEffect const* aurEff, AuraApplication const* aurApp) + void HandleTriggerSpell(AuraEffect const* aurEff) { PreventDefaultAction(); - if (Unit* caster = aurApp->GetBase()->GetCaster()) + if (Unit* caster = GetCaster()) { int32 radiusMod = 4; if (Aura* size = caster->GetAura(70347)) @@ -916,15 +916,15 @@ class spell_putricide_ooze_summon : public SpellScriptLoader { PrepareAuraScript(spell_putricide_ooze_summon_AuraScript); - void HandleTriggerSpell(AuraEffect const* aurEff, AuraApplication const* aurApp) + void HandleTriggerSpell(AuraEffect const* aurEff) { PreventDefaultAction(); if (Unit* caster = GetCaster()) { uint32 triggerSpellId = GetSpellProto()->EffectTriggerSpell[aurEff->GetEffIndex()]; float x, y, z; - aurApp->GetTarget()->GetPosition(x, y, z); - z = aurApp->GetTarget()->GetMap()->GetHeight(x, y, z, true, 25.0f); + GetTarget()->GetPosition(x, y, z); + z = GetTarget()->GetMap()->GetHeight(x, y, z, true, 25.0f); x += 10.0f * cosf(caster->GetOrientation()); y += 10.0f * sinf(caster->GetOrientation()); caster->CastSpell(x, y, z, triggerSpellId, true, NULL, NULL, GetCasterGUID(), caster); @@ -1116,7 +1116,7 @@ class spell_putricide_mutated_plague : public SpellScriptLoader { PrepareAuraScript(spell_putricide_mutated_plague_AuraScript); - void HandleTriggerSpell(AuraEffect const* aurEff, AuraApplication const* aurApp) + void HandleTriggerSpell(AuraEffect const* aurEff) { PreventDefaultAction(); Unit* caster = GetCaster(); @@ -1129,21 +1129,21 @@ class spell_putricide_mutated_plague : public SpellScriptLoader int32 damage = SpellMgr::CalculateSpellEffectAmount(spell, 0, caster); float multiplier = 2.0f; - if (aurApp->GetTarget()->GetMap()->GetSpawnMode() & 1) + if (GetTarget()->GetMap()->GetSpawnMode() & 1) multiplier = 3.0f; - damage *= int32(pow(multiplier, aurApp->GetBase()->GetStackAmount())); + damage *= int32(pow(multiplier, GetStackAmount())); damage = int32(damage * 1.5f); - aurApp->GetTarget()->CastCustomSpell(triggerSpell, SPELLVALUE_BASE_POINT0, damage, aurApp->GetTarget(), true, NULL, aurEff, GetCasterGUID()); + GetTarget()->CastCustomSpell(triggerSpell, SPELLVALUE_BASE_POINT0, damage, GetTarget(), true, NULL, aurEff, GetCasterGUID()); } - void OnRemove(AuraEffect const* /*aurEff*/, AuraApplication const* aurApp, AuraEffectHandleModes /*mode*/) + void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) { - if (aurApp->GetRemoveMode() == AURA_REMOVE_BY_STACK) + if (GetTargetApplication()->GetRemoveMode() == AURA_REMOVE_BY_STACK) return; uint32 healSpell = uint32(SpellMgr::CalculateSpellEffectAmount(GetSpellProto(), 0)); - aurApp->GetTarget()->CastSpell(aurApp->GetTarget(), healSpell, true, NULL, NULL, GetCasterGUID()); + GetTarget()->CastSpell(GetTarget(), healSpell, true, NULL, NULL, GetCasterGUID()); } void Register() @@ -1168,13 +1168,13 @@ class spell_putricide_mutation_init : public SpellScriptLoader { PrepareAuraScript(spell_putricide_mutation_init_AuraScript); - void OnRemove(AuraEffect const* /*aurEff*/, AuraApplication const* aurApp, AuraEffectHandleModes /*mode*/) + void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) { uint32 spellId = 70311; - if (aurApp->GetTarget()->GetMap()->GetSpawnMode() & 1) + if (GetTarget()->GetMap()->GetSpawnMode() & 1) spellId = 71503; - aurApp->GetTarget()->CastSpell(aurApp->GetTarget(), spellId, true); + GetTarget()->CastSpell(GetTarget(), spellId, true); } void Register() @@ -1198,9 +1198,9 @@ class spell_putricide_mutated_transformation_dismiss : public SpellScriptLoader { PrepareAuraScript(spell_putricide_mutated_transformation_dismiss_AuraScript); - void OnRemove(AuraEffect const* /*aurEff*/, AuraApplication const* aurApp, AuraEffectHandleModes /*mode*/) + void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) { - if (Vehicle* veh = aurApp->GetTarget()->GetVehicleKit()) + if (Vehicle* veh = GetTarget()->GetVehicleKit()) veh->RemoveAllPassengers(); } diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_rotface.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_rotface.cpp index a2f7b3b3a21..d2dab0cdeee 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_rotface.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_rotface.cpp @@ -708,10 +708,10 @@ class spell_rotface_unstable_ooze_explosion_suicide : public SpellScriptLoader { PrepareAuraScript(spell_rotface_unstable_ooze_explosion_suicide_AuraScript); - void DespawnSelf(AuraEffect const* /*aurEff*/, AuraApplication const* aurApp) + void DespawnSelf(AuraEffect const* /*aurEff*/) { PreventDefaultAction(); - Unit* target = aurApp->GetTarget(); + Unit* target = GetTarget(); if (target->GetTypeId() != TYPEID_UNIT) return; diff --git a/src/server/scripts/Northrend/Ulduar/ulduar/boss_ignis.cpp b/src/server/scripts/Northrend/Ulduar/ulduar/boss_ignis.cpp index 6b6ca975e72..1d6479d1ce0 100644 --- a/src/server/scripts/Northrend/Ulduar/ulduar/boss_ignis.cpp +++ b/src/server/scripts/Northrend/Ulduar/ulduar/boss_ignis.cpp @@ -443,13 +443,13 @@ class spell_ignis_slag_pot : public SpellScriptLoader return true; } - void HandleEffectPeriodic(AuraEffect const * aurEff, AuraApplication const * aurApp) + void HandleEffectPeriodic(AuraEffect const * aurEff) { Unit* aurEffCaster = aurEff->GetCaster(); if (!aurEffCaster) return; - Unit * target = aurApp->GetTarget(); + Unit * target = GetTarget(); aurEffCaster->CastSpell(target, SPELL_SLAG_POT_DAMAGE, true); if (target->isAlive() && !GetDuration()) target->CastSpell(target, SPELL_SLAG_IMBUED, true); diff --git a/src/server/scripts/Spells/spell_dk.cpp b/src/server/scripts/Spells/spell_dk.cpp index 907f1789d95..706853db0ae 100644 --- a/src/server/scripts/Spells/spell_dk.cpp +++ b/src/server/scripts/Spells/spell_dk.cpp @@ -157,9 +157,49 @@ public: } }; +// 49145 - Spell Deflection +class spell_dk_spell_deflection : public SpellScriptLoader +{ +public: + spell_dk_spell_deflection() : SpellScriptLoader("spell_dk_spell_deflection") { } + + class spell_dk_spell_deflection_AuraScript : public AuraScript + { + PrepareAuraScript(spell_dk_spell_deflection_AuraScript); + + uint32 absorbPct; + void CalculateAmount(AuraEffect const * /*aurEff*/, int32 & amount, bool & canBeRecalculated) + { + absorbPct = amount; + // Set absorbtion amount to unlimited + amount = -1; + } + + void Absorb(AuraEffect * /*aurEff*/, DamageInfo & dmgInfo, uint32 & absorbAmount) + { + // You have a chance equal to your Parry chance + if ((dmgInfo.GetDamageType() == DIRECT_DAMAGE) && roll_chance_f(GetTarget()->GetUnitParryChance())) + absorbAmount = CalculatePctN(dmgInfo.GetDamage(), absorbPct); + } + + void Register() + { + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_dk_spell_deflection_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_SCHOOL_ABSORB); + OnEffectAbsorb += AuraEffectAbsorbFn(spell_dk_spell_deflection_AuraScript::Absorb, EFFECT_0); + } + }; + + AuraScript *GetAuraScript() const + { + return new spell_dk_spell_deflection_AuraScript(); + } +}; + + void AddSC_deathknight_spell_scripts() { new spell_dk_corpse_explosion(); new spell_dk_runic_power_feed(); new spell_dk_scourge_strike(); + new spell_dk_spell_deflection(); } diff --git a/src/server/scripts/Spells/spell_druid.cpp b/src/server/scripts/Spells/spell_druid.cpp index 717bf093349..6fb2da82346 100644 --- a/src/server/scripts/Spells/spell_druid.cpp +++ b/src/server/scripts/Spells/spell_druid.cpp @@ -83,7 +83,126 @@ public: } }; +// 69366 - Moonkin Form passive +class spell_dru_moonkin_form_passive : public SpellScriptLoader +{ +public: + spell_dru_moonkin_form_passive() : SpellScriptLoader("spell_dru_moonkin_form_passive") { } + + class spell_dru_moonkin_form_passive_AuraScript : public AuraScript + { + PrepareAuraScript(spell_dru_moonkin_form_passive_AuraScript); + + uint32 absorbPct; + void CalculateAmount(AuraEffect const * /*aurEff*/, int32 & amount, bool & canBeRecalculated) + { + absorbPct = amount; + // Set absorbtion amount to unlimited + amount = -1; + } + + void Absorb(AuraEffect * /*aurEff*/, DamageInfo & dmgInfo, uint32 & absorbAmount) + { + // reduces all damage taken while Stunned in Cat Form + if (GetTarget()->GetUInt32Value(UNIT_FIELD_FLAGS) & (UNIT_FLAG_STUNNED)) + absorbAmount = CalculatePctN(dmgInfo.GetDamage(), absorbPct); + } + + void Register() + { + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_dru_moonkin_form_passive_AuraScript::CalculateAmount, EFFECT_1, SPELL_AURA_SCHOOL_ABSORB); + OnEffectAbsorb += AuraEffectAbsorbFn(spell_dru_moonkin_form_passive_AuraScript::Absorb, EFFECT_1); + } + }; + + AuraScript *GetAuraScript() const + { + return new spell_dru_moonkin_form_passive_AuraScript(); + } +}; + +// 33851 - Primal Tenacity +class spell_dru_primal_tenacity : public SpellScriptLoader +{ +public: + spell_dru_primal_tenacity() : SpellScriptLoader("spell_dru_primal_tenacity") { } + + class spell_dru_primal_tenacity_AuraScript : public AuraScript + { + PrepareAuraScript(spell_dru_primal_tenacity_AuraScript); + + uint32 absorbPct; + void CalculateAmount(AuraEffect const * /*aurEff*/, int32 & amount, bool & canBeRecalculated) + { + absorbPct = amount; + // Set absorbtion amount to unlimited + amount = -1; + } + + void Absorb(AuraEffect * /*aurEff*/, DamageInfo & dmgInfo, uint32 & absorbAmount) + { + // reduces all damage taken while Stunned in Cat Form + if ((GetTarget()->GetShapeshiftForm() == FORM_CAT) && (GetTarget()->GetUInt32Value(UNIT_FIELD_FLAGS) & (UNIT_FLAG_STUNNED))) + absorbAmount = CalculatePctN(dmgInfo.GetDamage(), absorbPct); + } + + void Register() + { + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_dru_primal_tenacity_AuraScript::CalculateAmount, EFFECT_1, SPELL_AURA_SCHOOL_ABSORB); + OnEffectAbsorb += AuraEffectAbsorbFn(spell_dru_primal_tenacity_AuraScript::Absorb, EFFECT_1); + } + }; + + AuraScript *GetAuraScript() const + { + return new spell_dru_primal_tenacity_AuraScript(); + } +}; + +// 62606 - Savage Defense +class spell_dru_savage_defense : public SpellScriptLoader +{ +public: + spell_dru_savage_defense() : SpellScriptLoader("spell_dru_savage_defense") { } + + class spell_dru_savage_defense_AuraScript : public AuraScript + { + PrepareAuraScript(spell_dru_savage_defense_AuraScript); + + uint32 absorbPct; + void CalculateAmount(AuraEffect const * /*aurEff*/, int32 & amount, bool & canBeRecalculated) + { + absorbPct = amount; + // Set absorbtion amount to unlimited + amount = -1; + } + + void Absorb(AuraEffect * aurEff, DamageInfo & dmgInfo, uint32 & absorbAmount) + { + // don't waste charge when no dmg + if (!dmgInfo.GetDamage()) + return; + absorbAmount = CalculatePctN(GetTarget()->GetTotalAttackPowerValue(BASE_ATTACK), absorbPct); + aurEff->SetAmount(0); + } + + void Register() + { + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_dru_savage_defense_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_SCHOOL_ABSORB); + OnEffectAbsorb += AuraEffectAbsorbFn(spell_dru_savage_defense_AuraScript::Absorb, EFFECT_0); + } + }; + + AuraScript *GetAuraScript() const + { + return new spell_dru_savage_defense_AuraScript(); + } +}; + void AddSC_druid_spell_scripts() { new spell_dru_glyph_of_starfire(); + new spell_dru_moonkin_form_passive(); + new spell_dru_primal_tenacity(); + new spell_dru_savage_defense(); } diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp index 45b98438a2c..e99d1e44548 100644 --- a/src/server/scripts/Spells/spell_generic.cpp +++ b/src/server/scripts/Spells/spell_generic.cpp @@ -104,9 +104,9 @@ public: return true; } - void HandleEffectPeriodic(AuraEffect const * /*aurEff*/, AuraApplication const * aurApp) + void HandleEffectPeriodic(AuraEffect const * /*aurEff*/) { - Unit* pTarget = aurApp->GetTarget(); + Unit* pTarget = GetTarget(); if (Player* pPlayerTarget = pTarget->ToPlayer()) if (pPlayerTarget->IsFalling()) { @@ -244,9 +244,9 @@ public: return true; } - void HandleEffectPeriodic(AuraEffect const * aurEff, AuraApplication const * aurApp) + void HandleEffectPeriodic(AuraEffect const * aurEff) { - Unit* pTarget = aurApp->GetTarget(); + Unit* pTarget = GetTarget(); if (Unit* pCaster = GetCaster()) { int32 lifeLeeched = pTarget->CountPctFromMaxHealth(aurEff->GetAmount()); @@ -405,9 +405,9 @@ class spell_creature_permanent_feign_death : public SpellScriptLoader class spell_creature_permanent_feign_deathAuraScript : public AuraScript { PrepareAuraScript(spell_creature_permanent_feign_deathAuraScript) - void HandleEffectApply(AuraEffect const * /*aurEff*/, AuraApplication const * aurApp, AuraEffectHandleModes /*mode*/) + void HandleEffectApply(AuraEffect const * /*aurEff*/, AuraEffectHandleModes /*mode*/) { - Unit* pTarget = aurApp->GetTarget(); + Unit* pTarget = GetTarget(); pTarget->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_DEAD); pTarget->SetFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FEIGN_DEATH); @@ -498,14 +498,14 @@ class spell_gen_animal_blood : public SpellScriptLoader return true; } - void OnApply(AuraEffect const* /*aurEff*/, AuraApplication const* /*aurApp*/, AuraEffectHandleModes /*mode*/) + void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) { // Remove all auras with spell id 46221, except the one currently being applied while (Aura* aur = GetUnitOwner()->GetOwnedAura(SPELL_ANIMAL_BLOOD, 0, 0, 0, GetAura())) GetUnitOwner()->RemoveOwnedAura(aur); } - void OnRemove(AuraEffect const* /*aurEff*/, AuraApplication const* /*aurApp*/, AuraEffectHandleModes /*mode*/) + void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) { if (GetUnitOwner()->IsInWater()) GetUnitOwner()->CastSpell(GetUnitOwner(), SPELL_SPAWN_BLOOD_POOL, true); @@ -533,16 +533,16 @@ class spell_gen_shroud_of_death : public SpellScriptLoader { PrepareAuraScript(spell_gen_shroud_of_deathAuraScript) - void HandleEffectApply(AuraEffect const * /*aurEff*/, AuraApplication const * aurApp, AuraEffectHandleModes /*mode*/) + void HandleEffectApply(AuraEffect const * /*aurEff*/, AuraEffectHandleModes /*mode*/) { - Unit* target = aurApp->GetTarget(); + Unit* target = GetTarget(); target->m_serverSideVisibility.SetValue(SERVERSIDE_VISIBILITY_GHOST, GHOST_VISIBILITY_GHOST); target->m_serverSideVisibilityDetect.SetValue(SERVERSIDE_VISIBILITY_GHOST, GHOST_VISIBILITY_GHOST); } - void HandleEffectRemove(AuraEffect const * /*aurEff*/, AuraApplication const * aurApp, AuraEffectHandleModes /*mode*/) + void HandleEffectRemove(AuraEffect const * /*aurEff*/, AuraEffectHandleModes /*mode*/) { - Unit* target = aurApp->GetTarget(); + Unit* target = GetTarget(); target->m_serverSideVisibility.SetValue(SERVERSIDE_VISIBILITY_GHOST, GHOST_VISIBILITY_ALIVE); target->m_serverSideVisibilityDetect.SetValue(SERVERSIDE_VISIBILITY_GHOST, GHOST_VISIBILITY_ALIVE); } diff --git a/src/server/scripts/Spells/spell_hunter.cpp b/src/server/scripts/Spells/spell_hunter.cpp index 98a7619c82c..47723e74598 100644 --- a/src/server/scripts/Spells/spell_hunter.cpp +++ b/src/server/scripts/Spells/spell_hunter.cpp @@ -357,14 +357,14 @@ public: return true; } - void HandlePeriodic(AuraEffect const * aurEff, AuraApplication const * aurApp) + void HandlePeriodic(AuraEffect const * aurEff) { PreventDefaultAction(); if (aurEff->GetAmount() > 0) return; uint32 spellId = SPELL_SNIPER_TRAINING_BUFF_R1 + GetId() - SPELL_SNIPER_TRAINING_R1; - Unit * pTarget = aurApp->GetTarget(); + Unit * pTarget = GetTarget(); if (!pTarget->HasAura(spellId)) { SpellEntry const * triggeredSpellInfo = sSpellStore.LookupEntry(spellId); diff --git a/src/server/scripts/Spells/spell_item.cpp b/src/server/scripts/Spells/spell_item.cpp index db095f048a8..95b40a2cc17 100644 --- a/src/server/scripts/Spells/spell_item.cpp +++ b/src/server/scripts/Spells/spell_item.cpp @@ -698,9 +698,9 @@ public: return true; } - void OnStackChange(AuraEffect const* /*aurEff*/, AuraApplication const* aurApp, AuraEffectHandleModes /*mode*/) + void OnStackChange(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) { - Unit* target = aurApp->GetTarget(); + Unit* target = GetTarget(); switch (GetStackAmount()) { @@ -718,11 +718,11 @@ public: } } - void OnRemove(AuraEffect const* /*aurEff*/, AuraApplication const* aurApp, AuraEffectHandleModes /*mode*/) + void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) { - Unit* target = aurApp->GetTarget(); + Unit* target = GetTarget(); - if (aurApp->GetRemoveMode() == AURA_REMOVE_BY_STACK) + if (GetTargetApplication()->GetRemoveMode() == AURA_REMOVE_BY_STACK) return; target->RemoveAurasDueToSpell(SPELL_SHADOWMOURNE_VISUAL_LOW); target->RemoveAurasDueToSpell(SPELL_SHADOWMOURNE_VISUAL_HIGH); diff --git a/src/server/scripts/Spells/spell_paladin.cpp b/src/server/scripts/Spells/spell_paladin.cpp index b237ead269d..b53f172bfdf 100644 --- a/src/server/scripts/Spells/spell_paladin.cpp +++ b/src/server/scripts/Spells/spell_paladin.cpp @@ -108,16 +108,16 @@ public: return true; } - void HandleEffectApply(AuraEffect const * /*aurEff*/, AuraApplication const * aurApp, AuraEffectHandleModes /*mode*/) + void HandleEffectApply(AuraEffect const * /*aurEff*/, AuraEffectHandleModes /*mode*/) { - Unit* pTarget = aurApp->GetTarget(); + Unit* pTarget = GetTarget(); if (Unit* pCaster = GetCaster()) pCaster->CastSpell(pTarget, PALADIN_SPELL_BLESSING_OF_SANCTUARY_BUFF, true); } - void HandleEffectRemove(AuraEffect const * /*aurEff*/, AuraApplication const * aurApp, AuraEffectHandleModes /*mode*/) + void HandleEffectRemove(AuraEffect const * /*aurEff*/, AuraEffectHandleModes /*mode*/) { - Unit* pTarget = aurApp->GetTarget(); + Unit* pTarget = GetTarget(); pTarget->RemoveAura(PALADIN_SPELL_BLESSING_OF_SANCTUARY_BUFF, GetCasterGUID()); } diff --git a/src/server/scripts/Spells/spell_quest.cpp b/src/server/scripts/Spells/spell_quest.cpp index 834c32d0528..dbd4f574bcc 100644 --- a/src/server/scripts/Spells/spell_quest.cpp +++ b/src/server/scripts/Spells/spell_quest.cpp @@ -219,16 +219,16 @@ public: class spell_q11396_11399_force_shield_arcane_purple_x3_AuraScript : public AuraScript { PrepareAuraScript(spell_q11396_11399_force_shield_arcane_purple_x3_AuraScript) - void HandleEffectApply(AuraEffect const * /*aurEff*/, AuraApplication const * aurApp, AuraEffectHandleModes /*mode*/) + void HandleEffectApply(AuraEffect const * /*aurEff*/, AuraEffectHandleModes /*mode*/) { - Unit* pTarget = aurApp->GetTarget(); + Unit* pTarget = GetTarget(); pTarget->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE); pTarget->AddUnitState(UNIT_STAT_ROOT); } - void HandleEffectRemove(AuraEffect const * /*aurEff*/, AuraApplication const * aurApp, AuraEffectHandleModes /*mode*/) + void HandleEffectRemove(AuraEffect const * /*aurEff*/, AuraEffectHandleModes /*mode*/) { - aurApp->GetTarget()->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE); + GetTarget()->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE); } void Register() diff --git a/src/server/scripts/Spells/spell_rogue.cpp b/src/server/scripts/Spells/spell_rogue.cpp index ed31db2d264..ffae231839c 100644 --- a/src/server/scripts/Spells/spell_rogue.cpp +++ b/src/server/scripts/Spells/spell_rogue.cpp @@ -30,6 +30,44 @@ enum RogueSpells ROGUE_SPELL_PREY_ON_THE_WEAK = 58670, }; +// 31130 - Nerves of Steel +class spell_rog_nerves_of_steel : public SpellScriptLoader +{ +public: + spell_rog_nerves_of_steel() : SpellScriptLoader("spell_rog_nerves_of_steel") { } + + class spell_rog_nerves_of_steel_AuraScript : public AuraScript + { + PrepareAuraScript(spell_rog_nerves_of_steel_AuraScript); + + uint32 absorbPct; + void CalculateAmount(AuraEffect const * /*aurEff*/, int32 & amount, bool & canBeRecalculated) + { + absorbPct = amount; + // Set absorbtion amount to unlimited + amount = -1; + } + + void Absorb(AuraEffect * /*aurEff*/, DamageInfo & dmgInfo, uint32 & absorbAmount) + { + // reduces all damage taken while stun or fear + if (GetTarget()->GetUInt32Value(UNIT_FIELD_FLAGS) & (UNIT_FLAG_STUNNED | UNIT_FLAG_FLEEING)) + absorbAmount = CalculatePctN(dmgInfo.GetDamage(), absorbPct); + } + + void Register() + { + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_rog_nerves_of_steel_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_SCHOOL_ABSORB); + OnEffectAbsorb += AuraEffectAbsorbFn(spell_rog_nerves_of_steel_AuraScript::Absorb, EFFECT_0); + } + }; + + AuraScript *GetAuraScript() const + { + return new spell_rog_nerves_of_steel_AuraScript(); + } +}; + class spell_rog_preparation : public SpellScriptLoader { public: @@ -109,9 +147,9 @@ public: return true; } - void HandleEffectPeriodic(AuraEffect const * /*aurEff*/, AuraApplication const * aurApp) + void HandleEffectPeriodic(AuraEffect const * /*aurEff*/) { - Unit* pTarget = aurApp->GetTarget(); + Unit* pTarget = GetTarget(); Unit* pVictim = pTarget->getVictim(); if (pVictim && (pTarget->GetHealthPct() > pVictim->GetHealthPct())) { @@ -178,6 +216,7 @@ class spell_rog_shiv : public SpellScriptLoader void AddSC_rogue_spell_scripts() { + new spell_rog_nerves_of_steel(); new spell_rog_preparation(); new spell_rog_prey_on_the_weak(); new spell_rog_shiv(); diff --git a/src/server/scripts/Spells/spell_shaman.cpp b/src/server/scripts/Spells/spell_shaman.cpp index 640faaad64f..bf8e179a438 100644 --- a/src/server/scripts/Spells/spell_shaman.cpp +++ b/src/server/scripts/Spells/spell_shaman.cpp @@ -36,6 +36,44 @@ enum ShamanSpells SHAMAN_TOTEM_SPELL_EARTHEN_POWER = 59566,//Spell witch remove snare effect }; +// 51474 - Astral shift +class spell_sha_astral_shift : public SpellScriptLoader +{ +public: + spell_sha_astral_shift() : SpellScriptLoader("spell_sha_astral_shift") { } + + class spell_sha_astral_shift_AuraScript : public AuraScript + { + PrepareAuraScript(spell_sha_astral_shift_AuraScript); + + uint32 absorbPct; + void CalculateAmount(AuraEffect const * /*aurEff*/, int32 & amount, bool & canBeRecalculated) + { + absorbPct = amount; + // Set absorbtion amount to unlimited + amount = -1; + } + + void Absorb(AuraEffect * /*aurEff*/, DamageInfo & dmgInfo, uint32 & absorbAmount) + { + // reduces all damage taken while stun, fear or silence + if (GetTarget()->GetUInt32Value(UNIT_FIELD_FLAGS) & (UNIT_FLAG_STUNNED | UNIT_FLAG_FLEEING | UNIT_FLAG_SILENCED)) + absorbAmount = CalculatePctN(dmgInfo.GetDamage(), absorbPct); + } + + void Register() + { + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_sha_astral_shift_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_SCHOOL_ABSORB); + OnEffectAbsorb += AuraEffectAbsorbFn(spell_sha_astral_shift_AuraScript::Absorb, EFFECT_0); + } + }; + + AuraScript *GetAuraScript() const + { + return new spell_sha_astral_shift_AuraScript(); + } +}; + // 1535 Fire Nova class spell_sha_fire_nova : public SpellScriptLoader { @@ -154,9 +192,9 @@ public: return true; } - void HandleEffectPeriodic(AuraEffect const * aurEff, AuraApplication const * aurApp) + void HandleEffectPeriodic(AuraEffect const * aurEff) { - Unit* target = aurApp->GetTarget(); + Unit* target = GetTarget(); if (Unit *caster = aurEff->GetBase()->GetCaster()) if (AuraEffect* aur = caster->GetDummyAuraEffect(SPELLFAMILY_SHAMAN, 2289, 0)) if (roll_chance_i(aur->GetBaseAmount())) @@ -174,8 +212,10 @@ public: return new spell_sha_earthbind_totem_AuraScript(); } }; + void AddSC_shaman_spell_scripts() { + new spell_sha_astral_shift(); new spell_sha_fire_nova(); new spell_sha_mana_tide_totem(); new spell_sha_earthbind_totem(); diff --git a/src/server/shared/Utilities/Util.h b/src/server/shared/Utilities/Util.h index e84b26d4df8..abe3c16c48e 100755 --- a/src/server/shared/Utilities/Util.h +++ b/src/server/shared/Utilities/Util.h @@ -154,6 +154,12 @@ inline T ApplyPctU(T& base, uint32 pct) return base = CalculatePctU(base, pct); } +template <class T> +inline T RoundToInterval(T& num, T floor, T ceil) +{ + return num = std::min(std::max(num, floor), ceil); +} + // UTF8 handling bool Utf8toWStr(const std::string& utf8str, std::wstring& wstr); // in wsize==max size of buffer, out wsize==real string size |