diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/game/Spell.cpp | 70 | ||||
-rw-r--r-- | src/game/SpellMgr.cpp | 7 | ||||
-rw-r--r-- | src/game/SpellMgr.h | 10 | ||||
-rw-r--r-- | src/game/Unit.cpp | 9 |
4 files changed, 57 insertions, 39 deletions
diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index a783707ca60..23b9a0069ff 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -758,6 +758,7 @@ void Spell::prepareDataForTriggerSystem(AuraEffect * triggeredByAura) // Create base triggers flags for Attacker and Victim ( m_procAttacker, m_procVictim and m_procEx) //========================================================================================== + m_procVictim = m_procAttacker = 0; // Get data for type of attack and fill base info for trigger switch (m_spellInfo->DmgClass) { @@ -779,37 +780,15 @@ void Spell::prepareDataForTriggerSystem(AuraEffect * triggeredByAura) } break; default: - if (IsPositiveSpell(m_spellInfo->Id)) // Check for positive spell - { - if(m_customAttr & SPELL_ATTR_CU_DIRECT_DAMAGE) - { - m_procAttacker = PROC_FLAG_SUCCESSFUL_HEALING_SPELL; - m_procVictim = PROC_FLAG_TAKEN_HEALING_SPELL; - } - else - { - m_procAttacker = PROC_FLAG_SUCCESSFUL_POSITIVE_SPELL; - m_procVictim = PROC_FLAG_TAKEN_POSITIVE_SPELL; - } - } - else if (m_spellInfo->AttributesEx2 & SPELL_ATTR_EX2_AUTOREPEAT_FLAG) // Wands auto attack + if (m_spellInfo->EquippedItemClass == ITEM_CLASS_WEAPON && + m_spellInfo->EquippedItemSubClassMask & ITEM_SUBCLASS_WEAPON_WAND + && m_spellInfo->AttributesEx2 & SPELL_ATTR_EX2_AUTOREPEAT_FLAG) // Wands auto attack { m_procAttacker = PROC_FLAG_SUCCESSFUL_RANGED_HIT; m_procVictim = PROC_FLAG_TAKEN_RANGED_HIT; } - else // Negative spell - { - if(m_customAttr & SPELL_ATTR_CU_DIRECT_DAMAGE) - { - m_procAttacker = PROC_FLAG_SUCCESSFUL_DAMAGING_SPELL_HIT; - m_procVictim = PROC_FLAG_TAKEN_DAMAGING_SPELL_HIT; - } - else - { - m_procAttacker = PROC_FLAG_SUCCESSFUL_NEGATIVE_SPELL_HIT; - m_procVictim = PROC_FLAG_TAKEN_NEGATIVE_SPELL_HIT; - } - } + // For other spells trigger procflags are set in Spell::DoAllEffectOnTarget + // Because spell positivity is dependant on target } m_procEx= PROC_EX_NONE; @@ -1109,6 +1088,12 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target) // Do healing and triggers if (m_healing > 0) { + // Trigger info was not filled in spell::preparedatafortriggersystem - we do it now + if (canEffectTrigger && !procAttacker && !procVictim) + { + procAttacker |= PROC_FLAG_SUCCESSFUL_HEALING_SPELL; + procVictim |= PROC_FLAG_TAKEN_HEALING_SPELL; + } bool crit = caster->isSpellCrit(unitTarget, m_spellInfo, m_spellSchoolMask); uint32 addhealth = m_healing; if (crit) @@ -1132,6 +1117,13 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target) // Do damage and triggers else if (m_damage > 0) { + // Trigger info was not filled in spell::preparedatafortriggersystem - we do it now + if (canEffectTrigger && !procAttacker && !procVictim) + { + procAttacker |= PROC_FLAG_SUCCESSFUL_DAMAGING_SPELL_HIT; + procVictim |= PROC_FLAG_TAKEN_DAMAGING_SPELL_HIT; + } + // Fill base damage struct (unitTarget - is real spell target) SpellNonMeleeDamage damageInfo(caster, unitTarget, m_spellInfo->Id, m_spellSchoolMask); @@ -1168,6 +1160,30 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target) // Passive spell hits/misses or active spells only misses (only triggers) else { + // Trigger info was not filled in spell::preparedatafortriggersystem - we do it now + if (canEffectTrigger && !procAttacker && !procVictim) + { + // Check spell positivity on target + bool positive = true; + for (uint8 i = 0; i< MAX_SPELL_EFFECTS; ++i) + // If at least one effect negative spell is negative hit + if (mask & (1<<i) && !IsPositiveEffect(m_spellInfo->Id, i)) + { + positive = false; + break; + } + if (positive) + { + procAttacker |= PROC_FLAG_SUCCESSFUL_POSITIVE_SPELL; + procVictim |= PROC_FLAG_TAKEN_POSITIVE_SPELL; + } + else + { + procAttacker |= PROC_FLAG_SUCCESSFUL_NEGATIVE_SPELL_HIT; + procVictim |= PROC_FLAG_TAKEN_NEGATIVE_SPELL_HIT; + } + } + // Fill base damage struct (unitTarget - is real spell target) SpellNonMeleeDamage damageInfo(caster, unitTarget, m_spellInfo->Id, m_spellSchoolMask); procEx |= createProcExtendMask(&damageInfo, missInfo); diff --git a/src/game/SpellMgr.cpp b/src/game/SpellMgr.cpp index 5f729c52944..e2434cb0010 100644 --- a/src/game/SpellMgr.cpp +++ b/src/game/SpellMgr.cpp @@ -1268,7 +1268,7 @@ void SpellMgr::LoadSpellBonusess() sLog.outString( ">> Loaded %u extra spell bonus data", count); } -bool SpellMgr::IsSpellProcEventCanTriggeredBy(SpellProcEventEntry const* spellProcEvent, uint32 EventProcFlag, SpellEntry const * procSpell, uint32 procFlags, uint32 procExtra) +bool SpellMgr::IsSpellProcEventCanTriggeredBy(SpellProcEventEntry const* spellProcEvent, uint32 EventProcFlag, SpellEntry const * procSpell, uint32 procFlags, uint32 procExtra, bool active) { // No extra req need uint32 procEvent_procEx = PROC_EX_NONE; @@ -1356,6 +1356,7 @@ bool SpellMgr::IsSpellProcEventCanTriggeredBy(SpellProcEventEntry const* spellPr if ((spellProcEvent->spellFamilyMask & procSpell->SpellFamilyFlags ) == 0) return false; hasFamilyMask = true; + active = true; } } } @@ -1369,8 +1370,8 @@ bool SpellMgr::IsSpellProcEventCanTriggeredBy(SpellProcEventEntry const* spellPr // Check for extra req (if none) and hit/crit if (procEvent_procEx == PROC_EX_NONE) { - // No extra req, so can trigger only for hit/crit - if((procExtra & (PROC_EX_NORMAL_HIT|PROC_EX_CRITICAL_HIT))) + // No extra req, so can trigger only for hit/crit - spell has to be active or to have PROC_FLAG_TAKEN_NEGATIVE_SPELL_HIT + if((procExtra & (PROC_EX_NORMAL_HIT|PROC_EX_CRITICAL_HIT)) && (active || procFlags & PROC_FLAG_TAKEN_NEGATIVE_SPELL_HIT)) return true; } else // Passive spells hits here only if resist/reflect/immune/evade diff --git a/src/game/SpellMgr.h b/src/game/SpellMgr.h index 226d2a6da6f..4ede6746122 100644 --- a/src/game/SpellMgr.h +++ b/src/game/SpellMgr.h @@ -393,7 +393,7 @@ enum ProcFlags PROC_FLAG_KILLED = 0x00000001, // 00 Killed by agressor PROC_FLAG_KILL = 0x00000002, // 01 Kill target (in most cases need XP/Honor reward) - PROC_FLAG_SUCCESSFUL_MILEE_HIT = 0x00000004, // 02 Successful melee auto attack + PROC_FLAG_SUCCESSFUL_MELEE_HIT = 0x00000004, // 02 Successful melee auto attack PROC_FLAG_TAKEN_MELEE_HIT = 0x00000008, // 03 Taken damage from melee auto attack hit PROC_FLAG_SUCCESSFUL_MELEE_SPELL_HIT = 0x00000010, // 04 Successful attack by Spell that use melee weapon @@ -429,7 +429,7 @@ enum ProcFlags PROC_FLAG_DEATH = 0x01000000 // 24 Died in any way }; -#define MELEE_BASED_TRIGGER_MASK (PROC_FLAG_SUCCESSFUL_MILEE_HIT | \ +#define MELEE_BASED_TRIGGER_MASK (PROC_FLAG_SUCCESSFUL_MELEE_HIT | \ PROC_FLAG_TAKEN_MELEE_HIT | \ PROC_FLAG_SUCCESSFUL_MELEE_SPELL_HIT | \ PROC_FLAG_TAKEN_MELEE_SPELL_HIT | \ @@ -458,9 +458,9 @@ enum ProcFlagsEx 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_INTERNAL_CANT_PROC = 0x0800000, + PROC_EX_INTERNAL_CANT_PROC = 0x0800000, // Only for internal use PROC_EX_INTERNAL_DOT = 0x1000000, // Only for internal use - PROC_EX_INTERNAL_HOT = 0x2000000, // 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_REQ_FAMILY = 0x8000000 // Only for internal use }; @@ -769,7 +769,7 @@ class SpellMgr return NULL; } - bool IsSpellProcEventCanTriggeredBy( SpellProcEventEntry const * spellProcEvent, uint32 EventProcFlag, SpellEntry const * procSpell, uint32 procFlags, uint32 procExtra); + bool IsSpellProcEventCanTriggeredBy( SpellProcEventEntry const * spellProcEvent, uint32 EventProcFlag, SpellEntry const * procSpell, uint32 procFlags, uint32 procExtra, bool active); SpellEnchantProcEntry const* GetSpellEnchantProcEvent(uint32 enchId) const { diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index df5334e3324..f6d54b488e3 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -1439,12 +1439,12 @@ void Unit::CalculateMeleeDamage(Unit *pVictim, uint32 damage, CalcDamageInfo *da switch (attackType) { case BASE_ATTACK: - damageInfo->procAttacker = PROC_FLAG_SUCCESSFUL_MILEE_HIT; + damageInfo->procAttacker = PROC_FLAG_SUCCESSFUL_MELEE_HIT; damageInfo->procVictim = PROC_FLAG_TAKEN_MELEE_HIT; damageInfo->HitInfo = HITINFO_NORMALSWING2; break; case OFF_ATTACK: - damageInfo->procAttacker = PROC_FLAG_SUCCESSFUL_MILEE_HIT | PROC_FLAG_SUCCESSFUL_OFFHAND_HIT; + damageInfo->procAttacker = PROC_FLAG_SUCCESSFUL_MELEE_HIT | PROC_FLAG_SUCCESSFUL_OFFHAND_HIT; damageInfo->procVictim = PROC_FLAG_TAKEN_MELEE_HIT;//|PROC_FLAG_TAKEN_OFFHAND_HIT // not used damageInfo->HitInfo = HITINFO_LEFTSWING; break; @@ -2982,7 +2982,7 @@ SpellMissInfo Unit::SpellHitResult(Unit *pVictim, SpellEntry const *spell, bool if (reflectchance > 0 && roll_chance_i(reflectchance)) { // Start triggers for remove charges if need (trigger only for victim, and mark as active spell) - ProcDamageAndSpell(pVictim, PROC_FLAG_NONE, PROC_FLAG_TAKEN_NEGATIVE_SPELL_HIT, PROC_EX_REFLECT, 0, BASE_ATTACK, spell); + ProcDamageAndSpell(pVictim, PROC_FLAG_NONE, PROC_FLAG_SUCCESSFUL_DAMAGING_SPELL_HIT, PROC_EX_REFLECT, 1, BASE_ATTACK, spell); return SPELL_MISS_REFLECT; } } @@ -12834,6 +12834,7 @@ void Unit::ProcDamageAndSpellFor( bool isVictim, Unit * pTarget, uint32 procFlag // Remove charge (aura can be removed by triggers) if(useCharges && takeCharges) { + sLog.outError("%d, %d, %d", Id, procSpell? procSpell->Id : 0, procFlag); i->aura->DropAuraCharge(); } } @@ -13480,7 +13481,7 @@ bool Unit::IsTriggeredAtSpellProcEvent(Unit *pVictim, Aura * aura, SpellEntry co } // Check spellProcEvent data requirements - if(!spellmgr.IsSpellProcEventCanTriggeredBy(spellProcEvent, EventProcFlag, procSpell, procFlag, procExtra)) + if(!spellmgr.IsSpellProcEventCanTriggeredBy(spellProcEvent, EventProcFlag, procSpell, procFlag, procExtra, active)) return false; // In most cases req get honor or XP from kill if (EventProcFlag & PROC_FLAG_KILL && GetTypeId() == TYPEID_PLAYER) |