Core/Spells: Rename SpellAttr1 to use official attribute names
* Implemented SPELL_ATTR1_NO_SKILL_INCREASE, SPELL_ATTR1_AURA_STAYS_AFTER_COMBAT, SPELL_ATTR1_DISPEL_ALL_STACKS
This commit is contained in:
1 parent
cbc2234f1b
commit
ca7d36873f
15 files changed
+184
-143
No files matched your search
@@ -3145,7 +3145,7 @@ void Creature::SetSpellFocus(Spell const* focusSpell, WorldObject const* target)
|
||||
ObjectGuid newTarget = [&]()
|
||||
{
|
||||
// Spells that do not allow turning or channeled spells that will track their channel target do not set a unit field target
|
||||
if (turnDisabled || noTurnDuringCast || spellInfo->HasAttribute(SPELL_ATTR1_CHANNEL_TRACK_TARGET) || target == this)
|
||||
if (turnDisabled || noTurnDuringCast || spellInfo->HasAttribute(SPELL_ATTR1_TRACK_TARGET_IN_CHANNEL) || target == this)
|
||||
return ObjectGuid::Empty;
|
||||
|
||||
return target->GetGUID();
|
||||
|
||||
@@ -3192,7 +3192,7 @@ bool WorldObject::IsValidAssistTarget(WorldObject const* target, SpellInfo const
|
||||
Unit* WorldObject::GetMagicHitRedirectTarget(Unit* victim, SpellInfo const* spellInfo)
|
||||
{
|
||||
// Patch 1.2 notes: Spell Reflection no longer reflects abilities
|
||||
if (spellInfo->HasAttribute(SPELL_ATTR0_IS_ABILITY) || spellInfo->HasAttribute(SPELL_ATTR1_CANT_BE_REDIRECTED) || spellInfo->HasAttribute(SPELL_ATTR0_NO_IMMUNITIES))
|
||||
if (spellInfo->HasAttribute(SPELL_ATTR0_IS_ABILITY) || spellInfo->HasAttribute(SPELL_ATTR1_NO_REDIRECTION) || spellInfo->HasAttribute(SPELL_ATTR0_NO_IMMUNITIES))
|
||||
return victim;
|
||||
|
||||
Unit::AuraEffectList const& magnetAuras = victim->GetAuraEffectsByType(SPELL_AURA_SPELL_MAGNET);
|
||||
|
||||
@@ -5207,12 +5207,15 @@ inline int32 SkillGainChance(Player const* player, uint32 SkillValue, uint32 Gra
|
||||
return chance;
|
||||
}
|
||||
|
||||
bool Player::UpdateCraftSkill(uint32 spellid)
|
||||
bool Player::UpdateCraftSkill(SpellInfo const* spellInfo)
|
||||
{
|
||||
TC_LOG_DEBUG("entities.player.skills", "Player::UpdateCraftSkill: Player '%s' (%s), SpellID: %d",
|
||||
GetName().c_str(), GetGUID().ToString().c_str(), spellid);
|
||||
if (spellInfo->HasAttribute(SPELL_ATTR1_NO_SKILL_INCREASE))
|
||||
return false;
|
||||
|
||||
SkillLineAbilityMapBounds bounds = sSpellMgr->GetSkillLineAbilityMapBounds(spellid);
|
||||
TC_LOG_DEBUG("entities.player.skills", "Player::UpdateCraftSkill: Player '%s' (%s), SpellID: %d",
|
||||
GetName().c_str(), GetGUID().ToString().c_str(), spellInfo->Id);
|
||||
|
||||
SkillLineAbilityMapBounds bounds = sSpellMgr->GetSkillLineAbilityMapBounds(spellInfo->Id);
|
||||
|
||||
for (SkillLineAbilityMap::const_iterator _spell_idx = bounds.first; _spell_idx != bounds.second; ++_spell_idx)
|
||||
{
|
||||
@@ -5221,10 +5224,9 @@ bool Player::UpdateCraftSkill(uint32 spellid)
|
||||
uint32 SkillValue = GetPureSkillValue(_spell_idx->second->SkillLine);
|
||||
|
||||
// Alchemy Discoveries here
|
||||
SpellInfo const* spellEntry = sSpellMgr->GetSpellInfo(spellid);
|
||||
if (spellEntry && spellEntry->Mechanic == MECHANIC_DISCOVERY)
|
||||
if (spellInfo && spellInfo->Mechanic == MECHANIC_DISCOVERY)
|
||||
{
|
||||
if (uint32 discoveredSpell = GetSkillDiscoverySpell(_spell_idx->second->SkillLine, spellid, this))
|
||||
if (uint32 discoveredSpell = GetSkillDiscoverySpell(_spell_idx->second->SkillLine, spellInfo->Id, this))
|
||||
LearnSpell(discoveredSpell, false);
|
||||
}
|
||||
|
||||
@@ -5234,7 +5236,6 @@ bool Player::UpdateCraftSkill(uint32 spellid)
|
||||
if (craft_skill_points)
|
||||
{
|
||||
craft_skill_points *= craft_skill_gain;
|
||||
TC_LOG_INFO("entities.player", "craft_skill_points is %u, spellID: %u, skillID: %u", craft_skill_points, spellid, _spell_idx->second->SkillLine);
|
||||
return UpdateSkillPro(_spell_idx->second->SkillLine, SkillGainChance(this, SkillValue,
|
||||
_spell_idx->second->TrivialSkillLineRankHigh,
|
||||
(_spell_idx->second->TrivialSkillLineRankHigh + _spell_idx->second->TrivialSkillLineRankLow) / 2,
|
||||
|
||||
@@ -1754,7 +1754,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
|
||||
bool UpdateSkill(uint32 skill_id, uint32 step);
|
||||
bool UpdateSkillPro(uint16 skillId, int32 chance, uint32 step);
|
||||
|
||||
bool UpdateCraftSkill(uint32 spellid);
|
||||
bool UpdateCraftSkill(SpellInfo const* spellInfo);
|
||||
bool UpdateGatherSkill(uint32 SkillId, uint32 SkillValue, uint32 RedLevel, uint32 Multiplicator = 1);
|
||||
bool UpdateFishingSkill();
|
||||
void GiveXpForGather(uint32 const& skillId);
|
||||
|
||||
@@ -443,7 +443,7 @@ void Unit::Update(uint32 p_time)
|
||||
{
|
||||
// Prioritize tracking channeled spells above unit targets if they should both be present at the same time.
|
||||
Spell const* channeledSpell = GetCurrentSpell(CURRENT_CHANNELED_SPELL);
|
||||
if (channeledSpell && channeledSpell->GetSpellInfo()->HasAttribute(SPELL_ATTR1_CHANNEL_TRACK_TARGET))
|
||||
if (channeledSpell && channeledSpell->GetSpellInfo()->HasAttribute(SPELL_ATTR1_TRACK_TARGET_IN_CHANNEL))
|
||||
{
|
||||
ObjectGuid const channelGuid = GetChannelObjectGuid();
|
||||
if (!channelGuid.IsEmpty() && channelGuid != GetGUID())
|
||||
@@ -3651,7 +3651,7 @@ void Unit::RemoveAurasDueToSpellByDispel(uint32 spellId, uint32 dispellerSpellId
|
||||
}
|
||||
}
|
||||
|
||||
void Unit::RemoveAurasDueToSpellBySteal(uint32 spellId, ObjectGuid casterGUID, WorldObject* stealer)
|
||||
void Unit::RemoveAurasDueToSpellBySteal(uint32 spellId, ObjectGuid casterGUID, WorldObject* stealer, int32 stolenCharges /*= 1*/)
|
||||
{
|
||||
AuraMapBoundsNonConst range = m_ownedAuras.equal_range(spellId);
|
||||
for (AuraMap::iterator iter = range.first; iter != range.second;)
|
||||
@@ -3685,9 +3685,9 @@ void Unit::RemoveAurasDueToSpellBySteal(uint32 spellId, ObjectGuid casterGUID, W
|
||||
if (Aura* oldAura = unitStealer->GetAura(aura->GetId(), aura->GetCasterGUID()))
|
||||
{
|
||||
if (stealCharge)
|
||||
oldAura->ModCharges(1);
|
||||
oldAura->ModCharges(stolenCharges);
|
||||
else
|
||||
oldAura->ModStackAmount(1);
|
||||
oldAura->ModStackAmount(stolenCharges);
|
||||
oldAura->SetDuration(int32(dur));
|
||||
}
|
||||
else
|
||||
@@ -3712,16 +3712,16 @@ void Unit::RemoveAurasDueToSpellBySteal(uint32 spellId, ObjectGuid casterGUID, W
|
||||
caster->GetLimitedCastAuras(aura->GetId()).push_back(aura);
|
||||
}
|
||||
// FIXME: using aura->GetMaxDuration() maybe not blizzlike but it fixes stealing of spells like Innervate
|
||||
newAura->SetLoadedState(aura->GetMaxDuration(), int32(dur), stealCharge ? 1 : aura->GetCharges(), 1, recalculateMask, aura->GetCritChance(), aura->CanApplyResilience(), &damage[0]);
|
||||
newAura->SetLoadedState(aura->GetMaxDuration(), int32(dur), stealCharge ? stolenCharges : aura->GetCharges(), stolenCharges, recalculateMask, aura->GetCritChance(), aura->CanApplyResilience(), &damage[0]);
|
||||
newAura->ApplyForTargets();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (stealCharge)
|
||||
aura->ModCharges(-1, AuraRemoveFlags::ByEnemySpell);
|
||||
aura->ModCharges(-stolenCharges, AuraRemoveFlags::ByEnemySpell);
|
||||
else
|
||||
aura->ModStackAmount(-1, AuraRemoveFlags::ByEnemySpell);
|
||||
aura->ModStackAmount(-stolenCharges, AuraRemoveFlags::ByEnemySpell);
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -4033,7 +4033,27 @@ void Unit::RemoveAurasOnEvade()
|
||||
|
||||
// don't remove vehicle auras, passengers aren't supposed to drop off the vehicle
|
||||
// don't remove clone caster on evade (to be verified)
|
||||
RemoveAllAurasExceptType(SPELL_AURA_CONTROL_VEHICLE, SPELL_AURA_CLONE_CASTER);
|
||||
auto evadeAuraCheck = [](Aura const* aura)
|
||||
{
|
||||
if (aura->HasEffectType(SPELL_AURA_CONTROL_VEHICLE))
|
||||
return false;
|
||||
|
||||
if (aura->HasEffectType(SPELL_AURA_CLONE_CASTER))
|
||||
return false;
|
||||
|
||||
if (aura->GetSpellInfo()->HasAttribute(SPELL_ATTR1_AURA_STAYS_AFTER_COMBAT))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
auto evadeAuraApplicationCheck = [&evadeAuraCheck](AuraApplication const* aurApp)
|
||||
{
|
||||
return evadeAuraCheck(aurApp->GetBase());
|
||||
};
|
||||
|
||||
RemoveAppliedAuras(evadeAuraApplicationCheck);
|
||||
RemoveOwnedAuras(evadeAuraCheck);
|
||||
}
|
||||
|
||||
void Unit::RemoveAllAurasOnDeath()
|
||||
@@ -7303,7 +7323,7 @@ bool Unit::IsImmunedToDamage(SpellInfo const* spellInfo) const
|
||||
if (spellInfo->HasAttribute(SPELL_ATTR0_NO_IMMUNITIES) && spellInfo->HasAttribute(SPELL_ATTR3_IGNORE_HIT_RESULT))
|
||||
return false;
|
||||
|
||||
if (spellInfo->HasAttribute(SPELL_ATTR1_UNAFFECTED_BY_SCHOOL_IMMUNE) || spellInfo->HasAttribute(SPELL_ATTR2_UNAFFECTED_BY_AURA_SCHOOL_IMMUNE))
|
||||
if (spellInfo->HasAttribute(SPELL_ATTR1_IMMUNITY_TO_HOSTILE_AND_FRIENDLY_EFFECTS) || spellInfo->HasAttribute(SPELL_ATTR2_UNAFFECTED_BY_AURA_SCHOOL_IMMUNE))
|
||||
return false;
|
||||
|
||||
if (uint32 schoolMask = spellInfo->GetSchoolMask())
|
||||
|
||||
@@ -115,12 +115,12 @@ class DispelableAura
|
||||
uint8 GetDispelCharges() const { return _charges; }
|
||||
|
||||
void IncrementCharges() { ++_charges; }
|
||||
bool DecrementCharge()
|
||||
bool DecrementCharge(uint8 charges)
|
||||
{
|
||||
if (!_charges)
|
||||
return false;
|
||||
|
||||
--_charges;
|
||||
_charges -= charges;
|
||||
return _charges > 0;
|
||||
}
|
||||
|
||||
@@ -1344,7 +1344,7 @@ class TC_GAME_API Unit : public WorldObject
|
||||
void RemoveAurasDueToSpell(uint32 spellId, ObjectGuid casterGUID = ObjectGuid::Empty, uint8 reqEffMask = 0, AuraRemoveFlags removeMode = AuraRemoveFlags::ByDefault);
|
||||
void RemoveAuraFromStack(uint32 spellId, ObjectGuid casterGUID = ObjectGuid::Empty, AuraRemoveFlags removeMode = AuraRemoveFlags::ByDefault);
|
||||
void RemoveAurasDueToSpellByDispel(uint32 spellId, uint32 dispellerSpellId, ObjectGuid casterGUID, WorldObject* dispeller, uint8 chargesRemoved = 1);
|
||||
void RemoveAurasDueToSpellBySteal(uint32 spellId, ObjectGuid casterGUID, WorldObject* stealer);
|
||||
void RemoveAurasDueToSpellBySteal(uint32 spellId, ObjectGuid casterGUID, WorldObject* stealer, int32 stolenCharges = 1);
|
||||
void RemoveAurasDueToItemSpell(uint32 spellId, ObjectGuid castItemGuid);
|
||||
void RemoveAurasByType(AuraType auraType, ObjectGuid casterGUID = ObjectGuid::Empty, Aura* except = nullptr, bool negative = true, bool positive = true);
|
||||
void RemoveNotOwnLimitedTargetAuras(bool onPhaseChange = false);
|
||||
|
||||
@@ -387,40 +387,41 @@ enum SpellAttr0 : uint32
|
||||
SPELL_ATTR0_NO_AURA_CANCEL = 0x80000000 // No Aura Cancel DESCRIPTION Prevents the player from voluntarily canceling a positive aura
|
||||
};
|
||||
|
||||
enum SpellAttr1
|
||||
// EnumUtils: DESCRIBE THIS
|
||||
enum SpellAttr1 : uint32
|
||||
{
|
||||
SPELL_ATTR1_DISMISS_PET = 0x00000001, // 0 for spells without this flag client doesn't allow to summon pet if caster has a pet
|
||||
SPELL_ATTR1_DRAIN_ALL_POWER = 0x00000002, // 1 use all power (Only paladin Lay of Hands and Bunyanize)
|
||||
SPELL_ATTR1_CHANNELED = 0x00000004, // 2 Is Channeled
|
||||
SPELL_ATTR1_CANT_BE_REDIRECTED = 0x00000008, // 3
|
||||
SPELL_ATTR1_UNK4 = 0x00000010, // 4 stealth and whirlwind
|
||||
SPELL_ATTR1_NOT_BREAK_STEALTH = 0x00000020, // 5 Not break stealth
|
||||
SPELL_ATTR1_SELF_CHANNELED = 0x00000040, // 6 Is Self Channeled
|
||||
SPELL_ATTR1_CANT_BE_REFLECTED = 0x00000080, // 7
|
||||
SPELL_ATTR1_CANT_TARGET_IN_COMBAT = 0x00000100, // 8 can target only out of combat units
|
||||
SPELL_ATTR1_MELEE_COMBAT_START = 0x00000200, // 9 player starts melee combat after this spell is cast
|
||||
SPELL_ATTR1_NO_THREAT = 0x00000400, // 10 no generates threat on cast 100% (old NO_INITIAL_AGGRO)
|
||||
SPELL_ATTR1_DONT_REFRESH_DURATION_ON_RECAST = 0x00000800, // 11 aura will not refresh its duration when recast
|
||||
SPELL_ATTR1_IS_PICKPOCKET = 0x00001000, // 12 Pickpocket
|
||||
SPELL_ATTR1_FARSIGHT = 0x00002000, // 13 Client removes farsight on aura loss
|
||||
SPELL_ATTR1_CHANNEL_TRACK_TARGET = 0x00004000, // 14 Client automatically forces player to face target when channeling
|
||||
SPELL_ATTR1_DISPEL_AURAS_ON_IMMUNITY = 0x00008000, // 15 remove auras on immunity
|
||||
SPELL_ATTR1_UNAFFECTED_BY_SCHOOL_IMMUNE = 0x00010000, // 16 on immuniy
|
||||
SPELL_ATTR1_UNAUTOCASTABLE_BY_PET = 0x00020000, // 17
|
||||
SPELL_ATTR1_UNK18 = 0x00040000, // 18 stun, polymorph, daze, hex
|
||||
SPELL_ATTR1_CANT_TARGET_SELF = 0x00080000, // 19
|
||||
SPELL_ATTR1_FINISHING_MOVE_DAMAGE = 0x00100000, // 20 Finishing Move - Damage
|
||||
SPELL_ATTR1_UNK21 = 0x00200000, // 21
|
||||
SPELL_ATTR1_FINISHING_MOVE_DURATION = 0x00400000, // 22 Finishing Move - Duration
|
||||
SPELL_ATTR1_UNK23 = 0x00800000, // 23
|
||||
SPELL_ATTR1_IS_FISHING = 0x01000000, // 24 only fishing spells
|
||||
SPELL_ATTR1_UNK25 = 0x02000000, // 25
|
||||
SPELL_ATTR1_UNK26 = 0x04000000, // 26 works correctly with [target=focus] and [target=mouseover] macros?
|
||||
SPELL_ATTR1_DISCOUNT_POWER_ON_MISS = 0x08000000, // 27 Discount Power On Miss
|
||||
SPELL_ATTR1_DONT_DISPLAY_IN_AURA_BAR = 0x10000000, // 28 client doesn't display these spells in aura bar
|
||||
SPELL_ATTR1_CHANNEL_DISPLAY_SPELL_NAME = 0x20000000, // 29 spell name is displayed in cast bar instead of 'channeling' text
|
||||
SPELL_ATTR1_ENABLE_AT_DODGE = 0x40000000, // 30 Overpower
|
||||
SPELL_ATTR1_CAST_WHEN_LEARNED = 0x80000000 // 31 Cast When Learned
|
||||
SPELL_ATTR1_DISMISS_PET_FIRST = 0x00000001, // Dismiss Pet First DESCRIPTION Without this attribute, summoning spells will fail if caster already has a pet
|
||||
SPELL_ATTR1_USE_ALL_MANA = 0x00000002, // Use All Mana DESCRIPTION Ignores listed power cost and drains entire pool instead
|
||||
SPELL_ATTR1_IS_CHANNELLED = 0x00000004, // Is Channelled DESCRIPTION Both "channeled" attributes have identical handling in server & client
|
||||
SPELL_ATTR1_NO_REDIRECTION = 0x00000008, // No Redirection DESCRIPTION Spell will not be attracted by SPELL_MAGNET auras (Grounding Totem)
|
||||
SPELL_ATTR1_NO_SKILL_INCREASE = 0x00000010, // No Skill Increase
|
||||
SPELL_ATTR1_ALLOW_WHILE_STEALTHED = 0x00000020, // Allow While Stealthed
|
||||
SPELL_ATTR1_IS_SELF_CHANNELLED = 0x00000040, // Is Self Channelled DESCRIPTION Both "channeled" attributes have identical handling in server & client
|
||||
SPELL_ATTR1_NO_REFLECTION = 0x00000080, // No Reflection DESCRIPTION Spell will pierce through Spell Reflection and similar
|
||||
SPELL_ATTR1_ONLY_PEACEFUL_TARGETS = 0x00000100, // Only Peaceful Targets DESCRIPTION Target cannot be in combat
|
||||
SPELL_ATTR1_INITIATES_COMBAT_ENABLES_AUTO_ATTACK = 0x00000200, // Initiates Combat (Enables Auto-Attack) (client only) DESCRIPTION Caster will begin auto-attacking the target on cast
|
||||
SPELL_ATTR1_NO_THREAT = 0x00000400, // Does not generate threat DESCRIPTION Also does not cause target to engage
|
||||
SPELL_ATTR1_AURA_UNIQUE = 0x00000800, // Aura Unique DESCRIPTION Aura will not refresh its duration when recast
|
||||
SPELL_ATTR1_FAILURE_BREAKS_STEALTH = 0x00001000, // Failure Breaks Stealth
|
||||
SPELL_ATTR1_TOGGLE_FAR_SIGHT = 0x00002000, // Toggle Far Sight (client only)
|
||||
SPELL_ATTR1_TRACK_TARGET_IN_CHANNEL = 0x00004000, // Track Target in Channel DESCRIPTION While channeling, adjust facing to face target
|
||||
SPELL_ATTR1_IMMUNITY_PURGES_EFFECT = 0x00008000, // Immunity Purges Effect DESCRIPTION For immunity spells, cancel all auras that this spell would make you immune to when the spell is applied
|
||||
SPELL_ATTR1_IMMUNITY_TO_HOSTILE_AND_FRIENDLY_EFFECTS = 0x00010000, /*WRONG IMPL*/ // Immunity to Hostile & Friendly Effects DESCRIPTION Will not pierce Divine Shield, Ice Block and other full invulnerabilities
|
||||
SPELL_ATTR1_NO_AUTOCAST_AI = 0x00020000, // No AutoCast (AI)
|
||||
SPELL_ATTR1_PREVENTS_ANIM = 0x00040000, /*NYI*/ // Prevents Anim DESCRIPTION Auras apply UNIT_FLAG_PREVENT_EMOTES_FROM_CHAT_TEXT
|
||||
SPELL_ATTR1_EXCLUDE_CASTER = 0x00080000, // Exclude Caster
|
||||
SPELL_ATTR1_FINISHING_MOVE_DAMAGE = 0x00100000, // Finishing Move - Damage
|
||||
SPELL_ATTR1_THREAT_ONLY_ON_MISS = 0x00200000, /*NYI*/ // Threat only on Miss
|
||||
SPELL_ATTR1_FINISHING_MOVE_DURATION = 0x00400000, // Finishing Move - Duration
|
||||
SPELL_ATTR1_IGNORE_OWNERS_DEATH = 0x00800000, /*NYI*/ // Ignore Owner's Death
|
||||
SPELL_ATTR1_SPECIAL_SKILLUP = 0x01000000, // Special Skillup
|
||||
SPELL_ATTR1_AURA_STAYS_AFTER_COMBAT = 0x02000000, // Aura Stays After Combat
|
||||
SPELL_ATTR1_REQUIRE_ALL_TARGETS = 0x04000000, /*NYI, UNK*/ // Require All Targets
|
||||
SPELL_ATTR1_DISCOUNT_POWER_ON_MISS = 0x08000000, // Discount Power On Miss
|
||||
SPELL_ATTR1_NO_AURA_ICON = 0x10000000, // No Aura Icon (client only)
|
||||
SPELL_ATTR1_NAME_IN_CHANNEL_BAR = 0x20000000, // Name in Channel Bar (client only)
|
||||
SPELL_ATTR1_DISPEL_ALL_STACKS = 0x40000000, // Dispel All Stacks
|
||||
SPELL_ATTR1_CAST_WHEN_LEARNED = 0x80000000 // Cast When Learned
|
||||
};
|
||||
|
||||
enum SpellAttr2
|
||||
|
||||
@@ -3325,7 +3325,7 @@ void AuraEffect::HandleAuraModSchoolImmunity(AuraApplication const* aurApp, uint
|
||||
target->RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags::StealthOrInvis);
|
||||
|
||||
// remove all flag auras (they are positive, but they must be removed when you are immune)
|
||||
if (GetSpellInfo()->HasAttribute(SPELL_ATTR1_DISPEL_AURAS_ON_IMMUNITY)
|
||||
if (GetSpellInfo()->HasAttribute(SPELL_ATTR1_IMMUNITY_PURGES_EFFECT)
|
||||
&& GetSpellInfo()->HasAttribute(SPELL_ATTR2_DAMAGE_REDUCED_SHIELD))
|
||||
target->RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags::StealthOrInvis);
|
||||
}
|
||||
|
||||
@@ -1037,7 +1037,7 @@ bool Aura::ModStackAmount(int32 num, AuraRemoveFlags removeMode /*= AuraRemoveFl
|
||||
|
||||
EnumFlag<AuraRemoveFlags> removeFlags = removeMode;
|
||||
|
||||
bool refresh = stackAmount >= GetStackAmount() && (m_spellInfo->StackAmount || !m_spellInfo->HasAttribute(SPELL_ATTR1_DONT_REFRESH_DURATION_ON_RECAST));
|
||||
bool refresh = stackAmount >= GetStackAmount() && (m_spellInfo->StackAmount || !m_spellInfo->HasAttribute(SPELL_ATTR1_AURA_UNIQUE));
|
||||
|
||||
// Update stack amount
|
||||
SetStackAmount(stackAmount);
|
||||
|
||||
@@ -667,7 +667,7 @@ m_caster((info->HasAttribute(SPELL_ATTR6_CAST_BY_CHARMER) && caster->GetCharmerO
|
||||
// Determine if spell can be reflected back to the caster
|
||||
// Patch 1.2 notes: Spell Reflection no longer reflects abilities
|
||||
m_canReflect = caster->IsUnit() && m_spellInfo->DmgClass == SPELL_DAMAGE_CLASS_MAGIC && !m_spellInfo->HasAttribute(SPELL_ATTR0_IS_ABILITY)
|
||||
&& !m_spellInfo->HasAttribute(SPELL_ATTR1_CANT_BE_REFLECTED) && !m_spellInfo->HasAttribute(SPELL_ATTR0_NO_IMMUNITIES)
|
||||
&& !m_spellInfo->HasAttribute(SPELL_ATTR1_NO_REFLECTION) && !m_spellInfo->HasAttribute(SPELL_ATTR0_NO_IMMUNITIES)
|
||||
&& !m_spellInfo->IsPassive();
|
||||
|
||||
CleanupTargetList();
|
||||
@@ -2673,7 +2673,7 @@ void Spell::TargetInfo::DoDamageAndTriggers(Spell* spell)
|
||||
}
|
||||
|
||||
// Failed Pickpocket, reveal rogue
|
||||
if (MissCondition == SPELL_MISS_RESIST && spell->m_spellInfo->HasAttribute(SPELL_ATTR0_CU_PICKPOCKET) && spell->unitTarget->GetTypeId() == TYPEID_UNIT)
|
||||
if (MissCondition == SPELL_MISS_RESIST && spell->m_spellInfo->HasAttribute(SPELL_ATTR1_FAILURE_BREAKS_STEALTH) && spell->unitTarget->GetTypeId() == TYPEID_UNIT)
|
||||
{
|
||||
Unit* unitCaster = ASSERT_NOTNULL(spell->m_caster->ToUnit());
|
||||
unitCaster->RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags::Interacting);
|
||||
@@ -3566,7 +3566,7 @@ void Spell::_cast(bool skipCheck)
|
||||
}
|
||||
|
||||
if (Unit* unitCaster = m_caster->ToUnit())
|
||||
if (m_spellInfo->HasAttribute(SPELL_ATTR1_DISMISS_PET))
|
||||
if (m_spellInfo->HasAttribute(SPELL_ATTR1_DISMISS_PET_FIRST))
|
||||
if (Creature* pet = ObjectAccessor::GetCreature(*m_caster, unitCaster->GetPetGUID()))
|
||||
pet->DespawnOrUnsummon();
|
||||
|
||||
@@ -4941,27 +4941,10 @@ void Spell::SendChannelStart(uint32 duration)
|
||||
if (!unitCaster)
|
||||
return;
|
||||
|
||||
ObjectGuid channelTarget = m_targets.GetObjectTargetGUID();
|
||||
if (!channelTarget && !m_spellInfo->NeedsExplicitUnitTarget())
|
||||
{
|
||||
// this is for TARGET_SELECT_CATEGORY_NEARBY
|
||||
if (m_UniqueTargetInfo.size() + m_UniqueGOTargetInfo.size() == 1)
|
||||
channelTarget = !m_UniqueTargetInfo.empty() ? m_UniqueTargetInfo.front().TargetGUID : m_UniqueGOTargetInfo.front().TargetGUID;
|
||||
else
|
||||
{
|
||||
// We assume that when we have a channel spell with more than one unique unit target that there is a caster and a target.
|
||||
// We don't want the caster but the target so we are looking for a non-caster entry within the target list
|
||||
for (auto& itr : m_UniqueTargetInfo)
|
||||
{
|
||||
if (itr.TargetGUID != m_caster->GetGUID())
|
||||
channelTarget = itr.TargetGUID;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// There must always be a channel target
|
||||
if (!channelTarget)
|
||||
channelTarget = m_caster->GetGUID();
|
||||
WorldPackets::Spells::ChannelStart packet;
|
||||
packet.CasterGUID = m_caster->GetGUID();
|
||||
packet.SpellID = m_spellInfo->Id;
|
||||
packet.ChannelDuration = duration;
|
||||
|
||||
uint32 castFlags = CAST_FLAG_HAS_TRAJECTORY;
|
||||
uint32 schoolImmunityMask = unitCaster->GetSchoolImmunityMask();
|
||||
@@ -4970,15 +4953,6 @@ void Spell::SendChannelStart(uint32 duration)
|
||||
if (schoolImmunityMask || mechanicImmunityMask)
|
||||
castFlags |= CAST_FLAG_IMMUNITY;
|
||||
|
||||
uint8 ticks = m_spellInfo->GetMaxTicks();
|
||||
if (m_spellInfo->HasAttribute(SPELL_ATTR5_START_PERIODIC_AT_APPLY))
|
||||
++ticks;
|
||||
|
||||
WorldPackets::Spells::ChannelStart packet;
|
||||
packet.CasterGUID = m_caster->GetGUID();
|
||||
packet.SpellID = m_spellInfo->Id;
|
||||
packet.ChannelDuration = duration;
|
||||
|
||||
if (castFlags & CAST_FLAG_IMMUNITY)
|
||||
{
|
||||
packet.InterruptImmunities.emplace();
|
||||
@@ -4986,26 +4960,62 @@ void Spell::SendChannelStart(uint32 duration)
|
||||
packet.InterruptImmunities->Immunities = mechanicImmunityMask; // CastImmunities
|
||||
}
|
||||
|
||||
if (!m_targets.HasDst())
|
||||
{
|
||||
uint32 channelAuraMask = 0;
|
||||
uint32 explicitTargetEffectMask = 0xFFFFFFFF;
|
||||
// if there is an explicit target, only add channel objects from effects that also hit it
|
||||
if (!m_targets.GetUnitTargetGUID().IsEmpty())
|
||||
{
|
||||
auto explicitTargetItr = std::find_if(m_UniqueTargetInfo.begin(), m_UniqueTargetInfo.end(), [&](TargetInfo const& target)
|
||||
{
|
||||
return target.TargetGUID == m_targets.GetUnitTargetGUID();
|
||||
});
|
||||
if (explicitTargetItr != m_UniqueTargetInfo.end())
|
||||
explicitTargetEffectMask = explicitTargetItr->EffectMask;
|
||||
}
|
||||
|
||||
for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
|
||||
{
|
||||
SpellEffectInfo const& spellEffectInfo = m_spellInfo->Effects[i];
|
||||
if (spellEffectInfo.IsEffect(SPELL_EFFECT_APPLY_AURA) && (explicitTargetEffectMask & (1u << i)))
|
||||
channelAuraMask |= 1 << i;
|
||||
}
|
||||
|
||||
for (TargetInfo const& target : m_UniqueTargetInfo)
|
||||
{
|
||||
if (!(target.EffectMask & channelAuraMask))
|
||||
continue;
|
||||
|
||||
SpellAttr1 requiredAttribute = target.TargetGUID != unitCaster->GetGUID() ? SPELL_ATTR1_IS_CHANNELLED : SPELL_ATTR1_IS_SELF_CHANNELLED;
|
||||
if (!m_spellInfo->HasAttribute(requiredAttribute))
|
||||
continue;
|
||||
|
||||
unitCaster->SetChannelObjectGuid(target.TargetGUID);
|
||||
}
|
||||
|
||||
for (GOTargetInfo const& target : m_UniqueGOTargetInfo)
|
||||
if (target.EffectMask & channelAuraMask)
|
||||
unitCaster->SetChannelObjectGuid(target.TargetGUID);
|
||||
}
|
||||
else if (m_spellInfo->HasAttribute(SPELL_ATTR1_IS_SELF_CHANNELLED))
|
||||
unitCaster->SetChannelObjectGuid(unitCaster->GetGUID());
|
||||
|
||||
|
||||
if (m_spellInfo->HasAttribute(SPELL_ATTR8_HEAL_PREDICTION))
|
||||
{
|
||||
castFlags |= CAST_FLAG_HEAL_PREDICTION;
|
||||
|
||||
WorldPackets::Spells::SpellHealPrediction predict;
|
||||
UpdateSpellHealPrediction(predict);
|
||||
packet.HealPrediction.emplace(channelTarget, predict);
|
||||
packet.HealPrediction.emplace(unitCaster->GetChannelObjectGuid(), predict);
|
||||
}
|
||||
|
||||
m_caster->SendMessageToSet(packet.Write(), true);
|
||||
|
||||
m_timer = duration;
|
||||
if (channelTarget)
|
||||
{
|
||||
unitCaster->SetChannelObjectGuid(channelTarget);
|
||||
|
||||
if (Creature* creatureCaster = m_caster->ToCreature())
|
||||
if (!creatureCaster->HasSpellFocus(this))
|
||||
creatureCaster->SetSpellFocus(this, ObjectAccessor::GetWorldObject(*creatureCaster, channelTarget));
|
||||
}
|
||||
if (Creature* creatureCaster = m_caster->ToCreature())
|
||||
if (!creatureCaster->HasSpellFocus(this))
|
||||
creatureCaster->SetSpellFocus(this, ObjectAccessor::GetWorldObject(*creatureCaster, unitCaster->GetChannelObjectGuid()));
|
||||
|
||||
m_caster->SetUInt32Value(UNIT_CHANNEL_SPELL, m_spellInfo->Id);
|
||||
}
|
||||
@@ -5550,7 +5560,7 @@ SpellCastResult Spell::CheckCast(bool strict, uint32* param1 /*= nullptr*/, uint
|
||||
{
|
||||
if (m_spellInfo->HasAttribute(SPELL_ATTR0_USES_RANGED_SLOT)
|
||||
|| m_spellInfo->IsNextMeleeSwingSpell()
|
||||
|| m_spellInfo->HasAttribute(SPELL_ATTR1_MELEE_COMBAT_START)
|
||||
|| m_spellInfo->HasAttribute(SPELL_ATTR1_INITIATES_COMBAT_ENABLES_AUTO_ATTACK)
|
||||
|| m_spellInfo->HasAttribute(SPELL_ATTR2_INITIATE_COMBAT_POST_CAST)
|
||||
|| m_spellInfo->HasEffect(SPELL_EFFECT_ATTACK)
|
||||
|| m_spellInfo->HasEffect(SPELL_EFFECT_NORMALIZED_WEAPON_DMG)
|
||||
@@ -6157,7 +6167,7 @@ SpellCastResult Spell::CheckCast(bool strict, uint32* param1 /*= nullptr*/, uint
|
||||
switch (SummonProperties->Control)
|
||||
{
|
||||
case SUMMON_CATEGORY_PET:
|
||||
if (!m_spellInfo->HasAttribute(SPELL_ATTR1_DISMISS_PET) && unitCaster->GetPetGUID())
|
||||
if (!m_spellInfo->HasAttribute(SPELL_ATTR1_DISMISS_PET_FIRST) && unitCaster->GetPetGUID())
|
||||
return SPELL_FAILED_ALREADY_HAVE_SUMMON;
|
||||
[[fallthrough]]; // check both GetPetGUID() and GetCharmGUID for SUMMON_CATEGORY_PET*/
|
||||
case SUMMON_CATEGORY_PUPPET:
|
||||
@@ -6173,7 +6183,7 @@ SpellCastResult Spell::CheckCast(bool strict, uint32* param1 /*= nullptr*/, uint
|
||||
{
|
||||
if (m_targets.GetUnitTarget()->GetTypeId() != TYPEID_PLAYER)
|
||||
return SPELL_FAILED_BAD_TARGETS;
|
||||
if (!m_spellInfo->HasAttribute(SPELL_ATTR1_DISMISS_PET) && m_targets.GetUnitTarget()->GetPetGUID())
|
||||
if (!m_spellInfo->HasAttribute(SPELL_ATTR1_DISMISS_PET_FIRST) && m_targets.GetUnitTarget()->GetPetGUID())
|
||||
return SPELL_FAILED_ALREADY_HAVE_SUMMON;
|
||||
}
|
||||
break;
|
||||
@@ -6192,7 +6202,7 @@ SpellCastResult Spell::CheckCast(bool strict, uint32* param1 /*= nullptr*/, uint
|
||||
if (Pet* pet = unitCaster->ToPlayer()->GetPet())
|
||||
pet->CastSpell(pet, 32752, pet->GetGUID());
|
||||
}
|
||||
else if (!m_spellInfo->HasAttribute(SPELL_ATTR1_DISMISS_PET))
|
||||
else if (!m_spellInfo->HasAttribute(SPELL_ATTR1_DISMISS_PET_FIRST))
|
||||
return SPELL_FAILED_ALREADY_HAVE_SUMMON;
|
||||
}
|
||||
|
||||
@@ -6325,7 +6335,7 @@ SpellCastResult Spell::CheckCast(bool strict, uint32* param1 /*= nullptr*/, uint
|
||||
if (m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_MOD_CHARM
|
||||
|| m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_MOD_POSSESS)
|
||||
{
|
||||
if (!m_spellInfo->HasAttribute(SPELL_ATTR1_DISMISS_PET) && unitCaster->GetPetGUID())
|
||||
if (!m_spellInfo->HasAttribute(SPELL_ATTR1_DISMISS_PET_FIRST) && unitCaster->GetPetGUID())
|
||||
return SPELL_FAILED_ALREADY_HAVE_SUMMON;
|
||||
|
||||
if (unitCaster->GetCharmedGUID())
|
||||
@@ -7712,7 +7722,7 @@ bool Spell::IsIgnoringCooldowns() const
|
||||
bool Spell::IsFocusDisabled() const
|
||||
{
|
||||
return ((_triggeredCastFlags & TRIGGERED_IGNORE_SET_FACING) != 0
|
||||
|| (m_spellInfo->IsChanneled() && !m_spellInfo->HasAttribute(SpellAttr1(SPELL_ATTR1_CHANNEL_TRACK_TARGET | SPELL_ATTR1_SELF_CHANNELED))));
|
||||
|| (m_spellInfo->IsChanneled() && !m_spellInfo->HasAttribute(SPELL_ATTR1_TRACK_TARGET_IN_CHANNEL)));
|
||||
}
|
||||
|
||||
bool Spell::IsProcDisabled() const
|
||||
|
||||
@@ -1370,7 +1370,7 @@ void Spell::DoCreateItem(uint32 /*i*/, uint32 itemtype)
|
||||
|
||||
// we succeeded in creating at least one item, so a levelup is possible
|
||||
if (bgType == 0)
|
||||
player->UpdateCraftSkill(m_spellInfo->Id);
|
||||
player->UpdateCraftSkill(m_spellInfo);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1406,7 +1406,7 @@ void Spell::EffectCreateItem2(SpellEffIndex effIndex)
|
||||
if (m_spellInfo->IsLootCrafting())
|
||||
{
|
||||
player->AutoStoreLoot(m_spellInfo->Id, LootTemplates_Spell, false);
|
||||
player->UpdateCraftSkill(m_spellInfo->Id);
|
||||
player->UpdateCraftSkill(m_spellInfo);
|
||||
}
|
||||
else // If there's no random loot entries for this spell, pick the item associated with this spell
|
||||
{
|
||||
@@ -2069,12 +2069,17 @@ void Spell::EffectDispel(SpellEffIndex effIndex)
|
||||
return false;
|
||||
});
|
||||
|
||||
uint8 dispelledCharges = 1;
|
||||
if (itr->GetAura()->GetSpellInfo()->HasAttribute(SPELL_ATTR1_DISPEL_ALL_STACKS))
|
||||
dispelledCharges = itr->GetDispelCharges();
|
||||
|
||||
|
||||
if (successItr == successList.end())
|
||||
successList.emplace_back(itr->GetAura(), 0, 1);
|
||||
successList.emplace_back(itr->GetAura(), 0, dispelledCharges);
|
||||
else
|
||||
successItr->IncrementCharges();
|
||||
|
||||
if (!itr->DecrementCharge())
|
||||
if (!itr->DecrementCharge(dispelledCharges))
|
||||
{
|
||||
--remaining;
|
||||
std::swap(*itr, dispelList[remaining]);
|
||||
@@ -2316,7 +2321,7 @@ void Spell::EffectEnchantItemPerm(SpellEffIndex effIndex)
|
||||
{
|
||||
// do not increase skill if vellum used
|
||||
if (!(m_CastItem && m_CastItem->GetTemplate()->GetFlags() & ITEM_FLAG_NO_REAGENT_COST))
|
||||
player->UpdateCraftSkill(m_spellInfo->Id);
|
||||
player->UpdateCraftSkill(m_spellInfo);
|
||||
|
||||
uint32 enchant_id = m_spellInfo->Effects[effIndex].MiscValue;
|
||||
if (!enchant_id)
|
||||
@@ -3976,7 +3981,7 @@ void Spell::EffectDisEnchant(SpellEffIndex /*effIndex*/)
|
||||
|
||||
if (Player* caster = m_caster->ToPlayer())
|
||||
{
|
||||
caster->UpdateCraftSkill(m_spellInfo->Id);
|
||||
caster->UpdateCraftSkill(m_spellInfo);
|
||||
caster->SendLoot(itemTarget->GetGUID(), LOOT_DISENCHANTING);
|
||||
}
|
||||
|
||||
@@ -5135,7 +5140,7 @@ void Spell::EffectStealBeneficialBuff(SpellEffIndex effIndex)
|
||||
|
||||
// Ok if exist some buffs for dispel try dispel it
|
||||
uint32 failCount = 0;
|
||||
DispelList successList;
|
||||
std::vector<std::tuple<uint32, ObjectGuid, int32>> successList;
|
||||
successList.reserve(damage);
|
||||
|
||||
WorldPacket dataFail(SMSG_DISPEL_FAILED, 8 + 8 + 4 + 4 + damage * 4);
|
||||
@@ -5148,8 +5153,12 @@ void Spell::EffectStealBeneficialBuff(SpellEffIndex effIndex)
|
||||
|
||||
if (itr->RollDispel())
|
||||
{
|
||||
successList.emplace_back(itr->GetAura()->GetId(), itr->GetAura()->GetCasterGUID());
|
||||
if (!itr->DecrementCharge())
|
||||
uint8 stolenCharges = 1;
|
||||
if (itr->GetAura()->GetSpellInfo()->HasAttribute(SPELL_ATTR1_DISPEL_ALL_STACKS))
|
||||
stolenCharges = itr->GetDispelCharges();
|
||||
|
||||
successList.emplace_back(itr->GetAura()->GetId(), itr->GetAura()->GetCasterGUID(), int32(stolenCharges));
|
||||
if (!itr->DecrementCharge(stolenCharges))
|
||||
{
|
||||
--remaining;
|
||||
std::swap(*itr, stealList[remaining]);
|
||||
@@ -5182,11 +5191,11 @@ void Spell::EffectStealBeneficialBuff(SpellEffIndex effIndex)
|
||||
dataSuccess << uint32(m_spellInfo->Id); // dispel spell id
|
||||
dataSuccess << uint8(0); // not used
|
||||
dataSuccess << uint32(successList.size()); // count
|
||||
for (auto itr = successList.begin(); itr != successList.end(); ++itr)
|
||||
for (auto const& [spellId, auraCaster, stolenCharges] : successList)
|
||||
{
|
||||
dataSuccess << uint32(itr->first); // Spell Id
|
||||
dataSuccess << uint32(spellId); // Spell Id
|
||||
dataSuccess << uint8(0); // 0 - steals !=0 transfers
|
||||
unitTarget->RemoveAurasDueToSpellBySteal(itr->first, itr->second, m_caster);
|
||||
unitTarget->RemoveAurasDueToSpellBySteal(spellId, auraCaster, m_caster, stolenCharges);
|
||||
}
|
||||
m_caster->SendMessageToSet(&dataSuccess, true);
|
||||
}
|
||||
|
||||
@@ -1319,7 +1319,7 @@ bool SpellInfo::IsAutocastable() const
|
||||
{
|
||||
if (IsPassive())
|
||||
return false;
|
||||
if (HasAttribute(SPELL_ATTR1_UNAUTOCASTABLE_BY_PET))
|
||||
if (HasAttribute(SPELL_ATTR1_NO_AUTOCAST_AI))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
@@ -1460,7 +1460,7 @@ bool SpellInfo::IsPositiveEffect(uint8 effIndex) const
|
||||
|
||||
bool SpellInfo::IsChanneled() const
|
||||
{
|
||||
return HasAttribute(SpellAttr1(SPELL_ATTR1_CHANNELED | SPELL_ATTR1_SELF_CHANNELED));
|
||||
return HasAttribute(SpellAttr1(SPELL_ATTR1_IS_CHANNELLED | SPELL_ATTR1_IS_SELF_CHANNELLED));
|
||||
}
|
||||
|
||||
bool SpellInfo::IsMoveAllowedChannel() const
|
||||
@@ -1480,7 +1480,7 @@ bool SpellInfo::IsNextMeleeSwingSpell() const
|
||||
|
||||
bool SpellInfo::IsBreakingStealth() const
|
||||
{
|
||||
return !HasAttribute(SPELL_ATTR1_NOT_BREAK_STEALTH);
|
||||
return !HasAttribute(SPELL_ATTR1_ALLOW_WHILE_STEALTHED);
|
||||
}
|
||||
|
||||
bool SpellInfo::IsRangedWeaponSpell() const
|
||||
@@ -1568,7 +1568,7 @@ bool SpellInfo::CanPierceImmuneAura(SpellInfo const* auraSpellInfo) const
|
||||
return true;
|
||||
|
||||
// these spells (Cyclone for example) can pierce all...
|
||||
if (HasAttribute(SPELL_ATTR1_UNAFFECTED_BY_SCHOOL_IMMUNE) || HasAttribute(SPELL_ATTR2_UNAFFECTED_BY_AURA_SCHOOL_IMMUNE))
|
||||
if (HasAttribute(SPELL_ATTR1_IMMUNITY_TO_HOSTILE_AND_FRIENDLY_EFFECTS) || HasAttribute(SPELL_ATTR2_UNAFFECTED_BY_AURA_SCHOOL_IMMUNE))
|
||||
{
|
||||
// ...but not these (Divine shield, Ice block, Cyclone and Banish for example)
|
||||
if (auraSpellInfo->Mechanic != MECHANIC_IMMUNE_SHIELD &&
|
||||
@@ -1578,7 +1578,7 @@ bool SpellInfo::CanPierceImmuneAura(SpellInfo const* auraSpellInfo) const
|
||||
}
|
||||
|
||||
// Dispels other auras on immunity, check if this spell makes the unit immune to aura
|
||||
if (HasAttribute(SPELL_ATTR1_DISPEL_AURAS_ON_IMMUNITY) && CanSpellProvideImmunityAgainstAura(auraSpellInfo))
|
||||
if (HasAttribute(SPELL_ATTR1_IMMUNITY_PURGES_EFFECT) && CanSpellProvideImmunityAgainstAura(auraSpellInfo))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
@@ -1595,7 +1595,7 @@ bool SpellInfo::CanDispelAura(SpellInfo const* auraSpellInfo) const
|
||||
return true;
|
||||
|
||||
// These auras (Cyclone for example) are not dispelable
|
||||
if ((auraSpellInfo->HasAttribute(SPELL_ATTR1_UNAFFECTED_BY_SCHOOL_IMMUNE) && auraSpellInfo->Mechanic != MECHANIC_NONE)
|
||||
if ((auraSpellInfo->HasAttribute(SPELL_ATTR1_IMMUNITY_TO_HOSTILE_AND_FRIENDLY_EFFECTS) && auraSpellInfo->Mechanic != MECHANIC_NONE)
|
||||
|| auraSpellInfo->HasAttribute(SPELL_ATTR2_UNAFFECTED_BY_AURA_SCHOOL_IMMUNE))
|
||||
return false;
|
||||
|
||||
@@ -1876,7 +1876,7 @@ SpellCastResult SpellInfo::CheckLocation(uint32 map_id, uint32 zone_id, uint32 a
|
||||
|
||||
SpellCastResult SpellInfo::CheckTarget(WorldObject const* caster, WorldObject const* target, bool implicit /*= true*/) const
|
||||
{
|
||||
if (HasAttribute(SPELL_ATTR1_CANT_TARGET_SELF) && caster == target)
|
||||
if (HasAttribute(SPELL_ATTR1_EXCLUDE_CASTER) && caster == target)
|
||||
return SPELL_FAILED_BAD_TARGETS;
|
||||
|
||||
// check visibility - ignore stealth for implicit (area) targets
|
||||
@@ -1889,7 +1889,7 @@ SpellCastResult SpellInfo::CheckTarget(WorldObject const* caster, WorldObject co
|
||||
if (unitTarget)
|
||||
{
|
||||
// spells cannot be cast if target has a pet in combat either
|
||||
if (HasAttribute(SPELL_ATTR1_CANT_TARGET_IN_COMBAT) && (unitTarget->IsInCombat() || unitTarget->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PET_IN_COMBAT)))
|
||||
if (HasAttribute(SPELL_ATTR1_ONLY_PEACEFUL_TARGETS) && (unitTarget->IsInCombat() || unitTarget->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PET_IN_COMBAT)))
|
||||
return SPELL_FAILED_TARGET_AFFECTING_COMBAT;
|
||||
|
||||
// only spells with SPELL_ATTR3_ONLY_TARGET_GHOSTS can target ghosts
|
||||
@@ -3105,7 +3105,7 @@ void SpellInfo::ApplyAllSpellImmunitiesTo(Unit* target, uint8 effIndex, bool app
|
||||
{
|
||||
target->ApplySpellImmune(Id, IMMUNITY_SCHOOL, schoolImmunity, apply);
|
||||
|
||||
if (apply && HasAttribute(SPELL_ATTR1_DISPEL_AURAS_ON_IMMUNITY))
|
||||
if (apply && HasAttribute(SPELL_ATTR1_IMMUNITY_PURGES_EFFECT))
|
||||
{
|
||||
target->RemoveAppliedAuras([this, schoolImmunity](AuraApplication const* aurApp) -> bool
|
||||
{
|
||||
@@ -3127,7 +3127,7 @@ void SpellInfo::ApplyAllSpellImmunitiesTo(Unit* target, uint8 effIndex, bool app
|
||||
if (mechanicImmunity & (1 << i))
|
||||
target->ApplySpellImmune(Id, IMMUNITY_MECHANIC, i, apply);
|
||||
|
||||
if(apply && HasAttribute(SPELL_ATTR1_DISPEL_AURAS_ON_IMMUNITY))
|
||||
if(apply && HasAttribute(SPELL_ATTR1_IMMUNITY_PURGES_EFFECT))
|
||||
target->RemoveAurasWithMechanic(mechanicImmunity, AuraRemoveFlags::ByDefault, Id);
|
||||
}
|
||||
|
||||
@@ -3135,7 +3135,7 @@ void SpellInfo::ApplyAllSpellImmunitiesTo(Unit* target, uint8 effIndex, bool app
|
||||
{
|
||||
target->ApplySpellImmune(Id, IMMUNITY_DISPEL, dispelImmunity, apply);
|
||||
|
||||
if (apply && HasAttribute(SPELL_ATTR1_DISPEL_AURAS_ON_IMMUNITY))
|
||||
if (apply && HasAttribute(SPELL_ATTR1_IMMUNITY_PURGES_EFFECT))
|
||||
{
|
||||
target->RemoveAppliedAuras([dispelImmunity](AuraApplication const* aurApp) -> bool
|
||||
{
|
||||
@@ -3159,7 +3159,7 @@ void SpellInfo::ApplyAllSpellImmunitiesTo(Unit* target, uint8 effIndex, bool app
|
||||
for (AuraType auraType : immuneInfo->AuraTypeImmune)
|
||||
{
|
||||
target->ApplySpellImmune(Id, IMMUNITY_STATE, auraType, apply);
|
||||
if (apply && HasAttribute(SPELL_ATTR1_DISPEL_AURAS_ON_IMMUNITY))
|
||||
if (apply && HasAttribute(SPELL_ATTR1_IMMUNITY_PURGES_EFFECT))
|
||||
target->RemoveAurasByType(auraType);
|
||||
}
|
||||
|
||||
@@ -3176,7 +3176,7 @@ bool SpellInfo::CanSpellProvideImmunityAgainstAura(SpellInfo const* auraSpellInf
|
||||
{
|
||||
ImmunityInfo const* immuneInfo = _immunityInfo + i;
|
||||
|
||||
if (!auraSpellInfo->HasAttribute(SPELL_ATTR1_UNAFFECTED_BY_SCHOOL_IMMUNE) && !auraSpellInfo->HasAttribute(SPELL_ATTR2_UNAFFECTED_BY_AURA_SCHOOL_IMMUNE))
|
||||
if (!auraSpellInfo->HasAttribute(SPELL_ATTR1_IMMUNITY_TO_HOSTILE_AND_FRIENDLY_EFFECTS) && !auraSpellInfo->HasAttribute(SPELL_ATTR2_UNAFFECTED_BY_AURA_SCHOOL_IMMUNE))
|
||||
{
|
||||
if (uint32 schoolImmunity = immuneInfo->SchoolImmuneMask)
|
||||
if ((auraSpellInfo->SchoolMask & schoolImmunity) != 0)
|
||||
@@ -3249,7 +3249,7 @@ bool SpellInfo::CanSpellProvideImmunityAgainstAura(SpellInfo const* auraSpellInf
|
||||
// based on client Spell_C::CancelsAuraEffect
|
||||
bool SpellInfo::SpellCancelsAuraEffect(SpellInfo const* auraSpellInfo, uint8 auraEffIndex) const
|
||||
{
|
||||
if (!HasAttribute(SPELL_ATTR1_DISPEL_AURAS_ON_IMMUNITY))
|
||||
if (!HasAttribute(SPELL_ATTR1_IMMUNITY_PURGES_EFFECT))
|
||||
return false;
|
||||
|
||||
if (auraSpellInfo->HasAttribute(SPELL_ATTR0_NO_IMMUNITIES))
|
||||
@@ -3534,7 +3534,7 @@ int32 SpellInfo::CalcPowerCost(WorldObject const* caster, SpellSchoolMask school
|
||||
return 0;
|
||||
|
||||
// Spell drain all exist power on cast (Only paladin lay of Hands)
|
||||
if (HasAttribute(SPELL_ATTR1_DRAIN_ALL_POWER))
|
||||
if (HasAttribute(SPELL_ATTR1_USE_ALL_MANA))
|
||||
{
|
||||
// If power type - health drain all
|
||||
if (PowerType == POWER_HEALTH)
|
||||
@@ -3923,7 +3923,7 @@ bool _isPositiveEffectImpl(SpellInfo const* spellInfo, uint8 effIndex, std::unor
|
||||
}
|
||||
|
||||
// Special case: effects which determine positivity of whole spell
|
||||
if (spellInfo->HasAttribute(SPELL_ATTR1_DONT_REFRESH_DURATION_ON_RECAST)) // @todo: rename to and handle SPELL_ATTR1_AURA_UNIQUE
|
||||
if (spellInfo->HasAttribute(SPELL_ATTR1_AURA_UNIQUE)) // @todo: rename to and handle SPELL_ATTR1_AURA_UNIQUE
|
||||
{
|
||||
// check for targets, there seems to be an assortment of dummy triggering spells that should be negative
|
||||
for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
|
||||
|
||||
@@ -3705,7 +3705,7 @@ void SpellMgr::LoadSpellInfoCorrections()
|
||||
// spell should dispel area aura, but doesn't have the attribute
|
||||
// may be db data bug, or blizz may keep reapplying area auras every update with checking immunity
|
||||
// that will be clear if we get more spells with problem like this
|
||||
spellInfo->AttributesEx |= SPELL_ATTR1_DISPEL_AURAS_ON_IMMUNITY;
|
||||
spellInfo->AttributesEx |= SPELL_ATTR1_IMMUNITY_PURGES_EFFECT;
|
||||
});
|
||||
|
||||
// Spinning Up (Mimiron)
|
||||
@@ -3925,7 +3925,7 @@ void SpellMgr::LoadSpellInfoCorrections()
|
||||
ApplySpellFix({ 69783, 69797, 69799, 69802 }, [](SpellInfo* spellInfo)
|
||||
{
|
||||
// Those spells are cast on creatures with same entry as caster while they have TARGET_UNIT_NEARBY_ENTRY.
|
||||
spellInfo->AttributesEx |= SPELL_ATTR1_CANT_TARGET_SELF;
|
||||
spellInfo->AttributesEx |= SPELL_ATTR1_EXCLUDE_CASTER;
|
||||
});
|
||||
|
||||
// Awaken Plagued Zombies
|
||||
@@ -4784,7 +4784,7 @@ void SpellMgr::LoadSpellInfoCorrections()
|
||||
// Spore Cloud
|
||||
ApplySpellFix({ 75701 }, [](SpellInfo* spellInfo)
|
||||
{
|
||||
spellInfo->AttributesEx &= ~SPELL_ATTR1_CHANNELED;
|
||||
spellInfo->AttributesEx &= ~SPELL_ATTR1_IS_CHANNELLED;
|
||||
});
|
||||
|
||||
// Noxious Spores
|
||||
@@ -4857,7 +4857,7 @@ void SpellMgr::LoadSpellInfoCorrections()
|
||||
// Gaze of Occu'thar
|
||||
ApplySpellFix({ 96942, 101009 }, [](SpellInfo* spellInfo)
|
||||
{
|
||||
spellInfo->AttributesEx &= ~SPELL_ATTR1_CHANNELED;
|
||||
spellInfo->AttributesEx &= ~SPELL_ATTR1_IS_CHANNELLED;
|
||||
});
|
||||
|
||||
// Meteor Slash
|
||||
@@ -4968,7 +4968,7 @@ void SpellMgr::LoadSpellInfoCorrections()
|
||||
100190
|
||||
}, [](SpellInfo* spellInfo)
|
||||
{
|
||||
spellInfo->AttributesEx &= ~SPELL_ATTR1_CHANNELED;
|
||||
spellInfo->AttributesEx &= ~SPELL_ATTR1_IS_CHANNELLED;
|
||||
});
|
||||
|
||||
// Fixate
|
||||
@@ -5202,7 +5202,7 @@ void SpellMgr::LoadSpellInfoCorrections()
|
||||
// Nurture
|
||||
ApplySpellFix({ 85425 }, [](SpellInfo* spellInfo)
|
||||
{
|
||||
spellInfo->AttributesEx &= ~SPELL_ATTR1_SELF_CHANNELED;
|
||||
spellInfo->AttributesEx &= ~SPELL_ATTR1_IS_CHANNELLED;
|
||||
});
|
||||
|
||||
// Soothing Breeze
|
||||
|
||||
@@ -1050,7 +1050,7 @@ struct npc_thorim_trashAI : public ScriptedAI
|
||||
static Unit* GetHealTarget(SpellInfo const* spellInfo, Unit* caster)
|
||||
{
|
||||
Unit* healTarget = nullptr;
|
||||
if (!spellInfo->HasAttribute(SPELL_ATTR1_CANT_TARGET_SELF) && !roll_chance_f(caster->GetHealthPct()) && ((caster->GetHealth() + GetRemainingHealOn(caster) + GetTotalHeal(spellInfo, caster)) <= caster->GetMaxHealth()))
|
||||
if (!spellInfo->HasAttribute(SPELL_ATTR1_EXCLUDE_CASTER) && !roll_chance_f(caster->GetHealthPct()) && ((caster->GetHealth() + GetRemainingHealOn(caster) + GetTotalHeal(spellInfo, caster)) <= caster->GetMaxHealth()))
|
||||
healTarget = caster;
|
||||
else
|
||||
healTarget = GetUnitWithMostMissingHp(spellInfo, caster);
|
||||
|
||||
@@ -2729,7 +2729,7 @@ class spell_gen_profession_research : public SpellScriptLoader
|
||||
if (uint32 discoveredSpellId = GetExplicitDiscoverySpell(spellId, caster))
|
||||
caster->LearnSpell(discoveredSpellId, false);
|
||||
|
||||
caster->UpdateCraftSkill(spellId);
|
||||
caster->UpdateCraftSkill(GetSpellInfo());
|
||||
}
|
||||
|
||||
void Register() override
|
||||
|
||||
Reference in new issue
Block a user