aboutsummaryrefslogtreecommitdiff
path: root/src/server/game
diff options
context:
space:
mode:
authorQAston <qaston@gmail.com>2010-12-30 19:05:19 +0100
committerQAston <qaston@gmail.com>2010-12-30 19:05:19 +0100
commit8cd2c73e454d81899f400f291a3ea8f91c0cfae7 (patch)
tree09244f828013217269151b222ac3539a92ffcc14 /src/server/game
parent71e959837b67e664ca23848f6a21c5e6d0dcfcb2 (diff)
Core/ScriptSystem: Add OnEffectManaShield and AfterEffectManaShield hooks to AuraScript class. Usage of these is the same as similar Absorb hooks.
Scripts: Move Incanter's Absorbtion script from Unit::CalcAbsorbResist to AuraScript.
Diffstat (limited to 'src/server/game')
-rwxr-xr-xsrc/server/game/Entities/Unit/Unit.cpp61
-rwxr-xr-xsrc/server/game/Spells/Auras/SpellAuras.cpp33
-rwxr-xr-xsrc/server/game/Spells/Auras/SpellAuras.h2
-rwxr-xr-xsrc/server/game/Spells/SpellScript.cpp20
-rwxr-xr-xsrc/server/game/Spells/SpellScript.h32
5 files changed, 110 insertions, 38 deletions
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index dcaea3186cc..df6ebbb8639 100755
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -1595,7 +1595,7 @@ void Unit::CalcAbsorbResist(Unit *pVictim, SpellSchoolMask schoolMask, DamageEff
probabilitySum += discreteResistProbability[i];
}
- float damageResisted = damage * i / 10;
+ float damageResisted = float(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)
@@ -1611,7 +1611,7 @@ void Unit::CalcAbsorbResist(Unit *pVictim, SpellSchoolMask schoolMask, DamageEff
if ((*j)->GetMiscValue() & schoolMask)
AddPctN(damageResisted, -(*j)->GetAmount());
}
- dmgInfo.ResistDamage(damageResisted);
+ dmgInfo.ResistDamage(uint32(damageResisted));
}
// Incanter's Absorption, for converting to spell power
@@ -1626,7 +1626,7 @@ void Unit::CalcAbsorbResist(Unit *pVictim, SpellSchoolMask schoolMask, DamageEff
continue;
if ((*itr)->GetAmount() > auraAbsorbMod)
- auraAbsorbMod = (*itr)->GetAmount();
+ auraAbsorbMod = float((*itr)->GetAmount());
}
AuraEffectList const & AbsIgnoreAurasB = GetAuraEffectsByType(SPELL_AURA_MOD_TARGET_ABILITY_ABSORB_SCHOOL);
@@ -1636,7 +1636,7 @@ void Unit::CalcAbsorbResist(Unit *pVictim, SpellSchoolMask schoolMask, DamageEff
continue;
if (((*itr)->GetAmount() > auraAbsorbMod) && (*itr)->IsAffectedOnSpell(spellInfo))
- auraAbsorbMod = (*itr)->GetAmount();
+ auraAbsorbMod = float((*itr)->GetAmount());
}
RoundToInterval(auraAbsorbMod, 0.0f, 100.0f);
@@ -1682,11 +1682,6 @@ void Unit::CalcAbsorbResist(Unit *pVictim, SpellSchoolMask schoolMask, DamageEff
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[2] & 0x8)
- incanterAbsorption += currentAbsorb;
-
absorb = currentAbsorb;
absorbAurEff->GetBase()->CallScriptEffectAfterAbsorbHandlers(absorbAurEff, aurApp, dmgInfo, absorb);
@@ -1707,9 +1702,10 @@ void Unit::CalcAbsorbResist(Unit *pVictim, SpellSchoolMask schoolMask, DamageEff
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;
+ 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;
// check damage school mask
if (!(absorbAurEff->GetMiscValue() & schoolMask))
@@ -1717,6 +1713,19 @@ void Unit::CalcAbsorbResist(Unit *pVictim, SpellSchoolMask schoolMask, DamageEff
// 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;
+
+ uint32 absorb = currentAbsorb;
+
+ bool defaultPrevented = false;
+
+ absorbAurEff->GetBase()->CallScriptEffectManaShieldHandlers(absorbAurEff, aurApp, dmgInfo, absorb, defaultPrevented);
+ currentAbsorb = absorb;
+
+ if (defaultPrevented)
+ continue;
AddPctF(currentAbsorb, -auraAbsorbMod);
@@ -1727,23 +1736,25 @@ void Unit::CalcAbsorbResist(Unit *pVictim, SpellSchoolMask schoolMask, DamageEff
// lower absorb amount by talents
if (float manaMultiplier = SpellMgr::CalculateSpellEffectValueMultiplier(absorbAurEff->GetSpellProto(), absorbAurEff->GetEffIndex(), absorbAurEff->GetCaster()))
- manaReduction = float(manaReduction) * manaMultiplier;
+ manaReduction = int32(float(manaReduction) * manaMultiplier);
int32 manaTaken = -pVictim->ModifyPower(POWER_MANA, -manaReduction);
// take case when mana has ended up into account
- currentAbsorb = float(currentAbsorb)*(float(manaTaken) / float(manaReduction));
-
- // Mana Shield (or Fire Ward or Frost Ward or Ice Barrier)
- // for Incanter's Absorption converting to spell power
- if (absorbAurEff->GetSpellProto()->SpellFamilyName == SPELLFAMILY_MAGE && absorbAurEff->GetSpellProto()->SpellFamilyFlags[2] & 0x8)
- incanterAbsorption += currentAbsorb;
+ currentAbsorb = int32(float(currentAbsorb)*(float(manaTaken) / float(manaReduction)));
dmgInfo.AbsorbDamage(currentAbsorb);
- absorbAurEff->SetAmount(absorbAurEff->GetAmount() - currentAbsorb);
- if ((absorbAurEff->GetAmount() <= 0))
- absorbAurEff->GetBase()->Remove(AURA_REMOVE_BY_ENEMY_SPELL);
+ absorb = currentAbsorb;
+ absorbAurEff->GetBase()->CallScriptEffectAfterManaShieldHandlers(absorbAurEff, aurApp, dmgInfo, absorb);
+
+ // Check if our aura is using amount to count damage
+ if (absorbAurEff->GetAmount() >= 0)
+ {
+ absorbAurEff->SetAmount(absorbAurEff->GetAmount() - currentAbsorb);
+ if ((absorbAurEff->GetAmount() <= 0))
+ absorbAurEff->GetBase()->Remove(AURA_REMOVE_BY_ENEMY_SPELL);
+ }
}
}
@@ -1826,16 +1837,8 @@ void Unit::CalcAbsorbResist(Unit *pVictim, SpellSchoolMask schoolMask, DamageEff
if (incanterAbsorption)
{
// Incanter's Absorption
- // TODO: move this code to procflag
if (AuraEffect const * aurEff = pVictim->GetDummyAuraEffect(SPELLFAMILY_GENERIC, 2941, EFFECT_0))
{
- // Get total damage bonus from auras
- int32 current_dmg = 0;
- std::pair<AuraApplicationMap::const_iterator, AuraApplicationMap::const_iterator> range = pVictim->GetAppliedAuras().equal_range(44413);
- for (AuraApplicationMap::const_iterator iter = range.first; iter != range.second; ++iter)
- if (AuraEffect const * bonusEff = iter->second->GetBase()->GetEffect(0))
- current_dmg += bonusEff->GetAmount();
-
int32 new_dmg = CalculatePctN(int32(*absorb), aurEff->GetAmount());
if (new_dmg > 0)
pVictim->CastCustomSpell(pVictim, 44413, &new_dmg, NULL, NULL, true);
diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp
index 4642b15c724..e0b785529fa 100755
--- a/src/server/game/Spells/Auras/SpellAuras.cpp
+++ b/src/server/game/Spells/Auras/SpellAuras.cpp
@@ -1800,6 +1800,39 @@ void Aura::CallScriptEffectAfterAbsorbHandlers(AuraEffect * aurEff, AuraApplicat
}
}
+
+void Aura::CallScriptEffectManaShieldHandlers(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_MANASHIELD, aurApp);
+ std::list<AuraScript::EffectManaShieldHandler>::iterator effEndItr = (*scritr)->OnEffectManaShield.end(), effItr = (*scritr)->OnEffectManaShield.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();
+ }
+}
+
+void Aura::CallScriptEffectAfterManaShieldHandlers(AuraEffect * aurEff, AuraApplication const * aurApp, DamageInfo & dmgInfo, uint32 & absorbAmount)
+{
+ for(std::list<AuraScript *>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end() ; ++scritr)
+ {
+ (*scritr)->_PrepareScriptCall(AURA_SCRIPT_HOOK_EFFECT_AFTER_MANASHIELD, aurApp);
+ std::list<AuraScript::EffectManaShieldHandler>::iterator effEndItr = (*scritr)->AfterEffectManaShield.end(), effItr = (*scritr)->AfterEffectManaShield.begin();
+ for(; effItr != effEndItr ; ++effItr)
+ {
+ if ((*effItr).IsEffectAffected(m_spellProto, aurEff->GetEffIndex()))
+ (*effItr).Call(*scritr, aurEff, dmgInfo, absorbAmount);
+ }
+ (*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 366373f6b53..07fdde2e0a7 100755
--- a/src/server/game/Spells/Auras/SpellAuras.h
+++ b/src/server/game/Spells/Auras/SpellAuras.h
@@ -176,6 +176,8 @@ class Aura
void CallScriptEffectCalcSpellModHandlers(AuraEffect const * aurEff, SpellModifier *& spellMod);
void CallScriptEffectAbsorbHandlers(AuraEffect * aurEff, AuraApplication const * aurApp, DamageInfo & dmgInfo, uint32 & absorbAmount, bool & defaultPrevented);
void CallScriptEffectAfterAbsorbHandlers(AuraEffect * aurEff, AuraApplication const * aurApp, DamageInfo & dmgInfo, uint32 & absorbAmount);
+ void CallScriptEffectManaShieldHandlers(AuraEffect * aurEff, AuraApplication const * aurApp, DamageInfo & dmgInfo, uint32 & absorbAmount, bool & defaultPrevented);
+ void CallScriptEffectAfterManaShieldHandlers(AuraEffect * aurEff, AuraApplication const * aurApp, DamageInfo & dmgInfo, uint32 & absorbAmount);
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 e175e9d688e..dee3dac825d 100755
--- a/src/server/game/Spells/SpellScript.cpp
+++ b/src/server/game/Spells/SpellScript.cpp
@@ -451,6 +451,14 @@ 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<EffectManaShieldHandler>::iterator itr = OnEffectManaShield.begin(); itr != OnEffectManaShield.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<EffectManaShieldHandler>::iterator itr = AfterEffectManaShield.begin(); itr != AfterEffectManaShield.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());
+
return _SpellScript::_Validate(entry);
}
@@ -548,6 +556,17 @@ void AuraScript::EffectAbsorbHandler::Call(AuraScript * auraScript, AuraEffect *
(auraScript->*pEffectHandlerScript)(aurEff, dmgInfo, absorbAmount);
}
+AuraScript::EffectManaShieldHandler::EffectManaShieldHandler(AuraEffectAbsorbFnType _pEffectHandlerScript,uint8 _effIndex)
+ : AuraScript::EffectBase(_effIndex, SPELL_AURA_MANA_SHIELD)
+{
+ pEffectHandlerScript = _pEffectHandlerScript;
+}
+
+void AuraScript::EffectManaShieldHandler::Call(AuraScript * auraScript, AuraEffect * aurEff, DamageInfo & dmgInfo, uint32 & absorbAmount)
+{
+ (auraScript->*pEffectHandlerScript)(aurEff, dmgInfo, absorbAmount);
+}
+
bool AuraScript::_Load(Aura * aura)
{
m_currentScriptState = SPELL_SCRIPT_STATE_LOADING;
@@ -566,6 +585,7 @@ void AuraScript::_PrepareScriptCall(AuraScriptHookType hookType, AuraApplication
case AURA_SCRIPT_HOOK_EFFECT_REMOVE:
case AURA_SCRIPT_HOOK_EFFECT_PERIODIC:
case AURA_SCRIPT_HOOK_EFFECT_ABSORB:
+ case AURA_SCRIPT_HOOK_EFFECT_MANASHIELD:
m_defaultActionPrevented = false;
break;
default:
diff --git a/src/server/game/Spells/SpellScript.h b/src/server/game/Spells/SpellScript.h
index ad231d757f5..47f186c05e9 100755
--- a/src/server/game/Spells/SpellScript.h
+++ b/src/server/game/Spells/SpellScript.h
@@ -284,6 +284,8 @@ enum AuraScriptHookType
AURA_SCRIPT_HOOK_EFFECT_CALC_SPELLMOD,
AURA_SCRIPT_HOOK_EFFECT_ABSORB,
AURA_SCRIPT_HOOK_EFFECT_AFTER_ABSORB,
+ AURA_SCRIPT_HOOK_EFFECT_MANASHIELD,
+ AURA_SCRIPT_HOOK_EFFECT_AFTER_MANASHIELD,
/*AURA_SCRIPT_HOOK_APPLY,
AURA_SCRIPT_HOOK_REMOVE,*/
};
@@ -305,7 +307,6 @@ class AuraScript : public _SpellScript
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)
@@ -373,6 +374,14 @@ class AuraScript : public _SpellScript
private:
AuraEffectAbsorbFnType pEffectHandlerScript;
};
+ class EffectManaShieldHandler : public EffectBase
+ {
+ public:
+ EffectManaShieldHandler(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) {} }; \
@@ -382,6 +391,7 @@ class AuraScript : public _SpellScript
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) {} }; \
+ class EffectManaShieldFunction : public AuraScript::EffectManaShieldHandler { public: EffectManaShieldFunction(AuraEffectAbsorbFnType _pEffectHandlerScript,uint8 _effIndex) : AuraScript::EffectManaShieldHandler((AuraScript::AuraEffectAbsorbFnType)_pEffectHandlerScript, _effIndex) {} }; \
#define PrepareAuraScript(CLASSNAME) AURASCRIPT_FUNCTION_TYPE_DEFINES(CLASSNAME) AURASCRIPT_FUNCTION_CAST_DEFINES(CLASSNAME)
@@ -448,17 +458,21 @@ class AuraScript : public _SpellScript
HookList<EffectAbsorbHandler> OnEffectAbsorb;
#define AuraEffectAbsorbFn(F, I) EffectAbsorbFunction(&F, I)
- // executed after absorb aura effect to reduced damage to target - absorbAmount is real amount absorbed by aura
- // example: OnEffectAbsorb += AuraEffectAbsorbFn(class::function, EffectIndexSpecifier);
+ // executed after absorb aura effect reduced damage to target - absorbAmount is real amount absorbed by aura
+ // example: AfterEffectAbsorb += AuraEffectAbsorbFn(class::function, EffectIndexSpecifier);
// where function is: void function (AuraEffect * aurEff, DamageInfo & dmgInfo, uint32 & absorbAmount);
HookList<EffectAbsorbHandler> AfterEffectAbsorb;
- #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)
+ // executed when mana shield aura effect is going to reduce damage
+ // example: OnEffectManaShield += AuraEffectAbsorbFn(class::function, EffectIndexSpecifier);
+ // where function is: void function (AuraEffect * aurEff, DamageInfo & dmgInfo, uint32 & absorbAmount);
+ HookList<EffectManaShieldHandler> OnEffectManaShield;
+ #define AuraEffectManaShieldFn(F, I) EffectManaShieldFunction(&F, I)
+
+ // executed after mana shield aura effect reduced damage to target - absorbAmount is real amount absorbed by aura
+ // example: AfterEffectManaShield += AuraEffectAbsorbFn(class::function, EffectIndexSpecifier);
+ // where function is: void function (AuraEffect * aurEff, DamageInfo & dmgInfo, uint32 & absorbAmount);
+ HookList<EffectManaShieldHandler> AfterEffectManaShield;
// AuraScript interface - hook/effect execution manipulators