Core/Spells: Named and implemented most of SpellAttr7

This commit is contained in:
Shauren
2023-10-21 14:49:42 +02:00
parent 42e6a10456
commit 4e87bd7942
13 changed files with 208 additions and 196 deletions
+2 -2
View File
@@ -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))
-18
View File
@@ -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)
+22 -11
View File
@@ -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;
+1 -1
View File
@@ -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;
+34 -34
View File
@@ -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
@@ -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;
@@ -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;
@@ -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
+41 -37
View File
@@ -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.
+1
View File
@@ -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();
+3 -3
View File
@@ -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;
+1 -1
View File
@@ -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)
@@ -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;
}
};