Merge pull request #7811 from Faq/SplitDamage2
Core/Spells: Implementing some hooks for split damage taken, fixes the l...
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
DELETE FROM spell_script_names WHERE spell_id = 6940;
|
||||
INSERT INTO spell_script_names (spell_id, ScriptName) VALUES
|
||||
(6940, 'spell_pal_hand_of_sacrifice');
|
||||
@@ -1770,8 +1770,10 @@ void Unit::CalcAbsorbResist(Unit* victim, SpellSchoolMask schoolMask, DamageEffe
|
||||
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(victim->GetGUID())))
|
||||
AuraApplication const* aurApp = (*itr)->GetBase()->GetApplicationOfTarget(victim->GetGUID());
|
||||
if (!aurApp)
|
||||
continue;
|
||||
|
||||
// check damage school mask
|
||||
if (!((*itr)->GetMiscValue() & schoolMask))
|
||||
continue;
|
||||
@@ -1781,13 +1783,14 @@ void Unit::CalcAbsorbResist(Unit* victim, SpellSchoolMask schoolMask, DamageEffe
|
||||
if (!caster || (caster == victim) || !caster->IsInWorld() || !caster->isAlive())
|
||||
continue;
|
||||
|
||||
int32 splitDamage = CalculatePctN(dmgInfo.GetDamage(), (*itr)->GetAmount());
|
||||
uint32 splitDamage = CalculatePctN(dmgInfo.GetDamage(), (*itr)->GetAmount());
|
||||
|
||||
(*itr)->GetBase()->CallScriptEffectSplitHandlers((*itr), aurApp, dmgInfo, splitDamage);
|
||||
|
||||
// absorb must be smaller than the damage itself
|
||||
splitDamage = RoundToInterval(splitDamage, 0, int32(dmgInfo.GetDamage()));
|
||||
splitDamage = RoundToInterval(splitDamage, uint32(0), uint32(dmgInfo.GetDamage()));
|
||||
|
||||
dmgInfo.AbsorbDamage(splitDamage);
|
||||
|
||||
uint32 splitted = splitDamage;
|
||||
uint32 split_absorb = 0;
|
||||
DealDamageMods(caster, splitted, &split_absorb);
|
||||
|
||||
@@ -2327,6 +2327,21 @@ void Aura::CallScriptEffectAfterManaShieldHandlers(AuraEffect* aurEff, AuraAppli
|
||||
}
|
||||
}
|
||||
|
||||
void Aura::CallScriptEffectSplitHandlers(AuraEffect* aurEff, AuraApplication const* aurApp, DamageInfo & dmgInfo, uint32 & splitAmount)
|
||||
{
|
||||
for (std::list<AuraScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
|
||||
{
|
||||
(*scritr)->_PrepareScriptCall(AURA_SCRIPT_HOOK_EFFECT_SPLIT, aurApp);
|
||||
std::list<AuraScript::EffectSplitHandler>::iterator effEndItr = (*scritr)->OnEffectSplit.end(), effItr = (*scritr)->OnEffectSplit.begin();
|
||||
for (; effItr != effEndItr; ++effItr)
|
||||
{
|
||||
if ((*effItr).IsEffectAffected(m_spellInfo, aurEff->GetEffIndex()))
|
||||
(*effItr).Call(*scritr, aurEff, dmgInfo, splitAmount);
|
||||
}
|
||||
(*scritr)->_FinishScriptCall();
|
||||
}
|
||||
}
|
||||
|
||||
UnitAura::UnitAura(SpellInfo const* spellproto, uint8 effMask, WorldObject* owner, Unit* caster, int32 *baseAmount, Item* castItem, uint64 casterGUID)
|
||||
: Aura(spellproto, owner, caster, castItem, casterGUID)
|
||||
{
|
||||
|
||||
@@ -217,6 +217,8 @@ class Aura
|
||||
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);
|
||||
void CallScriptEffectSplitHandlers(AuraEffect* aurEff, AuraApplication const* aurApp, DamageInfo & dmgInfo, uint32 & splitAmount);
|
||||
|
||||
std::list<AuraScript*> m_loadedScripts;
|
||||
private:
|
||||
void _DeleteRemovedApplications();
|
||||
|
||||
@@ -675,6 +675,10 @@ bool AuraScript::_Validate(SpellInfo const* entry)
|
||||
if (!(*itr).GetAffectedEffectsMask(entry))
|
||||
sLog->outError(LOG_FILTER_TSCR, "Spell `%u` Effect `%s` of script `%s` did not match dbc effect data - handler bound to hook `AfterEffectManaShield` of AuraScript won't be executed", entry->Id, (*itr).ToString().c_str(), m_scriptName->c_str());
|
||||
|
||||
for (std::list<EffectSplitHandler>::iterator itr = OnEffectSplit.begin(); itr != OnEffectSplit.end(); ++itr)
|
||||
if (!(*itr).GetAffectedEffectsMask(entry))
|
||||
sLog->outError(LOG_FILTER_TSCR, "Spell `%u` Effect `%s` of script `%s` did not match dbc effect data - handler bound to hook `OnEffectSplit` of AuraScript won't be executed", entry->Id, (*itr).ToString().c_str(), m_scriptName->c_str());
|
||||
|
||||
return _SpellScript::_Validate(entry);
|
||||
}
|
||||
|
||||
@@ -803,6 +807,17 @@ void AuraScript::EffectManaShieldHandler::Call(AuraScript* auraScript, AuraEffec
|
||||
(auraScript->*pEffectHandlerScript)(aurEff, dmgInfo, absorbAmount);
|
||||
}
|
||||
|
||||
AuraScript::EffectSplitHandler::EffectSplitHandler(AuraEffectSplitFnType _pEffectHandlerScript, uint8 _effIndex)
|
||||
: AuraScript::EffectBase(_effIndex, SPELL_AURA_SPLIT_DAMAGE_PCT)
|
||||
{
|
||||
pEffectHandlerScript = _pEffectHandlerScript;
|
||||
}
|
||||
|
||||
void AuraScript::EffectSplitHandler::Call(AuraScript* auraScript, AuraEffect* aurEff, DamageInfo& dmgInfo, uint32& splitAmount)
|
||||
{
|
||||
(auraScript->*pEffectHandlerScript)(aurEff, dmgInfo, splitAmount);
|
||||
}
|
||||
|
||||
bool AuraScript::_Load(Aura* aura)
|
||||
{
|
||||
m_aura = aura;
|
||||
@@ -837,6 +852,7 @@ bool AuraScript::_IsDefaultActionPrevented()
|
||||
case AURA_SCRIPT_HOOK_EFFECT_REMOVE:
|
||||
case AURA_SCRIPT_HOOK_EFFECT_PERIODIC:
|
||||
case AURA_SCRIPT_HOOK_EFFECT_ABSORB:
|
||||
case AURA_SCRIPT_HOOK_EFFECT_SPLIT:
|
||||
return m_defaultActionPrevented;
|
||||
default:
|
||||
ASSERT(false && "AuraScript::_IsDefaultActionPrevented is called in a wrong place");
|
||||
@@ -852,6 +868,7 @@ void AuraScript::PreventDefaultAction()
|
||||
case AURA_SCRIPT_HOOK_EFFECT_REMOVE:
|
||||
case AURA_SCRIPT_HOOK_EFFECT_PERIODIC:
|
||||
case AURA_SCRIPT_HOOK_EFFECT_ABSORB:
|
||||
case AURA_SCRIPT_HOOK_EFFECT_SPLIT:
|
||||
m_defaultActionPrevented = true;
|
||||
break;
|
||||
default:
|
||||
@@ -1033,6 +1050,7 @@ Unit* AuraScript::GetTarget() const
|
||||
case AURA_SCRIPT_HOOK_EFFECT_AFTER_ABSORB:
|
||||
case AURA_SCRIPT_HOOK_EFFECT_MANASHIELD:
|
||||
case AURA_SCRIPT_HOOK_EFFECT_AFTER_MANASHIELD:
|
||||
case AURA_SCRIPT_HOOK_EFFECT_SPLIT:
|
||||
return m_auraApplication->GetTarget();
|
||||
default:
|
||||
sLog->outError(LOG_FILTER_TSCR, "Script: `%s` Spell: `%u` AuraScript::GetTarget called in a hook in which the call won't have effect!", m_scriptName->c_str(), m_scriptSpellId);
|
||||
|
||||
@@ -423,6 +423,7 @@ enum AuraScriptHookType
|
||||
AURA_SCRIPT_HOOK_EFFECT_AFTER_ABSORB,
|
||||
AURA_SCRIPT_HOOK_EFFECT_MANASHIELD,
|
||||
AURA_SCRIPT_HOOK_EFFECT_AFTER_MANASHIELD,
|
||||
AURA_SCRIPT_HOOK_EFFECT_SPLIT,
|
||||
AURA_SCRIPT_HOOK_CHECK_AREA_TARGET,
|
||||
AURA_SCRIPT_HOOK_DISPEL,
|
||||
AURA_SCRIPT_HOOK_AFTER_DISPEL
|
||||
@@ -449,6 +450,7 @@ 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::*AuraEffectSplitFnType)(AuraEffect*, DamageInfo &, uint32 &); \
|
||||
|
||||
AURASCRIPT_FUNCTION_TYPE_DEFINES(AuraScript)
|
||||
|
||||
@@ -540,6 +542,14 @@ class AuraScript : public _SpellScript
|
||||
private:
|
||||
AuraEffectAbsorbFnType pEffectHandlerScript;
|
||||
};
|
||||
class EffectSplitHandler : public EffectBase
|
||||
{
|
||||
public:
|
||||
EffectSplitHandler(AuraEffectSplitFnType _pEffectHandlerScript, uint8 _effIndex);
|
||||
void Call(AuraScript* auraScript, AuraEffect* aurEff, DamageInfo & dmgInfo, uint32 & splitAmount);
|
||||
private:
|
||||
AuraEffectSplitFnType pEffectHandlerScript;
|
||||
};
|
||||
|
||||
#define AURASCRIPT_FUNCTION_CAST_DEFINES(CLASSNAME) \
|
||||
class CheckAreaTargetFunction : public AuraScript::CheckAreaTargetHandler { public: CheckAreaTargetFunction(AuraCheckAreaTargetFnType _pHandlerScript) : AuraScript::CheckAreaTargetHandler((AuraScript::AuraCheckAreaTargetFnType)_pHandlerScript) {} }; \
|
||||
@@ -552,6 +562,7 @@ class AuraScript : public _SpellScript
|
||||
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) {} }; \
|
||||
class EffectSplitFunction : public AuraScript::EffectSplitHandler { public: EffectSplitFunction(AuraEffectSplitFnType _pEffectHandlerScript, uint8 _effIndex) : AuraScript::EffectSplitHandler((AuraScript::AuraEffectSplitFnType)_pEffectHandlerScript, _effIndex) {} }; \
|
||||
|
||||
#define PrepareAuraScript(CLASSNAME) AURASCRIPT_FUNCTION_TYPE_DEFINES(CLASSNAME) AURASCRIPT_FUNCTION_CAST_DEFINES(CLASSNAME)
|
||||
|
||||
@@ -676,6 +687,12 @@ class AuraScript : public _SpellScript
|
||||
// where function is: void function (AuraEffect* aurEff, DamageInfo& dmgInfo, uint32& absorbAmount);
|
||||
HookList<EffectManaShieldHandler> AfterEffectManaShield;
|
||||
|
||||
// executed when the caster of some spell with split dmg aura gets damaged through it
|
||||
// example: OnEffectSplit += AuraEffectSplitFn(class::function, EffectIndexSpecifier);
|
||||
// where function is: void function (AuraEffect* aurEff, DamageInfo& dmgInfo, uint32& splitAmount);
|
||||
HookList<EffectSplitHandler> OnEffectSplit;
|
||||
#define AuraEffectSplitFn(F, I) EffectSplitFunction(&F, I)
|
||||
|
||||
// AuraScript interface - hook/effect execution manipulators
|
||||
|
||||
// prevents default action of a hook from being executed (works only while called in a hook which default action can be prevented)
|
||||
|
||||
@@ -47,6 +47,8 @@ enum PaladinSpells
|
||||
SPELL_FORBEARANCE = 25771,
|
||||
SPELL_AVENGING_WRATH_MARKER = 61987,
|
||||
SPELL_IMMUNE_SHIELD_MARKER = 61988,
|
||||
|
||||
SPELL_HAND_OF_SACRIFICE = 6940,
|
||||
};
|
||||
|
||||
// 31850 - Ardent Defender
|
||||
@@ -566,6 +568,52 @@ class spell_pal_exorcism_and_holy_wrath_damage : public SpellScriptLoader
|
||||
}
|
||||
};
|
||||
|
||||
class spell_pal_hand_of_sacrifice : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_pal_hand_of_sacrifice() : SpellScriptLoader("spell_pal_hand_of_sacrifice") { }
|
||||
|
||||
class spell_pal_hand_of_sacrifice_AuraScript : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_pal_hand_of_sacrifice_AuraScript);
|
||||
|
||||
uint32 splitPct;
|
||||
int32 remainingAmount;
|
||||
Unit* caster;
|
||||
|
||||
bool Load()
|
||||
{
|
||||
caster = GetCaster();
|
||||
if (!caster)
|
||||
return false;
|
||||
remainingAmount = caster->GetMaxHealth();
|
||||
splitPct = GetSpellInfo()->Effects[EFFECT_0].CalcValue(GetCaster());
|
||||
return true;
|
||||
}
|
||||
|
||||
void Split(AuraEffect* /*aurEff*/, DamageInfo & /*dmgInfo*/, uint32 & splitAmount)
|
||||
{
|
||||
remainingAmount -= splitAmount;
|
||||
|
||||
if (remainingAmount <= 0)
|
||||
{
|
||||
Unit* target = GetTarget();
|
||||
target->RemoveAura(SPELL_HAND_OF_SACRIFICE);
|
||||
}
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnEffectSplit += AuraEffectSplitFn(spell_pal_hand_of_sacrifice_AuraScript::Split, EFFECT_0);
|
||||
}
|
||||
};
|
||||
|
||||
AuraScript* GetAuraScript() const
|
||||
{
|
||||
return new spell_pal_hand_of_sacrifice_AuraScript();
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_paladin_spell_scripts()
|
||||
{
|
||||
new spell_pal_ardent_defender();
|
||||
@@ -579,4 +627,5 @@ void AddSC_paladin_spell_scripts()
|
||||
new spell_pal_lay_on_hands();
|
||||
new spell_pal_righteous_defense();
|
||||
new spell_pal_exorcism_and_holy_wrath_damage();
|
||||
new spell_pal_hand_of_sacrifice();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user