Scripts/Spell: extend SpellScript class: add target aura accessors and functions which prevent various effects of the spell from being executed. Check out SpellScript.h for details
--HG-- branch : trunk
This commit is contained in:
@@ -1578,7 +1578,7 @@ bool Unit::IsDamageReducedByArmor(SpellSchoolMask schoolMask, SpellEntry const *
|
|||||||
|
|
||||||
// bleeding effects are not reduced by armor
|
// bleeding effects are not reduced by armor
|
||||||
if (effIndex != MAX_SPELL_EFFECTS && spellInfo->EffectApplyAuraName[effIndex] == SPELL_AURA_PERIODIC_DAMAGE)
|
if (effIndex != MAX_SPELL_EFFECTS && spellInfo->EffectApplyAuraName[effIndex] == SPELL_AURA_PERIODIC_DAMAGE)
|
||||||
if (GetSpellMechanicMask(spellInfo, effIndex) & MECHANIC_BLEED)
|
if (GetSpellMechanicMask(spellInfo, effIndex) & (1<<MECHANIC_BLEED))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -1404,6 +1404,8 @@ SpellMissInfo Spell::DoSpellHitOnUnit(Unit *unit, const uint32 effectMask, bool
|
|||||||
if (m_spellInfo->speed && (unit->IsImmunedToDamage(m_spellInfo) || unit->IsImmunedToSpell(m_spellInfo)))
|
if (m_spellInfo->speed && (unit->IsImmunedToDamage(m_spellInfo) || unit->IsImmunedToSpell(m_spellInfo)))
|
||||||
return SPELL_MISS_IMMUNE;
|
return SPELL_MISS_IMMUNE;
|
||||||
|
|
||||||
|
PrepareTargetHitForScripts();
|
||||||
|
|
||||||
if (unit->GetTypeId() == TYPEID_PLAYER)
|
if (unit->GetTypeId() == TYPEID_PLAYER)
|
||||||
{
|
{
|
||||||
unit->ToPlayer()->GetAchievementMgr().StartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_SPELL_TARGET, m_spellInfo->Id);
|
unit->ToPlayer()->GetAchievementMgr().StartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_SPELL_TARGET, m_spellInfo->Id);
|
||||||
@@ -1639,6 +1641,8 @@ void Spell::DoAllEffectOnTarget(GOTargetInfo *target)
|
|||||||
if (!go)
|
if (!go)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
PrepareTargetHitForScripts();
|
||||||
|
|
||||||
for (uint32 effectNumber = 0; effectNumber < 3; ++effectNumber)
|
for (uint32 effectNumber = 0; effectNumber < 3; ++effectNumber)
|
||||||
if (effectMask & (1 << effectNumber))
|
if (effectMask & (1 << effectNumber))
|
||||||
HandleEffects(NULL, NULL, go, effectNumber);
|
HandleEffects(NULL, NULL, go, effectNumber);
|
||||||
@@ -1658,6 +1662,8 @@ void Spell::DoAllEffectOnTarget(ItemTargetInfo *target)
|
|||||||
if (!target->item || !effectMask)
|
if (!target->item || !effectMask)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
PrepareTargetHitForScripts();
|
||||||
|
|
||||||
for (uint32 effectNumber = 0; effectNumber < 3; ++effectNumber)
|
for (uint32 effectNumber = 0; effectNumber < 3; ++effectNumber)
|
||||||
if (effectMask & (1 << effectNumber))
|
if (effectMask & (1 << effectNumber))
|
||||||
HandleEffects(NULL, target->item, NULL, effectNumber);
|
HandleEffects(NULL, target->item, NULL, effectNumber);
|
||||||
@@ -3255,6 +3261,8 @@ void Spell::cast(bool skipCheck)
|
|||||||
// CAST SPELL
|
// CAST SPELL
|
||||||
SendSpellCooldown();
|
SendSpellCooldown();
|
||||||
|
|
||||||
|
PrepareTargetHitForScripts();
|
||||||
|
|
||||||
for (uint32 i = 0; i < 3; ++i)
|
for (uint32 i = 0; i < 3; ++i)
|
||||||
{
|
{
|
||||||
switch(m_spellInfo->Effect[i])
|
switch(m_spellInfo->Effect[i])
|
||||||
@@ -3419,6 +3427,8 @@ void Spell::_handle_immediate_phase()
|
|||||||
// handle some immediate features of the spell here
|
// handle some immediate features of the spell here
|
||||||
HandleThreatSpells(m_spellInfo->Id);
|
HandleThreatSpells(m_spellInfo->Id);
|
||||||
|
|
||||||
|
PrepareTargetHitForScripts();
|
||||||
|
|
||||||
m_needSpellLog = IsNeedSendToClient();
|
m_needSpellLog = IsNeedSendToClient();
|
||||||
for (uint32 j = 0; j < 3; ++j)
|
for (uint32 j = 0; j < 3; ++j)
|
||||||
{
|
{
|
||||||
@@ -4667,17 +4677,22 @@ void Spell::HandleEffects(Unit *pUnitTarget,Item *pItemTarget,GameObject *pGOTar
|
|||||||
//we do not need DamageMultiplier here.
|
//we do not need DamageMultiplier here.
|
||||||
damage = CalculateDamage(i, NULL);
|
damage = CalculateDamage(i, NULL);
|
||||||
|
|
||||||
|
// execute script effect handler hooks and check if effects was prevented
|
||||||
|
bool preventDefault = false;
|
||||||
for(std::list<SpellScript *>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end() ; ++scritr)
|
for(std::list<SpellScript *>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end() ; ++scritr)
|
||||||
{
|
{
|
||||||
std::list<SpellScript::EffectHandler>::iterator effEndItr = (*scritr)->EffectHandlers.end(), effItr = (*scritr)->EffectHandlers.begin();
|
std::list<SpellScript::EffectHandler>::iterator effEndItr = (*scritr)->EffectHandlers.end(), effItr = (*scritr)->EffectHandlers.begin();
|
||||||
for(; effItr != effEndItr ; ++effItr)
|
for(; effItr != effEndItr ; ++effItr)
|
||||||
{
|
{
|
||||||
if ((*effItr).IsEffectAffected(m_spellInfo, i))
|
// effect execution can be prevented
|
||||||
|
if (!(*scritr)->_IsEffectPrevented((SpellEffIndex)i) && (*effItr).IsEffectAffected(m_spellInfo, i))
|
||||||
(*effItr).Call(*scritr, (SpellEffIndex)i);
|
(*effItr).Call(*scritr, (SpellEffIndex)i);
|
||||||
}
|
}
|
||||||
|
if (!preventDefault)
|
||||||
|
preventDefault = (*scritr)->_IsDefaultEffectPrevented((SpellEffIndex)i);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (eff < TOTAL_SPELL_EFFECTS)
|
if (!preventDefault && eff < TOTAL_SPELL_EFFECTS)
|
||||||
{
|
{
|
||||||
(this->*SpellEffects[eff])(i);
|
(this->*SpellEffects[eff])(i);
|
||||||
}
|
}
|
||||||
@@ -7290,3 +7305,11 @@ void Spell::LoadScripts()
|
|||||||
++itr;
|
++itr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Spell::PrepareTargetHitForScripts()
|
||||||
|
{
|
||||||
|
for(std::list<SpellScript *>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end() ; ++scritr)
|
||||||
|
{
|
||||||
|
(*scritr)->_InitHit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -672,6 +672,7 @@ class Spell
|
|||||||
|
|
||||||
// Scripting system
|
// Scripting system
|
||||||
void LoadScripts();
|
void LoadScripts();
|
||||||
|
void PrepareTargetHitForScripts();
|
||||||
std::list<SpellScript *> m_loadedScripts;
|
std::list<SpellScript *> m_loadedScripts;
|
||||||
|
|
||||||
// effect helpers
|
// effect helpers
|
||||||
|
|||||||
@@ -3856,15 +3856,16 @@ void SpellMgr::LoadSpellCustomAttr()
|
|||||||
case 18500: // Wing Buffet
|
case 18500: // Wing Buffet
|
||||||
case 33086: // Wild Bite
|
case 33086: // Wild Bite
|
||||||
case 49749: // Piercing Blow
|
case 49749: // Piercing Blow
|
||||||
|
case 52890: // Penetrating Strike
|
||||||
case 53454: // Impale
|
case 53454: // Impale
|
||||||
case 59446: // Impale
|
case 59446: // Impale
|
||||||
case 62383: // Shatter
|
case 62383: // Shatter
|
||||||
case 64777: // Machine Gun
|
case 64777: // Machine Gun
|
||||||
case 65239: // Machine Gun
|
case 65239: // Machine Gun
|
||||||
case 65919: // Pursuing Spikes
|
case 65919: // Impale
|
||||||
case 67858: // Pursuing Spikes
|
case 67858: // Impale
|
||||||
case 67859: // Pursuing Spikes
|
case 67859: // Impale
|
||||||
case 67860: // Pursuing Spikes
|
case 67860: // Impale
|
||||||
case 69293: // Wing Buffet
|
case 69293: // Wing Buffet
|
||||||
case 74439: // Machine Gun
|
case 74439: // Machine Gun
|
||||||
mSpellCustomAttr[i] |= SPELL_ATTR_CU_IGNORE_ARMOR;
|
mSpellCustomAttr[i] |= SPELL_ATTR_CU_IGNORE_ARMOR;
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include "SpellScript.h"
|
#include "SpellScript.h"
|
||||||
#include "Spell.h"
|
#include "Spell.h"
|
||||||
|
#include "SpellAuras.h"
|
||||||
|
|
||||||
bool _SpellScript::_Validate(SpellEntry const * entry, const char * scriptname)
|
bool _SpellScript::_Validate(SpellEntry const * entry, const char * scriptname)
|
||||||
{
|
{
|
||||||
@@ -164,6 +165,12 @@ bool SpellScript::_Load(Spell * spell)
|
|||||||
return Load();
|
return Load();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SpellScript::_InitHit()
|
||||||
|
{
|
||||||
|
m_hitPreventEffectMask = 0;
|
||||||
|
m_hitPreventDefaultEffectMask = 0;
|
||||||
|
}
|
||||||
|
|
||||||
Unit * SpellScript::GetCaster()
|
Unit * SpellScript::GetCaster()
|
||||||
{
|
{
|
||||||
return m_spell->GetCaster();
|
return m_spell->GetCaster();
|
||||||
@@ -237,6 +244,32 @@ void SpellScript::SetHitHeal(int32 heal)
|
|||||||
m_spell->m_healing = heal;
|
m_spell->m_healing = heal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Aura* SpellScript::GetHitAura()
|
||||||
|
{
|
||||||
|
if (!m_spell->m_spellAura)
|
||||||
|
return NULL;
|
||||||
|
if (m_spell->m_spellAura->IsRemoved())
|
||||||
|
return NULL;
|
||||||
|
return m_spell->m_spellAura;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpellScript::PreventHitAura()
|
||||||
|
{
|
||||||
|
if (m_spell->m_spellAura)
|
||||||
|
m_spell->m_spellAura->Remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpellScript::PreventHitEffect(SpellEffIndex effIndex)
|
||||||
|
{
|
||||||
|
m_hitPreventEffectMask |= 1 << effIndex;
|
||||||
|
PreventHitDefaultEffect(effIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpellScript::PreventHitDefaultEffect(SpellEffIndex effIndex)
|
||||||
|
{
|
||||||
|
m_hitPreventDefaultEffectMask |= 1 << effIndex;
|
||||||
|
}
|
||||||
|
|
||||||
int32 SpellScript::GetEffectValue()
|
int32 SpellScript::GetEffectValue()
|
||||||
{
|
{
|
||||||
return m_spell->damage;
|
return m_spell->damage;
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ class Unit;
|
|||||||
struct SpellEntry;
|
struct SpellEntry;
|
||||||
class SpellScript;
|
class SpellScript;
|
||||||
class Spell;
|
class Spell;
|
||||||
|
class Aura;
|
||||||
class Creature;
|
class Creature;
|
||||||
class GameObject;
|
class GameObject;
|
||||||
class Player;
|
class Player;
|
||||||
@@ -110,8 +111,13 @@ class SpellScript : public _SpellScript
|
|||||||
public:
|
public:
|
||||||
bool _Validate(SpellEntry const * entry, const char * scriptname);
|
bool _Validate(SpellEntry const * entry, const char * scriptname);
|
||||||
bool _Load(Spell * spell);
|
bool _Load(Spell * spell);
|
||||||
|
void _InitHit();
|
||||||
|
bool _IsEffectPrevented(SpellEffIndex effIndex) {return m_hitPreventEffectMask & (1<<effIndex);};
|
||||||
|
bool _IsDefaultEffectPrevented(SpellEffIndex effIndex) {return m_hitPreventDefaultEffectMask & (1<<effIndex);};
|
||||||
private:
|
private:
|
||||||
Spell * m_spell;
|
Spell * m_spell;
|
||||||
|
uint8 m_hitPreventEffectMask;
|
||||||
|
uint8 m_hitPreventDefaultEffectMask;
|
||||||
public:
|
public:
|
||||||
//
|
//
|
||||||
// SpellScript interface
|
// SpellScript interface
|
||||||
@@ -149,9 +155,27 @@ class SpellScript : public _SpellScript
|
|||||||
// setter/getter for for damage done by spell to target of spell hit
|
// setter/getter for for damage done by spell to target of spell hit
|
||||||
int32 GetHitDamage();
|
int32 GetHitDamage();
|
||||||
void SetHitDamage(int32 damage);
|
void SetHitDamage(int32 damage);
|
||||||
|
void PreventHitDamage() { SetHitDamage(0); };
|
||||||
// setter/getter for for heal done by spell to target of spell hit
|
// setter/getter for for heal done by spell to target of spell hit
|
||||||
int32 GetHitHeal();
|
int32 GetHitHeal();
|
||||||
void SetHitHeal(int32 heal);
|
void SetHitHeal(int32 heal);
|
||||||
|
void PreventHitHeal() { SetHitHeal(0); };
|
||||||
|
|
||||||
|
// returns current spell hit target aura
|
||||||
|
Aura * GetHitAura();
|
||||||
|
// prevents applying aura on current spell hit target
|
||||||
|
void PreventHitAura();
|
||||||
|
|
||||||
|
// prevents effect execution on current spell hit target
|
||||||
|
// including other effect/hit scripts
|
||||||
|
// will not work on aura/damage/heal
|
||||||
|
// will not work if effects were already handled
|
||||||
|
void PreventHitEffect(SpellEffIndex effIndex);
|
||||||
|
|
||||||
|
// prevents default effect execution on current spell hit target
|
||||||
|
// will not work on aura/damage/heal effects
|
||||||
|
// will not work if effects were already handled
|
||||||
|
void PreventHitDefaultEffect(SpellEffIndex effIndex);
|
||||||
|
|
||||||
// method avalible only in EffectHandler method
|
// method avalible only in EffectHandler method
|
||||||
int32 GetEffectValue();
|
int32 GetEffectValue();
|
||||||
|
|||||||
Reference in New Issue
Block a user