diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/server/game/Entities/Unit/Unit.cpp | 2 | ||||
| -rw-r--r-- | src/server/game/Spells/Spell.cpp | 27 | ||||
| -rw-r--r-- | src/server/game/Spells/Spell.h | 1 | ||||
| -rw-r--r-- | src/server/game/Spells/SpellMgr.cpp | 9 | ||||
| -rw-r--r-- | src/server/game/Spells/SpellScript.cpp | 33 | ||||
| -rw-r--r-- | src/server/game/Spells/SpellScript.h | 24 |
6 files changed, 89 insertions, 7 deletions
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 3cdb94ef86c..31dae14c4c1 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -1578,7 +1578,7 @@ bool Unit::IsDamageReducedByArmor(SpellSchoolMask schoolMask, SpellEntry const * // bleeding effects are not reduced by armor 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 true; diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 7d85b70d498..0972c84b3e5 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -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))) return SPELL_MISS_IMMUNE; + PrepareTargetHitForScripts(); + if (unit->GetTypeId() == TYPEID_PLAYER) { unit->ToPlayer()->GetAchievementMgr().StartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_SPELL_TARGET, m_spellInfo->Id); @@ -1639,6 +1641,8 @@ void Spell::DoAllEffectOnTarget(GOTargetInfo *target) if (!go) return; + PrepareTargetHitForScripts(); + for (uint32 effectNumber = 0; effectNumber < 3; ++effectNumber) if (effectMask & (1 << effectNumber)) HandleEffects(NULL, NULL, go, effectNumber); @@ -1658,6 +1662,8 @@ void Spell::DoAllEffectOnTarget(ItemTargetInfo *target) if (!target->item || !effectMask) return; + PrepareTargetHitForScripts(); + for (uint32 effectNumber = 0; effectNumber < 3; ++effectNumber) if (effectMask & (1 << effectNumber)) HandleEffects(NULL, target->item, NULL, effectNumber); @@ -3255,6 +3261,8 @@ void Spell::cast(bool skipCheck) // CAST SPELL SendSpellCooldown(); + PrepareTargetHitForScripts(); + for (uint32 i = 0; i < 3; ++i) { switch(m_spellInfo->Effect[i]) @@ -3419,6 +3427,8 @@ void Spell::_handle_immediate_phase() // handle some immediate features of the spell here HandleThreatSpells(m_spellInfo->Id); + PrepareTargetHitForScripts(); + m_needSpellLog = IsNeedSendToClient(); 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. 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) { std::list<SpellScript::EffectHandler>::iterator effEndItr = (*scritr)->EffectHandlers.end(), effItr = (*scritr)->EffectHandlers.begin(); 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); } + if (!preventDefault) + preventDefault = (*scritr)->_IsDefaultEffectPrevented((SpellEffIndex)i); } - if (eff < TOTAL_SPELL_EFFECTS) + if (!preventDefault && eff < TOTAL_SPELL_EFFECTS) { (this->*SpellEffects[eff])(i); } @@ -7290,3 +7305,11 @@ void Spell::LoadScripts() ++itr; } } + +void Spell::PrepareTargetHitForScripts() +{ + for(std::list<SpellScript *>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end() ; ++scritr) + { + (*scritr)->_InitHit(); + } +} diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h index bca77c647a7..7dd1ae3a9cd 100644 --- a/src/server/game/Spells/Spell.h +++ b/src/server/game/Spells/Spell.h @@ -672,6 +672,7 @@ class Spell // Scripting system void LoadScripts(); + void PrepareTargetHitForScripts(); std::list<SpellScript *> m_loadedScripts; // effect helpers diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index 08d5b673366..43599c40ca2 100644 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -3856,15 +3856,16 @@ void SpellMgr::LoadSpellCustomAttr() case 18500: // Wing Buffet case 33086: // Wild Bite case 49749: // Piercing Blow + case 52890: // Penetrating Strike case 53454: // Impale case 59446: // Impale case 62383: // Shatter case 64777: // Machine Gun case 65239: // Machine Gun - case 65919: // Pursuing Spikes - case 67858: // Pursuing Spikes - case 67859: // Pursuing Spikes - case 67860: // Pursuing Spikes + case 65919: // Impale + case 67858: // Impale + case 67859: // Impale + case 67860: // Impale case 69293: // Wing Buffet case 74439: // Machine Gun mSpellCustomAttr[i] |= SPELL_ATTR_CU_IGNORE_ARMOR; diff --git a/src/server/game/Spells/SpellScript.cpp b/src/server/game/Spells/SpellScript.cpp index 4e4557801b9..3e8894bae00 100644 --- a/src/server/game/Spells/SpellScript.cpp +++ b/src/server/game/Spells/SpellScript.cpp @@ -19,6 +19,7 @@ #include <string> #include "SpellScript.h" #include "Spell.h" +#include "SpellAuras.h" bool _SpellScript::_Validate(SpellEntry const * entry, const char * scriptname) { @@ -164,6 +165,12 @@ bool SpellScript::_Load(Spell * spell) return Load(); } +void SpellScript::_InitHit() +{ + m_hitPreventEffectMask = 0; + m_hitPreventDefaultEffectMask = 0; +} + Unit * SpellScript::GetCaster() { return m_spell->GetCaster(); @@ -237,6 +244,32 @@ void SpellScript::SetHitHeal(int32 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() { return m_spell->damage; diff --git a/src/server/game/Spells/SpellScript.h b/src/server/game/Spells/SpellScript.h index 090318f696d..fae3dfcbd58 100644 --- a/src/server/game/Spells/SpellScript.h +++ b/src/server/game/Spells/SpellScript.h @@ -26,6 +26,7 @@ class Unit; struct SpellEntry; class SpellScript; class Spell; +class Aura; class Creature; class GameObject; class Player; @@ -110,8 +111,13 @@ class SpellScript : public _SpellScript public: bool _Validate(SpellEntry const * entry, const char * scriptname); 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: Spell * m_spell; + uint8 m_hitPreventEffectMask; + uint8 m_hitPreventDefaultEffectMask; public: // // SpellScript interface @@ -149,9 +155,27 @@ class SpellScript : public _SpellScript // setter/getter for for damage done by spell to target of spell hit int32 GetHitDamage(); void SetHitDamage(int32 damage); + void PreventHitDamage() { SetHitDamage(0); }; // setter/getter for for heal done by spell to target of spell hit int32 GetHitHeal(); 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 int32 GetEffectValue(); |
