Core/Spell: unified handling of SPELL_ATTR5_USABLE_WHILE_* attributes
Port TrinityCore Commit: https://github.com/TrinityCore/TrinityCore/commit/2b0c73960b431acb25ddfba916017fbfe84f065b
This commit is contained in:
+72
-21
@@ -5388,8 +5388,16 @@ namespace Game.Spells
|
|||||||
if (m_spellInfo.HasAttribute(SpellAttr6.IgnoreCasterAuras))
|
if (m_spellInfo.HasAttribute(SpellAttr6.IgnoreCasterAuras))
|
||||||
return SpellCastResult.SpellCastOk;
|
return SpellCastResult.SpellCastOk;
|
||||||
|
|
||||||
|
// these attributes only show the spell as usable on the client when it has related aura applied
|
||||||
|
// still they need to be checked against certain mechanics
|
||||||
|
|
||||||
|
// SPELL_ATTR5_USABLE_WHILE_STUNNED by default only MECHANIC_STUN (ie no sleep, knockout, freeze, etc.)
|
||||||
bool usableWhileStunned = m_spellInfo.HasAttribute(SpellAttr5.UsableWhileStunned);
|
bool usableWhileStunned = m_spellInfo.HasAttribute(SpellAttr5.UsableWhileStunned);
|
||||||
|
|
||||||
|
// SPELL_ATTR5_USABLE_WHILE_FEARED by default only fear (ie no horror)
|
||||||
bool usableWhileFeared = m_spellInfo.HasAttribute(SpellAttr5.UsableWhileFeared);
|
bool usableWhileFeared = m_spellInfo.HasAttribute(SpellAttr5.UsableWhileFeared);
|
||||||
|
|
||||||
|
// SPELL_ATTR5_USABLE_WHILE_CONFUSED by default only disorient (ie no polymorph)
|
||||||
bool usableWhileConfused = m_spellInfo.HasAttribute(SpellAttr5.UsableWhileConfused);
|
bool usableWhileConfused = m_spellInfo.HasAttribute(SpellAttr5.UsableWhileConfused);
|
||||||
|
|
||||||
// Check whether the cast should be prevented by any state you might have.
|
// Check whether the cast should be prevented by any state you might have.
|
||||||
@@ -5407,35 +5415,54 @@ namespace Game.Spells
|
|||||||
result = SpellCastResult.Charmed;
|
result = SpellCastResult.Charmed;
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
if (unitflag.HasAnyFlag(UnitFlags.Stunned))
|
// spell has attribute usable while having a cc state, check if caster has allowed mechanic auras, another mechanic types must prevent cast spell
|
||||||
|
SpellCastResult mechanicCheck(AuraType auraType, ref uint _param1)
|
||||||
{
|
{
|
||||||
// spell is usable while stunned, check if caster has allowed stun auras, another stun types must prevent cast spell
|
bool foundNotMechanic = false;
|
||||||
if (usableWhileStunned)
|
var auras = m_caster.GetAuraEffectsByType(auraType);
|
||||||
|
foreach (AuraEffect aurEff in auras)
|
||||||
{
|
{
|
||||||
uint allowedStunMask = 1 << (int)Mechanics.Stun | 1 << (int)Mechanics.Sleep;
|
uint mechanicMask = aurEff.GetSpellInfo().GetAllEffectsMechanicMask();
|
||||||
|
if (mechanicMask != 0 && !Convert.ToBoolean(mechanicMask & GetSpellInfo().GetAllowedMechanicMask()))
|
||||||
bool foundNotStun = false;
|
|
||||||
var stunAuras = m_caster.GetAuraEffectsByType(AuraType.ModStun);
|
|
||||||
foreach (AuraEffect stunEff in stunAuras)
|
|
||||||
{
|
{
|
||||||
uint stunMechanicMask = stunEff.GetSpellInfo().GetAllEffectsMechanicMask();
|
foundNotMechanic = true;
|
||||||
if (stunMechanicMask != 0 && !Convert.ToBoolean(stunMechanicMask & allowedStunMask))
|
|
||||||
{
|
|
||||||
foundNotStun = true;
|
|
||||||
|
|
||||||
// fill up aura mechanic info to send client proper error message
|
// fill up aura mechanic info to send client proper error message
|
||||||
param1 = (uint)stunEff.GetSpellInfo().GetEffect(stunEff.GetEffIndex()).Mechanic;
|
_param1 = (uint)aurEff.GetSpellInfo().GetEffect(aurEff.GetEffIndex()).Mechanic;
|
||||||
if (param1 == 0)
|
if (_param1 == 0)
|
||||||
param1 = (uint)stunEff.GetSpellInfo().Mechanic;
|
_param1 = (uint)aurEff.GetSpellInfo().Mechanic;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (foundNotStun)
|
if (foundNotMechanic)
|
||||||
result = SpellCastResult.Stunned;
|
{
|
||||||
|
switch (auraType)
|
||||||
|
{
|
||||||
|
case AuraType.ModStun:
|
||||||
|
return SpellCastResult.Stunned;
|
||||||
|
case AuraType.ModFear:
|
||||||
|
return SpellCastResult.Fleeing;
|
||||||
|
case AuraType.ModConfuse:
|
||||||
|
return SpellCastResult.Confused;
|
||||||
|
default:
|
||||||
|
//ABORT();
|
||||||
|
return SpellCastResult.NotKnown;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return SpellCastResult.SpellCastOk;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (unitflag.HasAnyFlag(UnitFlags.Stunned))
|
||||||
|
{
|
||||||
|
if (usableWhileStunned)
|
||||||
|
{
|
||||||
|
SpellCastResult mechanicResult = mechanicCheck(AuraType.ModStun, ref param1);
|
||||||
|
if (mechanicResult != SpellCastResult.SpellCastOk)
|
||||||
|
result = mechanicResult;
|
||||||
}
|
}
|
||||||
// Not usable while stunned, however spell might provide some immunity that allows to cast it anyway
|
|
||||||
else if (!CheckSpellCancelsStun(ref param1))
|
else if (!CheckSpellCancelsStun(ref param1))
|
||||||
result = SpellCastResult.Stunned;
|
result = SpellCastResult.Stunned;
|
||||||
}
|
}
|
||||||
@@ -5443,16 +5470,35 @@ namespace Game.Spells
|
|||||||
result = SpellCastResult.Silenced;
|
result = SpellCastResult.Silenced;
|
||||||
else if (unitflag.HasAnyFlag(UnitFlags.Pacified) && m_spellInfo.PreventionType.HasAnyFlag(SpellPreventionType.Pacify) && !CheckSpellCancelsPacify(ref param1))
|
else if (unitflag.HasAnyFlag(UnitFlags.Pacified) && m_spellInfo.PreventionType.HasAnyFlag(SpellPreventionType.Pacify) && !CheckSpellCancelsPacify(ref param1))
|
||||||
result = SpellCastResult.Pacified;
|
result = SpellCastResult.Pacified;
|
||||||
else if (unitflag.HasAnyFlag(UnitFlags.Fleeing) && !usableWhileFeared && !CheckSpellCancelsFear(ref param1))
|
else if (unitflag.HasAnyFlag(UnitFlags.Fleeing))
|
||||||
|
{
|
||||||
|
if (usableWhileFeared)
|
||||||
|
{
|
||||||
|
SpellCastResult mechanicResult = mechanicCheck(AuraType.ModFear, ref param1);
|
||||||
|
if (mechanicResult != SpellCastResult.SpellCastOk)
|
||||||
|
result = mechanicResult;
|
||||||
|
}
|
||||||
|
else if (!CheckSpellCancelsFear(ref param1))
|
||||||
result = SpellCastResult.Fleeing;
|
result = SpellCastResult.Fleeing;
|
||||||
else if (unitflag.HasAnyFlag(UnitFlags.Confused) && !usableWhileConfused && !CheckSpellCancelsConfuse(ref param1))
|
}
|
||||||
|
else if (unitflag.HasAnyFlag(UnitFlags.Confused))
|
||||||
|
{
|
||||||
|
if (usableWhileConfused)
|
||||||
|
{
|
||||||
|
SpellCastResult mechanicResult = mechanicCheck(AuraType.ModConfuse, ref param1);
|
||||||
|
if (mechanicResult != SpellCastResult.SpellCastOk)
|
||||||
|
result = mechanicResult;
|
||||||
|
}
|
||||||
|
else if (!CheckSpellCancelsConfuse(ref param1))
|
||||||
result = SpellCastResult.Confused;
|
result = SpellCastResult.Confused;
|
||||||
else if (m_caster.HasUnitFlag2(UnitFlags2.NoActions) && m_spellInfo.PreventionType.HasAnyFlag(SpellPreventionType.NoActions))
|
}
|
||||||
|
else if (m_caster.HasUnitFlag2(UnitFlags2.NoActions) && m_spellInfo.PreventionType.HasAnyFlag(SpellPreventionType.NoActions) && !CheckSpellCancelsNoActions(ref param1))
|
||||||
result = SpellCastResult.NoActions;
|
result = SpellCastResult.NoActions;
|
||||||
|
|
||||||
// Attr must make flag drop spell totally immune from all effects
|
// Attr must make flag drop spell totally immune from all effects
|
||||||
if (result != SpellCastResult.SpellCastOk)
|
if (result != SpellCastResult.SpellCastOk)
|
||||||
return (param1 != 0) ? SpellCastResult.PreventedByMechanic : result;
|
return (param1 != 0) ? SpellCastResult.PreventedByMechanic : result;
|
||||||
|
|
||||||
return SpellCastResult.SpellCastOk;
|
return SpellCastResult.SpellCastOk;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5513,6 +5559,11 @@ namespace Game.Spells
|
|||||||
return CheckSpellCancelsAuraEffect(AuraType.ModConfuse, ref param1);
|
return CheckSpellCancelsAuraEffect(AuraType.ModConfuse, ref param1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CheckSpellCancelsNoActions(ref uint param1)
|
||||||
|
{
|
||||||
|
return CheckSpellCancelsAuraEffect(AuraType.ModNoActions, ref param1);
|
||||||
|
}
|
||||||
|
|
||||||
SpellCastResult CheckArenaAndRatedBattlegroundCastRules()
|
SpellCastResult CheckArenaAndRatedBattlegroundCastRules()
|
||||||
{
|
{
|
||||||
bool isRatedBattleground = false; // NYI
|
bool isRatedBattleground = false; // NYI
|
||||||
|
|||||||
@@ -2371,6 +2371,8 @@ namespace Game.Spells
|
|||||||
immuneInfo.MechanicImmuneMask = mechanicImmunityMask;
|
immuneInfo.MechanicImmuneMask = mechanicImmunityMask;
|
||||||
immuneInfo.DispelImmune = dispelImmunity;
|
immuneInfo.DispelImmune = dispelImmunity;
|
||||||
immuneInfo.DamageSchoolMask = damageImmunityMask;
|
immuneInfo.DamageSchoolMask = damageImmunityMask;
|
||||||
|
|
||||||
|
_allowedMechanicMask |= immuneInfo.MechanicImmuneMask;
|
||||||
});
|
});
|
||||||
|
|
||||||
foreach (var effects in _effects)
|
foreach (var effects in _effects)
|
||||||
@@ -2383,6 +2385,31 @@ namespace Game.Spells
|
|||||||
loadImmunityInfoFn(effect);
|
loadImmunityInfoFn(effect);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (HasAttribute(SpellAttr5.UsableWhileStunned))
|
||||||
|
{
|
||||||
|
switch (Id)
|
||||||
|
{
|
||||||
|
case 22812: // Barkskin
|
||||||
|
_allowedMechanicMask |=
|
||||||
|
(1 << (int)Mechanics.Stun) |
|
||||||
|
(1 << (int)Mechanics.Freeze) |
|
||||||
|
(1 << (int)Mechanics.Knockout) |
|
||||||
|
(1 << (int)Mechanics.Sleep);
|
||||||
|
break;
|
||||||
|
case 49039: // Lichborne, don't allow normal stuns
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
_allowedMechanicMask |= (1 << (int)Mechanics.Stun);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (HasAttribute(SpellAttr5.UsableWhileConfused))
|
||||||
|
_allowedMechanicMask |= (1 << (int)Mechanics.Disoriented);
|
||||||
|
|
||||||
|
if (HasAttribute(SpellAttr5.UsableWhileFeared))
|
||||||
|
_allowedMechanicMask |= (1 << (int)Mechanics.Fear);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ApplyAllSpellImmunitiesTo(Unit target, SpellEffectInfo effect, bool apply)
|
public void ApplyAllSpellImmunitiesTo(Unit target, SpellEffectInfo effect, bool apply)
|
||||||
@@ -2590,6 +2617,11 @@ namespace Game.Spells
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public uint GetAllowedMechanicMask()
|
||||||
|
{
|
||||||
|
return _allowedMechanicMask;
|
||||||
|
}
|
||||||
|
|
||||||
public float GetMinRange(bool positive = false)
|
public float GetMinRange(bool positive = false)
|
||||||
{
|
{
|
||||||
if (RangeEntry == null)
|
if (RangeEntry == null)
|
||||||
@@ -3733,6 +3765,7 @@ namespace Game.Spells
|
|||||||
AuraStateType _auraState;
|
AuraStateType _auraState;
|
||||||
|
|
||||||
SpellDiminishInfo _diminishInfo;
|
SpellDiminishInfo _diminishInfo;
|
||||||
|
uint _allowedMechanicMask;
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
public struct ScalingInfo
|
public struct ScalingInfo
|
||||||
|
|||||||
Reference in New Issue
Block a user