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:
QAston
2010-08-19 14:31:31 +02:00
parent d4605c5f7f
commit 30bcf8c659
6 changed files with 89 additions and 7 deletions
+1 -1
View File
@@ -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;
+25 -2
View File
@@ -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();
}
}
+1
View File
@@ -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
+5 -4
View File
@@ -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;
+33
View File
@@ -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;
+24
View File
@@ -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();