diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/Entities/Object/Object.cpp | 2 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 14 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.h | 2 | ||||
-rw-r--r-- | src/server/game/Entities/Unit/Unit.cpp | 36 | ||||
-rw-r--r-- | src/server/game/Entities/Unit/Unit.h | 6 | ||||
-rw-r--r-- | src/server/game/Miscellaneous/SharedDefines.h | 64 | ||||
-rw-r--r-- | src/server/game/Miscellaneous/enuminfo_SharedDefines.cpp | 176 | ||||
-rw-r--r-- | src/server/game/Spells/Auras/SpellAuraEffects.cpp | 4 | ||||
-rw-r--r-- | src/server/game/Spells/Auras/SpellAuras.cpp | 2 | ||||
-rw-r--r-- | src/server/game/Spells/Spell.cpp | 77 | ||||
-rw-r--r-- | src/server/game/Spells/SpellEffects.cpp | 32 | ||||
-rw-r--r-- | src/server/game/Spells/SpellInfo.cpp | 34 | ||||
-rw-r--r-- | src/server/game/Spells/SpellMgr.cpp | 6 | ||||
-rw-r--r-- | src/server/scripts/Northrend/Ulduar/Ulduar/boss_thorim.cpp | 2 |
14 files changed, 249 insertions, 208 deletions
diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index e8ada623675..3c9976139f7 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -3142,7 +3142,7 @@ bool WorldObject::IsValidAssistTarget(WorldObject const* target, SpellInfo const Unit* WorldObject::GetMagicHitRedirectTarget(Unit* victim, SpellInfo const* spellInfo) { // Patch 1.2 notes: Spell Reflection no longer reflects abilities - if (spellInfo->HasAttribute(SPELL_ATTR0_IS_ABILITY) || spellInfo->HasAttribute(SPELL_ATTR1_CANT_BE_REDIRECTED) || spellInfo->HasAttribute(SPELL_ATTR0_NO_IMMUNITIES)) + if (spellInfo->HasAttribute(SPELL_ATTR0_IS_ABILITY) || spellInfo->HasAttribute(SPELL_ATTR1_NO_REDIRECTION) || spellInfo->HasAttribute(SPELL_ATTR0_NO_IMMUNITIES)) return victim; Unit::AuraEffectList const& magnetAuras = victim->GetAuraEffectsByType(SPELL_AURA_SPELL_MAGNET); diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index a19f835c649..3e5f86cbbca 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -5448,12 +5448,15 @@ inline int SkillGainChance(uint32 SkillValue, uint32 GrayLevel, uint32 GreenLeve return sWorld->getIntConfig(CONFIG_SKILL_CHANCE_ORANGE)*10; } -bool Player::UpdateCraftSkill(uint32 spellid) +bool Player::UpdateCraftSkill(SpellInfo const* spellInfo) { + if (spellInfo->HasAttribute(SPELL_ATTR1_NO_SKILL_INCREASE)) + return false; + TC_LOG_DEBUG("entities.player.skills", "Player::UpdateCraftSkill: Player '%s' (%s), SpellID: %d", - GetName().c_str(), GetGUID().ToString().c_str(), spellid); + GetName().c_str(), GetGUID().ToString().c_str(), spellInfo->Id); - SkillLineAbilityMapBounds bounds = sSpellMgr->GetSkillLineAbilityMapBounds(spellid); + SkillLineAbilityMapBounds bounds = sSpellMgr->GetSkillLineAbilityMapBounds(spellInfo->Id); for (SkillLineAbilityMap::const_iterator _spell_idx = bounds.first; _spell_idx != bounds.second; ++_spell_idx) { @@ -5462,10 +5465,9 @@ bool Player::UpdateCraftSkill(uint32 spellid) uint32 SkillValue = GetPureSkillValue(_spell_idx->second->SkillupSkillLineID); // Alchemy Discoveries here - SpellInfo const* spellEntry = sSpellMgr->GetSpellInfo(spellid, DIFFICULTY_NONE); - if (spellEntry && spellEntry->Mechanic == MECHANIC_DISCOVERY) + if (spellInfo && spellInfo->Mechanic == MECHANIC_DISCOVERY) { - if (uint32 discoveredSpell = GetSkillDiscoverySpell(_spell_idx->second->SkillupSkillLineID, spellid, this)) + if (uint32 discoveredSpell = GetSkillDiscoverySpell(_spell_idx->second->SkillupSkillLineID, spellInfo->Id, this)) LearnSpell(discoveredSpell, false); } diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 40816c70cd6..38e49656374 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -2003,7 +2003,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player> void SendRaidGroupOnlyMessage(RaidGroupReason reason, int32 delay) const; bool UpdateSkillPro(uint16 skillId, int32 chance, uint32 step); - bool UpdateCraftSkill(uint32 spellid); + bool UpdateCraftSkill(SpellInfo const* spellInfo); bool UpdateGatherSkill(uint32 SkillId, uint32 SkillValue, uint32 RedLevel, uint32 Multiplicator = 1); bool UpdateFishingSkill(); diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 30577190507..332ac0e21f1 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -3743,7 +3743,7 @@ void Unit::RemoveAurasDueToSpellByDispel(uint32 spellId, uint32 dispellerSpellId } } -void Unit::RemoveAurasDueToSpellBySteal(uint32 spellId, ObjectGuid casterGUID, WorldObject* stealer) +void Unit::RemoveAurasDueToSpellBySteal(uint32 spellId, ObjectGuid casterGUID, WorldObject* stealer, int32 stolenCharges /*= 1*/) { AuraMapBoundsNonConst range = m_ownedAuras.equal_range(spellId); for (AuraMap::iterator iter = range.first; iter != range.second;) @@ -3782,9 +3782,9 @@ void Unit::RemoveAurasDueToSpellBySteal(uint32 spellId, ObjectGuid casterGUID, W if (Aura* oldAura = unitStealer->GetAura(aura->GetId(), aura->GetCasterGUID())) { if (stealCharge) - oldAura->ModCharges(1); + oldAura->ModCharges(stolenCharges); else - oldAura->ModStackAmount(1); + oldAura->ModStackAmount(stolenCharges); oldAura->SetDuration(int32(dur)); } else @@ -3809,16 +3809,16 @@ void Unit::RemoveAurasDueToSpellBySteal(uint32 spellId, ObjectGuid casterGUID, W caster->GetSingleCastAuras().push_back(aura); } // FIXME: using aura->GetMaxDuration() maybe not blizzlike but it fixes stealing of spells like Innervate - newAura->SetLoadedState(aura->GetMaxDuration(), int32(dur), stealCharge ? 1 : aura->GetCharges(), 1, recalculateMask, &damage[0]); + newAura->SetLoadedState(aura->GetMaxDuration(), int32(dur), stealCharge ? stolenCharges : aura->GetCharges(), stolenCharges, recalculateMask, &damage[0]); newAura->ApplyForTargets(); } } } if (stealCharge) - aura->ModCharges(-1, AURA_REMOVE_BY_ENEMY_SPELL); + aura->ModCharges(-stolenCharges, AURA_REMOVE_BY_ENEMY_SPELL); else - aura->ModStackAmount(-1, AURA_REMOVE_BY_ENEMY_SPELL); + aura->ModStackAmount(-stolenCharges, AURA_REMOVE_BY_ENEMY_SPELL); return; } @@ -4143,7 +4143,27 @@ void Unit::RemoveAurasOnEvade() // don't remove vehicle auras, passengers aren't supposed to drop off the vehicle // don't remove clone caster on evade (to be verified) - RemoveAllAurasExceptType(SPELL_AURA_CONTROL_VEHICLE, SPELL_AURA_CLONE_CASTER); + auto evadeAuraCheck = [](Aura const* aura) + { + if (aura->HasEffectType(SPELL_AURA_CONTROL_VEHICLE)) + return false; + + if (aura->HasEffectType(SPELL_AURA_CLONE_CASTER)) + return false; + + if (aura->GetSpellInfo()->HasAttribute(SPELL_ATTR1_AURA_STAYS_AFTER_COMBAT)) + return false; + + return true; + }; + + auto evadeAuraApplicationCheck = [&evadeAuraCheck](AuraApplication const* aurApp) + { + return evadeAuraCheck(aurApp->GetBase()); + }; + + RemoveAppliedAuras(evadeAuraApplicationCheck); + RemoveOwnedAuras(evadeAuraCheck); } void Unit::RemoveAllAurasOnDeath() @@ -7149,7 +7169,7 @@ bool Unit::IsImmunedToDamage(SpellInfo const* spellInfo) const if (spellInfo->HasAttribute(SPELL_ATTR0_NO_IMMUNITIES) && spellInfo->HasAttribute(SPELL_ATTR3_IGNORE_HIT_RESULT)) return false; - if (spellInfo->HasAttribute(SPELL_ATTR1_UNAFFECTED_BY_SCHOOL_IMMUNE) || spellInfo->HasAttribute(SPELL_ATTR2_UNAFFECTED_BY_AURA_SCHOOL_IMMUNE)) + if (spellInfo->HasAttribute(SPELL_ATTR1_IMMUNITY_TO_HOSTILE_AND_FRIENDLY_EFFECTS) || spellInfo->HasAttribute(SPELL_ATTR2_UNAFFECTED_BY_AURA_SCHOOL_IMMUNE)) return false; if (uint32 schoolMask = spellInfo->GetSchoolMask()) diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index 0fbb844891d..b1dc82c6421 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -123,12 +123,12 @@ class TC_GAME_API DispelableAura uint8 GetDispelCharges() const { return _charges; } void IncrementCharges() { ++_charges; } - bool DecrementCharge() + bool DecrementCharge(uint8 charges) { if (!_charges) return false; - --_charges; + _charges -= charges; return _charges > 0; } @@ -1377,7 +1377,7 @@ class TC_GAME_API Unit : public WorldObject void RemoveAurasDueToSpell(uint32 spellId, ObjectGuid casterGUID = ObjectGuid::Empty, uint32 reqEffMask = 0, AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT); void RemoveAuraFromStack(uint32 spellId, ObjectGuid casterGUID = ObjectGuid::Empty, AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT, uint16 num = 1); void RemoveAurasDueToSpellByDispel(uint32 spellId, uint32 dispellerSpellId, ObjectGuid casterGUID, WorldObject* dispeller, uint8 chargesRemoved = 1); - void RemoveAurasDueToSpellBySteal(uint32 spellId, ObjectGuid casterGUID, WorldObject* stealer); + void RemoveAurasDueToSpellBySteal(uint32 spellId, ObjectGuid casterGUID, WorldObject* stealer, int32 stolenCharges = 1); void RemoveAurasDueToItemSpell(uint32 spellId, ObjectGuid castItemGuid); void RemoveAurasByType(AuraType auraType, ObjectGuid casterGUID = ObjectGuid::Empty, Aura* except = nullptr, bool negative = true, bool positive = true); void RemoveNotOwnSingleTargetAuras(bool onPhaseChange = false); diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h index 9f02b54393c..8ef099d970b 100644 --- a/src/server/game/Miscellaneous/SharedDefines.h +++ b/src/server/game/Miscellaneous/SharedDefines.h @@ -441,38 +441,38 @@ enum SpellAttr0 : uint32 // EnumUtils: DESCRIBE THIS enum SpellAttr1 : uint32 { - SPELL_ATTR1_DISMISS_PET = 0x00000001, // TITLE Dismiss Pet on cast DESCRIPTION Without this attribute, summoning spells will fail if caster already has a pet - SPELL_ATTR1_DRAIN_ALL_POWER = 0x00000002, // TITLE Drain all power DESCRIPTION Ignores listed power cost and drains entire pool instead - SPELL_ATTR1_CHANNELED_1 = 0x00000004, // TITLE Channeled (type 1) DESCRIPTION Both "channeled" attributes have identical handling in server & client - SPELL_ATTR1_CANT_BE_REDIRECTED = 0x00000008, // TITLE Ignore redirection effects DESCRIPTION Spell will not be attracted by SPELL_MAGNET auras (Grounding Totem) - SPELL_ATTR1_UNK4 = 0x00000010, // TITLE Unknown attribute 4@Attr1 - SPELL_ATTR1_NOT_BREAK_STEALTH = 0x00000020, // TITLE Does not break stealth - SPELL_ATTR1_CHANNELED_2 = 0x00000040, // TITLE Channeled (type 2) DESCRIPTION Both "channeled" attributes have identical handling in server & client - SPELL_ATTR1_CANT_BE_REFLECTED = 0x00000080, // TITLE Ignore reflection effects DESCRIPTION Spell will pierce through Spell Reflection and similar - SPELL_ATTR1_CANT_TARGET_IN_COMBAT = 0x00000100, // TITLE Target cannot be in combat - SPELL_ATTR1_MELEE_COMBAT_START = 0x00000200, // TITLE Starts auto-attack (client only) DESCRIPTION Caster will begin auto-attacking the target on cast - SPELL_ATTR1_NO_THREAT = 0x00000400, // TITLE Does not generate threat DESCRIPTION Also does not cause target to engage - SPELL_ATTR1_DONT_REFRESH_DURATION_ON_RECAST = 0x00000800, // TITLE Aura will not refresh its duration when recast - SPELL_ATTR1_IS_PICKPOCKET = 0x00001000, // TITLE Pickpocket (client only) - SPELL_ATTR1_FARSIGHT = 0x00002000, // TITLE Farsight aura (client only) - SPELL_ATTR1_CHANNEL_TRACK_TARGET = 0x00004000, // TITLE Track target while channeling DESCRIPTION While channeling, adjust facing to face target - SPELL_ATTR1_DISPEL_AURAS_ON_IMMUNITY = 0x00008000, // TITLE Immunity cancels preapplied auras DESCRIPTION For immunity spells, cancel all auras that this spell would make you immune to when the spell is applied - SPELL_ATTR1_UNAFFECTED_BY_SCHOOL_IMMUNE = 0x00010000, // TITLE Unaffected by school immunities DESCRIPTION Will not pierce Divine Shield, Ice Block and other full invulnerabilities - SPELL_ATTR1_UNAUTOCASTABLE_BY_PET = 0x00020000, // TITLE Cannot be autocast by pet - SPELL_ATTR1_PREVENTS_ANIM = 0x00040000, // TITLE Prevents Anim DESCRIPTION NYI, auras apply UNIT_FLAG_PREVENT_EMOTES_FROM_CHAT_TEXT - SPELL_ATTR1_CANT_TARGET_SELF = 0x00080000, // TITLE Cannot be self-cast - SPELL_ATTR1_REQ_COMBO_POINTS1 = 0x00100000, // TITLE Requires combo points (type 1) - SPELL_ATTR1_UNK21 = 0x00200000, // TITLE Unknown attribute 21@Attr1 - SPELL_ATTR1_REQ_COMBO_POINTS2 = 0x00400000, // TITLE Requires combo points (type 2) - SPELL_ATTR1_UNK23 = 0x00800000, // TITLE Unknwon attribute 23@Attr1 - SPELL_ATTR1_IS_FISHING = 0x01000000, // TITLE Fishing (client only) - SPELL_ATTR1_UNK25 = 0x02000000, // TITLE Unknown attribute 25@Attr1 - SPELL_ATTR1_UNK26 = 0x04000000, // TITLE Unknown attribute 26@Attr1 DESCRIPTION Related to [target=focus] and [target=mouseover] macros? - SPELL_ATTR1_UNK27 = 0x08000000, // TITLE Unknown attribute 27@Attr1 DESCRIPTION Melee spell? - SPELL_ATTR1_DONT_DISPLAY_IN_AURA_BAR = 0x10000000, // TITLE Hide in aura bar (client only) - SPELL_ATTR1_CHANNEL_DISPLAY_SPELL_NAME = 0x20000000, // TITLE Show spell name during channel (client only) - SPELL_ATTR1_ENABLE_AT_DODGE = 0x40000000, // TITLE Enable at dodge - SPELL_ATTR1_CAST_WHEN_LEARNED = 0x80000000 // TITLE Cast When Learned + SPELL_ATTR1_DISMISS_PET_FIRST = 0x00000001, // TITLE Dismiss Pet First DESCRIPTION Without this attribute, summoning spells will fail if caster already has a pet + SPELL_ATTR1_USE_ALL_MANA = 0x00000002, // TITLE Use All Mana DESCRIPTION Ignores listed power cost and drains entire pool instead + SPELL_ATTR1_IS_CHANNELLED = 0x00000004, // TITLE Is Channelled DESCRIPTION Both "channeled" attributes have identical handling in server & client + SPELL_ATTR1_NO_REDIRECTION = 0x00000008, // TITLE No Redirection DESCRIPTION Spell will not be attracted by SPELL_MAGNET auras (Grounding Totem) + SPELL_ATTR1_NO_SKILL_INCREASE = 0x00000010, // TITLE No Skill Increase + SPELL_ATTR1_ALLOW_WHILE_STEALTHED = 0x00000020, // TITLE Allow While Stealthed + SPELL_ATTR1_IS_SELF_CHANNELLED = 0x00000040, // TITLE Is Self Channelled DESCRIPTION Both "channeled" attributes have identical handling in server & client + SPELL_ATTR1_NO_REFLECTION = 0x00000080, // TITLE No Reflection DESCRIPTION Spell will pierce through Spell Reflection and similar + SPELL_ATTR1_ONLY_PEACEFUL_TARGETS = 0x00000100, // TITLE Only Peaceful Targets DESCRIPTION Target cannot be in combat + SPELL_ATTR1_INITIATES_COMBAT_ENABLES_AUTO_ATTACK = 0x00000200, // TITLE Initiates Combat (Enables Auto-Attack) (client only) DESCRIPTION Caster will begin auto-attacking the target on cast + SPELL_ATTR1_NO_THREAT = 0x00000400, // TITLE Does not generate threat DESCRIPTION Also does not cause target to engage + SPELL_ATTR1_AURA_UNIQUE = 0x00000800, // TITLE Aura Unique DESCRIPTION Aura will not refresh its duration when recast + SPELL_ATTR1_FAILURE_BREAKS_STEALTH = 0x00001000, // TITLE Failure Breaks Stealth + SPELL_ATTR1_TOGGLE_FAR_SIGHT = 0x00002000, // TITLE Toggle Far Sight (client only) + SPELL_ATTR1_TRACK_TARGET_IN_CHANNEL = 0x00004000, // TITLE Track Target in Channel DESCRIPTION While channeling, adjust facing to face target + SPELL_ATTR1_IMMUNITY_PURGES_EFFECT = 0x00008000, // TITLE Immunity Purges Effect DESCRIPTION For immunity spells, cancel all auras that this spell would make you immune to when the spell is applied + SPELL_ATTR1_IMMUNITY_TO_HOSTILE_AND_FRIENDLY_EFFECTS = 0x00010000, /*WRONG IMPL*/ // TITLE Immunity to Hostile & Friendly Effects DESCRIPTION Will not pierce Divine Shield, Ice Block and other full invulnerabilities + SPELL_ATTR1_NO_AUTOCAST_AI = 0x00020000, // TITLE No AutoCast (AI) + SPELL_ATTR1_PREVENTS_ANIM = 0x00040000, /*NYI*/ // TITLE Prevents Anim DESCRIPTION Auras apply UNIT_FLAG_PREVENT_EMOTES_FROM_CHAT_TEXT + SPELL_ATTR1_EXCLUDE_CASTER = 0x00080000, // TITLE Exclude Caster + SPELL_ATTR1_FINISHING_MOVE_DAMAGE = 0x00100000, // TITLE Finishing Move - Damage + SPELL_ATTR1_THREAT_ONLY_ON_MISS = 0x00200000, /*NYI*/ // TITLE Threat only on Miss + SPELL_ATTR1_FINISHING_MOVE_DURATION = 0x00400000, // TITLE Finishing Move - Duration + SPELL_ATTR1_IGNORE_OWNERS_DEATH = 0x00800000, /*NYI*/ // TITLE Ignore Owner's Death + SPELL_ATTR1_SPECIAL_SKILLUP = 0x01000000, // TITLE Special Skillup + SPELL_ATTR1_AURA_STAYS_AFTER_COMBAT = 0x02000000, // TITLE Aura Stays After Combat + SPELL_ATTR1_REQUIRE_ALL_TARGETS = 0x04000000, /*NYI, UNK*/ // TITLE Require All Targets + SPELL_ATTR1_DISCOUNT_POWER_ON_MISS = 0x08000000, // TITLE Discount Power On Miss + SPELL_ATTR1_NO_AURA_ICON = 0x10000000, // TITLE No Aura Icon (client only) + SPELL_ATTR1_NAME_IN_CHANNEL_BAR = 0x20000000, // TITLE Name in Channel Bar (client only) + SPELL_ATTR1_DISPEL_ALL_STACKS = 0x40000000, // TITLE Dispel All Stacks + SPELL_ATTR1_CAST_WHEN_LEARNED = 0x80000000 // TITLE Cast When Learned }; // EnumUtils: DESCRIBE THIS diff --git a/src/server/game/Miscellaneous/enuminfo_SharedDefines.cpp b/src/server/game/Miscellaneous/enuminfo_SharedDefines.cpp index eb95f10bf93..4f8622d9efd 100644 --- a/src/server/game/Miscellaneous/enuminfo_SharedDefines.cpp +++ b/src/server/game/Miscellaneous/enuminfo_SharedDefines.cpp @@ -376,37 +376,37 @@ TC_API_EXPORT EnumText EnumUtils<SpellAttr1>::ToString(SpellAttr1 value) { switch (value) { - case SPELL_ATTR1_DISMISS_PET: return { "SPELL_ATTR1_DISMISS_PET", "Dismiss Pet on cast", "Without this attribute, summoning spells will fail if caster already has a pet" }; - case SPELL_ATTR1_DRAIN_ALL_POWER: return { "SPELL_ATTR1_DRAIN_ALL_POWER", "Drain all power", "Ignores listed power cost and drains entire pool instead" }; - case SPELL_ATTR1_CHANNELED_1: return { "SPELL_ATTR1_CHANNELED_1", "Channeled (type 1)", "Both \042channeled\042 attributes have identical handling in server & client" }; - case SPELL_ATTR1_CANT_BE_REDIRECTED: return { "SPELL_ATTR1_CANT_BE_REDIRECTED", "Ignore redirection effects", "Spell will not be attracted by SPELL_MAGNET auras (Grounding Totem)" }; - case SPELL_ATTR1_UNK4: return { "SPELL_ATTR1_UNK4", "Unknown attribute 4@Attr1", "" }; - case SPELL_ATTR1_NOT_BREAK_STEALTH: return { "SPELL_ATTR1_NOT_BREAK_STEALTH", "Does not break stealth", "" }; - case SPELL_ATTR1_CHANNELED_2: return { "SPELL_ATTR1_CHANNELED_2", "Channeled (type 2)", "Both \042channeled\042 attributes have identical handling in server & client" }; - case SPELL_ATTR1_CANT_BE_REFLECTED: return { "SPELL_ATTR1_CANT_BE_REFLECTED", "Ignore reflection effects", "Spell will pierce through Spell Reflection and similar" }; - case SPELL_ATTR1_CANT_TARGET_IN_COMBAT: return { "SPELL_ATTR1_CANT_TARGET_IN_COMBAT", "Target cannot be in combat", "" }; - case SPELL_ATTR1_MELEE_COMBAT_START: return { "SPELL_ATTR1_MELEE_COMBAT_START", "Starts auto-attack (client only)", "Caster will begin auto-attacking the target on cast" }; + case SPELL_ATTR1_DISMISS_PET_FIRST: return { "SPELL_ATTR1_DISMISS_PET_FIRST", "Dismiss Pet First", "Without this attribute, summoning spells will fail if caster already has a pet" }; + case SPELL_ATTR1_USE_ALL_MANA: return { "SPELL_ATTR1_USE_ALL_MANA", "Use All Mana", "Ignores listed power cost and drains entire pool instead" }; + case SPELL_ATTR1_IS_CHANNELLED: return { "SPELL_ATTR1_IS_CHANNELLED", "Is Channelled", "Both \042channeled\042 attributes have identical handling in server & client" }; + case SPELL_ATTR1_NO_REDIRECTION: return { "SPELL_ATTR1_NO_REDIRECTION", "No Redirection", "Spell will not be attracted by SPELL_MAGNET auras (Grounding Totem)" }; + case SPELL_ATTR1_NO_SKILL_INCREASE: return { "SPELL_ATTR1_NO_SKILL_INCREASE", "No Skill Increase", "" }; + case SPELL_ATTR1_ALLOW_WHILE_STEALTHED: return { "SPELL_ATTR1_ALLOW_WHILE_STEALTHED", "Allow While Stealthed", "" }; + case SPELL_ATTR1_IS_SELF_CHANNELLED: return { "SPELL_ATTR1_IS_SELF_CHANNELLED", "Is Self Channelled", "Both \042channeled\042 attributes have identical handling in server & client" }; + case SPELL_ATTR1_NO_REFLECTION: return { "SPELL_ATTR1_NO_REFLECTION", "No Reflection", "Spell will pierce through Spell Reflection and similar" }; + case SPELL_ATTR1_ONLY_PEACEFUL_TARGETS: return { "SPELL_ATTR1_ONLY_PEACEFUL_TARGETS", "Only Peaceful Targets", "Target cannot be in combat" }; + case SPELL_ATTR1_INITIATES_COMBAT_ENABLES_AUTO_ATTACK: return { "SPELL_ATTR1_INITIATES_COMBAT_ENABLES_AUTO_ATTACK", "Initiates Combat (Enables Auto-Attack) (client only)", "Caster will begin auto-attacking the target on cast" }; case SPELL_ATTR1_NO_THREAT: return { "SPELL_ATTR1_NO_THREAT", "Does not generate threat", "Also does not cause target to engage" }; - case SPELL_ATTR1_DONT_REFRESH_DURATION_ON_RECAST: return { "SPELL_ATTR1_DONT_REFRESH_DURATION_ON_RECAST", "Aura will not refresh its duration when recast", "" }; - case SPELL_ATTR1_IS_PICKPOCKET: return { "SPELL_ATTR1_IS_PICKPOCKET", "Pickpocket (client only)", "" }; - case SPELL_ATTR1_FARSIGHT: return { "SPELL_ATTR1_FARSIGHT", "Farsight aura (client only)", "" }; - case SPELL_ATTR1_CHANNEL_TRACK_TARGET: return { "SPELL_ATTR1_CHANNEL_TRACK_TARGET", "Track target while channeling", "While channeling, adjust facing to face target" }; - case SPELL_ATTR1_DISPEL_AURAS_ON_IMMUNITY: return { "SPELL_ATTR1_DISPEL_AURAS_ON_IMMUNITY", "Immunity cancels preapplied auras", "For immunity spells, cancel all auras that this spell would make you immune to when the spell is applied" }; - case SPELL_ATTR1_UNAFFECTED_BY_SCHOOL_IMMUNE: return { "SPELL_ATTR1_UNAFFECTED_BY_SCHOOL_IMMUNE", "Unaffected by school immunities", "Will not pierce Divine Shield, Ice Block and other full invulnerabilities" }; - case SPELL_ATTR1_UNAUTOCASTABLE_BY_PET: return { "SPELL_ATTR1_UNAUTOCASTABLE_BY_PET", "Cannot be autocast by pet", "" }; - case SPELL_ATTR1_PREVENTS_ANIM: return { "SPELL_ATTR1_PREVENTS_ANIM", "Prevents Anim", "NYI, auras apply UNIT_FLAG_PREVENT_EMOTES_FROM_CHAT_TEXT" }; - case SPELL_ATTR1_CANT_TARGET_SELF: return { "SPELL_ATTR1_CANT_TARGET_SELF", "Cannot be self-cast", "" }; - case SPELL_ATTR1_REQ_COMBO_POINTS1: return { "SPELL_ATTR1_REQ_COMBO_POINTS1", "Requires combo points (type 1)", "" }; - case SPELL_ATTR1_UNK21: return { "SPELL_ATTR1_UNK21", "Unknown attribute 21@Attr1", "" }; - case SPELL_ATTR1_REQ_COMBO_POINTS2: return { "SPELL_ATTR1_REQ_COMBO_POINTS2", "Requires combo points (type 2)", "" }; - case SPELL_ATTR1_UNK23: return { "SPELL_ATTR1_UNK23", "Unknwon attribute 23@Attr1", "" }; - case SPELL_ATTR1_IS_FISHING: return { "SPELL_ATTR1_IS_FISHING", "Fishing (client only)", "" }; - case SPELL_ATTR1_UNK25: return { "SPELL_ATTR1_UNK25", "Unknown attribute 25@Attr1", "" }; - case SPELL_ATTR1_UNK26: return { "SPELL_ATTR1_UNK26", "Unknown attribute 26@Attr1", "Related to [target=focus] and [target=mouseover] macros?" }; - case SPELL_ATTR1_UNK27: return { "SPELL_ATTR1_UNK27", "Unknown attribute 27@Attr1", "Melee spell?" }; - case SPELL_ATTR1_DONT_DISPLAY_IN_AURA_BAR: return { "SPELL_ATTR1_DONT_DISPLAY_IN_AURA_BAR", "Hide in aura bar (client only)", "" }; - case SPELL_ATTR1_CHANNEL_DISPLAY_SPELL_NAME: return { "SPELL_ATTR1_CHANNEL_DISPLAY_SPELL_NAME", "Show spell name during channel (client only)", "" }; - case SPELL_ATTR1_ENABLE_AT_DODGE: return { "SPELL_ATTR1_ENABLE_AT_DODGE", "Enable at dodge", "" }; + case SPELL_ATTR1_AURA_UNIQUE: return { "SPELL_ATTR1_AURA_UNIQUE", "Aura Unique", "Aura will not refresh its duration when recast" }; + case SPELL_ATTR1_FAILURE_BREAKS_STEALTH: return { "SPELL_ATTR1_FAILURE_BREAKS_STEALTH", "Failure Breaks Stealth", "" }; + case SPELL_ATTR1_TOGGLE_FAR_SIGHT: return { "SPELL_ATTR1_TOGGLE_FAR_SIGHT", "Toggle Far Sight (client only)", "" }; + case SPELL_ATTR1_TRACK_TARGET_IN_CHANNEL: return { "SPELL_ATTR1_TRACK_TARGET_IN_CHANNEL", "Track Target in Channel", "While channeling, adjust facing to face target" }; + case SPELL_ATTR1_IMMUNITY_PURGES_EFFECT: return { "SPELL_ATTR1_IMMUNITY_PURGES_EFFECT", "Immunity Purges Effect", "For immunity spells, cancel all auras that this spell would make you immune to when the spell is applied" }; + case SPELL_ATTR1_IMMUNITY_TO_HOSTILE_AND_FRIENDLY_EFFECTS: return { "SPELL_ATTR1_IMMUNITY_TO_HOSTILE_AND_FRIENDLY_EFFECTS", "Immunity to Hostile & Friendly Effects", "Will not pierce Divine Shield, Ice Block and other full invulnerabilities" }; + case SPELL_ATTR1_NO_AUTOCAST_AI: return { "SPELL_ATTR1_NO_AUTOCAST_AI", "No AutoCast (AI)", "" }; + case SPELL_ATTR1_PREVENTS_ANIM: return { "SPELL_ATTR1_PREVENTS_ANIM", "Prevents Anim", "Auras apply UNIT_FLAG_PREVENT_EMOTES_FROM_CHAT_TEXT" }; + case SPELL_ATTR1_EXCLUDE_CASTER: return { "SPELL_ATTR1_EXCLUDE_CASTER", "Exclude Caster", "" }; + case SPELL_ATTR1_FINISHING_MOVE_DAMAGE: return { "SPELL_ATTR1_FINISHING_MOVE_DAMAGE", "Finishing Move - Damage", "" }; + case SPELL_ATTR1_THREAT_ONLY_ON_MISS: return { "SPELL_ATTR1_THREAT_ONLY_ON_MISS", "Threat only on Miss", "" }; + case SPELL_ATTR1_FINISHING_MOVE_DURATION: return { "SPELL_ATTR1_FINISHING_MOVE_DURATION", "Finishing Move - Duration", "" }; + case SPELL_ATTR1_IGNORE_OWNERS_DEATH: return { "SPELL_ATTR1_IGNORE_OWNERS_DEATH", "Ignore Owner's Death", "" }; + case SPELL_ATTR1_SPECIAL_SKILLUP: return { "SPELL_ATTR1_SPECIAL_SKILLUP", "Special Skillup", "" }; + case SPELL_ATTR1_AURA_STAYS_AFTER_COMBAT: return { "SPELL_ATTR1_AURA_STAYS_AFTER_COMBAT", "Aura Stays After Combat", "" }; + case SPELL_ATTR1_REQUIRE_ALL_TARGETS: return { "SPELL_ATTR1_REQUIRE_ALL_TARGETS", "Require All Targets", "" }; + case SPELL_ATTR1_DISCOUNT_POWER_ON_MISS: return { "SPELL_ATTR1_DISCOUNT_POWER_ON_MISS", "Discount Power On Miss", "" }; + case SPELL_ATTR1_NO_AURA_ICON: return { "SPELL_ATTR1_NO_AURA_ICON", "No Aura Icon (client only)", "" }; + case SPELL_ATTR1_NAME_IN_CHANNEL_BAR: return { "SPELL_ATTR1_NAME_IN_CHANNEL_BAR", "Name in Channel Bar (client only)", "" }; + case SPELL_ATTR1_DISPEL_ALL_STACKS: return { "SPELL_ATTR1_DISPEL_ALL_STACKS", "Dispel All Stacks", "" }; case SPELL_ATTR1_CAST_WHEN_LEARNED: return { "SPELL_ATTR1_CAST_WHEN_LEARNED", "Cast When Learned", "" }; default: throw std::out_of_range("value"); } @@ -420,37 +420,37 @@ TC_API_EXPORT SpellAttr1 EnumUtils<SpellAttr1>::FromIndex(size_t index) { switch (index) { - case 0: return SPELL_ATTR1_DISMISS_PET; - case 1: return SPELL_ATTR1_DRAIN_ALL_POWER; - case 2: return SPELL_ATTR1_CHANNELED_1; - case 3: return SPELL_ATTR1_CANT_BE_REDIRECTED; - case 4: return SPELL_ATTR1_UNK4; - case 5: return SPELL_ATTR1_NOT_BREAK_STEALTH; - case 6: return SPELL_ATTR1_CHANNELED_2; - case 7: return SPELL_ATTR1_CANT_BE_REFLECTED; - case 8: return SPELL_ATTR1_CANT_TARGET_IN_COMBAT; - case 9: return SPELL_ATTR1_MELEE_COMBAT_START; + case 0: return SPELL_ATTR1_DISMISS_PET_FIRST; + case 1: return SPELL_ATTR1_USE_ALL_MANA; + case 2: return SPELL_ATTR1_IS_CHANNELLED; + case 3: return SPELL_ATTR1_NO_REDIRECTION; + case 4: return SPELL_ATTR1_NO_SKILL_INCREASE; + case 5: return SPELL_ATTR1_ALLOW_WHILE_STEALTHED; + case 6: return SPELL_ATTR1_IS_SELF_CHANNELLED; + case 7: return SPELL_ATTR1_NO_REFLECTION; + case 8: return SPELL_ATTR1_ONLY_PEACEFUL_TARGETS; + case 9: return SPELL_ATTR1_INITIATES_COMBAT_ENABLES_AUTO_ATTACK; case 10: return SPELL_ATTR1_NO_THREAT; - case 11: return SPELL_ATTR1_DONT_REFRESH_DURATION_ON_RECAST; - case 12: return SPELL_ATTR1_IS_PICKPOCKET; - case 13: return SPELL_ATTR1_FARSIGHT; - case 14: return SPELL_ATTR1_CHANNEL_TRACK_TARGET; - case 15: return SPELL_ATTR1_DISPEL_AURAS_ON_IMMUNITY; - case 16: return SPELL_ATTR1_UNAFFECTED_BY_SCHOOL_IMMUNE; - case 17: return SPELL_ATTR1_UNAUTOCASTABLE_BY_PET; + case 11: return SPELL_ATTR1_AURA_UNIQUE; + case 12: return SPELL_ATTR1_FAILURE_BREAKS_STEALTH; + case 13: return SPELL_ATTR1_TOGGLE_FAR_SIGHT; + case 14: return SPELL_ATTR1_TRACK_TARGET_IN_CHANNEL; + case 15: return SPELL_ATTR1_IMMUNITY_PURGES_EFFECT; + case 16: return SPELL_ATTR1_IMMUNITY_TO_HOSTILE_AND_FRIENDLY_EFFECTS; + case 17: return SPELL_ATTR1_NO_AUTOCAST_AI; case 18: return SPELL_ATTR1_PREVENTS_ANIM; - case 19: return SPELL_ATTR1_CANT_TARGET_SELF; - case 20: return SPELL_ATTR1_REQ_COMBO_POINTS1; - case 21: return SPELL_ATTR1_UNK21; - case 22: return SPELL_ATTR1_REQ_COMBO_POINTS2; - case 23: return SPELL_ATTR1_UNK23; - case 24: return SPELL_ATTR1_IS_FISHING; - case 25: return SPELL_ATTR1_UNK25; - case 26: return SPELL_ATTR1_UNK26; - case 27: return SPELL_ATTR1_UNK27; - case 28: return SPELL_ATTR1_DONT_DISPLAY_IN_AURA_BAR; - case 29: return SPELL_ATTR1_CHANNEL_DISPLAY_SPELL_NAME; - case 30: return SPELL_ATTR1_ENABLE_AT_DODGE; + case 19: return SPELL_ATTR1_EXCLUDE_CASTER; + case 20: return SPELL_ATTR1_FINISHING_MOVE_DAMAGE; + case 21: return SPELL_ATTR1_THREAT_ONLY_ON_MISS; + case 22: return SPELL_ATTR1_FINISHING_MOVE_DURATION; + case 23: return SPELL_ATTR1_IGNORE_OWNERS_DEATH; + case 24: return SPELL_ATTR1_SPECIAL_SKILLUP; + case 25: return SPELL_ATTR1_AURA_STAYS_AFTER_COMBAT; + case 26: return SPELL_ATTR1_REQUIRE_ALL_TARGETS; + case 27: return SPELL_ATTR1_DISCOUNT_POWER_ON_MISS; + case 28: return SPELL_ATTR1_NO_AURA_ICON; + case 29: return SPELL_ATTR1_NAME_IN_CHANNEL_BAR; + case 30: return SPELL_ATTR1_DISPEL_ALL_STACKS; case 31: return SPELL_ATTR1_CAST_WHEN_LEARNED; default: throw std::out_of_range("index"); } @@ -461,37 +461,37 @@ TC_API_EXPORT size_t EnumUtils<SpellAttr1>::ToIndex(SpellAttr1 value) { switch (value) { - case SPELL_ATTR1_DISMISS_PET: return 0; - case SPELL_ATTR1_DRAIN_ALL_POWER: return 1; - case SPELL_ATTR1_CHANNELED_1: return 2; - case SPELL_ATTR1_CANT_BE_REDIRECTED: return 3; - case SPELL_ATTR1_UNK4: return 4; - case SPELL_ATTR1_NOT_BREAK_STEALTH: return 5; - case SPELL_ATTR1_CHANNELED_2: return 6; - case SPELL_ATTR1_CANT_BE_REFLECTED: return 7; - case SPELL_ATTR1_CANT_TARGET_IN_COMBAT: return 8; - case SPELL_ATTR1_MELEE_COMBAT_START: return 9; + case SPELL_ATTR1_DISMISS_PET_FIRST: return 0; + case SPELL_ATTR1_USE_ALL_MANA: return 1; + case SPELL_ATTR1_IS_CHANNELLED: return 2; + case SPELL_ATTR1_NO_REDIRECTION: return 3; + case SPELL_ATTR1_NO_SKILL_INCREASE: return 4; + case SPELL_ATTR1_ALLOW_WHILE_STEALTHED: return 5; + case SPELL_ATTR1_IS_SELF_CHANNELLED: return 6; + case SPELL_ATTR1_NO_REFLECTION: return 7; + case SPELL_ATTR1_ONLY_PEACEFUL_TARGETS: return 8; + case SPELL_ATTR1_INITIATES_COMBAT_ENABLES_AUTO_ATTACK: return 9; case SPELL_ATTR1_NO_THREAT: return 10; - case SPELL_ATTR1_DONT_REFRESH_DURATION_ON_RECAST: return 11; - case SPELL_ATTR1_IS_PICKPOCKET: return 12; - case SPELL_ATTR1_FARSIGHT: return 13; - case SPELL_ATTR1_CHANNEL_TRACK_TARGET: return 14; - case SPELL_ATTR1_DISPEL_AURAS_ON_IMMUNITY: return 15; - case SPELL_ATTR1_UNAFFECTED_BY_SCHOOL_IMMUNE: return 16; - case SPELL_ATTR1_UNAUTOCASTABLE_BY_PET: return 17; + case SPELL_ATTR1_AURA_UNIQUE: return 11; + case SPELL_ATTR1_FAILURE_BREAKS_STEALTH: return 12; + case SPELL_ATTR1_TOGGLE_FAR_SIGHT: return 13; + case SPELL_ATTR1_TRACK_TARGET_IN_CHANNEL: return 14; + case SPELL_ATTR1_IMMUNITY_PURGES_EFFECT: return 15; + case SPELL_ATTR1_IMMUNITY_TO_HOSTILE_AND_FRIENDLY_EFFECTS: return 16; + case SPELL_ATTR1_NO_AUTOCAST_AI: return 17; case SPELL_ATTR1_PREVENTS_ANIM: return 18; - case SPELL_ATTR1_CANT_TARGET_SELF: return 19; - case SPELL_ATTR1_REQ_COMBO_POINTS1: return 20; - case SPELL_ATTR1_UNK21: return 21; - case SPELL_ATTR1_REQ_COMBO_POINTS2: return 22; - case SPELL_ATTR1_UNK23: return 23; - case SPELL_ATTR1_IS_FISHING: return 24; - case SPELL_ATTR1_UNK25: return 25; - case SPELL_ATTR1_UNK26: return 26; - case SPELL_ATTR1_UNK27: return 27; - case SPELL_ATTR1_DONT_DISPLAY_IN_AURA_BAR: return 28; - case SPELL_ATTR1_CHANNEL_DISPLAY_SPELL_NAME: return 29; - case SPELL_ATTR1_ENABLE_AT_DODGE: return 30; + case SPELL_ATTR1_EXCLUDE_CASTER: return 19; + case SPELL_ATTR1_FINISHING_MOVE_DAMAGE: return 20; + case SPELL_ATTR1_THREAT_ONLY_ON_MISS: return 21; + case SPELL_ATTR1_FINISHING_MOVE_DURATION: return 22; + case SPELL_ATTR1_IGNORE_OWNERS_DEATH: return 23; + case SPELL_ATTR1_SPECIAL_SKILLUP: return 24; + case SPELL_ATTR1_AURA_STAYS_AFTER_COMBAT: return 25; + case SPELL_ATTR1_REQUIRE_ALL_TARGETS: return 26; + case SPELL_ATTR1_DISCOUNT_POWER_ON_MISS: return 27; + case SPELL_ATTR1_NO_AURA_ICON: return 28; + case SPELL_ATTR1_NAME_IN_CHANNEL_BAR: return 29; + case SPELL_ATTR1_DISPEL_ALL_STACKS: return 30; case SPELL_ATTR1_CAST_WHEN_LEARNED: return 31; default: throw std::out_of_range("value"); } diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index 43782937122..5c550058033 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -1066,7 +1066,7 @@ void AuraEffect::PeriodicTick(AuraApplication* aurApp, Unit* caster) const // Update serverside orientation of tracking channeled auras on periodic update ticks // exclude players because can turn during channeling and shouldn't desync orientation client/server - if (caster && !caster->IsPlayer() && m_spellInfo->IsChanneled() && m_spellInfo->HasAttribute(SPELL_ATTR1_CHANNEL_TRACK_TARGET) && caster->m_unitData->ChannelObjects.size()) + if (caster && !caster->IsPlayer() && m_spellInfo->IsChanneled() && m_spellInfo->HasAttribute(SPELL_ATTR1_TRACK_TARGET_IN_CHANNEL) && caster->m_unitData->ChannelObjects.size()) { ObjectGuid const channelGuid = caster->m_unitData->ChannelObjects[0]; if (channelGuid != caster->GetGUID()) @@ -3217,7 +3217,7 @@ void AuraEffect::HandleAuraModSchoolImmunity(AuraApplication const* aurApp, uint target->RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags::StealthOrInvis); // remove all flag auras (they are positive, but they must be removed when you are immune) - if (GetSpellInfo()->HasAttribute(SPELL_ATTR1_DISPEL_AURAS_ON_IMMUNITY) + if (GetSpellInfo()->HasAttribute(SPELL_ATTR1_IMMUNITY_PURGES_EFFECT) && GetSpellInfo()->HasAttribute(SPELL_ATTR2_DAMAGE_REDUCED_SHIELD)) target->RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags::StealthOrInvis); } diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp index 98c849ccee6..2b8353dd6d8 100644 --- a/src/server/game/Spells/Auras/SpellAuras.cpp +++ b/src/server/game/Spells/Auras/SpellAuras.cpp @@ -1064,7 +1064,7 @@ bool Aura::ModStackAmount(int32 num, AuraRemoveMode removeMode /*= AURA_REMOVE_B return true; } - bool refresh = stackAmount >= GetStackAmount() && (m_spellInfo->StackAmount || !m_spellInfo->HasAttribute(SPELL_ATTR1_DONT_REFRESH_DURATION_ON_RECAST)); + bool refresh = stackAmount >= GetStackAmount() && (m_spellInfo->StackAmount || !m_spellInfo->HasAttribute(SPELL_ATTR1_AURA_UNIQUE)); // Update stack amount SetStackAmount(stackAmount); diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index ab0e2a95894..d42b2ce8812 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -589,7 +589,7 @@ m_spellValue(new SpellValue(m_spellInfo, caster)), _spellEvent(nullptr) // Determine if spell can be reflected back to the caster // Patch 1.2 notes: Spell Reflection no longer reflects abilities m_canReflect = caster->IsUnit() && m_spellInfo->DmgClass == SPELL_DAMAGE_CLASS_MAGIC && !m_spellInfo->HasAttribute(SPELL_ATTR0_IS_ABILITY) - && !m_spellInfo->HasAttribute(SPELL_ATTR1_CANT_BE_REFLECTED) && !m_spellInfo->HasAttribute(SPELL_ATTR0_NO_IMMUNITIES) + && !m_spellInfo->HasAttribute(SPELL_ATTR1_NO_REFLECTION) && !m_spellInfo->HasAttribute(SPELL_ATTR0_NO_IMMUNITIES) && !m_spellInfo->IsPassive(); CleanupTargetList(); @@ -2713,7 +2713,7 @@ void Spell::TargetInfo::DoDamageAndTriggers(Spell* spell) } // Failed Pickpocket, reveal rogue - if (MissCondition == SPELL_MISS_RESIST && spell->m_spellInfo->HasAttribute(SPELL_ATTR0_CU_PICKPOCKET) && spell->unitTarget->GetTypeId() == TYPEID_UNIT) + if (MissCondition == SPELL_MISS_RESIST && spell->m_spellInfo->HasAttribute(SPELL_ATTR1_FAILURE_BREAKS_STEALTH) && spell->unitTarget->GetTypeId() == TYPEID_UNIT) { Unit* unitCaster = ASSERT_NOTNULL(spell->m_caster->ToUnit()); unitCaster->RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags::Interacting); @@ -3565,7 +3565,7 @@ void Spell::_cast(bool skipCheck) } if (Unit* unitCaster = m_caster->ToUnit()) - if (m_spellInfo->HasAttribute(SPELL_ATTR1_DISMISS_PET)) + if (m_spellInfo->HasAttribute(SPELL_ATTR1_DISMISS_PET_FIRST)) if (Creature* pet = ObjectAccessor::GetCreature(*m_caster, unitCaster->GetPetGUID())) pet->DespawnOrUnsummon(); @@ -4930,37 +4930,48 @@ void Spell::SendChannelStart(uint32 duration) m_timer = duration; - uint32 channelAuraMask = 0; - uint32 explicitTargetEffectMask = 0xFFFFFFFF; - // if there is an explicit target, only add channel objects from effects that also hit ut - if (!m_targets.GetUnitTargetGUID().IsEmpty()) + if (!m_targets.HasDst()) { - auto explicitTargetItr = std::find_if(m_UniqueTargetInfo.begin(), m_UniqueTargetInfo.end(), [&](TargetInfo const& target) + uint32 channelAuraMask = 0; + uint32 explicitTargetEffectMask = 0xFFFFFFFF; + // if there is an explicit target, only add channel objects from effects that also hit it + if (!m_targets.GetUnitTargetGUID().IsEmpty()) { - return target.TargetGUID == m_targets.GetUnitTargetGUID(); - }); - if (explicitTargetItr != m_UniqueTargetInfo.end()) - explicitTargetEffectMask = explicitTargetItr->EffectMask; - } + auto explicitTargetItr = std::find_if(m_UniqueTargetInfo.begin(), m_UniqueTargetInfo.end(), [&](TargetInfo const& target) + { + return target.TargetGUID == m_targets.GetUnitTargetGUID(); + }); + if (explicitTargetItr != m_UniqueTargetInfo.end()) + explicitTargetEffectMask = explicitTargetItr->EffectMask; + } - for (SpellEffectInfo const& spellEffectInfo : m_spellInfo->GetEffects()) - if (spellEffectInfo.IsEffect(SPELL_EFFECT_APPLY_AURA) && (explicitTargetEffectMask & (1u << spellEffectInfo.EffectIndex))) - channelAuraMask |= 1 << spellEffectInfo.EffectIndex; + for (SpellEffectInfo const& spellEffectInfo : m_spellInfo->GetEffects()) + if (spellEffectInfo.IsEffect(SPELL_EFFECT_APPLY_AURA) && (explicitTargetEffectMask & (1u << spellEffectInfo.EffectIndex))) + channelAuraMask |= 1 << spellEffectInfo.EffectIndex; + + for (TargetInfo const& target : m_UniqueTargetInfo) + { + if (!(target.EffectMask & channelAuraMask)) + continue; + + SpellAttr1 requiredAttribute = target.TargetGUID != unitCaster->GetGUID() ? SPELL_ATTR1_IS_CHANNELLED : SPELL_ATTR1_IS_SELF_CHANNELLED; + if (!m_spellInfo->HasAttribute(requiredAttribute)) + continue; - for (TargetInfo const& target : m_UniqueTargetInfo) - { - if (target.EffectMask & channelAuraMask) unitCaster->AddChannelObject(target.TargetGUID); + } - if (m_UniqueTargetInfo.size() == 1 && m_UniqueGOTargetInfo.empty()) - if (Creature* creatureCaster = unitCaster->ToCreature()) - if (!creatureCaster->HasSpellFocus(this)) - creatureCaster->SetSpellFocus(this, ObjectAccessor::GetWorldObject(*creatureCaster, target.TargetGUID)); + for (GOTargetInfo const& target : m_UniqueGOTargetInfo) + if (target.EffectMask & channelAuraMask) + unitCaster->AddChannelObject(target.TargetGUID); } + else if (m_spellInfo->HasAttribute(SPELL_ATTR1_IS_SELF_CHANNELLED)) + unitCaster->AddChannelObject(unitCaster->GetGUID()); - for (GOTargetInfo const& target : m_UniqueGOTargetInfo) - if (target.EffectMask & channelAuraMask) - unitCaster->AddChannelObject(target.TargetGUID); + if (Creature* creatureCaster = unitCaster->ToCreature()) + if (unitCaster->m_unitData->ChannelObjects.size() == 1 && unitCaster->m_unitData->ChannelObjects[0].IsUnit()) + if (!creatureCaster->HasSpellFocus(this)) + creatureCaster->SetSpellFocus(this, ObjectAccessor::GetWorldObject(*creatureCaster, unitCaster->m_unitData->ChannelObjects[0])); unitCaster->SetChannelSpellId(m_spellInfo->Id); unitCaster->SetChannelVisual(m_SpellVisual); @@ -5079,7 +5090,7 @@ void Spell::TakePower() bool hit = true; if (unitCaster->GetTypeId() == TYPEID_PLAYER) { - if (powerType == POWER_RAGE || powerType == POWER_ENERGY || powerType == POWER_RUNES) + if (m_spellInfo->HasAttribute(SPELL_ATTR1_DISCOUNT_POWER_ON_MISS)) { ObjectGuid targetGUID = m_targets.GetUnitTargetGUID(); if (!targetGUID.IsEmpty()) @@ -5344,7 +5355,7 @@ SpellCastResult Spell::CheckCast(bool strict, int32* param1 /*= nullptr*/, int32 { if (m_spellInfo->HasAttribute(SPELL_ATTR0_USES_RANGED_SLOT) || m_spellInfo->IsNextMeleeSwingSpell() - || m_spellInfo->HasAttribute(SPELL_ATTR1_MELEE_COMBAT_START) + || m_spellInfo->HasAttribute(SPELL_ATTR1_INITIATES_COMBAT_ENABLES_AUTO_ATTACK) || m_spellInfo->HasAttribute(SPELL_ATTR2_UNK20) || m_spellInfo->HasEffect(SPELL_EFFECT_ATTACK) || m_spellInfo->HasEffect(SPELL_EFFECT_NORMALIZED_WEAPON_DMG) @@ -5983,7 +5994,7 @@ SpellCastResult Spell::CheckCast(bool strict, int32* param1 /*= nullptr*/, int32 switch (SummonProperties->Control) { case SUMMON_CATEGORY_PET: - if (!m_spellInfo->HasAttribute(SPELL_ATTR1_DISMISS_PET) && !unitCaster->GetPetGUID().IsEmpty()) + if (!m_spellInfo->HasAttribute(SPELL_ATTR1_DISMISS_PET_FIRST) && !unitCaster->GetPetGUID().IsEmpty()) return SPELL_FAILED_ALREADY_HAVE_SUMMON; [[fallthrough]]; // check both GetPetGUID() and GetCharmGUID for SUMMON_CATEGORY_PET case SUMMON_CATEGORY_PUPPET: @@ -5999,7 +6010,7 @@ SpellCastResult Spell::CheckCast(bool strict, int32* param1 /*= nullptr*/, int32 { if (m_targets.GetUnitTarget()->GetTypeId() != TYPEID_PLAYER) return SPELL_FAILED_BAD_TARGETS; - if (!m_spellInfo->HasAttribute(SPELL_ATTR1_DISMISS_PET) && !m_targets.GetUnitTarget()->GetPetGUID().IsEmpty()) + if (!m_spellInfo->HasAttribute(SPELL_ATTR1_DISMISS_PET_FIRST) && !m_targets.GetUnitTarget()->GetPetGUID().IsEmpty()) return SPELL_FAILED_ALREADY_HAVE_SUMMON; } break; @@ -6020,7 +6031,7 @@ SpellCastResult Spell::CheckCast(bool strict, int32* param1 /*= nullptr*/, int32 .SetOriginalCaster(pet->GetGUID()) .SetTriggeringSpell(this)); } - else if (!m_spellInfo->HasAttribute(SPELL_ATTR1_DISMISS_PET)) + else if (!m_spellInfo->HasAttribute(SPELL_ATTR1_DISMISS_PET_FIRST)) return SPELL_FAILED_ALREADY_HAVE_SUMMON; } @@ -6345,7 +6356,7 @@ SpellCastResult Spell::CheckCast(bool strict, int32* param1 /*= nullptr*/, int32 if (spellEffectInfo.ApplyAuraName == SPELL_AURA_MOD_CHARM || spellEffectInfo.ApplyAuraName == SPELL_AURA_MOD_POSSESS) { - if (!m_spellInfo->HasAttribute(SPELL_ATTR1_DISMISS_PET) && !unitCaster->GetPetGUID().IsEmpty()) + if (!m_spellInfo->HasAttribute(SPELL_ATTR1_DISMISS_PET_FIRST) && !unitCaster->GetPetGUID().IsEmpty()) return SPELL_FAILED_ALREADY_HAVE_SUMMON; if (!unitCaster->GetCharmedGUID().IsEmpty()) @@ -7815,7 +7826,7 @@ bool Spell::IsIgnoringCooldowns() const bool Spell::IsFocusDisabled() const { - return ((_triggeredCastFlags & TRIGGERED_IGNORE_SET_FACING) || (m_spellInfo->IsChanneled() && !m_spellInfo->HasAttribute(SPELL_ATTR1_CHANNEL_TRACK_TARGET))); + return ((_triggeredCastFlags & TRIGGERED_IGNORE_SET_FACING) || (m_spellInfo->IsChanneled() && !m_spellInfo->HasAttribute(SPELL_ATTR1_TRACK_TARGET_IN_CHANNEL))); } bool Spell::IsProcDisabled() const diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index dc528083a0f..4a9aaa12ef9 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -1324,7 +1324,7 @@ void Spell::DoCreateItem(uint32 itemId, ItemContext context /*= ItemContext::NON guild->AddGuildNews(GUILD_NEWS_ITEM_CRAFTED, player->GetGUID(), 0, pProto->GetId()); // we succeeded in creating at least one item, so a levelup is possible - player->UpdateCraftSkill(m_spellInfo->Id); + player->UpdateCraftSkill(m_spellInfo); } } @@ -1353,7 +1353,7 @@ void Spell::EffectCreateItem2() if (m_spellInfo->IsLootCrafting()) { player->AutoStoreLoot(m_spellInfo->Id, LootTemplates_Spell, context, false, true); - player->UpdateCraftSkill(m_spellInfo->Id); + player->UpdateCraftSkill(m_spellInfo); } else // If there's no random loot entries for this spell, pick the item associated with this spell { @@ -2132,12 +2132,16 @@ void Spell::EffectDispel() return false; }); + uint8 dispelledCharges = 1; + if (itr->GetAura()->GetSpellInfo()->HasAttribute(SPELL_ATTR1_DISPEL_ALL_STACKS)) + dispelledCharges = itr->GetDispelCharges(); + if (successItr == successList.end()) - successList.emplace_back(itr->GetAura(), 0, 1); + successList.emplace_back(itr->GetAura(), 0, dispelledCharges); else successItr->IncrementCharges(); - if (!itr->DecrementCharge()) + if (!itr->DecrementCharge(dispelledCharges)) { --remaining; std::swap(*itr, dispelList[remaining]); @@ -2354,7 +2358,7 @@ void Spell::EffectEnchantItemPerm() { // do not increase skill if vellum used if (!(m_CastItem && m_CastItem->GetTemplate()->HasFlag(ITEM_FLAG_NO_REAGENT_COST))) - player->UpdateCraftSkill(m_spellInfo->Id); + player->UpdateCraftSkill(m_spellInfo); uint32 enchant_id = effectInfo->MiscValue; if (!enchant_id) @@ -3416,7 +3420,7 @@ void Spell::EffectDisEnchant() if (Player* caster = m_caster->ToPlayer()) { - caster->UpdateCraftSkill(m_spellInfo->Id); + caster->UpdateCraftSkill(m_spellInfo); caster->SendLoot(itemTarget->GetGUID(), LOOT_DISENCHANTING); } @@ -4605,7 +4609,7 @@ void Spell::EffectStealBeneficialBuff() // Ok if exist some buffs for dispel try dispel it uint32 failCount = 0; - DispelList successList; + std::vector<std::tuple<uint32, ObjectGuid, int32>> successList; successList.reserve(damage); WorldPackets::Spells::DispelFailed dispelFailed; @@ -4622,8 +4626,12 @@ void Spell::EffectStealBeneficialBuff() if (itr->RollDispel()) { - successList.emplace_back(itr->GetAura()->GetId(), itr->GetAura()->GetCasterGUID()); - if (!itr->DecrementCharge()) + uint8 stolenCharges = 1; + if (itr->GetAura()->GetSpellInfo()->HasAttribute(SPELL_ATTR1_DISPEL_ALL_STACKS)) + stolenCharges = itr->GetDispelCharges(); + + successList.emplace_back(itr->GetAura()->GetId(), itr->GetAura()->GetCasterGUID(), int32(stolenCharges)); + if (!itr->DecrementCharge(stolenCharges)) { --remaining; std::swap(*itr, stealList[remaining]); @@ -4651,13 +4659,13 @@ void Spell::EffectStealBeneficialBuff() spellDispellLog.CasterGUID = m_caster->GetGUID(); spellDispellLog.DispelledBySpellID = m_spellInfo->Id; - for (std::pair<uint32, ObjectGuid> const& dispell : successList) + for (auto const& [spellId, auraCaster, stolenCharges] : successList) { WorldPackets::CombatLog::SpellDispellData dispellData; - dispellData.SpellID = dispell.first; + dispellData.SpellID = spellId; dispellData.Harmful = false; // TODO: use me - unitTarget->RemoveAurasDueToSpellBySteal(dispell.first, dispell.second, m_caster); + unitTarget->RemoveAurasDueToSpellBySteal(spellId, auraCaster, m_caster, stolenCharges); spellDispellLog.DispellData.emplace_back(dispellData); } diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp index 8bee05dbeb1..035a19f744e 100644 --- a/src/server/game/Spells/SpellInfo.cpp +++ b/src/server/game/Spells/SpellInfo.cpp @@ -1524,7 +1524,7 @@ bool SpellInfo::IsAutocastable() const { if (IsPassive()) return false; - if (HasAttribute(SPELL_ATTR1_UNAUTOCASTABLE_BY_PET)) + if (HasAttribute(SPELL_ATTR1_NO_AUTOCAST_AI)) return false; return true; } @@ -1643,7 +1643,7 @@ bool SpellInfo::IsPositiveEffect(uint8 effIndex) const bool SpellInfo::IsChanneled() const { - return HasAttribute(SpellAttr1(SPELL_ATTR1_CHANNELED_1 | SPELL_ATTR1_CHANNELED_2)); + return HasAttribute(SpellAttr1(SPELL_ATTR1_IS_CHANNELLED | SPELL_ATTR1_IS_SELF_CHANNELLED)); } bool SpellInfo::IsMoveAllowedChannel() const @@ -1653,7 +1653,7 @@ bool SpellInfo::IsMoveAllowedChannel() const bool SpellInfo::NeedsComboPoints() const { - return HasAttribute(SpellAttr1(SPELL_ATTR1_REQ_COMBO_POINTS1 | SPELL_ATTR1_REQ_COMBO_POINTS2)); + return HasAttribute(SpellAttr1(SPELL_ATTR1_FINISHING_MOVE_DAMAGE | SPELL_ATTR1_FINISHING_MOVE_DURATION)); } bool SpellInfo::IsNextMeleeSwingSpell() const @@ -1663,7 +1663,7 @@ bool SpellInfo::IsNextMeleeSwingSpell() const bool SpellInfo::IsBreakingStealth() const { - return !HasAttribute(SPELL_ATTR1_NOT_BREAK_STEALTH); + return !HasAttribute(SPELL_ATTR1_ALLOW_WHILE_STEALTHED); } bool SpellInfo::IsRangedWeaponSpell() const @@ -1784,7 +1784,7 @@ bool SpellInfo::CanPierceImmuneAura(SpellInfo const* auraSpellInfo) const return true; // these spells (Cyclone for example) can pierce all... - if (HasAttribute(SPELL_ATTR1_UNAFFECTED_BY_SCHOOL_IMMUNE) || HasAttribute(SPELL_ATTR2_UNAFFECTED_BY_AURA_SCHOOL_IMMUNE)) + if (HasAttribute(SPELL_ATTR1_IMMUNITY_TO_HOSTILE_AND_FRIENDLY_EFFECTS) || HasAttribute(SPELL_ATTR2_UNAFFECTED_BY_AURA_SCHOOL_IMMUNE)) { // ...but not these (Divine shield, Ice block, Cyclone and Banish for example) if (auraSpellInfo->Mechanic != MECHANIC_IMMUNE_SHIELD && @@ -1794,7 +1794,7 @@ bool SpellInfo::CanPierceImmuneAura(SpellInfo const* auraSpellInfo) const } // Dispels other auras on immunity, check if this spell makes the unit immune to aura - if (HasAttribute(SPELL_ATTR1_DISPEL_AURAS_ON_IMMUNITY) && CanSpellProvideImmunityAgainstAura(auraSpellInfo)) + if (HasAttribute(SPELL_ATTR1_IMMUNITY_PURGES_EFFECT) && CanSpellProvideImmunityAgainstAura(auraSpellInfo)) return true; return false; @@ -1811,7 +1811,7 @@ bool SpellInfo::CanDispelAura(SpellInfo const* auraSpellInfo) const return true; // These auras (Cyclone for example) are not dispelable - if ((auraSpellInfo->HasAttribute(SPELL_ATTR1_UNAFFECTED_BY_SCHOOL_IMMUNE) && auraSpellInfo->Mechanic != MECHANIC_NONE) + if ((auraSpellInfo->HasAttribute(SPELL_ATTR1_IMMUNITY_TO_HOSTILE_AND_FRIENDLY_EFFECTS) && auraSpellInfo->Mechanic != MECHANIC_NONE) || auraSpellInfo->HasAttribute(SPELL_ATTR2_UNAFFECTED_BY_AURA_SCHOOL_IMMUNE)) return false; @@ -2108,7 +2108,7 @@ SpellCastResult SpellInfo::CheckLocation(uint32 map_id, uint32 zone_id, uint32 a SpellCastResult SpellInfo::CheckTarget(WorldObject const* caster, WorldObject const* target, bool implicit /*= true*/) const { - if (HasAttribute(SPELL_ATTR1_CANT_TARGET_SELF) && caster == target) + if (HasAttribute(SPELL_ATTR1_EXCLUDE_CASTER) && caster == target) return SPELL_FAILED_BAD_TARGETS; // check visibility - ignore stealth for implicit (area) targets @@ -2121,7 +2121,7 @@ SpellCastResult SpellInfo::CheckTarget(WorldObject const* caster, WorldObject co if (unitTarget) { // spells cannot be cast if target has a pet in combat either - if (HasAttribute(SPELL_ATTR1_CANT_TARGET_IN_COMBAT) && (unitTarget->IsInCombat() || unitTarget->HasUnitFlag(UNIT_FLAG_PET_IN_COMBAT))) + if (HasAttribute(SPELL_ATTR1_ONLY_PEACEFUL_TARGETS) && (unitTarget->IsInCombat() || unitTarget->HasUnitFlag(UNIT_FLAG_PET_IN_COMBAT))) return SPELL_FAILED_TARGET_AFFECTING_COMBAT; // only spells with SPELL_ATTR3_ONLY_TARGET_GHOSTS can target ghosts @@ -3519,7 +3519,7 @@ void SpellInfo::ApplyAllSpellImmunitiesTo(Unit* target, SpellEffectInfo const& s { target->ApplySpellImmune(Id, IMMUNITY_SCHOOL, schoolImmunity, apply); - if (apply && HasAttribute(SPELL_ATTR1_DISPEL_AURAS_ON_IMMUNITY)) + if (apply && HasAttribute(SPELL_ATTR1_IMMUNITY_PURGES_EFFECT)) { target->RemoveAppliedAuras([this, schoolImmunity](AuraApplication const* aurApp) -> bool { @@ -3542,7 +3542,7 @@ void SpellInfo::ApplyAllSpellImmunitiesTo(Unit* target, SpellEffectInfo const& s if (mechanicImmunity & (1 << i)) target->ApplySpellImmune(Id, IMMUNITY_MECHANIC, i, apply); - if (apply && HasAttribute(SPELL_ATTR1_DISPEL_AURAS_ON_IMMUNITY)) + if (apply && HasAttribute(SPELL_ATTR1_IMMUNITY_PURGES_EFFECT)) { // exception for purely snare mechanic (eg. hands of freedom)! if (mechanicImmunity == (1 << MECHANIC_SNARE)) @@ -3556,7 +3556,7 @@ void SpellInfo::ApplyAllSpellImmunitiesTo(Unit* target, SpellEffectInfo const& s { target->ApplySpellImmune(Id, IMMUNITY_DISPEL, dispelImmunity, apply); - if (apply && HasAttribute(SPELL_ATTR1_DISPEL_AURAS_ON_IMMUNITY)) + if (apply && HasAttribute(SPELL_ATTR1_IMMUNITY_PURGES_EFFECT)) { target->RemoveAppliedAuras([dispelImmunity](AuraApplication const* aurApp) -> bool { @@ -3580,7 +3580,7 @@ void SpellInfo::ApplyAllSpellImmunitiesTo(Unit* target, SpellEffectInfo const& s for (AuraType auraType : immuneInfo.AuraTypeImmune) { target->ApplySpellImmune(Id, IMMUNITY_STATE, auraType, apply); - if (apply && HasAttribute(SPELL_ATTR1_DISPEL_AURAS_ON_IMMUNITY)) + if (apply && HasAttribute(SPELL_ATTR1_IMMUNITY_PURGES_EFFECT)) target->RemoveAurasByType(auraType); } @@ -3600,7 +3600,7 @@ bool SpellInfo::CanSpellProvideImmunityAgainstAura(SpellInfo const* auraSpellInf ImmunityInfo const& immuneInfo = effectInfo.GetImmunityInfo(); - if (!auraSpellInfo->HasAttribute(SPELL_ATTR1_UNAFFECTED_BY_SCHOOL_IMMUNE) && !auraSpellInfo->HasAttribute(SPELL_ATTR2_UNAFFECTED_BY_AURA_SCHOOL_IMMUNE)) + if (!auraSpellInfo->HasAttribute(SPELL_ATTR1_IMMUNITY_TO_HOSTILE_AND_FRIENDLY_EFFECTS) && !auraSpellInfo->HasAttribute(SPELL_ATTR2_UNAFFECTED_BY_AURA_SCHOOL_IMMUNE)) { if (uint32 schoolImmunity = immuneInfo.SchoolImmuneMask) if ((auraSpellInfo->SchoolMask & schoolImmunity) != 0) @@ -3672,7 +3672,7 @@ bool SpellInfo::CanSpellProvideImmunityAgainstAura(SpellInfo const* auraSpellInf // based on client Spell_C::CancelsAuraEffect bool SpellInfo::SpellCancelsAuraEffect(AuraEffect const* aurEff) const { - if (!HasAttribute(SPELL_ATTR1_DISPEL_AURAS_ON_IMMUNITY)) + if (!HasAttribute(SPELL_ATTR1_IMMUNITY_PURGES_EFFECT)) return false; if (aurEff->GetSpellInfo()->HasAttribute(SPELL_ATTR0_NO_IMMUNITIES)) @@ -3875,7 +3875,7 @@ Optional<SpellPowerCost> SpellInfo::CalcPowerCost(SpellPowerEntry const* power, return {}; // Spell drain all exist power on cast (Only paladin lay of Hands) - if (HasAttribute(SPELL_ATTR1_DRAIN_ALL_POWER)) + if (HasAttribute(SPELL_ATTR1_USE_ALL_MANA)) { // If power type - health drain all if (power->PowerType == POWER_HEALTH) @@ -4473,7 +4473,7 @@ bool _isPositiveEffectImpl(SpellInfo const* spellInfo, SpellEffectInfo const& ef } // Special case: effects which determine positivity of whole spell - if (spellInfo->HasAttribute(SPELL_ATTR1_DONT_REFRESH_DURATION_ON_RECAST)) + if (spellInfo->HasAttribute(SPELL_ATTR1_AURA_UNIQUE)) { // check for targets, there seems to be an assortment of dummy triggering spells that should be negative for (SpellEffectInfo const& otherEffect : spellInfo->GetEffects()) diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index 56e9c85da22..07dc8bb7cde 100644 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -4033,7 +4033,7 @@ void SpellMgr::LoadSpellInfoCorrections() // spell should dispel area aura, but doesn't have the attribute // may be db data bug, or blizz may keep reapplying area auras every update with checking immunity // that will be clear if we get more spells with problem like this - spellInfo->AttributesEx |= SPELL_ATTR1_DISPEL_AURAS_ON_IMMUNITY; + spellInfo->AttributesEx |= SPELL_ATTR1_IMMUNITY_PURGES_EFFECT; }); // Blizzard (Thorim) @@ -4424,7 +4424,7 @@ void SpellMgr::LoadSpellInfoCorrections() // Awaken Flames ApplySpellFix({ 75888 }, [](SpellInfo* spellInfo) { - spellInfo->AttributesEx |= SPELL_ATTR1_CANT_TARGET_SELF; + spellInfo->AttributesEx |= SPELL_ATTR1_EXCLUDE_CASTER; }); // ENDOF RUBY SANCTUM SPELLS @@ -4523,7 +4523,7 @@ void SpellMgr::LoadSpellInfoCorrections() // Gaze of Occu'thar ApplySpellFix({ 96942 }, [](SpellInfo* spellInfo) { - spellInfo->AttributesEx &= ~SPELL_ATTR1_CHANNELED_1; + spellInfo->AttributesEx &= ~SPELL_ATTR1_IS_CHANNELLED; }); // Evolution diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_thorim.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_thorim.cpp index 2225ccf68c4..3bae76d19c8 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_thorim.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_thorim.cpp @@ -1031,7 +1031,7 @@ struct npc_thorim_trashAI : public ScriptedAI static Unit* GetHealTarget(SpellInfo const* spellInfo, Unit* caster) { Unit* healTarget = nullptr; - if (!spellInfo->HasAttribute(SPELL_ATTR1_CANT_TARGET_SELF) && !roll_chance_f(caster->GetHealthPct()) && ((caster->GetHealth() + GetRemainingHealOn(caster) + GetTotalHeal(spellInfo, caster)) <= caster->GetMaxHealth())) + if (!spellInfo->HasAttribute(SPELL_ATTR1_EXCLUDE_CASTER) && !roll_chance_f(caster->GetHealthPct()) && ((caster->GetHealth() + GetRemainingHealOn(caster) + GetTotalHeal(spellInfo, caster)) <= caster->GetMaxHealth())) healTarget = caster; else healTarget = GetUnitWithMostMissingHp(spellInfo, caster); |