diff options
author | Shauren <shauren.trinity@gmail.com> | 2023-10-21 14:49:42 +0200 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2023-10-21 14:49:42 +0200 |
commit | 4e87bd7942d932225436940f62e26d48719a42dd (patch) | |
tree | dc03209881d6a12ecc7bd02ca441ef6251d9729d /src | |
parent | 42e6a1045690cb536d11610b01bf2331ebb033e0 (diff) |
Core/Spells: Named and implemented most of SpellAttr7
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/Entities/Object/Object.cpp | 4 | ||||
-rw-r--r-- | src/server/game/Entities/Pet/Pet.cpp | 18 | ||||
-rw-r--r-- | src/server/game/Entities/Unit/Unit.cpp | 33 | ||||
-rw-r--r-- | src/server/game/Entities/Unit/Unit.h | 2 | ||||
-rw-r--r-- | src/server/game/Miscellaneous/SharedDefines.h | 68 | ||||
-rw-r--r-- | src/server/game/Miscellaneous/enuminfo_SharedDefines.cpp | 168 | ||||
-rw-r--r-- | src/server/game/Spells/Auras/SpellAuraEffects.cpp | 8 | ||||
-rw-r--r-- | src/server/game/Spells/Auras/SpellAuras.cpp | 14 | ||||
-rw-r--r-- | src/server/game/Spells/Spell.cpp | 78 | ||||
-rw-r--r-- | src/server/game/Spells/Spell.h | 1 | ||||
-rw-r--r-- | src/server/game/Spells/SpellEffects.cpp | 6 | ||||
-rw-r--r-- | src/server/game/Spells/SpellInfo.cpp | 2 | ||||
-rw-r--r-- | src/server/scripts/Northrend/IcecrownCitadel/go_icecrown_citadel_teleport.cpp | 2 |
13 files changed, 208 insertions, 196 deletions
diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index 1a141a7203d..f736bb676c0 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -2392,7 +2392,7 @@ int32 WorldObject::ModSpellDuration(SpellInfo const* spellInfo, WorldObject cons return duration; // some auras are not affected by duration modifiers - if (spellInfo->HasAttribute(SPELL_ATTR7_IGNORE_DURATION_MODS)) + if (spellInfo->HasAttribute(SPELL_ATTR7_NO_TARGET_DURATION_MOD)) return duration; // cut duration only of negative effects @@ -2633,7 +2633,7 @@ SpellMissInfo WorldObject::SpellHitResult(Unit* victim, SpellInfo const* spellIn reflectchance += victim->GetTotalAuraModifierByMiscMask(SPELL_AURA_REFLECT_SPELLS_SCHOOL, spellInfo->GetSchoolMask()); if (reflectchance > 0 && roll_chance_i(reflectchance)) - return SPELL_MISS_REFLECT; + return spellInfo->HasAttribute(SPELL_ATTR7_REFLECTION_ONLY_DEFENDS) ? SPELL_MISS_DEFLECT : SPELL_MISS_REFLECT; } if (spellInfo->HasAttribute(SPELL_ATTR3_ALWAYS_HIT)) diff --git a/src/server/game/Entities/Pet/Pet.cpp b/src/server/game/Entities/Pet/Pet.cpp index dd66132f216..067b2f6b74f 100644 --- a/src/server/game/Entities/Pet/Pet.cpp +++ b/src/server/game/Entities/Pet/Pet.cpp @@ -371,24 +371,6 @@ bool Pet::LoadPetFromDB(Player* owner, uint32 petEntry, uint32 petnumber, bool c petStable->SetCurrentActivePetIndex(newPetIndex); } - // Send fake summon spell cast - this is needed for correct cooldown application for spells - // Example: 46584 - without this cooldown (which should be set always when pet is loaded) isn't set clientside - /// @todo pets should be summoned from real cast instead of just faking it? - if (petInfo->CreatedBySpellId) - { - WorldPackets::Spells::SpellGo spellGo; - WorldPackets::Spells::SpellCastData& castData = spellGo.Cast; - - castData.CasterGUID = owner->GetGUID(); - castData.CasterUnit = owner->GetGUID(); - castData.CastID = ObjectGuid::Create<HighGuid::Cast>(SPELL_CAST_SOURCE_NORMAL, petInfo->CreatedBySpellId, map->GenerateLowGuid<HighGuid::Cast>()); - castData.SpellID = petInfo->CreatedBySpellId; - castData.CastFlags = CAST_FLAG_UNKNOWN_9; - castData.CastTime = getMSTime(); - - owner->SendMessageToSet(spellGo.Write(), true); - } - owner->SetMinion(this, true); if (!isTemporarySummon) diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 530f459f45c..d5e611f4906 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -917,7 +917,7 @@ bool Unit::HasBreakableByDamageCrowdControlAura(Unit* excludeCasterChannel) cons if (Player* killer = attacker->ToPlayer()) { // in bg, count dmg if victim is also a player - if (victim->GetTypeId() == TYPEID_PLAYER) + if (victim->GetTypeId() == TYPEID_PLAYER && !(spellProto && spellProto->HasAttribute(SPELL_ATTR7_DO_NOT_COUNT_FOR_PVP_SCOREBOARD))) if (Battleground* bg = killer->GetBattleground()) bg->UpdatePlayerScore(killer, SCORE_DAMAGE_DONE, damageDone); @@ -1054,7 +1054,7 @@ bool Unit::HasBreakableByDamageCrowdControlAura(Unit* excludeCasterChannel) cons if (damagetype != NODAMAGE && damagetype != DOT) { - if (victim != attacker && (!spellProto || !(spellProto->HasAttribute(SPELL_ATTR6_NO_PUSHBACK) || spellProto->HasAttribute(SPELL_ATTR7_NO_PUSHBACK_ON_DAMAGE) || spellProto->HasAttribute(SPELL_ATTR3_TREAT_AS_PERIODIC)))) + if (victim != attacker && (!spellProto || !(spellProto->HasAttribute(SPELL_ATTR6_NO_PUSHBACK) || spellProto->HasAttribute(SPELL_ATTR7_DONT_CAUSE_SPELL_PUSHBACK) || spellProto->HasAttribute(SPELL_ATTR3_TREAT_AS_PERIODIC)))) { if (Spell* spell = victim->m_currentSpells[CURRENT_GENERIC_SPELL]) { @@ -3783,7 +3783,7 @@ void Unit::RemoveAurasDueToSpellByDispel(uint32 spellId, uint32 dispellerSpellId // Call OnDispel hook on AuraScript aura->CallScriptDispel(&dispelInfo); - if (aura->GetSpellInfo()->HasAttribute(SPELL_ATTR7_DISPEL_CHARGES)) + if (aura->GetSpellInfo()->HasAttribute(SPELL_ATTR7_DISPEL_REMOVES_CHARGES)) aura->ModCharges(-dispelInfo.GetRemovedCharges(), AURA_REMOVE_BY_ENEMY_SPELL); else aura->ModStackAmount(-dispelInfo.GetRemovedCharges(), AURA_REMOVE_BY_ENEMY_SPELL); @@ -3828,7 +3828,7 @@ void Unit::RemoveAurasDueToSpellBySteal(uint32 spellId, ObjectGuid casterGUID, W } } - bool stealCharge = aura->GetSpellInfo()->HasAttribute(SPELL_ATTR7_DISPEL_CHARGES); + bool stealCharge = aura->GetSpellInfo()->HasAttribute(SPELL_ATTR7_DISPEL_REMOVES_CHARGES); // Cast duration to unsigned to prevent permanent aura's such as Righteous Fury being permanently added to caster uint32 dur = std::min(2u * MINUTE * IN_MILLISECONDS, uint32(aura->GetDuration())); @@ -4532,7 +4532,7 @@ void Unit::GetDispellableAuraList(WorldObject const* caster, uint32 dispelMask, // The charges / stack amounts don't count towards the total number of auras that can be dispelled. // Ie: A dispel on a target with 5 stacks of Winters Chill and a Polymorph has 1 / (1 + 1) -> 50% chance to dispell // Polymorph instead of 1 / (5 + 1) -> 16%. - bool const dispelCharges = aura->GetSpellInfo()->HasAttribute(SPELL_ATTR7_DISPEL_CHARGES); + bool const dispelCharges = aura->GetSpellInfo()->HasAttribute(SPELL_ATTR7_DISPEL_REMOVES_CHARGES); uint8 charges = dispelCharges ? aura->GetCharges() : aura->GetStackAmount(); if (charges > 0) dispelList.emplace_back(aura, chance, charges); @@ -5327,10 +5327,20 @@ void Unit::SendSpellNonMeleeDamageLog(SpellNonMeleeDamage const* log) } WeaponAttackType attType = damageInfo ? damageInfo->GetAttackType() : BASE_ATTACK; - if (typeMaskActor && actor) + SpellInfo const* spellInfo = [&]() -> SpellInfo const* + { + if (spell) + return spell->GetSpellInfo(); + if (damageInfo) + return damageInfo->GetSpellInfo(); + if (healInfo) + return healInfo->GetSpellInfo(); + return nullptr; + }(); + if (typeMaskActor && actor && !(spellInfo && spellInfo->HasAttribute(SPELL_ATTR3_SUPPRESS_CASTER_PROCS))) actor->ProcSkillsAndReactives(false, actionTarget, typeMaskActor, hitMask, attType); - if (typeMaskActionTarget && actionTarget) + if (typeMaskActionTarget && actionTarget && !(spellInfo && spellInfo->HasAttribute(SPELL_ATTR3_SUPPRESS_TARGET_PROCS))) actionTarget->ProcSkillsAndReactives(true, actor, typeMaskActionTarget, hitMask, attType); if (actor) @@ -6250,8 +6260,9 @@ void Unit::SetCharm(Unit* charm, bool apply) { if (Player* player = unit->ToPlayer()) { - if (Battleground* bg = player->GetBattleground()) - bg->UpdatePlayerScore(player, SCORE_HEALING_DONE, gain); + if (!healInfo.GetSpellInfo() || !healInfo.GetSpellInfo()->HasAttribute(SPELL_ATTR7_DO_NOT_COUNT_FOR_PVP_SCOREBOARD)) + if (Battleground* bg = player->GetBattleground()) + bg->UpdatePlayerScore(player, SCORE_HEALING_DONE, gain); // use the actual gain, as the overheal shall not be counted, skip gain 0 (it ignored anyway in to criteria) if (gain) @@ -11847,10 +11858,10 @@ bool Unit::CanApplyResilience() const *damage -= target->GetDamageReduction(*damage); } -int32 Unit::CalculateAOEAvoidance(int32 damage, uint32 schoolMask, ObjectGuid const& casterGuid) const +int32 Unit::CalculateAOEAvoidance(int32 damage, uint32 schoolMask, bool npcCaster) const { damage = int32(float(damage) * GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_AOE_DAMAGE_AVOIDANCE, schoolMask)); - if (casterGuid.IsAnyTypeCreature()) + if (npcCaster) damage = int32(float(damage) * GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_CREATURE_AOE_DAMAGE_AVOIDANCE, schoolMask)); return damage; diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index 32d56807dab..04be57e1837 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -1074,7 +1074,7 @@ class TC_GAME_API Unit : public WorldObject virtual bool CanApplyResilience() const; static void ApplyResilience(Unit const* victim, int32* damage); - int32 CalculateAOEAvoidance(int32 damage, uint32 schoolMask, ObjectGuid const& casterGuid) const; + int32 CalculateAOEAvoidance(int32 damage, uint32 schoolMask, bool npcCaster) const; float MeleeSpellMissChance(Unit const* victim, WeaponAttackType attType, SpellInfo const* spellInfo) const override; SpellMissInfo MeleeSpellHitResult(Unit* victim, SpellInfo const* spellInfo) const override; diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h index edcf30d293a..8a9fd0e6f55 100644 --- a/src/server/game/Miscellaneous/SharedDefines.h +++ b/src/server/game/Miscellaneous/SharedDefines.h @@ -685,38 +685,38 @@ enum SpellAttr6 : uint32 // EnumUtils: DESCRIBE THIS enum SpellAttr7 : uint32 { - SPELL_ATTR7_UNK0 = 0x00000001, // TITLE Unknown attribute 0@Attr7 - SPELL_ATTR7_IGNORE_DURATION_MODS = 0x00000002, // TITLE Ignore duration modifiers - SPELL_ATTR7_DISABLE_AURA_WHILE_DEAD = 0x00000004, // TITLE Disable Aura While Dead - SPELL_ATTR7_IS_CHEAT_SPELL = 0x00000008, // TITLE Is cheat spell DESCRIPTION Cannot cast if caster doesn't have UnitFlag2 & UNIT_FLAG2_ALLOW_CHEAT_SPELLS - SPELL_ATTR7_UNK4 = 0x00000010, // TITLE Unknown attribute 4@Attr7 DESCRIPTION Soulstone related? - SPELL_ATTR7_SUMMON_TOTEM = 0x00000020, // TITLE Summons player-owned totem - SPELL_ATTR7_NO_PUSHBACK_ON_DAMAGE = 0x00000040, // TITLE Damage dealt by this does not cause spell pushback - SPELL_ATTR7_UNK7 = 0x00000080, // TITLE Unknown attribute 7@Attr7 - SPELL_ATTR7_HORDE_ONLY = 0x00000100, // TITLE Horde only - SPELL_ATTR7_ALLIANCE_ONLY = 0x00000200, // TITLE Alliance only - SPELL_ATTR7_DISPEL_CHARGES = 0x00000400, // TITLE Dispel/Spellsteal remove individual charges - SPELL_ATTR7_INTERRUPT_ONLY_NONPLAYER = 0x00000800, // TITLE Can Cause Interrupt DESCRIPTION Only interrupt non-player casting - SPELL_ATTR7_SILENCE_ONLY_NONPLAYER = 0x00001000, // TITLE Can Cause Silence - SPELL_ATTR7_CAN_ALWAYS_BE_INTERRUPTED = 0x00002000, // TITLE No UI Not Interruptible DESCRIPTION Can always be interrupted, even if caster is immune - SPELL_ATTR7_UNK14 = 0x00004000, // TITLE Unknown attribute 14@Attr7 - SPELL_ATTR7_UNK15 = 0x00008000, // TITLE Unknown attribute 15@Attr7 DESCRIPTION Exorcism - guaranteed crit vs families? - SPELL_ATTR7_HIDDEN_IN_SPELLBOOK_WHEN_LEARNED = 0x00010000, // TITLE Only In Spellbook Until Learned DESCRIPTION After learning these spells become hidden in spellbook (but are visible when not learned for low level characters) - SPELL_ATTR7_UNK17 = 0x00020000, // TITLE Unknown attribute 17@Attr7 - SPELL_ATTR7_HAS_CHARGE_EFFECT = 0x00040000, // TITLE Has charge effect - SPELL_ATTR7_ZONE_TELEPORT = 0x00080000, // TITLE Is zone teleport - SPELL_ATTR7_UNK20 = 0x00100000, // TITLE Unknown attribute 20@Attr7 DESCRIPTION Invulnerability related? - SPELL_ATTR7_UNK21 = 0x00200000, // TITLE Unknown attribute 21@Attr7 - SPELL_ATTR7_IGNORES_COLD_WEATHER_FLYING_REQUIREMENT = 0x00400000, // TITLE Ignores Cold Weather Flying Requirement - SPELL_ATTR7_NO_ATTACK_DODGE = 0x00800000, // TITLE No Attack Dodge - SPELL_ATTR7_NO_ATTACK_PARRY = 0x01000000, // TITLE No Attack Parry - SPELL_ATTR7_NO_ATTACK_MISS = 0x02000000, // TITLE No Attack Miss - SPELL_ATTR7_UNK26 = 0x04000000, // TITLE Unknown attribute 26@Attr7 - SPELL_ATTR7_BYPASS_NO_RESURRECT_AURA = 0x08000000, // TITLE Bypass No Resurrect Aura - SPELL_ATTR7_CONSOLIDATED_RAID_BUFF = 0x10000000, // TITLE Consolidate in raid buff frame (client only) - SPELL_ATTR7_UNK29 = 0x20000000, // TITLE Unknown attribute 29@Attr7 - SPELL_ATTR7_UNK30 = 0x40000000, // TITLE Unknown attribute 30@Attr7 - SPELL_ATTR7_CLIENT_INDICATOR = 0x80000000 // TITLE Client indicator (client only) + SPELL_ATTR7_ALLOW_SPELL_REFLECTION = 0x00000001, // TITLE Allow Spell Reflection + SPELL_ATTR7_NO_TARGET_DURATION_MOD = 0x00000002, // TITLE No Target Duration Mod + SPELL_ATTR7_DISABLE_AURA_WHILE_DEAD = 0x00000004, // TITLE Disable Aura While Dead + SPELL_ATTR7_DEBUG_SPELL = 0x00000008, // TITLE Debug Spell DESCRIPTION Cannot cast if caster doesn't have UnitFlag2 & UNIT_FLAG2_ALLOW_CHEAT_SPELLS + SPELL_ATTR7_TREAT_AS_RAID_BUFF = 0x00000010, /*NYI*/ // TITLE Treat as Raid Buff + SPELL_ATTR7_CAN_BE_MULTI_CAST = 0x00000020, // TITLE Can Be Multi Cast + SPELL_ATTR7_DONT_CAUSE_SPELL_PUSHBACK = 0x00000040, // TITLE Don't Cause Spell Pushback DESCRIPTION Damage dealt by this does not cause spell pushback + SPELL_ATTR7_PREPARE_FOR_VEHICLE_CONTROL_END = 0x00000080, /*NYI*/ // TITLE Prepare for Vehicle Control End + SPELL_ATTR7_HORDE_SPECIFIC_SPELL = 0x00000100, /*NYI*/ // TITLE Horde Specific Spell + SPELL_ATTR7_ALLIANCE_SPECIFIC_SPELL = 0x00000200, /*NYI*/ // TITLE Alliance Specific Spell + SPELL_ATTR7_DISPEL_REMOVES_CHARGES = 0x00000400, // TITLE Dispel Removes Charges DESCRIPTION Dispel/Spellsteal remove individual charges + SPELL_ATTR7_CAN_CAUSE_INTERRUPT = 0x00000800, // TITLE Can Cause Interrupt DESCRIPTION Only interrupt non-player casting + SPELL_ATTR7_CAN_CAUSE_SILENCE = 0x00001000, /*NYI*/ // TITLE Can Cause Silence + SPELL_ATTR7_NO_UI_NOT_INTERRUPTIBLE = 0x00002000, // TITLE No UI Not Interruptible DESCRIPTION Can always be interrupted, even if caster is immune + SPELL_ATTR7_RECAST_ON_RESUMMON = 0x00004000, /*NYI - deprecated attribute, there is no SPELL_GO sent anymore on pet resummon*/ // TITLE Recast On Resummon + SPELL_ATTR7_RESET_SWING_TIMER_AT_SPELL_START = 0x00008000, // TITLE Reset Swing Timer at spell start + SPELL_ATTR7_ONLY_IN_SPELLBOOK_UNTIL_LEARNED = 0x00010000, // TITLE Only In Spellbook Until Learned DESCRIPTION After learning these spells become hidden in spellbook (but are visible when not learned for low level characters) + SPELL_ATTR7_DO_NOT_LOG_PVP_KILL = 0x00020000, /*NYI, only used by 1 spell that is already filtered out in pvp credits because its self targeting*/ // TITLE Do Not Log PvP Kill + SPELL_ATTR7_ATTACK_ON_CHARGE_TO_UNIT = 0x00040000, // TITLE Attack on Charge to Unit + SPELL_ATTR7_REPORT_SPELL_FAILURE_TO_UNIT_TARGET = 0x00080000, // TITLE Report Spell failure to unit target + SPELL_ATTR7_NO_CLIENT_FAIL_WHILE_STUNNED_FLEEING_CONFUSED = 0x00100000, // TITLE No Client Fail While Stunned, Fleeing, Confused DESCRIPTION Clientside - skips stunned/fleeing/confused checks + SPELL_ATTR7_RETAIN_COOLDOWN_THROUGH_LOAD = 0x00200000, /*NYI*/ // TITLE Retain Cooldown Through Load + SPELL_ATTR7_IGNORES_COLD_WEATHER_FLYING_REQUIREMENT = 0x00400000, /*NYI - deprecated attribute*/ // TITLE Ignores Cold Weather Flying Requirement + SPELL_ATTR7_NO_ATTACK_DODGE = 0x00800000, // TITLE No Attack Dodge + SPELL_ATTR7_NO_ATTACK_PARRY = 0x01000000, // TITLE No Attack Parry + SPELL_ATTR7_NO_ATTACK_MISS = 0x02000000, // TITLE No Attack Miss + SPELL_ATTR7_TREAT_AS_NPC_AOE = 0x04000000, // TITLE Treat as NPC AoE + SPELL_ATTR7_BYPASS_NO_RESURRECT_AURA = 0x08000000, // TITLE Bypass No Resurrect Aura + SPELL_ATTR7_DO_NOT_COUNT_FOR_PVP_SCOREBOARD = 0x10000000, // TITLE Do Not Count For PvP Scoreboard + SPELL_ATTR7_REFLECTION_ONLY_DEFENDS = 0x20000000, // TITLE Reflection Only Defends + SPELL_ATTR7_CAN_PROC_FROM_SUPPRESSED_TARGET_PROCS = 0x40000000, // TITLE Can Proc From Suppressed Target Procs + SPELL_ATTR7_ALWAYS_CAST_LOG = 0x80000000 // TITLE Always Cast Log }; // EnumUtils: DESCRIBE THIS @@ -870,8 +870,8 @@ enum SpellAttr11 : uint32 // EnumUtils: DESCRIBE THIS enum SpellAttr12 : uint32 { - SPELL_ATTR12_UNK0 = 0x00000001, // TITLE Unknown attribute 0@Attr12 - SPELL_ATTR12_UNK1 = 0x00000002, // TITLE Unknown attribute 1@Attr12 + SPELL_ATTR12_ENABLE_PROCS_FROM_SUPPRESSED_CASTER_PROCS = 0x00000001, // TITLE Enable Procs from Suppressed Caster Procs + SPELL_ATTR12_CAN_PROC_FROM_SUPPRESSED_CASTER_PROCS = 0x00000002, // TITLE Can Proc from Suppressed Caster Procs SPELL_ATTR12_UNK2 = 0x00000004, // TITLE Unknown attribute 2@Attr12 SPELL_ATTR12_UNK3 = 0x00000008, // TITLE Unknown attribute 3@Attr12 SPELL_ATTR12_UNK4 = 0x00000010, // TITLE Unknown attribute 4@Attr12 diff --git a/src/server/game/Miscellaneous/enuminfo_SharedDefines.cpp b/src/server/game/Miscellaneous/enuminfo_SharedDefines.cpp index 1887aaa6d2d..48651b9e309 100644 --- a/src/server/game/Miscellaneous/enuminfo_SharedDefines.cpp +++ b/src/server/game/Miscellaneous/enuminfo_SharedDefines.cpp @@ -1177,38 +1177,38 @@ TC_API_EXPORT EnumText EnumUtils<SpellAttr7>::ToString(SpellAttr7 value) { switch (value) { - case SPELL_ATTR7_UNK0: return { "SPELL_ATTR7_UNK0", "Unknown attribute 0@Attr7", "" }; - case SPELL_ATTR7_IGNORE_DURATION_MODS: return { "SPELL_ATTR7_IGNORE_DURATION_MODS", "Ignore duration modifiers", "" }; + case SPELL_ATTR7_ALLOW_SPELL_REFLECTION: return { "SPELL_ATTR7_ALLOW_SPELL_REFLECTION", "Allow Spell Reflection", "" }; + case SPELL_ATTR7_NO_TARGET_DURATION_MOD: return { "SPELL_ATTR7_NO_TARGET_DURATION_MOD", "No Target Duration Mod", "" }; case SPELL_ATTR7_DISABLE_AURA_WHILE_DEAD: return { "SPELL_ATTR7_DISABLE_AURA_WHILE_DEAD", "Disable Aura While Dead", "" }; - case SPELL_ATTR7_IS_CHEAT_SPELL: return { "SPELL_ATTR7_IS_CHEAT_SPELL", "Is cheat spell", "Cannot cast if caster doesn't have UnitFlag2 & UNIT_FLAG2_ALLOW_CHEAT_SPELLS" }; - case SPELL_ATTR7_UNK4: return { "SPELL_ATTR7_UNK4", "Unknown attribute 4@Attr7", "Soulstone related?" }; - case SPELL_ATTR7_SUMMON_TOTEM: return { "SPELL_ATTR7_SUMMON_TOTEM", "Summons player-owned totem", "" }; - case SPELL_ATTR7_NO_PUSHBACK_ON_DAMAGE: return { "SPELL_ATTR7_NO_PUSHBACK_ON_DAMAGE", "Damage dealt by this does not cause spell pushback", "" }; - case SPELL_ATTR7_UNK7: return { "SPELL_ATTR7_UNK7", "Unknown attribute 7@Attr7", "" }; - case SPELL_ATTR7_HORDE_ONLY: return { "SPELL_ATTR7_HORDE_ONLY", "Horde only", "" }; - case SPELL_ATTR7_ALLIANCE_ONLY: return { "SPELL_ATTR7_ALLIANCE_ONLY", "Alliance only", "" }; - case SPELL_ATTR7_DISPEL_CHARGES: return { "SPELL_ATTR7_DISPEL_CHARGES", "Dispel/Spellsteal remove individual charges", "" }; - case SPELL_ATTR7_INTERRUPT_ONLY_NONPLAYER: return { "SPELL_ATTR7_INTERRUPT_ONLY_NONPLAYER", "Can Cause Interrupt", "Only interrupt non-player casting" }; - case SPELL_ATTR7_SILENCE_ONLY_NONPLAYER: return { "SPELL_ATTR7_SILENCE_ONLY_NONPLAYER", "Can Cause Silence", "" }; - case SPELL_ATTR7_CAN_ALWAYS_BE_INTERRUPTED: return { "SPELL_ATTR7_CAN_ALWAYS_BE_INTERRUPTED", "No UI Not Interruptible", "Can always be interrupted, even if caster is immune" }; - case SPELL_ATTR7_UNK14: return { "SPELL_ATTR7_UNK14", "Unknown attribute 14@Attr7", "" }; - case SPELL_ATTR7_UNK15: return { "SPELL_ATTR7_UNK15", "Unknown attribute 15@Attr7", "Exorcism - guaranteed crit vs families?" }; - case SPELL_ATTR7_HIDDEN_IN_SPELLBOOK_WHEN_LEARNED: return { "SPELL_ATTR7_HIDDEN_IN_SPELLBOOK_WHEN_LEARNED", "Only In Spellbook Until Learned", "After learning these spells become hidden in spellbook (but are visible when not learned for low level characters)" }; - case SPELL_ATTR7_UNK17: return { "SPELL_ATTR7_UNK17", "Unknown attribute 17@Attr7", "" }; - case SPELL_ATTR7_HAS_CHARGE_EFFECT: return { "SPELL_ATTR7_HAS_CHARGE_EFFECT", "Has charge effect", "" }; - case SPELL_ATTR7_ZONE_TELEPORT: return { "SPELL_ATTR7_ZONE_TELEPORT", "Is zone teleport", "" }; - case SPELL_ATTR7_UNK20: return { "SPELL_ATTR7_UNK20", "Unknown attribute 20@Attr7", "Invulnerability related?" }; - case SPELL_ATTR7_UNK21: return { "SPELL_ATTR7_UNK21", "Unknown attribute 21@Attr7", "" }; + case SPELL_ATTR7_DEBUG_SPELL: return { "SPELL_ATTR7_DEBUG_SPELL", "Debug Spell", "Cannot cast if caster doesn't have UnitFlag2 & UNIT_FLAG2_ALLOW_CHEAT_SPELLS" }; + case SPELL_ATTR7_TREAT_AS_RAID_BUFF: return { "SPELL_ATTR7_TREAT_AS_RAID_BUFF", "Treat as Raid Buff", "" }; + case SPELL_ATTR7_CAN_BE_MULTI_CAST: return { "SPELL_ATTR7_CAN_BE_MULTI_CAST", "Can Be Multi Cast", "" }; + case SPELL_ATTR7_DONT_CAUSE_SPELL_PUSHBACK: return { "SPELL_ATTR7_DONT_CAUSE_SPELL_PUSHBACK", "Don't Cause Spell Pushback", "Damage dealt by this does not cause spell pushback" }; + case SPELL_ATTR7_PREPARE_FOR_VEHICLE_CONTROL_END: return { "SPELL_ATTR7_PREPARE_FOR_VEHICLE_CONTROL_END", "Prepare for Vehicle Control End", "" }; + case SPELL_ATTR7_HORDE_SPECIFIC_SPELL: return { "SPELL_ATTR7_HORDE_SPECIFIC_SPELL", "Horde Specific Spell", "" }; + case SPELL_ATTR7_ALLIANCE_SPECIFIC_SPELL: return { "SPELL_ATTR7_ALLIANCE_SPECIFIC_SPELL", "Alliance Specific Spell", "" }; + case SPELL_ATTR7_DISPEL_REMOVES_CHARGES: return { "SPELL_ATTR7_DISPEL_REMOVES_CHARGES", "Dispel Removes Charges", "Dispel/Spellsteal remove individual charges" }; + case SPELL_ATTR7_CAN_CAUSE_INTERRUPT: return { "SPELL_ATTR7_CAN_CAUSE_INTERRUPT", "Can Cause Interrupt", "Only interrupt non-player casting" }; + case SPELL_ATTR7_CAN_CAUSE_SILENCE: return { "SPELL_ATTR7_CAN_CAUSE_SILENCE", "Can Cause Silence", "" }; + case SPELL_ATTR7_NO_UI_NOT_INTERRUPTIBLE: return { "SPELL_ATTR7_NO_UI_NOT_INTERRUPTIBLE", "No UI Not Interruptible", "Can always be interrupted, even if caster is immune" }; + case SPELL_ATTR7_RECAST_ON_RESUMMON: return { "SPELL_ATTR7_RECAST_ON_RESUMMON", "Recast On Resummon", "" }; + case SPELL_ATTR7_RESET_SWING_TIMER_AT_SPELL_START: return { "SPELL_ATTR7_RESET_SWING_TIMER_AT_SPELL_START", "Reset Swing Timer at spell start", "" }; + case SPELL_ATTR7_ONLY_IN_SPELLBOOK_UNTIL_LEARNED: return { "SPELL_ATTR7_ONLY_IN_SPELLBOOK_UNTIL_LEARNED", "Only In Spellbook Until Learned", "After learning these spells become hidden in spellbook (but are visible when not learned for low level characters)" }; + case SPELL_ATTR7_DO_NOT_LOG_PVP_KILL: return { "SPELL_ATTR7_DO_NOT_LOG_PVP_KILL", "Do Not Log PvP Kill", "" }; + case SPELL_ATTR7_ATTACK_ON_CHARGE_TO_UNIT: return { "SPELL_ATTR7_ATTACK_ON_CHARGE_TO_UNIT", "Attack on Charge to Unit", "" }; + case SPELL_ATTR7_REPORT_SPELL_FAILURE_TO_UNIT_TARGET: return { "SPELL_ATTR7_REPORT_SPELL_FAILURE_TO_UNIT_TARGET", "Report Spell failure to unit target", "" }; + case SPELL_ATTR7_NO_CLIENT_FAIL_WHILE_STUNNED_FLEEING_CONFUSED: return { "SPELL_ATTR7_NO_CLIENT_FAIL_WHILE_STUNNED_FLEEING_CONFUSED", "No Client Fail While Stunned, Fleeing, Confused", "Clientside - skips stunned/fleeing/confused checks" }; + case SPELL_ATTR7_RETAIN_COOLDOWN_THROUGH_LOAD: return { "SPELL_ATTR7_RETAIN_COOLDOWN_THROUGH_LOAD", "Retain Cooldown Through Load", "" }; case SPELL_ATTR7_IGNORES_COLD_WEATHER_FLYING_REQUIREMENT: return { "SPELL_ATTR7_IGNORES_COLD_WEATHER_FLYING_REQUIREMENT", "Ignores Cold Weather Flying Requirement", "" }; case SPELL_ATTR7_NO_ATTACK_DODGE: return { "SPELL_ATTR7_NO_ATTACK_DODGE", "No Attack Dodge", "" }; case SPELL_ATTR7_NO_ATTACK_PARRY: return { "SPELL_ATTR7_NO_ATTACK_PARRY", "No Attack Parry", "" }; case SPELL_ATTR7_NO_ATTACK_MISS: return { "SPELL_ATTR7_NO_ATTACK_MISS", "No Attack Miss", "" }; - case SPELL_ATTR7_UNK26: return { "SPELL_ATTR7_UNK26", "Unknown attribute 26@Attr7", "" }; + case SPELL_ATTR7_TREAT_AS_NPC_AOE: return { "SPELL_ATTR7_TREAT_AS_NPC_AOE", "Treat as NPC AoE", "" }; case SPELL_ATTR7_BYPASS_NO_RESURRECT_AURA: return { "SPELL_ATTR7_BYPASS_NO_RESURRECT_AURA", "Bypass No Resurrect Aura", "" }; - case SPELL_ATTR7_CONSOLIDATED_RAID_BUFF: return { "SPELL_ATTR7_CONSOLIDATED_RAID_BUFF", "Consolidate in raid buff frame (client only)", "" }; - case SPELL_ATTR7_UNK29: return { "SPELL_ATTR7_UNK29", "Unknown attribute 29@Attr7", "" }; - case SPELL_ATTR7_UNK30: return { "SPELL_ATTR7_UNK30", "Unknown attribute 30@Attr7", "" }; - case SPELL_ATTR7_CLIENT_INDICATOR: return { "SPELL_ATTR7_CLIENT_INDICATOR", "Client indicator (client only)", "" }; + case SPELL_ATTR7_DO_NOT_COUNT_FOR_PVP_SCOREBOARD: return { "SPELL_ATTR7_DO_NOT_COUNT_FOR_PVP_SCOREBOARD", "Do Not Count For PvP Scoreboard", "" }; + case SPELL_ATTR7_REFLECTION_ONLY_DEFENDS: return { "SPELL_ATTR7_REFLECTION_ONLY_DEFENDS", "Reflection Only Defends", "" }; + case SPELL_ATTR7_CAN_PROC_FROM_SUPPRESSED_TARGET_PROCS: return { "SPELL_ATTR7_CAN_PROC_FROM_SUPPRESSED_TARGET_PROCS", "Can Proc From Suppressed Target Procs", "" }; + case SPELL_ATTR7_ALWAYS_CAST_LOG: return { "SPELL_ATTR7_ALWAYS_CAST_LOG", "Always Cast Log", "" }; default: throw std::out_of_range("value"); } } @@ -1221,38 +1221,38 @@ TC_API_EXPORT SpellAttr7 EnumUtils<SpellAttr7>::FromIndex(size_t index) { switch (index) { - case 0: return SPELL_ATTR7_UNK0; - case 1: return SPELL_ATTR7_IGNORE_DURATION_MODS; + case 0: return SPELL_ATTR7_ALLOW_SPELL_REFLECTION; + case 1: return SPELL_ATTR7_NO_TARGET_DURATION_MOD; case 2: return SPELL_ATTR7_DISABLE_AURA_WHILE_DEAD; - case 3: return SPELL_ATTR7_IS_CHEAT_SPELL; - case 4: return SPELL_ATTR7_UNK4; - case 5: return SPELL_ATTR7_SUMMON_TOTEM; - case 6: return SPELL_ATTR7_NO_PUSHBACK_ON_DAMAGE; - case 7: return SPELL_ATTR7_UNK7; - case 8: return SPELL_ATTR7_HORDE_ONLY; - case 9: return SPELL_ATTR7_ALLIANCE_ONLY; - case 10: return SPELL_ATTR7_DISPEL_CHARGES; - case 11: return SPELL_ATTR7_INTERRUPT_ONLY_NONPLAYER; - case 12: return SPELL_ATTR7_SILENCE_ONLY_NONPLAYER; - case 13: return SPELL_ATTR7_CAN_ALWAYS_BE_INTERRUPTED; - case 14: return SPELL_ATTR7_UNK14; - case 15: return SPELL_ATTR7_UNK15; - case 16: return SPELL_ATTR7_HIDDEN_IN_SPELLBOOK_WHEN_LEARNED; - case 17: return SPELL_ATTR7_UNK17; - case 18: return SPELL_ATTR7_HAS_CHARGE_EFFECT; - case 19: return SPELL_ATTR7_ZONE_TELEPORT; - case 20: return SPELL_ATTR7_UNK20; - case 21: return SPELL_ATTR7_UNK21; + case 3: return SPELL_ATTR7_DEBUG_SPELL; + case 4: return SPELL_ATTR7_TREAT_AS_RAID_BUFF; + case 5: return SPELL_ATTR7_CAN_BE_MULTI_CAST; + case 6: return SPELL_ATTR7_DONT_CAUSE_SPELL_PUSHBACK; + case 7: return SPELL_ATTR7_PREPARE_FOR_VEHICLE_CONTROL_END; + case 8: return SPELL_ATTR7_HORDE_SPECIFIC_SPELL; + case 9: return SPELL_ATTR7_ALLIANCE_SPECIFIC_SPELL; + case 10: return SPELL_ATTR7_DISPEL_REMOVES_CHARGES; + case 11: return SPELL_ATTR7_CAN_CAUSE_INTERRUPT; + case 12: return SPELL_ATTR7_CAN_CAUSE_SILENCE; + case 13: return SPELL_ATTR7_NO_UI_NOT_INTERRUPTIBLE; + case 14: return SPELL_ATTR7_RECAST_ON_RESUMMON; + case 15: return SPELL_ATTR7_RESET_SWING_TIMER_AT_SPELL_START; + case 16: return SPELL_ATTR7_ONLY_IN_SPELLBOOK_UNTIL_LEARNED; + case 17: return SPELL_ATTR7_DO_NOT_LOG_PVP_KILL; + case 18: return SPELL_ATTR7_ATTACK_ON_CHARGE_TO_UNIT; + case 19: return SPELL_ATTR7_REPORT_SPELL_FAILURE_TO_UNIT_TARGET; + case 20: return SPELL_ATTR7_NO_CLIENT_FAIL_WHILE_STUNNED_FLEEING_CONFUSED; + case 21: return SPELL_ATTR7_RETAIN_COOLDOWN_THROUGH_LOAD; case 22: return SPELL_ATTR7_IGNORES_COLD_WEATHER_FLYING_REQUIREMENT; case 23: return SPELL_ATTR7_NO_ATTACK_DODGE; case 24: return SPELL_ATTR7_NO_ATTACK_PARRY; case 25: return SPELL_ATTR7_NO_ATTACK_MISS; - case 26: return SPELL_ATTR7_UNK26; + case 26: return SPELL_ATTR7_TREAT_AS_NPC_AOE; case 27: return SPELL_ATTR7_BYPASS_NO_RESURRECT_AURA; - case 28: return SPELL_ATTR7_CONSOLIDATED_RAID_BUFF; - case 29: return SPELL_ATTR7_UNK29; - case 30: return SPELL_ATTR7_UNK30; - case 31: return SPELL_ATTR7_CLIENT_INDICATOR; + case 28: return SPELL_ATTR7_DO_NOT_COUNT_FOR_PVP_SCOREBOARD; + case 29: return SPELL_ATTR7_REFLECTION_ONLY_DEFENDS; + case 30: return SPELL_ATTR7_CAN_PROC_FROM_SUPPRESSED_TARGET_PROCS; + case 31: return SPELL_ATTR7_ALWAYS_CAST_LOG; default: throw std::out_of_range("index"); } } @@ -1262,38 +1262,38 @@ TC_API_EXPORT size_t EnumUtils<SpellAttr7>::ToIndex(SpellAttr7 value) { switch (value) { - case SPELL_ATTR7_UNK0: return 0; - case SPELL_ATTR7_IGNORE_DURATION_MODS: return 1; + case SPELL_ATTR7_ALLOW_SPELL_REFLECTION: return 0; + case SPELL_ATTR7_NO_TARGET_DURATION_MOD: return 1; case SPELL_ATTR7_DISABLE_AURA_WHILE_DEAD: return 2; - case SPELL_ATTR7_IS_CHEAT_SPELL: return 3; - case SPELL_ATTR7_UNK4: return 4; - case SPELL_ATTR7_SUMMON_TOTEM: return 5; - case SPELL_ATTR7_NO_PUSHBACK_ON_DAMAGE: return 6; - case SPELL_ATTR7_UNK7: return 7; - case SPELL_ATTR7_HORDE_ONLY: return 8; - case SPELL_ATTR7_ALLIANCE_ONLY: return 9; - case SPELL_ATTR7_DISPEL_CHARGES: return 10; - case SPELL_ATTR7_INTERRUPT_ONLY_NONPLAYER: return 11; - case SPELL_ATTR7_SILENCE_ONLY_NONPLAYER: return 12; - case SPELL_ATTR7_CAN_ALWAYS_BE_INTERRUPTED: return 13; - case SPELL_ATTR7_UNK14: return 14; - case SPELL_ATTR7_UNK15: return 15; - case SPELL_ATTR7_HIDDEN_IN_SPELLBOOK_WHEN_LEARNED: return 16; - case SPELL_ATTR7_UNK17: return 17; - case SPELL_ATTR7_HAS_CHARGE_EFFECT: return 18; - case SPELL_ATTR7_ZONE_TELEPORT: return 19; - case SPELL_ATTR7_UNK20: return 20; - case SPELL_ATTR7_UNK21: return 21; + case SPELL_ATTR7_DEBUG_SPELL: return 3; + case SPELL_ATTR7_TREAT_AS_RAID_BUFF: return 4; + case SPELL_ATTR7_CAN_BE_MULTI_CAST: return 5; + case SPELL_ATTR7_DONT_CAUSE_SPELL_PUSHBACK: return 6; + case SPELL_ATTR7_PREPARE_FOR_VEHICLE_CONTROL_END: return 7; + case SPELL_ATTR7_HORDE_SPECIFIC_SPELL: return 8; + case SPELL_ATTR7_ALLIANCE_SPECIFIC_SPELL: return 9; + case SPELL_ATTR7_DISPEL_REMOVES_CHARGES: return 10; + case SPELL_ATTR7_CAN_CAUSE_INTERRUPT: return 11; + case SPELL_ATTR7_CAN_CAUSE_SILENCE: return 12; + case SPELL_ATTR7_NO_UI_NOT_INTERRUPTIBLE: return 13; + case SPELL_ATTR7_RECAST_ON_RESUMMON: return 14; + case SPELL_ATTR7_RESET_SWING_TIMER_AT_SPELL_START: return 15; + case SPELL_ATTR7_ONLY_IN_SPELLBOOK_UNTIL_LEARNED: return 16; + case SPELL_ATTR7_DO_NOT_LOG_PVP_KILL: return 17; + case SPELL_ATTR7_ATTACK_ON_CHARGE_TO_UNIT: return 18; + case SPELL_ATTR7_REPORT_SPELL_FAILURE_TO_UNIT_TARGET: return 19; + case SPELL_ATTR7_NO_CLIENT_FAIL_WHILE_STUNNED_FLEEING_CONFUSED: return 20; + case SPELL_ATTR7_RETAIN_COOLDOWN_THROUGH_LOAD: return 21; case SPELL_ATTR7_IGNORES_COLD_WEATHER_FLYING_REQUIREMENT: return 22; case SPELL_ATTR7_NO_ATTACK_DODGE: return 23; case SPELL_ATTR7_NO_ATTACK_PARRY: return 24; case SPELL_ATTR7_NO_ATTACK_MISS: return 25; - case SPELL_ATTR7_UNK26: return 26; + case SPELL_ATTR7_TREAT_AS_NPC_AOE: return 26; case SPELL_ATTR7_BYPASS_NO_RESURRECT_AURA: return 27; - case SPELL_ATTR7_CONSOLIDATED_RAID_BUFF: return 28; - case SPELL_ATTR7_UNK29: return 29; - case SPELL_ATTR7_UNK30: return 30; - case SPELL_ATTR7_CLIENT_INDICATOR: return 31; + case SPELL_ATTR7_DO_NOT_COUNT_FOR_PVP_SCOREBOARD: return 28; + case SPELL_ATTR7_REFLECTION_ONLY_DEFENDS: return 29; + case SPELL_ATTR7_CAN_PROC_FROM_SUPPRESSED_TARGET_PROCS: return 30; + case SPELL_ATTR7_ALWAYS_CAST_LOG: return 31; default: throw std::out_of_range("value"); } } @@ -1822,8 +1822,8 @@ TC_API_EXPORT EnumText EnumUtils<SpellAttr12>::ToString(SpellAttr12 value) { switch (value) { - case SPELL_ATTR12_UNK0: return { "SPELL_ATTR12_UNK0", "Unknown attribute 0@Attr12", "" }; - case SPELL_ATTR12_UNK1: return { "SPELL_ATTR12_UNK1", "Unknown attribute 1@Attr12", "" }; + case SPELL_ATTR12_ENABLE_PROCS_FROM_SUPPRESSED_CASTER_PROCS: return { "SPELL_ATTR12_ENABLE_PROCS_FROM_SUPPRESSED_CASTER_PROCS", "Enable Procs from Suppressed Caster Procs", "" }; + case SPELL_ATTR12_CAN_PROC_FROM_SUPPRESSED_CASTER_PROCS: return { "SPELL_ATTR12_CAN_PROC_FROM_SUPPRESSED_CASTER_PROCS", "Can Proc from Suppressed Caster Procs", "" }; case SPELL_ATTR12_UNK2: return { "SPELL_ATTR12_UNK2", "Unknown attribute 2@Attr12", "" }; case SPELL_ATTR12_UNK3: return { "SPELL_ATTR12_UNK3", "Unknown attribute 3@Attr12", "" }; case SPELL_ATTR12_UNK4: return { "SPELL_ATTR12_UNK4", "Unknown attribute 4@Attr12", "" }; @@ -1866,8 +1866,8 @@ TC_API_EXPORT SpellAttr12 EnumUtils<SpellAttr12>::FromIndex(size_t index) { switch (index) { - case 0: return SPELL_ATTR12_UNK0; - case 1: return SPELL_ATTR12_UNK1; + case 0: return SPELL_ATTR12_ENABLE_PROCS_FROM_SUPPRESSED_CASTER_PROCS; + case 1: return SPELL_ATTR12_CAN_PROC_FROM_SUPPRESSED_CASTER_PROCS; case 2: return SPELL_ATTR12_UNK2; case 3: return SPELL_ATTR12_UNK3; case 4: return SPELL_ATTR12_UNK4; @@ -1907,8 +1907,8 @@ TC_API_EXPORT size_t EnumUtils<SpellAttr12>::ToIndex(SpellAttr12 value) { switch (value) { - case SPELL_ATTR12_UNK0: return 0; - case SPELL_ATTR12_UNK1: return 1; + case SPELL_ATTR12_ENABLE_PROCS_FROM_SUPPRESSED_CASTER_PROCS: return 0; + case SPELL_ATTR12_CAN_PROC_FROM_SUPPRESSED_CASTER_PROCS: return 1; case SPELL_ATTR12_UNK2: return 2; case SPELL_ATTR12_UNK3: return 3; case SPELL_ATTR12_UNK4: return 4; diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index d7a08f4b1dc..26bd7a0c0ba 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -5459,8 +5459,8 @@ void AuraEffect::HandlePeriodicDamageAurasTick(Unit* target, Unit* caster) const if (!GetSpellInfo()->HasAttribute(SPELL_ATTR4_IGNORE_DAMAGE_TAKEN_MODIFIERS)) { - if (GetSpellEffectInfo().IsTargetingArea() || GetSpellEffectInfo().IsAreaAuraEffect() || GetSpellEffectInfo().IsEffect(SPELL_EFFECT_PERSISTENT_AREA_AURA) || GetSpellInfo()->HasAttribute(SPELL_ATTR5_TREAT_AS_AREA_EFFECT)) - damage = target->CalculateAOEAvoidance(damage, m_spellInfo->SchoolMask, GetBase()->GetCasterGUID()); + if (GetSpellEffectInfo().IsTargetingArea() || GetSpellEffectInfo().IsAreaAuraEffect() || GetSpellEffectInfo().IsEffect(SPELL_EFFECT_PERSISTENT_AREA_AURA) || GetSpellInfo()->HasAttribute(SPELL_ATTR5_TREAT_AS_AREA_EFFECT) || GetSpellInfo()->HasAttribute(SPELL_ATTR7_TREAT_AS_NPC_AOE)) + damage = target->CalculateAOEAvoidance(damage, m_spellInfo->SchoolMask, (caster && !caster->IsControlledByPlayer()) || GetSpellInfo()->HasAttribute(SPELL_ATTR7_TREAT_AS_NPC_AOE)); } int32 dmg = damage; @@ -5548,8 +5548,8 @@ void AuraEffect::HandlePeriodicHealthLeechAuraTick(Unit* target, Unit* caster) c if (!GetSpellInfo()->HasAttribute(SPELL_ATTR4_IGNORE_DAMAGE_TAKEN_MODIFIERS)) { - if (GetSpellEffectInfo().IsTargetingArea() || GetSpellEffectInfo().IsAreaAuraEffect() || GetSpellEffectInfo().IsEffect(SPELL_EFFECT_PERSISTENT_AREA_AURA) || GetSpellInfo()->HasAttribute(SPELL_ATTR5_TREAT_AS_AREA_EFFECT)) - damage = target->CalculateAOEAvoidance(damage, m_spellInfo->SchoolMask, GetBase()->GetCasterGUID()); + if (GetSpellEffectInfo().IsTargetingArea() || GetSpellEffectInfo().IsAreaAuraEffect() || GetSpellEffectInfo().IsEffect(SPELL_EFFECT_PERSISTENT_AREA_AURA) || GetSpellInfo()->HasAttribute(SPELL_ATTR5_TREAT_AS_AREA_EFFECT) || GetSpellInfo()->HasAttribute(SPELL_ATTR7_TREAT_AS_NPC_AOE)) + damage = target->CalculateAOEAvoidance(damage, m_spellInfo->SchoolMask, (caster && !caster->IsControlledByPlayer()) || GetSpellInfo()->HasAttribute(SPELL_ATTR7_TREAT_AS_NPC_AOE)); } int32 dmg = damage; diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp index 6c48b5cb247..8ca596c16a9 100644 --- a/src/server/game/Spells/Auras/SpellAuras.cpp +++ b/src/server/game/Spells/Auras/SpellAuras.cpp @@ -1815,6 +1815,20 @@ uint32 Aura::GetProcEffectMask(AuraApplication* aurApp, ProcEventInfo& eventInfo if (GetSpellInfo()->HasAttribute(SPELL_ATTR12_ONLY_PROC_FROM_CLASS_ABILITIES) && !spell->GetSpellInfo()->HasAttribute(SPELL_ATTR13_ALLOW_CLASS_ABILITY_PROCS)) return 0; + + if (eventInfo.GetTypeMask() & TAKEN_HIT_PROC_FLAG_MASK) + { + if (spell->GetSpellInfo()->HasAttribute(SPELL_ATTR3_SUPPRESS_TARGET_PROCS) + && !GetSpellInfo()->HasAttribute(SPELL_ATTR7_CAN_PROC_FROM_SUPPRESSED_TARGET_PROCS)) + return 0; + } + else + { + if (spell->GetSpellInfo()->HasAttribute(SPELL_ATTR3_SUPPRESS_CASTER_PROCS) + && !spell->GetSpellInfo()->HasAttribute(SPELL_ATTR12_ENABLE_PROCS_FROM_SUPPRESSED_CASTER_PROCS) + && !GetSpellInfo()->HasAttribute(SPELL_ATTR12_CAN_PROC_FROM_SUPPRESSED_CASTER_PROCS)) + return 0; + } } // check don't break stealth attr present diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 6a5d1eb855e..c0bc954a8b2 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -600,7 +600,8 @@ 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_canReflect = caster->IsUnit() + && ((m_spellInfo->DmgClass == SPELL_DAMAGE_CLASS_MAGIC && !m_spellInfo->HasAttribute(SPELL_ATTR0_IS_ABILITY)) || m_spellInfo->HasAttribute(SPELL_ATTR7_ALLOW_SPELL_REFLECTION)) && !m_spellInfo->HasAttribute(SPELL_ATTR1_NO_REFLECTION) && !m_spellInfo->HasAttribute(SPELL_ATTR0_NO_IMMUNITIES) && !m_spellInfo->IsPassive(); @@ -2777,8 +2778,7 @@ void Spell::TargetInfo::DoDamageAndTriggers(Spell* spell) ProcFlagsHit hitMask = PROC_HIT_NONE; // Spells with this flag cannot trigger if effect is cast on self - bool const canEffectTrigger = (!spell->m_spellInfo->HasAttribute(SPELL_ATTR3_SUPPRESS_CASTER_PROCS) || !spell->m_spellInfo->HasAttribute(SPELL_ATTR3_SUPPRESS_TARGET_PROCS)) - && spell->unitTarget->CanProc(); + bool const canEffectTrigger = spell->unitTarget->CanProc(); // Trigger info was not filled in Spell::prepareDataForTriggerSystem - we do it now if (canEffectTrigger && !procAttacker && !procVictim) @@ -2945,12 +2945,6 @@ void Spell::TargetInfo::DoDamageAndTriggers(Spell* spell) // Do triggers for unit if (canEffectTrigger) { - if (spell->m_spellInfo->HasAttribute(SPELL_ATTR3_SUPPRESS_CASTER_PROCS)) - procAttacker = ProcFlagsInit(PROC_FLAG_NONE, PROC_FLAG_2_NONE); - - if (spell->m_spellInfo->HasAttribute(SPELL_ATTR3_SUPPRESS_TARGET_PROCS)) - procVictim = ProcFlagsInit(PROC_FLAG_NONE, PROC_FLAG_2_NONE); - Unit::ProcSkillsAndAuras(caster, spell->unitTarget, procAttacker, procVictim, procSpellType, PROC_SPELL_PHASE_HIT, hitMask, spell, spellDamageInfo.get(), healInfo.get()); // item spells (spell hit of non-damage spell may also activate items, for example seal of corruption hidden hit) @@ -2984,7 +2978,7 @@ void Spell::TargetInfo::DoDamageAndTriggers(Spell* spell) } // Check for SPELL_ATTR7_INTERRUPT_ONLY_NONPLAYER - if (MissCondition == SPELL_MISS_NONE && spell->m_spellInfo->HasAttribute(SPELL_ATTR7_INTERRUPT_ONLY_NONPLAYER) && unit->GetTypeId() != TYPEID_PLAYER) + if (MissCondition == SPELL_MISS_NONE && spell->m_spellInfo->HasAttribute(SPELL_ATTR7_CAN_CAUSE_INTERRUPT) && unit->GetTypeId() != TYPEID_PLAYER) caster->CastSpell(unit, SPELL_INTERRUPT_NONPLAYER, spell); } @@ -3523,6 +3517,9 @@ SpellCastResult Spell::prepare(SpellCastTargets const& targets, AuraEffect const if (m_spellInfo->HasAttribute(SPELL_ATTR12_START_COOLDOWN_ON_CAST_START)) SendSpellCooldown(); + if (m_spellInfo->HasAttribute(SPELL_ATTR7_RESET_SWING_TIMER_AT_SPELL_START) && IsAutoActionResetSpell()) + ResetCombatTimers(); + //Containers for channeled spells have to be set /// @todoApply this to all cast spells if needed // Why check duration? 29350: channelled triggers channelled @@ -3825,6 +3822,9 @@ void Spell::_cast(bool skipCheck) m_launchHandled = true; } + if (!m_spellInfo->HasAttribute(SPELL_ATTR7_RESET_SWING_TIMER_AT_SPELL_START) && IsAutoActionResetSpell()) + ResetCombatTimers(); + // we must send smsg_spell_go packet before m_castItem delete in TakeCastItem()... SendSpellGo(); @@ -3924,8 +3924,7 @@ void Spell::_cast(bool skipCheck) if (!(_triggeredCastFlags & TRIGGERED_IGNORE_CAST_IN_PROGRESS) && !m_spellInfo->HasAttribute(SPELL_ATTR2_NOT_AN_ACTION)) m_originalCaster->RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags::ActionDelayed, m_spellInfo); - if (!m_spellInfo->HasAttribute(SPELL_ATTR3_SUPPRESS_CASTER_PROCS)) - Unit::ProcSkillsAndAuras(m_originalCaster, nullptr, procAttacker, PROC_FLAG_NONE, PROC_SPELL_TYPE_MASK_ALL, PROC_SPELL_PHASE_CAST, hitMask, this, nullptr, nullptr); + Unit::ProcSkillsAndAuras(m_originalCaster, nullptr, procAttacker, PROC_FLAG_NONE, PROC_SPELL_TYPE_MASK_ALL, PROC_SPELL_PHASE_CAST, hitMask, this, nullptr, nullptr); // Call CreatureAI hook OnSpellCast if (Creature* caster = m_originalCaster->ToCreature()) @@ -4176,8 +4175,7 @@ void Spell::_handle_finish_phase() } } - if (!m_spellInfo->HasAttribute(SPELL_ATTR3_SUPPRESS_CASTER_PROCS)) - Unit::ProcSkillsAndAuras(m_originalCaster, nullptr, procAttacker, PROC_FLAG_NONE, m_procSpellType, PROC_SPELL_PHASE_FINISH, m_hitMask, this, nullptr, nullptr); + Unit::ProcSkillsAndAuras(m_originalCaster, nullptr, procAttacker, PROC_FLAG_NONE, m_procSpellType, PROC_SPELL_PHASE_FINISH, m_hitMask, this, nullptr, nullptr); } void Spell::SendSpellCooldown() @@ -4317,8 +4315,7 @@ void Spell::finish(SpellCastResult result) if (Creature* creatureCaster = unitCaster->ToCreature()) creatureCaster->ReleaseSpellFocus(this); - if (!m_spellInfo->HasAttribute(SPELL_ATTR3_SUPPRESS_CASTER_PROCS)) - Unit::ProcSkillsAndAuras(unitCaster, nullptr, PROC_FLAG_CAST_ENDED, PROC_FLAG_NONE, PROC_SPELL_TYPE_MASK_ALL, PROC_SPELL_PHASE_NONE, PROC_HIT_NONE, this, nullptr, nullptr); + Unit::ProcSkillsAndAuras(unitCaster, nullptr, PROC_FLAG_CAST_ENDED, PROC_FLAG_NONE, PROC_SPELL_TYPE_MASK_ALL, PROC_SPELL_PHASE_NONE, PROC_HIT_NONE, this, nullptr, nullptr); if (result != SPELL_CAST_OK) { @@ -4346,17 +4343,6 @@ void Spell::finish(SpellCastResult result) } } - if (IsAutoActionResetSpell()) - { - if (!m_spellInfo->HasAttribute(SPELL_ATTR2_DO_NOT_RESET_COMBAT_TIMERS)) - { - unitCaster->resetAttackTimer(BASE_ATTACK); - if (unitCaster->haveOffhandWeapon()) - unitCaster->resetAttackTimer(OFF_ATTACK); - unitCaster->resetAttackTimer(RANGED_ATTACK); - } - } - // potions disabled by client, send event "not in combat" if need if (unitCaster->GetTypeId() == TYPEID_PLAYER) { @@ -4546,7 +4532,7 @@ inline void FillSpellCastFailedArgs(T& packet, ObjectGuid castId, SpellInfo cons uint32 itemid = spellInfo->Reagent[i]; uint32 itemcount = spellInfo->ReagentCount[i]; - if (!caster->HasItemCount(itemid, itemcount)) + if (caster && !caster->HasItemCount(itemid, itemcount)) { packet.FailedArg1 = itemid; // first missing item break; @@ -4560,7 +4546,7 @@ inline void FillSpellCastFailedArgs(T& packet, ObjectGuid castId, SpellInfo cons { for (SpellReagentsCurrencyEntry const* reagentsCurrency : spellInfo->ReagentsCurrency) { - if (!caster->HasCurrency(reagentsCurrency->CurrencyTypesID, reagentsCurrency->CurrencyCount)) + if (caster && !caster->HasCurrency(reagentsCurrency->CurrencyTypesID, reagentsCurrency->CurrencyCount)) { packet.FailedArg1 = -1; packet.FailedArg2 = reagentsCurrency->CurrencyTypesID; @@ -4588,10 +4574,15 @@ void Spell::SendCastResult(SpellCastResult result, int32* param1 /*= nullptr*/, if (result == SPELL_CAST_OK) return; - if (m_caster->GetTypeId() != TYPEID_PLAYER) + Player const* receiver = m_caster->ToPlayer(); + if (m_spellInfo->HasAttribute(SPELL_ATTR7_REPORT_SPELL_FAILURE_TO_UNIT_TARGET)) + if (Player const* target = Object::ToPlayer(m_targets.GetUnitTarget())) + receiver = target; + + if (!receiver) return; - if (m_caster->ToPlayer()->IsLoading()) // don't send cast results at loading time + if (receiver->IsLoading()) // don't send cast results at loading time return; if (_triggeredCastFlags & TRIGGERED_DONT_REPORT_CAST_ERROR) @@ -4600,7 +4591,7 @@ void Spell::SendCastResult(SpellCastResult result, int32* param1 /*= nullptr*/, WorldPackets::Spells::CastFailed castFailed; castFailed.Visual = m_SpellVisual; FillSpellCastFailedArgs(castFailed, m_castId, m_spellInfo, result, m_customError, param1, param2, m_caster->ToPlayer()); - m_caster->ToPlayer()->SendDirectMessage(castFailed.Write()); + receiver->SendDirectMessage(castFailed.Write()); } void Spell::SendPetCastResult(SpellCastResult result, int32* param1 /*= nullptr*/, int32* param2 /*= nullptr*/) const @@ -5597,7 +5588,7 @@ SpellCastResult Spell::CheckCast(bool strict, int32* param1 /*= nullptr*/, int32 } } - if (m_spellInfo->HasAttribute(SPELL_ATTR7_IS_CHEAT_SPELL) && m_caster->IsUnit() && !m_caster->ToUnit()->HasUnitFlag2(UNIT_FLAG2_ALLOW_CHEAT_SPELLS)) + if (m_spellInfo->HasAttribute(SPELL_ATTR7_DEBUG_SPELL) && m_caster->IsUnit() && !m_caster->ToUnit()->HasUnitFlag2(UNIT_FLAG2_ALLOW_CHEAT_SPELLS)) { m_customError = SPELL_CUSTOM_ERROR_GM_ONLY; return SPELL_FAILED_CUSTOM_ERROR; @@ -8067,7 +8058,7 @@ bool Spell::IsChannelActive() const bool Spell::IsAutoActionResetSpell() const { - if (IsTriggered()) + if (IsTriggered() || m_spellInfo->HasAttribute(SPELL_ATTR2_DO_NOT_RESET_COMBAT_TIMERS)) return false; if (!m_casttime && m_spellInfo->HasAttribute(SPELL_ATTR6_DOESNT_RESET_SWING_TIMER_IF_INSTANT)) @@ -8084,7 +8075,8 @@ bool Spell::IsPositive() const bool Spell::IsNeedSendToClient() const { return m_SpellVisual.SpellXSpellVisualID || m_SpellVisual.ScriptVisualID || m_spellInfo->IsChanneled() || - (m_spellInfo->HasAttribute(SPELL_ATTR8_AURA_SEND_AMOUNT)) || m_spellInfo->HasHitDelay() || (!m_triggeredByAuraSpell && !IsTriggered()); + (m_spellInfo->HasAttribute(SPELL_ATTR8_AURA_SEND_AMOUNT)) || m_spellInfo->HasHitDelay() || (!m_triggeredByAuraSpell && !IsTriggered()) || + m_spellInfo->HasAttribute(SPELL_ATTR7_ALWAYS_CAST_LOG); } Unit* Spell::GetUnitCasterForEffectHandlers() const @@ -8318,9 +8310,9 @@ void Spell::DoEffectOnLaunchTarget(TargetInfo& targetInfo, float multiplier, Spe if (m_originalCaster && m_damage > 0) { bool isAoeTarget = spellEffectInfo.IsTargetingArea() || spellEffectInfo.IsAreaAuraEffect() || spellEffectInfo.IsEffect(SPELL_EFFECT_PERSISTENT_AREA_AURA); - if (isAoeTarget || m_spellInfo->HasAttribute(SPELL_ATTR5_TREAT_AS_AREA_EFFECT)) + if (isAoeTarget || m_spellInfo->HasAttribute(SPELL_ATTR5_TREAT_AS_AREA_EFFECT) || m_spellInfo->HasAttribute(SPELL_ATTR7_TREAT_AS_NPC_AOE)) { - m_damage = unit->CalculateAOEAvoidance(m_damage, m_spellInfo->SchoolMask, m_originalCaster->GetGUID()); + m_damage = unit->CalculateAOEAvoidance(m_damage, m_spellInfo->SchoolMask, !m_originalCaster->IsControlledByPlayer() || m_spellInfo->HasAttribute(SPELL_ATTR7_TREAT_AS_NPC_AOE)); if (m_originalCaster->GetTypeId() == TYPEID_PLAYER) { @@ -8371,6 +8363,18 @@ void Spell::DoEffectOnLaunchTarget(TargetInfo& targetInfo, float multiplier, Spe targetInfo.Healing += m_healing; } +void Spell::ResetCombatTimers() +{ + Unit* unitCaster = m_caster->ToUnit(); + if (!unitCaster) + return; + + unitCaster->resetAttackTimer(BASE_ATTACK); + if (unitCaster->haveOffhandWeapon()) + unitCaster->resetAttackTimer(OFF_ATTACK); + unitCaster->resetAttackTimer(RANGED_ATTACK); +} + SpellCastResult Spell::CanOpenLock(SpellEffectInfo const& effect, uint32 lockId, SkillType& skillId, int32& reqSkillValue, int32& skillValue) { if (!lockId) // possible case for GO and maybe for items. diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h index 9c5f969af72..25f65e51759 100644 --- a/src/server/game/Spells/Spell.h +++ b/src/server/game/Spells/Spell.h @@ -837,6 +837,7 @@ class TC_GAME_API Spell bool IsValidDeadOrAliveTarget(Unit const* target) const; void HandleLaunchPhase(); void DoEffectOnLaunchTarget(TargetInfo& targetInfo, float multiplier, SpellEffectInfo const& spellEffectInfo); + void ResetCombatTimers(); void PrepareTargetProcessing(); void FinishTargetProcessing(); diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index f53a2280340..b2c1ad91459 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -3880,7 +3880,7 @@ void Spell::EffectCharge() if (effectHandleMode == SPELL_EFFECT_HANDLE_HIT_TARGET) { // not all charge effects used in negative spells - if (!m_spellInfo->IsPositive() && m_caster->GetTypeId() == TYPEID_PLAYER) + if (m_spellInfo->HasAttribute(SPELL_ATTR7_ATTACK_ON_CHARGE_TO_UNIT)) unitCaster->Attack(unitTarget, true); if (effectInfo->TriggerSpell) @@ -4655,7 +4655,7 @@ void Spell::EffectStealBeneficialBuff() // The charges / stack amounts don't count towards the total number of auras that can be dispelled. // Ie: A dispel on a target with 5 stacks of Winters Chill and a Polymorph has 1 / (1 + 1) -> 50% chance to dispell // Polymorph instead of 1 / (5 + 1) -> 16%. - bool dispelCharges = aura->GetSpellInfo()->HasAttribute(SPELL_ATTR7_DISPEL_CHARGES); + bool dispelCharges = aura->GetSpellInfo()->HasAttribute(SPELL_ATTR7_DISPEL_REMOVES_CHARGES); uint8 charges = dispelCharges ? aura->GetCharges() : aura->GetStackAmount(); if (charges > 0) stealList.emplace_back(aura, chance, charges); @@ -5102,7 +5102,7 @@ void Spell::EffectCastButtons() if (!player->HasSpell(spell_id) || player->GetSpellHistory()->HasCooldown(spell_id)) continue; - if (!spellInfo->HasAttribute(SPELL_ATTR9_SUMMON_PLAYER_TOTEM)) + if (!spellInfo->HasAttribute(SPELL_ATTR7_CAN_BE_MULTI_CAST)) continue; CastSpellExtraArgs args; diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp index 5e8d9c56732..541496075a1 100644 --- a/src/server/game/Spells/SpellInfo.cpp +++ b/src/server/game/Spells/SpellInfo.cpp @@ -1436,7 +1436,7 @@ bool SpellInfo::HasTargetType(::Targets target) const bool SpellInfo::CanBeInterrupted(WorldObject const* interruptCaster, Unit const* interruptTarget, bool ignoreImmunity /*= false*/) const { - return HasAttribute(SPELL_ATTR7_CAN_ALWAYS_BE_INTERRUPTED) + return HasAttribute(SPELL_ATTR7_NO_UI_NOT_INTERRUPTIBLE) || HasChannelInterruptFlag(SpellAuraInterruptFlags::Damage | SpellAuraInterruptFlags::EnteringCombat) || (interruptTarget->IsPlayer() && InterruptFlags.HasFlag(SpellInterruptFlags::DamageCancelsPlayerOnly)) || InterruptFlags.HasFlag(SpellInterruptFlags::DamageCancels) diff --git a/src/server/scripts/Northrend/IcecrownCitadel/go_icecrown_citadel_teleport.cpp b/src/server/scripts/Northrend/IcecrownCitadel/go_icecrown_citadel_teleport.cpp index 72bdf4c087f..a1d34f3ea5b 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/go_icecrown_citadel_teleport.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/go_icecrown_citadel_teleport.cpp @@ -75,7 +75,7 @@ class icecrown_citadel_teleport : public GameObjectScript if (TransportBase* transport = player->GetTransport()) transport->RemovePassenger(player); - player->CastSpell(player, spell->Id, true); + me->CastSpell(player, spell->Id, true); return true; } }; |