diff options
author | megamage <none@none> | 2009-05-17 16:40:40 -0500 |
---|---|---|
committer | megamage <none@none> | 2009-05-17 16:40:40 -0500 |
commit | 1c134f81e38137bbfb1c6925a3a42d9628571d4c (patch) | |
tree | 479972a69d9badeffab98d51e8c19178afb99ec1 /src | |
parent | b95e67375c00e7e24609450178c4f7ba44064441 (diff) | |
parent | 7c6757d7ee652c8e688caa5c6856d116c1f034c1 (diff) |
*Merge.
--HG--
branch : trunk
Diffstat (limited to 'src')
-rw-r--r-- | src/game/AggressorAI.cpp | 2 | ||||
-rw-r--r-- | src/game/Spell.cpp | 42 | ||||
-rw-r--r-- | src/game/Spell.h | 6 | ||||
-rw-r--r-- | src/game/SpellAuras.cpp | 26 | ||||
-rw-r--r-- | src/game/SpellAuras.h | 7 | ||||
-rw-r--r-- | src/game/SpellMgr.cpp | 9 | ||||
-rw-r--r-- | src/game/SpellMgr.h | 5 | ||||
-rw-r--r-- | src/game/Unit.cpp | 30 | ||||
-rw-r--r-- | src/game/Unit.h | 1 |
9 files changed, 83 insertions, 45 deletions
diff --git a/src/game/AggressorAI.cpp b/src/game/AggressorAI.cpp index 22ebe87cdc6..218f19a1c21 100644 --- a/src/game/AggressorAI.cpp +++ b/src/game/AggressorAI.cpp @@ -67,7 +67,7 @@ void SpellAI::EnterCombat(Unit *who) for(SpellVct::iterator i = spells.begin(); i != spells.end(); ++i) { if(AISpellInfo[*i].condition == AICOND_AGGRO) - me->CastSpell(who, *i, true); + me->CastSpell(who, *i, false); else if(AISpellInfo[*i].condition == AICOND_COMBAT) events.ScheduleEvent(*i, AISpellInfo[*i].cooldown + rand()%AISpellInfo[*i].cooldown); } diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index 7e94e86ab4d..33a3e4e1599 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -364,6 +364,8 @@ Spell::Spell( Unit* Caster, SpellEntry const *info, bool triggered, uint64 origi m_delayStart = 0; m_delayAtDamageCount = 0; + m_canTrigger=true; + m_applyMultiplierMask = 0; m_effectMask = 0; @@ -723,14 +725,38 @@ void Spell::FillTargetMap() } } -void Spell::prepareDataForTriggerSystem() +void Spell::prepareDataForTriggerSystem(AuraEffect * triggeredByAura) { //========================================================================================== // Now fill data for trigger system, need know: - // an spell trigger another or not ( m_canTrigger ) - // Create base triggers flags for Attacker and Victim ( m_procAttacker and m_procVictim) + // can spell trigger another or not ( m_canTrigger ) + // 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()->CanProc()) + { + m_canTrigger=false; + } + + m_procEx = (m_IsTriggeredSpell) + && !(m_spellInfo->AttributesEx2 & SPELL_ATTR_EX2_TRIGGERED_CAN_TRIGGER) + && !(m_spellInfo->AttributesEx2 & SPELL_ATTR_EX2_TRIGGERED_CAN_TRIGGER_2) + ? PROC_EX_INTERNAL_TRIGGERED : PROC_EX_NONE; + + if (m_IsTriggeredSpell && (m_spellInfo->AttributesEx2 & SPELL_ATTR_EX2_TRIGGERED_CAN_TRIGGER_2 | SPELL_ATTR_EX2_TRIGGERED_CAN_TRIGGER)) + 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) { @@ -973,15 +999,13 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target) // Fill base trigger info uint32 procAttacker = m_procAttacker; uint32 procVictim = m_procVictim; - uint32 procEx = m_triggeredByAuraSpell - && !(m_spellInfo->AttributesEx2 & SPELL_ATTR_EX2_TRIGGERED_CAN_TRIGGER) - && !(m_spellInfo->AttributesEx2 & SPELL_ATTR_EX2_TRIGGERED_CAN_TRIGGER_2) - ? PROC_EX_INTERNAL_TRIGGERED : PROC_EX_NONE; + uint32 procEx = m_procEx; + m_spellAura = NULL; // Set aura to null for every target-make sure that pointer is not used for unit without aura applied //Spells with this flag cannot trigger if effect is casted on self // Slice and Dice, relentless strikes, eviscerate - bool canEffectTrigger = (m_spellInfo->AttributesEx4 & (SPELL_ATTR_EX4_CANT_PROC_FROM_SELFCAST | SPELL_ATTR_EX4_UNK4) ? m_caster!=unitTarget : true); + bool canEffectTrigger = m_canTrigger && (m_spellInfo->AttributesEx4 & (SPELL_ATTR_EX4_CANT_PROC_FROM_SELFCAST | SPELL_ATTR_EX4_UNK4) ? m_caster!=unitTarget : true); Unit * spellHitTarget = NULL; if (missInfo==SPELL_MISS_NONE) // In case spell hit target, do all effect on that target @@ -2327,7 +2351,7 @@ void Spell::prepare(SpellCastTargets const* targets, AuraEffect* triggeredByAura } // Prepare data for triggers - prepareDataForTriggerSystem(); + prepareDataForTriggerSystem(triggeredByAura); // Set combo point requirement if (m_IsTriggeredSpell || m_CastItem || m_caster->GetTypeId()!=TYPEID_PLAYER) diff --git a/src/game/Spell.h b/src/game/Spell.h index 083bb338371..99017742e2f 100644 --- a/src/game/Spell.h +++ b/src/game/Spell.h @@ -458,7 +458,7 @@ class Spell bool IsDeletable() const { return !m_referencedFromCurrentSpell && !m_executedCurrently; } void SetReferencedFromCurrent(bool yes) { m_referencedFromCurrentSpell = yes; } bool IsInterruptable() const { return !m_executedCurrently; } - void SetExecutedCurrently(bool yes) { m_executedCurrently = yes; } + void SetExecutedCurrently(bool yes) {m_executedCurrently = yes;} uint64 GetDelayStart() const { return m_delayStart; } void SetDelayStart(uint64 m_time) { m_delayStart = m_time; } uint64 GetDelayMoment() const { return m_delayMoment; } @@ -552,7 +552,9 @@ class Spell //****************************************** uint32 m_procAttacker; // Attacker trigger flags uint32 m_procVictim; // Victim trigger flags - void prepareDataForTriggerSystem(); + uint32 m_procEx; + bool m_canTrigger; + void prepareDataForTriggerSystem(AuraEffect * triggeredByAura); //***************************************** // Spell target subsystem diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index 8867522e549..6ca43844c76 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -346,7 +346,7 @@ pAuraHandler AuraHandler[TOTAL_AURAS]= Aura::Aura(SpellEntry const* spellproto, uint32 effMask, int32 *currentBasePoints, Unit *target, Unit *caster, Item* castItem, Unit * formalCaster) : m_caster_guid(0), m_castItemGuid(castItem?castItem->GetGUID():0), m_target(target), m_timeCla(1000), m_removeMode(AURA_REMOVE_BY_DEFAULT), m_AuraDRGroup(DIMINISHING_NONE), -m_auraSlot(MAX_AURAS), m_auraLevel(1), m_procCharges(0), m_stackAmount(1),m_auraStateMask(0), m_updated(false), m_isRemoved(false) +m_auraSlot(MAX_AURAS), m_auraLevel(1), m_procCharges(0), m_stackAmount(1),m_auraStateMask(0), m_updated(false), m_isRemoved(false), m_canProc(true) { assert(target); @@ -613,6 +613,8 @@ Unit* AreaAuraEffect::GetFormalCaster() const void Aura::Update(uint32 diff) { + // Reset can proc requirement-prevent use of outdated value + m_canProc = true; if (m_duration > 0) { m_duration -= diff; @@ -1837,7 +1839,7 @@ void AuraEffect::TriggerSpell() // Doom case 31347: { - m_target->CastSpell(m_target,31350,true); + m_target->CastSpell(m_target,31350,true, NULL, this); m_target->DealDamage(m_target, m_target->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); return; } @@ -1867,9 +1869,9 @@ void AuraEffect::TriggerSpell() { // cast 24 spells 34269-34289, 34314-34316 for(uint32 spell_id = 34269; spell_id != 34290; ++spell_id) - caster->CastSpell(m_target,spell_id,true); + caster->CastSpell(m_target,spell_id,true, NULL, this); for(uint32 spell_id = 34314; spell_id != 34317; ++spell_id) - caster->CastSpell(m_target,spell_id,true); + caster->CastSpell(m_target,spell_id,true, NULL, this); return; } // // Gravity Lapse @@ -1951,7 +1953,7 @@ void AuraEffect::TriggerSpell() // Eye of Grillok case 38495: { - m_target->CastSpell(m_target, 38530, true); + m_target->CastSpell(m_target, 38530, true, NULL, this); return; } // Absorb Eye of Grillok (Zezzak's Shard) @@ -1960,7 +1962,7 @@ void AuraEffect::TriggerSpell() if(m_target->GetTypeId() != TYPEID_UNIT) return; - caster->CastSpell(caster, 38495, true); + caster->CastSpell(caster, 38495, true, NULL, this); Creature* creatureTarget = (Creature*)m_target; @@ -2198,7 +2200,7 @@ void AuraEffect::TriggerSpell() } if(all) - caster->CastSpell(caster,38437,true); + caster->CastSpell(caster,38437,true, NULL, this); else caster->RemoveAurasDueToSpell(38437); return; @@ -2278,7 +2280,7 @@ void AuraEffect::TriggerSpell() // Curse of the Plaguebringer (22/15) case 29213: case 54835: - caster->CastSpell(m_target, trigger_spell_id, true); + caster->CastSpell(m_target, trigger_spell_id, true, NULL, this); return; } } @@ -4244,10 +4246,10 @@ void AuraEffect::HandleModMechanicImmunity(bool apply, bool Real, bool /*changeA { if(apply) { - m_target->CastSpell(m_target,24395,true); - m_target->CastSpell(m_target,24396,true); - m_target->CastSpell(m_target,24397,true); - m_target->CastSpell(m_target,26592,true); + m_target->CastSpell(m_target,24395,true, NULL, this); + m_target->CastSpell(m_target,24396,true, NULL, this); + m_target->CastSpell(m_target,24397,true, NULL, this); + m_target->CastSpell(m_target,26592,true, NULL, this); } else { diff --git a/src/game/SpellAuras.h b/src/game/SpellAuras.h index b4d7eefb706..fc0b42f58bf 100644 --- a/src/game/SpellAuras.h +++ b/src/game/SpellAuras.h @@ -107,6 +107,8 @@ class TRINITY_DLL_SPEC Aura bool IsRemoved() const { return m_isRemoved; } void SetUpdated(bool val) { m_updated = val; } + bool CanProc(){return m_canProc;} + void SetCanProc(bool val){ m_canProc = val; } bool IsPersistent() const; bool IsAreaAura() const; bool IsAuraType(AuraType type) const; @@ -152,11 +154,13 @@ class TRINITY_DLL_SPEC Aura uint8 m_auraFlags; // Aura info flag (for send data to client) uint8 m_auraLevel; // Aura level (store caster level for correct show level dep amount) uint8 m_procCharges; // Aura charges (0 for infinite) - uint32 m_procDamage; // used in aura proc code uint8 m_stackAmount; // Aura stack amount uint32 m_auraStateMask; AuraEffect * m_partAuras[3]; + uint32 m_procDamage; // used in aura proc code + bool m_canProc:1; + bool m_isDeathPersist:1; bool m_isRemovedOnShapeLost:1; bool m_isPassive:1; @@ -396,6 +400,7 @@ class TRINITY_DLL_SPEC AreaAuraEffect : public AuraEffect AreaAuraEffect(Aura * parentAura, uint32 effIndex, int32 * currentBasePoints, Unit * caster=NULL, Item * castItem=NULL, Unit * formalCaster=NULL); ~AreaAuraEffect(); Unit* GetFormalCaster() const; + uint64 const& GetFormalCasterGUID() const { return m_formalCasterGUID; } void Update(uint32 diff); private: float m_radius; diff --git a/src/game/SpellMgr.cpp b/src/game/SpellMgr.cpp index a960942579e..c7bf8cd5bac 100644 --- a/src/game/SpellMgr.cpp +++ b/src/game/SpellMgr.cpp @@ -1222,6 +1222,8 @@ bool SpellMgr::IsSpellProcEventCanTriggeredBy(SpellProcEventEntry const* spellPr if((procFlags & EventProcFlag) == 0) return false; + bool hasFamilyMask = false; + /* Check Periodic Auras * Both hots and dots can trigger if spell has no PROC_FLAG_SUCCESSFUL_POSITIVE_SPELL @@ -1288,10 +1290,17 @@ bool SpellMgr::IsSpellProcEventCanTriggeredBy(SpellProcEventEntry const* spellPr if ((spellProcEvent->spellFamilyMask & procSpell->SpellFamilyFlags ) == 0) return false; active = true; // Spell added manualy -> so its active spell + hasFamilyMask = true; } } } + if (procExtra & PROC_EX_INTERNAL_REQ_FAMILY) + { + if (!hasFamilyMask) + return false; + } + // Check for extra req (if none) and hit/crit if (procEvent_procEx == PROC_EX_NONE) { diff --git a/src/game/SpellMgr.h b/src/game/SpellMgr.h index 1848cf03805..4427e4c6abb 100644 --- a/src/game/SpellMgr.h +++ b/src/game/SpellMgr.h @@ -467,11 +467,12 @@ enum ProcFlagsEx PROC_EX_AURA_REMOVE_DESTROY = 0x0002000, // aura absorb destroy or dispel PROC_EX_AURA_REMOVE_EXPIRE = 0x0004000, // aura remove by default and by cancel PROC_EX_EX_TRIGGER_ALWAYS = 0x0010000, // If set trigger always ( no matter another flags) used for drop charges - PROC_EX_EX_ONE_TIME_TRIGGER = 0x0020000, // If set trigger always but only one time (not used) + PROC_EX_EX_ONE_TIME_TRIGGER = 0x0020000, // If set trigger always but only one time (not used) + PROC_EX_INTERNAL_CANT_PROC = 0x0800000, PROC_EX_INTERNAL_DOT = 0x1000000, // Only for internal use PROC_EX_INTERNAL_HOT = 0x2000000, // Only for internal use PROC_EX_INTERNAL_TRIGGERED = 0x4000000, // Only for internal use - PROC_EX_INTERNAL_ITEM_CAST = 0x8000000 + PROC_EX_INTERNAL_REQ_FAMILY = 0x8000000 // Only for internal use }; #define AURA_REMOVE_PROC_EX_MASK \ (PROC_EX_AURA_REMOVE_DESTROY | PROC_EX_AURA_REMOVE_EXPIRE) diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index a5e285f7149..8b7677e6d2f 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -1046,7 +1046,7 @@ void Unit::CastSpell(Unit* Victim,SpellEntry const *spellInfo, bool triggered, I return; } - if (!originalCaster && GetTypeId()==TYPEID_UNIT && ((Creature*)this)->isTotem()) + if (!originalCaster && GetTypeId()==TYPEID_UNIT && ((Creature*)this)->isTotem() && IsControlledByPlayer()) if (Unit * owner = GetOwner()) originalCaster=owner->GetGUID(); @@ -4236,7 +4236,7 @@ void Unit::RemoveAura(AuraMap::iterator &i, AuraRemoveMode mode) // Remove totem at next update if totem looses its aura if (GetTypeId()==TYPEID_UNIT && ((Creature*)this)->isTotem()&& ((TempSummon*)this)->GetSummonerGUID()==Aur->GetCasterGUID()) { - if (((Totem*)this)->GetSpell()==Aur->GetId()) + if (((Totem*)this)->GetSpell()==Aur->GetId() && ((Totem*)this)->GetTotemType()==TOTEM_PASSIVE) ((Totem*)this)->setDeathState(JUST_DIED); } @@ -5571,7 +5571,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, AuraEffect* trigger { if(!pVictim || !pVictim->isAlive()) return false; - pVictim->CastSpell(pVictim, 60946,true); + pVictim->CastSpell(pVictim, 60946,true, castItem, triggeredByAura); return true; } // Improved Fear (Rank 2) @@ -5579,7 +5579,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, AuraEffect* trigger { if(!pVictim || !pVictim->isAlive()) return false; - pVictim->CastSpell(pVictim, 60947,true); + pVictim->CastSpell(pVictim, 60947,true, castItem, triggeredByAura); return true; } // Shadowflame (Voidheart Raiment set bonus) @@ -5711,7 +5711,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, AuraEffect* trigger { if(!pVictim || !pVictim->isAlive()) return false; - pVictim->CastSpell(pVictim, 59980,true); + pVictim->CastSpell(pVictim, 59980,true, castItem, triggeredByAura); return true; } // Psychic Horror (Rank 2) @@ -5719,7 +5719,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, AuraEffect* trigger { if(!pVictim || !pVictim->isAlive()) return false; - pVictim->CastSpell(pVictim, 59981,true); + pVictim->CastSpell(pVictim, 59981,true, castItem, triggeredByAura); return true; } // Glyph of Dispel Magic @@ -6038,7 +6038,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, AuraEffect* trigger target = this; triggered_spell_id = 31930; // replenishment - CastSpell(this,57669,true); + CastSpell(this,57669,true, castItem, triggeredByAura); break; } // Sanctified Wrath @@ -6869,8 +6869,6 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, AuraEffect* trig // Set trigger spell id, target, custom basepoints uint32 trigger_spell_id = auraSpellInfo->EffectTriggerSpell[triggeredByAura->GetEffIndex()]; - if(procSpell && procSpell->Id == trigger_spell_id) - return false; Unit* target = NULL; int32 basepoints0 = 0; @@ -8502,8 +8500,6 @@ Unit* Unit::SelectMagnetTarget(Unit *victim, SpellEntry const *spellInfo) if(Unit* magnet = (*itr)->IsAreaAura() ? ((AreaAuraEffect*)(*itr))->GetFormalCaster():(*itr)->GetCaster() ) if(magnet->isAlive()) { - if (Aura * aur = magnet->GetAura((*itr)->GetId(),(*itr)->GetCasterGUID())) - aur->DropAuraCharge(); return magnet; } } @@ -12003,7 +11999,6 @@ void Unit::ProcDamageAndSpellFor( bool isVictim, Unit * pTarget, uint32 procFlag for(AuraMap::const_iterator itr = GetAuras().begin(); itr!= GetAuras().end(); ++itr) { ProcTriggeredData triggerData(itr->second); - if(!IsTriggeredAtSpellProcEvent(pTarget, triggerData.aura, procSpell, procFlag, procExtra, attType, isVictim, (damage > 0), triggerData.spellProcEvent)) continue; for (uint8 i=0; i<MAX_SPELL_EFFECTS;++i) @@ -12017,6 +12012,10 @@ void Unit::ProcDamageAndSpellFor( bool isVictim, Unit * pTarget, uint32 procFlag if (!isTriggerAura[aurEff->GetAuraName()] && triggerData.spellProcEvent==NULL) continue; triggerData.effMask |= 1<<i; + if (procExtra & (PROC_EX_INTERNAL_TRIGGERED | PROC_EX_INTERNAL_CANT_PROC)) + itr->second->SetCanProc(false); + else + itr->second->SetCanProc(true); } } if (triggerData.effMask) @@ -12832,11 +12831,6 @@ bool Unit::IsTriggeredAtSpellProcEvent(Unit *pVictim, Aura * aura, SpellEntry co if (!EventProcFlag) return false; - // Do not proc spells for totem if aura does not require family to proc - if (GetTypeId()==TYPEID_UNIT && ((Creature*)this)->isTotem() && ((Totem*)this)->IsControlledByPlayer()) - if (!spellProcEvent || !spellProcEvent->spellFamilyName) - return false; - // Additional checks for triggered spells if (procExtra & PROC_EX_INTERNAL_TRIGGERED) { @@ -13027,7 +13021,7 @@ void Unit::SetToNotify() void Unit::Kill(Unit *pVictim, bool durabilityLoss) { // Prevent killing unit twice (and giving reward from kill twice) - if (!pVictim->isAlive()) + if (!pVictim->GetHealth()) return; pVictim->SetHealth(0); diff --git a/src/game/Unit.h b/src/game/Unit.h index bbd7471b1b8..084dcd53789 100644 --- a/src/game/Unit.h +++ b/src/game/Unit.h @@ -1659,6 +1659,7 @@ class TRINITY_DLL_SPEC Unit : public WorldObject void _DeleteAuras(); void _UpdateAutoRepeatSpell(); + bool m_AutoRepeatFirstCast; uint32 m_attackTimer[MAX_ATTACK]; |