diff options
author | QAston <none@none> | 2009-06-06 08:27:36 +0200 |
---|---|---|
committer | QAston <none@none> | 2009-06-06 08:27:36 +0200 |
commit | 39548d6822ce2a8cea49e4467f8329335aa0d85d (patch) | |
tree | ca1055ea31b1b8b994c693ab713626a3d00c405c /src/game/Spell.cpp | |
parent | 00582cf9d4bebbf812f2cccb14be8dce288c2f07 (diff) |
*Update spellmod system
*Implement SPELL_ATTR_EX6_IGNORE_CASTER_AURAS
*Fix some bugs with traps proc flags
--HG--
branch : trunk
Diffstat (limited to 'src/game/Spell.cpp')
-rw-r--r-- | src/game/Spell.cpp | 111 |
1 files changed, 76 insertions, 35 deletions
diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index a7e7212f9e9..f7fb0137c78 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -733,32 +733,6 @@ void Spell::prepareDataForTriggerSystem(AuraEffect * triggeredByAura) // Create base triggers flags for Attacker and Victim ( m_procAttacker, m_procVictim and m_procEx) //========================================================================================== - /* - Effects which are result of aura proc from triggered spell cannot proc - to prevent chain proc of these spells - */ - - if (triggeredByAura && !triggeredByAura->GetParentAura()->GetTarget()->CanProc()) - { - m_canTrigger=false; - } - - m_procEx = (m_IsTriggeredSpell) - && !(m_spellInfo->AttributesEx2 & SPELL_ATTR_EX2_TRIGGERED_CAN_TRIGGER) - && !(m_spellInfo->AttributesEx3 & SPELL_ATTR_EX3_TRIGGERED_CAN_TRIGGER_2) - ? PROC_EX_INTERNAL_TRIGGERED : PROC_EX_NONE; - - if (m_IsTriggeredSpell && - (m_spellInfo->AttributesEx2 & SPELL_ATTR_EX2_TRIGGERED_CAN_TRIGGER || - m_spellInfo->AttributesEx3 & SPELL_ATTR_EX3_TRIGGERED_CAN_TRIGGER_2)) - m_procEx |= PROC_EX_INTERNAL_CANT_PROC; - - // Totem casts require spellfamilymask defined in spell_proc_event to proc - if (m_originalCaster && m_caster != m_originalCaster && m_caster->GetTypeId()==TYPEID_UNIT && ((Creature*)m_caster)->isTotem() && m_caster->IsControlledByPlayer()) - { - m_procEx |= PROC_EX_INTERNAL_REQ_FAMILY; - } - // Get data for type of attack and fill base info for trigger switch (m_spellInfo->DmgClass) { @@ -797,10 +771,36 @@ void Spell::prepareDataForTriggerSystem(AuraEffect * triggeredByAura) } break; } + m_procEx= PROC_EX_NONE; + // Hunter traps spells (for Entrapment trigger) // Gives your Immolation Trap, Frost Trap, Explosive Trap, and Snake Trap .... if (m_spellInfo->SpellFamilyName == SPELLFAMILY_HUNTER && (m_spellInfo->SpellFamilyFlags[1] & 0x00002000 || m_spellInfo->SpellFamilyFlags[0] & 0x1C)) - m_procAttacker |= PROC_FLAG_ON_TRAP_ACTIVATION; + { + m_procAttacker = PROC_FLAG_ON_TRAP_ACTIVATION; + } + else + { + /* + Effects which are result of aura proc from triggered spell cannot proc + to prevent chain proc of these spells + */ + if (triggeredByAura && !triggeredByAura->GetParentAura()->GetTarget()->CanProc()) + { + m_canTrigger=false; + } + + if (m_IsTriggeredSpell && + (m_spellInfo->AttributesEx2 & SPELL_ATTR_EX2_TRIGGERED_CAN_TRIGGER || + m_spellInfo->AttributesEx3 & SPELL_ATTR_EX3_TRIGGERED_CAN_TRIGGER_2)) + m_procEx |= PROC_EX_INTERNAL_CANT_PROC | PROC_EX_INTERNAL_TRIGGERED; + + // Totem casts require spellfamilymask defined in spell_proc_event to proc + if (m_originalCaster && m_caster != m_originalCaster && m_caster->GetTypeId()==TYPEID_UNIT && ((Creature*)m_caster)->isTotem() && m_caster->IsControlledByPlayer()) + { + m_procEx |= PROC_EX_INTERNAL_REQ_FAMILY; + } + } } void Spell::CleanupTargetList() @@ -2514,6 +2514,12 @@ void Spell::cancel() SendChannelUpdate(0); SendInterrupted(0); SendCastResult(SPELL_FAILED_INTERRUPTED); + + // spell is canceled-take mods and clear list + if (m_caster->GetTypeId() == TYPEID_PLAYER) + ((Player*)m_caster)->RemoveSpellMods(this); + + m_appliedMods.clear(); } break; default: @@ -2548,6 +2554,12 @@ void Spell::cast(bool skipCheck) if(m_caster->GetTypeId() != TYPEID_PLAYER && m_targets.getUnitTarget() && m_targets.getUnitTarget() != m_caster) m_caster->SetInFront(m_targets.getUnitTarget()); + // Should this be done for original caster? + if (m_caster->GetTypeId()==TYPEID_PLAYER) + { + // Set spell which will drop charges for triggered cast spells + ((Player*)m_caster)->SetSpellModTakingSpell(this, true); + } // triggered cast called from Spell::prepare where it was already checked if(!m_IsTriggeredSpell || !skipCheck) @@ -2673,6 +2685,9 @@ void Spell::cast(bool skipCheck) m_caster->CastSpell(m_targets.getUnitTarget() ? m_targets.getUnitTarget() : m_caster, *i, true); } + if (m_caster->GetTypeId()==TYPEID_PLAYER) + ((Player*)m_caster)->SetSpellModTakingSpell(this, false); + SetExecutedCurrently(false); } @@ -2717,6 +2732,10 @@ void Spell::handle_immediate() uint64 Spell::handle_delayed(uint64 t_offset) { UpdatePointers(); + + if (m_caster->GetTypeId()==TYPEID_PLAYER) + ((Player*)m_caster)->SetSpellModTakingSpell(this, true); + uint64 next_time = 0; if (!m_immediateHandled) @@ -2750,6 +2769,7 @@ uint64 Spell::handle_delayed(uint64 t_offset) next_time = ighit->timeDelay; } } + // All targets passed - need finish phase if (next_time == 0) { @@ -2763,6 +2783,9 @@ uint64 Spell::handle_delayed(uint64 t_offset) } else { + if (m_caster->GetTypeId()==TYPEID_PLAYER) + ((Player*)m_caster)->SetSpellModTakingSpell(this, false); + // spell is unfinished, return next execution time return next_time; } @@ -2996,7 +3019,12 @@ void Spell::finish(bool ok) { //restore spell mods if (m_caster->GetTypeId() == TYPEID_PLAYER) + { ((Player*)m_caster)->RestoreSpellMods(this); + // cleanup after mod system + // triggered spell pointer can be not removed in some cases + ((Player*)m_caster)->SetSpellModTakingSpell(this, false); + } return; } @@ -3013,10 +3041,6 @@ void Spell::finish(bool ok) } } - //remove spell mods - if (m_caster->GetTypeId() == TYPEID_PLAYER) - ((Player*)m_caster)->RemoveSpellMods(this); - // Okay to remove extra attacks if(IsSpellHaveEffect(m_spellInfo, SPELL_EFFECT_ADD_EXTRA_ATTACKS)) m_caster->m_extraAttacks = 0; @@ -3036,13 +3060,27 @@ void Spell::finish(bool ok) // potions disabled by client, send event "not in combat" if need if (!m_triggeredByAuraSpell && m_caster->GetTypeId() == TYPEID_PLAYER) + { ((Player*)m_caster)->UpdatePotionCooldown(this); + // triggered spell pointer can be not set in some cases + // this is needed for proper apply of triggered spell mods + ((Player*)m_caster)->SetSpellModTakingSpell(this, true); + } + // call triggered spell only at successful cast (after clear combo points -> for add some if need) // I assume what he means is that some triggered spells may add combo points if(!m_TriggerSpells.empty()) TriggerSpell(); + // Take mods after trigger spell (needed for 14177 to affect 48664) + // mods are taken only on succesfull cast and independantly from targets of the spell + if (m_caster->GetTypeId() == TYPEID_PLAYER) + { + ((Player*)m_caster)->RemoveSpellMods(this); + ((Player*)m_caster)->SetSpellModTakingSpell(this, false); + } + // Stop Attack for some spells if( m_spellInfo->Attributes & SPELL_ATTR_STOP_ATTACK_TARGET ) m_caster->AttackStop(); @@ -4797,10 +4835,8 @@ SpellCastResult Spell::CheckPetCast(Unit* target) SpellCastResult Spell::CheckCasterAuras() const { - // Flag drop spells totally immuned to caster auras - // FIXME: find more nice check for all totally immuned spells - // AttributesEx3 & 0x10000000? - if(m_spellInfo->Id == 23336 || m_spellInfo->Id == 23334 || m_spellInfo->Id == 34991) + // spells totally immuned to caster auras ( wsg flag drop, give marks etc + if(m_spellInfo->AttributesEx6& SPELL_ATTR_EX6_IGNORE_CASTER_AURAS) return SPELL_CAST_OK; uint8 school_immune = 0; @@ -5863,8 +5899,13 @@ bool SpellEvent::Execute(uint64 e_time, uint32 p_time) } else { + // Set last not triggered spell for apply spellmods + ((Player*)m_Spell->GetCaster())->SetSpellModTakingSpell(m_Spell, true); // do the action (pass spell to channeling state) m_Spell->handle_immediate(); + + // And remove after effect handling + ((Player*)m_Spell->GetCaster())->SetSpellModTakingSpell(m_Spell, false); } // event will be re-added automatically at the end of routine) } |