diff options
| author | ariel- <ariel-@users.noreply.github.com> | 2016-10-30 00:16:10 -0300 |
|---|---|---|
| committer | ariel- <ariel-@users.noreply.github.com> | 2016-10-30 00:16:45 -0300 |
| commit | b3a4815067d154fb35da87aa8e7365995d6f65f5 (patch) | |
| tree | 494900f8811541b47eb565a65bacd203386dcd4e | |
| parent | d48cf7500585f277e1ee2016f2321ea48c118766 (diff) | |
Core/Spells: workaround stealth interaction with Death and Decay and GameObject casts
Closes #10179
Closes #16154
| -rw-r--r-- | src/server/game/Entities/Unit/Unit.cpp | 3 | ||||
| -rw-r--r-- | src/server/game/Spells/Spell.cpp | 22 | ||||
| -rw-r--r-- | src/server/game/Spells/SpellMgr.cpp | 5 |
3 files changed, 23 insertions, 7 deletions
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 995a4179421..bb2d98793f6 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -8679,7 +8679,8 @@ bool Unit::_IsValidAttackTarget(Unit const* target, SpellInfo const* bySpell, Wo return false; // can't attack invisible (ignore stealth for aoe spells) also if the area being looked at is from a spell use the dynamic object created instead of the casting unit. Ignore stealth if target is player and unit in combat with same player - if ((!bySpell || !bySpell->HasAttribute(SPELL_ATTR6_CAN_TARGET_INVISIBLE)) && (obj ? !obj->CanSeeOrDetect(target, bySpell && bySpell->IsAffectingArea()) : !CanSeeOrDetect(target, (bySpell && bySpell->IsAffectingArea()) || (target->GetTypeId() == TYPEID_PLAYER && target->HasStealthAura() && target->IsInCombat() && IsInCombatWith(target))))) + // skip visibility check for GO casts, needs removal when go cast is implemented + if (GetEntry() != WORLD_TRIGGER && (!bySpell || !bySpell->HasAttribute(SPELL_ATTR6_CAN_TARGET_INVISIBLE)) && (obj ? !obj->CanSeeOrDetect(target, bySpell && bySpell->IsAffectingArea()) : !CanSeeOrDetect(target, (bySpell && bySpell->IsAffectingArea()) || (target->GetTypeId() == TYPEID_PLAYER && target->HasStealthAura() && target->IsInCombat() && IsInCombatWith(target))))) return false; // can't attack dead diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index b86f0b20d68..f9aff4d70b4 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -1992,11 +1992,17 @@ void Spell::prepareDataForTriggerSystem() // Hunter trap spells - activation proc for Lock and Load, Entrapment and Misdirection if (m_spellInfo->SpellFamilyName == SPELLFAMILY_HUNTER && - (m_spellInfo->SpellFamilyFlags[0] & 0x18 || // Freezing and Frost Trap, Freezing Arrow - m_spellInfo->Id == 57879 || // Snake Trap - done this way to avoid double proc - m_spellInfo->SpellFamilyFlags[2] & 0x00024000)) // Explosive and Immolation Trap + (m_spellInfo->SpellFamilyFlags[0] & 0x18 || // Freezing and Frost Trap, Freezing Arrow + m_spellInfo->Id == 57879 || // Snake Trap - done this way to avoid double proc + m_spellInfo->SpellFamilyFlags[2] & 0x00024000)) // Explosive and Immolation Trap + { m_procAttacker |= PROC_FLAG_DONE_TRAP_ACTIVATION; + // also fill up other flags (DoAllEffectOnTarget only fills up flag if both are not set) + m_procAttacker |= PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG; + m_procVictim |= PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG; + } + // Hellfire Effect - trigger as DOT if (m_spellInfo->SpellFamilyName == SPELLFAMILY_WARLOCK && m_spellInfo->SpellFamilyFlags[0] & 0x00000040) { @@ -2050,7 +2056,7 @@ void Spell::AddUnitTarget(Unit* target, uint32 effectMask, bool checkIfValid /*= return; if (checkIfValid) - if (m_spellInfo->CheckTarget(m_caster, target, implicit) != SPELL_CAST_OK) + if (m_spellInfo->CheckTarget(m_caster, target, implicit || m_caster->GetEntry() == WORLD_TRIGGER) != SPELL_CAST_OK) // skip stealth checks for GO casts return; // Check for effect immune skip if immuned @@ -4902,14 +4908,18 @@ SpellCastResult Spell::CheckCast(bool strict) if (!(m_spellInfo->IsPassive() && (!m_targets.GetUnitTarget() || m_targets.GetUnitTarget() == m_caster))) { // Check explicit target for m_originalCaster - todo: get rid of such workarounds - SpellCastResult castResult = m_spellInfo->CheckExplicitTarget(m_originalCaster ? m_originalCaster : m_caster, m_targets.GetObjectTarget(), m_targets.GetItemTarget()); + Unit* caster = m_caster; + if (m_originalCaster && m_caster->GetEntry() != WORLD_TRIGGER) // Do a simplified check for gameobject casts + caster = m_originalCaster; + + SpellCastResult castResult = m_spellInfo->CheckExplicitTarget(caster, m_targets.GetObjectTarget(), m_targets.GetItemTarget()); if (castResult != SPELL_CAST_OK) return castResult; } if (Unit* target = m_targets.GetUnitTarget()) { - SpellCastResult castResult = m_spellInfo->CheckTarget(m_caster, target, false); + SpellCastResult castResult = m_spellInfo->CheckTarget(m_caster, target, m_caster->GetEntry() == WORLD_TRIGGER); // skip stealth checks for GO casts if (castResult != SPELL_CAST_OK) return castResult; diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index 03a1e1dd28d..22e0f4cf141 100644 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -1593,6 +1593,8 @@ void SpellMgr::LoadSpellProcs() isTriggerAura[SPELL_AURA_ABILITY_IGNORE_AURASTATE] = true; isAlwaysTriggeredAura[SPELL_AURA_OVERRIDE_CLASS_SCRIPTS] = true; + isAlwaysTriggeredAura[SPELL_AURA_MOD_STEALTH] = true; + isAlwaysTriggeredAura[SPELL_AURA_MOD_CONFUSE] = true; isAlwaysTriggeredAura[SPELL_AURA_MOD_FEAR] = true; isAlwaysTriggeredAura[SPELL_AURA_MOD_ROOT] = true; isAlwaysTriggeredAura[SPELL_AURA_MOD_STUN] = true; @@ -2762,6 +2764,9 @@ void SpellMgr::LoadSpellInfoCorrections() case 49611: // Magic Suppression - DK spellInfo->ProcCharges = 0; break; + case 52212: // Death and Decay + spellInfo->AttributesEx6 |= SPELL_ATTR6_CAN_TARGET_INVISIBLE; + break; case 37408: // Oscillation Field spellInfo->AttributesEx3 |= SPELL_ATTR3_STACK_FOR_DIFF_CASTERS; break; |
