aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorQAston <none@none>2010-10-04 17:44:49 +0200
committerQAston <none@none>2010-10-04 17:44:49 +0200
commitcaaa77deb285d65b1bc3a0c6f7b5f88ec3508d0c (patch)
treec4ae1d28125763aff7b4a4adbf2b188c40f7094c /src
parent5adaf5887ec3bbc5af122966b506d33deccf8814 (diff)
Core/ScriptSystem:
Add basic code for runtime checks of function calls in AuraScripts Make AuraScript::PreventDefaultAction() do not take parameters and add description for the function Remove PreventDefaultEffect() from aura script, use PreventDefaultAction() instead Unload aura scripts memory on aura delete --HG-- branch : trunk
Diffstat (limited to 'src')
-rw-r--r--src/server/game/Globals/ObjectMgr.cpp10
-rw-r--r--src/server/game/Scripting/ScriptMgr.cpp4
-rw-r--r--src/server/game/Spells/Auras/SpellAuras.cpp32
-rw-r--r--src/server/game/Spells/Spell.cpp3
-rw-r--r--src/server/game/Spells/SpellScript.cpp107
-rw-r--r--src/server/game/Spells/SpellScript.h59
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp3
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp2
8 files changed, 178 insertions, 42 deletions
diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp
index 765599d6711..1a15a4953ff 100644
--- a/src/server/game/Globals/ObjectMgr.cpp
+++ b/src/server/game/Globals/ObjectMgr.cpp
@@ -5234,15 +5234,17 @@ void ObjectMgr::ValidateSpellScripts()
}
if (spellScript)
{
- spellScript->Register();
- if (!spellScript->_Validate(spellEntry, sObjectMgr.GetScriptName(sitr->second->second)))
+ spellScript->_Init(&sitr->first->GetName(), spellEntry->Id);
+ spellScript->_Register();
+ if (!spellScript->_Validate(spellEntry))
valid = false;
delete spellScript;
}
if (auraScript)
{
- auraScript->Register();
- if (!auraScript->_Validate(spellEntry, sObjectMgr.GetScriptName(sitr->second->second)))
+ auraScript->_Init(&sitr->first->GetName(), spellEntry->Id);
+ auraScript->_Register();
+ if (!auraScript->_Validate(spellEntry))
valid = false;
delete auraScript;
}
diff --git a/src/server/game/Scripting/ScriptMgr.cpp b/src/server/game/Scripting/ScriptMgr.cpp
index 08c3f181c4b..a71ad0dcb8e 100644
--- a/src/server/game/Scripting/ScriptMgr.cpp
+++ b/src/server/game/Scripting/ScriptMgr.cpp
@@ -307,6 +307,8 @@ void ScriptMgr::CreateSpellScripts(uint32 spell_id, std::list<SpellScript *> & s
if (!script)
continue;
+ script->_Init(&tmpscript->GetName(), spell_id);
+
script_vector.push_back(script);
}
}
@@ -326,6 +328,8 @@ void ScriptMgr::CreateAuraScripts(uint32 spell_id, std::list<AuraScript *> & scr
if (!script)
continue;
+ script->_Init(&tmpscript->GetName(), spell_id);
+
script_vector.push_back(script);
}
}
diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp
index 5228d099f8c..ad379c530d5 100644
--- a/src/server/game/Spells/Auras/SpellAuras.cpp
+++ b/src/server/game/Spells/Auras/SpellAuras.cpp
@@ -366,6 +366,15 @@ m_isRemoved(false), m_isSingleTarget(false)
Aura::~Aura()
{
+ // unload scripts
+ while(!m_loadedScripts.empty())
+ {
+ std::list<AuraScript *>::iterator itr = m_loadedScripts.begin();
+ (*itr)->_Unload();
+ delete (*itr);
+ m_loadedScripts.erase(itr);
+ }
+
// free effects memory
for (uint8 i = 0 ; i < MAX_SPELL_EFFECTS; ++i)
delete m_effects[i];
@@ -1640,7 +1649,7 @@ 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)->_ResetDefault();
+ (*scritr)->_PrepareScriptCall(AURA_SCRIPT_HOOK_EFFECT_APPLY);
std::list<AuraScript::EffectApplyHandler>::iterator effEndItr = (*scritr)->OnEffectApply.end(), effItr = (*scritr)->OnEffectApply.begin();
for(; effItr != effEndItr ; ++effItr)
{
@@ -1648,7 +1657,8 @@ bool Aura::CallScriptEffectApplyHandlers(AuraEffect const * aurEff, AuraApplicat
(*effItr).Call(*scritr, aurEff, aurApp, mode);
}
if (!preventDefault)
- preventDefault = (*scritr)->_IsDefaultActionPrevented((SpellEffIndex)aurEff->GetEffIndex());
+ preventDefault = (*scritr)->_IsDefaultActionPrevented();
+ (*scritr)->_FinishScriptCall();
}
return preventDefault;
}
@@ -1658,7 +1668,7 @@ 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)->_ResetDefault();
+ (*scritr)->_PrepareScriptCall(AURA_SCRIPT_HOOK_EFFECT_REMOVE);
std::list<AuraScript::EffectApplyHandler>::iterator effEndItr = (*scritr)->OnEffectRemove.end(), effItr = (*scritr)->OnEffectRemove.begin();
for(; effItr != effEndItr ; ++effItr)
{
@@ -1666,7 +1676,8 @@ bool Aura::CallScriptEffectRemoveHandlers(AuraEffect const * aurEff, AuraApplica
(*effItr).Call(*scritr, aurEff, aurApp, mode);
}
if (!preventDefault)
- preventDefault = (*scritr)->_IsDefaultActionPrevented((SpellEffIndex)aurEff->GetEffIndex());
+ preventDefault = (*scritr)->_IsDefaultActionPrevented();
+ (*scritr)->_FinishScriptCall();
}
return preventDefault;
}
@@ -1676,7 +1687,7 @@ 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)->_ResetDefault();
+ (*scritr)->_PrepareScriptCall(AURA_SCRIPT_HOOK_EFFECT_PERIODIC);
std::list<AuraScript::EffectPeriodicHandler>::iterator effEndItr = (*scritr)->OnEffectPeriodic.end(), effItr = (*scritr)->OnEffectPeriodic.begin();
for(; effItr != effEndItr ; ++effItr)
{
@@ -1684,7 +1695,8 @@ bool Aura::CallScriptEffectPeriodicHandlers(AuraEffect const * aurEff, AuraAppli
(*effItr).Call(*scritr, aurEff, aurApp);
}
if (!preventDefault)
- preventDefault = (*scritr)->_IsDefaultActionPrevented((SpellEffIndex)aurEff->GetEffIndex());
+ preventDefault = (*scritr)->_IsDefaultActionPrevented();
+ (*scritr)->_FinishScriptCall();
}
return preventDefault;
}
@@ -1693,12 +1705,14 @@ void Aura::CallScriptEffectUpdatePeriodicHandlers(AuraEffect * aurEff)
{
for(std::list<AuraScript *>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end() ; ++scritr)
{
+ (*scritr)->_PrepareScriptCall(AURA_SCRIPT_HOOK_EFFECT_UPDATE_PERIODIC);
std::list<AuraScript::EffectUpdatePeriodicHandler>::iterator effEndItr = (*scritr)->OnEffectUpdatePeriodic.end(), effItr = (*scritr)->OnEffectUpdatePeriodic.begin();
for(; effItr != effEndItr ; ++effItr)
{
if ((*effItr).IsEffectAffected(m_spellProto, aurEff->GetEffIndex()))
(*effItr).Call(*scritr, aurEff);
}
+ (*scritr)->_FinishScriptCall();
}
}
@@ -1706,12 +1720,14 @@ 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();
for(; effItr != effEndItr ; ++effItr)
{
if ((*effItr).IsEffectAffected(m_spellProto, aurEff->GetEffIndex()))
(*effItr).Call(*scritr, aurEff, amount, canBeRecalculated);
}
+ (*scritr)->_FinishScriptCall();
}
}
@@ -1719,12 +1735,14 @@ 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();
for(; effItr != effEndItr ; ++effItr)
{
if ((*effItr).IsEffectAffected(m_spellProto, aurEff->GetEffIndex()))
(*effItr).Call(*scritr, aurEff, isPeriodic, amplitude);
}
+ (*scritr)->_FinishScriptCall();
}
}
@@ -1732,12 +1750,14 @@ 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();
for(; effItr != effEndItr ; ++effItr)
{
if ((*effItr).IsEffectAffected(m_spellProto, aurEff->GetEffIndex()))
(*effItr).Call(*scritr, aurEff, spellMod);
}
+ (*scritr)->_FinishScriptCall();
}
}
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index e01aa4f94af..861cc57dc01 100644
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -541,10 +541,11 @@ Spell::~Spell()
while(!m_loadedScripts.empty())
{
std::list<SpellScript *>::iterator itr = m_loadedScripts.begin();
- (*itr)->Unload();
+ (*itr)->_Unload();
delete (*itr);
m_loadedScripts.erase(itr);
}
+
if (m_referencedFromCurrentSpell && m_selfContainer && *m_selfContainer == this)
{
// Clean the reference to avoid later crash.
diff --git a/src/server/game/Spells/SpellScript.cpp b/src/server/game/Spells/SpellScript.cpp
index 221b2de4cca..b79e6b28399 100644
--- a/src/server/game/Spells/SpellScript.cpp
+++ b/src/server/game/Spells/SpellScript.cpp
@@ -21,16 +21,37 @@
#include "SpellAuras.h"
#include "SpellScript.h"
-bool _SpellScript::_Validate(SpellEntry const * entry, const char * scriptname)
+bool _SpellScript::_Validate(SpellEntry const * entry)
{
if (!Validate(entry))
{
- sLog.outError("TSCR: Spell `%u` did not pass Validate() function of script `%s` - script will be not added to the spell", entry->Id, scriptname);
+ sLog.outError("TSCR: Spell `%u` did not pass Validate() function of script `%s` - script will be not added to the spell", entry->Id, m_scriptName->c_str());
return false;
}
return true;
}
+void _SpellScript::_Register()
+{
+ m_currentScriptState = SPELL_SCRIPT_STATE_REGISTRATION;
+ Register();
+ m_currentScriptState = SPELL_SCRIPT_STATE_NONE;
+}
+
+void _SpellScript::_Unload()
+{
+ m_currentScriptState = SPELL_SCRIPT_STATE_UNLOADING;
+ Unload();
+ m_currentScriptState = SPELL_SCRIPT_STATE_NONE;
+}
+
+void _SpellScript::_Init(const std::string * scriptname, uint32 spellId)
+{
+ m_currentScriptState = SPELL_SCRIPT_STATE_NONE;
+ m_scriptName = scriptname;
+ m_scriptSpellId = spellId;
+}
+
_SpellScript::EffectHook::EffectHook(uint8 _effIndex)
{
// effect index must be in range <0;2>, allow use of special effindexes
@@ -147,22 +168,25 @@ void SpellScript::EffectHandler::Call(SpellScript * spellScript, SpellEffIndex e
(spellScript->*pEffectHandlerScript)(effIndex);
}
-bool SpellScript::_Validate(SpellEntry const * entry, const char * scriptname)
+bool SpellScript::_Validate(SpellEntry const * entry)
{
for (std::list<EffectHandler>::iterator itr = OnEffect.begin(); itr != OnEffect.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(), scriptname);
+ 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, scriptname);
+ return _SpellScript::_Validate(entry);
}
bool SpellScript::_Load(Spell * spell)
{
+ m_currentScriptState = SPELL_SCRIPT_STATE_LOADING;
m_spell = spell;
- return Load();
+ bool load = Load();
+ m_currentScriptState = SPELL_SCRIPT_STATE_NONE;
+ return load;
}
void SpellScript::_InitHit()
@@ -285,37 +309,37 @@ void SpellScript::CreateItem(uint32 effIndex, uint32 itemId)
m_spell->DoCreateItem(effIndex, itemId);
}
-bool AuraScript::_Validate(SpellEntry const * entry, const char * scriptname)
+bool AuraScript::_Validate(SpellEntry const * entry)
{
for (std::list<EffectApplyHandler>::iterator itr = OnEffectApply.begin(); itr != OnEffectApply.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(), scriptname);
+ 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<EffectApplyHandler>::iterator itr = OnEffectRemove.begin(); itr != OnEffectRemove.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(), scriptname);
+ 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<EffectPeriodicHandler>::iterator itr = OnEffectPeriodic.begin(); itr != OnEffectPeriodic.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(), scriptname);
+ 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<EffectUpdatePeriodicHandler>::iterator itr = OnEffectUpdatePeriodic.begin(); itr != OnEffectUpdatePeriodic.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(), scriptname);
+ 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)
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(), scriptname);
+ 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)
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(), scriptname);
+ 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)
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(), scriptname);
+ 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, scriptname);
+ return _SpellScript::_Validate(entry);
}
AuraScript::EffectBase::EffectBase(uint8 _effIndex, uint16 _effName)
@@ -403,8 +427,59 @@ void AuraScript::EffectApplyHandler::Call(AuraScript * auraScript, AuraEffect co
bool AuraScript::_Load(Aura * aura)
{
+ m_currentScriptState = SPELL_SCRIPT_STATE_LOADING;
m_aura = aura;
- return Load();
+ bool load = Load();
+ m_currentScriptState = SPELL_SCRIPT_STATE_NONE;
+ return load;
+}
+
+void AuraScript::_PrepareScriptCall(AuraScriptHookType hookType)
+{
+ m_currentScriptState = hookType;
+ switch (m_currentScriptState)
+ {
+ case AURA_SCRIPT_HOOK_EFFECT_APPLY:
+ case AURA_SCRIPT_HOOK_EFFECT_REMOVE:
+ case AURA_SCRIPT_HOOK_EFFECT_PERIODIC:
+ m_defaultActionPrevented = false;
+ break;
+ default:
+ break;
+ }
+}
+
+void AuraScript::_FinishScriptCall()
+{
+ m_currentScriptState = SPELL_SCRIPT_STATE_NONE;
+}
+
+bool AuraScript::_IsDefaultActionPrevented()
+{
+ switch (m_currentScriptState)
+ {
+ case AURA_SCRIPT_HOOK_EFFECT_APPLY:
+ case AURA_SCRIPT_HOOK_EFFECT_REMOVE:
+ case AURA_SCRIPT_HOOK_EFFECT_PERIODIC:
+ return m_defaultActionPrevented;
+ default:
+ return false;
+ }
+}
+
+void AuraScript::PreventDefaultAction()
+{
+ switch (m_currentScriptState)
+ {
+ case AURA_SCRIPT_HOOK_EFFECT_APPLY:
+ case AURA_SCRIPT_HOOK_EFFECT_REMOVE:
+ case AURA_SCRIPT_HOOK_EFFECT_PERIODIC:
+ m_defaultActionPrevented = true;
+ break;
+ default:
+ sLog.outError("TSCR: Script: `%s` Spell: `%u` AuraScript::PreventDefaultAction called in a hook in which the call won't have effect!", m_scriptName->c_str(), m_scriptSpellId);
+ break;
+ }
}
SpellEntry const* AuraScript::GetSpellProto() const
diff --git a/src/server/game/Spells/SpellScript.h b/src/server/game/Spells/SpellScript.h
index dea3ebbfc8d..f152fe28e98 100644
--- a/src/server/game/Spells/SpellScript.h
+++ b/src/server/game/Spells/SpellScript.h
@@ -41,13 +41,26 @@ class WorldObject;
#define SPELL_EFFECT_ANY (uint16)-1
#define SPELL_AURA_ANY (uint16)-1
+enum SpellScriptState
+{
+ SPELL_SCRIPT_STATE_NONE = 0,
+ SPELL_SCRIPT_STATE_REGISTRATION,
+ SPELL_SCRIPT_STATE_LOADING,
+ SPELL_SCRIPT_STATE_UNLOADING,
+};
+#define SPELL_SCRIPT_STATE_END SPELL_SCRIPT_STATE_UNLOADING + 1
+
// helper class from which SpellScript and SpellAura derive, use these classes instead
class _SpellScript
{
// internal use classes & functions
// DO NOT OVERRIDE THESE IN SCRIPTS
protected:
- virtual bool _Validate(SpellEntry const * entry, const char * scriptname);
+ virtual bool _Validate(SpellEntry const * entry);
+ public:
+ virtual void _Register();
+ virtual void _Unload();
+ virtual void _Init(const std::string * scriptname, uint32 spellId);
protected:
class EffectHook
{
@@ -78,6 +91,10 @@ class _SpellScript
private:
uint16 effAurName;
};
+
+ uint8 m_currentScriptState;
+ const std::string * m_scriptName;
+ uint32 m_scriptSpellId;
public:
//
// SpellScript/AuraScript interface base
@@ -116,7 +133,7 @@ class SpellScript : public _SpellScript
};
typedef SpellHitFnType HitHandler;
public:
- bool _Validate(SpellEntry const * entry, const char * scriptname);
+ bool _Validate(SpellEntry const * entry);
bool _Load(Spell * spell);
void _InitHit();
bool _IsEffectPrevented(SpellEffIndex effIndex) {return m_hitPreventEffectMask & (1<<effIndex);};
@@ -209,6 +226,23 @@ class SpellScript : public _SpellScript
void CreateItem(uint32 effIndex, uint32 itemId);
};
+// AuraScript interface - enum used for manipulations on hooks by their type
+enum AuraScriptHookType
+{
+ AURA_SCRIPT_HOOK_EFFECT_APPLY = SPELL_SCRIPT_STATE_END,
+ AURA_SCRIPT_HOOK_EFFECT_REMOVE,
+ AURA_SCRIPT_HOOK_EFFECT_PERIODIC,
+ AURA_SCRIPT_HOOK_EFFECT_UPDATE_PERIODIC,
+ AURA_SCRIPT_HOOK_EFFECT_CALC_AMOUNT,
+ AURA_SCRIPT_HOOK_EFFECT_CALC_PERIODIC,
+ AURA_SCRIPT_HOOK_EFFECT_CALC_SPELLMOD,
+ /*AURA_SCRIPT_HOOK_APPLY,
+ AURA_SCRIPT_HOOK_REMOVE,*/
+};
+#define HOOK_AURA_EFFECT_START HOOK_AURA_EFFECT_APPLY
+#define HOOK_AURA_EFFECT_END HOOK_AURA_EFFECT_CALC_SPELLMOD + 1
+#define HOOK_AURA_EFFECT_COUNT HOOK_AURA_EFFECT_END - HOOK_AURA_EFFECT_START
+
class AuraScript : public _SpellScript
{
// internal use classes & functions
@@ -278,20 +312,14 @@ class AuraScript : public _SpellScript
AuraEffectHandleModes mode;
};
public:
- bool _Validate(SpellEntry const * entry, const char * scriptname);
+ bool _Validate(SpellEntry const * entry);
bool _Load(Aura * aura);
- void _ResetDefault() { m_defaultPreventedActionsMask = 0; }
- bool _IsDefaultActionPrevented(SpellEffIndex effIndex)
- {
- uint8 effIndexMask = 1 << effIndex;
- return (m_defaultPreventedActionsMask & effIndexMask) || (m_defaultPreventedEffectsMask & effIndexMask);
- }
- void PreventDefaultAction(SpellEffIndex effIndex) { m_defaultPreventedActionsMask |= 1 << effIndex; }
- void PreventDefaultEffect(SpellEffIndex effIndex) { m_defaultPreventedEffectsMask |= 1 << effIndex; }
+ void _PrepareScriptCall(AuraScriptHookType hookType);
+ void _FinishScriptCall();
+ bool _IsDefaultActionPrevented();
private:
Aura * m_aura;
- uint8 m_defaultPreventedActionsMask;
- uint8 m_defaultPreventedEffectsMask;
+ bool m_defaultActionPrevented;
public:
//
// AuraScript interface
@@ -338,6 +366,11 @@ class AuraScript : public _SpellScript
HookList<EffectCalcSpellModHandler> OnEffectCalcSpellMod;
#define AuraEffectCalcSpellModFn(F, I, N) EffectCalcSpellModHandler((AuraEffectCalcSpellModFnType)&F, I, N)
+ // 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)
+ void PreventDefaultAction();
+
// AuraScript interface - functions which are redirecting to Aura class
// returns proto of the spell
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp
index 9c7d595944b..0ec7fa7d2a7 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp
@@ -961,11 +961,12 @@ class spell_deathbringer_blood_link_aura : public SpellScriptLoader
if (GetUnitOwner()->getPowerType() == POWER_ENERGY && GetUnitOwner()->GetPower(POWER_ENERGY) == GetUnitOwner()->GetMaxPower(POWER_ENERGY))
if (Creature* saurfang = GetUnitOwner()->ToCreature())
saurfang->AI()->DoAction(ACTION_MARK_OF_THE_FALLEN_CHAMPION);
+
+ PreventDefaultAction();
}
void Register()
{
- PreventDefaultEffect(EFFECT_1);
OnEffectPeriodic += AuraEffectPeriodicFn(spell_deathbringer_blood_link_AuraScript::HandlePeriodicTick, EFFECT_1, SPELL_AURA_PERIODIC_DUMMY);
}
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp
index 551967b5743..c2d3d0f87f7 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp
@@ -754,11 +754,11 @@ class spell_deathwhisper_mana_barrier : public SpellScriptLoader
int32 missingHealth = caster->GetMaxHealth() - caster->GetHealth();
caster->ModifyHealth(missingHealth);
caster->ModifyPower(POWER_MANA, -missingHealth);
+ PreventDefaultAction();
}
void Register()
{
- PreventDefaultEffect(EFFECT_0);
OnEffectPeriodic += AuraEffectPeriodicFn(spell_deathwhisper_mana_barrier_AuraScript::HandlePeriodicTick, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
}
};