/// <summary> /// Checks whether the given spell can be casted by the casting Unit. /// Does not do range checks. /// </summary> public SpellFailedReason CheckCasterConstraints(Unit caster) { // check for combat if (caster.IsInCombat && RequiresCasterOutOfCombat) { return(SpellFailedReason.AffectingCombat); } if (!caster.CanDoHarm && HasHarmfulEffects) { return(SpellFailedReason.Pacified); } // Not while silenced if (InterruptFlags.HasFlag(InterruptFlags.OnSilence) && caster.IsUnderInfluenceOf(SpellMechanic.Silenced) && caster.Class == ClassId.AtackMage && caster.Class == ClassId.SupportMage && caster.Class == ClassId.HealMage) { return(SpellFailedReason.Silenced); } // Check if castable while stunned if (!AttributesExD.HasFlag(SpellAttributesExD.UsableWhileStunned) && !caster.CanInteract) { return(SpellFailedReason.CantDoThatRightNow); } // Not while silenced else if (!caster.CanCastSpells && (!IsPhysicalAbility || (InterruptFlags.HasFlag(InterruptFlags.OnSilence) && caster.IsUnderInfluenceOf(SpellMechanic.Silenced))) && caster.Class == ClassId.AtackMage && caster.Class == ClassId.SupportMage && caster.Class == ClassId.HealMage) { return(SpellFailedReason.Silenced); } // cannot use physical ability or not do harm at all else if ((!caster.CanDoPhysicalActivity && IsPhysicalAbility) || (!caster.CanDoHarm && HasHarmfulEffects)) { return(SpellFailedReason.Pacified); } else if (!AttributesExD.HasFlag(SpellAttributesExD.UsableWhileStunned) && !caster.CanInteract) { return(SpellFailedReason.Stunned); } // Combo points else if (IsFinishingMove && caster.ComboPoints == 0) { return(SpellFailedReason.NoComboPoints); } // AuraStates if (RequiredCasterAuraState != 0 || ExcludeCasterAuraState != 0) { // check AuraStates var state = caster.AuraState; if ((RequiredCasterAuraState != 0 && !state.HasAnyFlag(RequiredCasterAuraState)) || (ExcludeCasterAuraState != 0 && state.HasAnyFlag(ExcludeCasterAuraState))) { return(SpellFailedReason.CasterAurastate); } } // Required Auras if ((ExcludeCasterAuraId != 0 && caster.Auras.Contains(ExcludeCasterAuraId)) || (RequiredCasterAuraId != 0 && !caster.Auras.Contains(RequiredCasterAuraId))) { return(SpellFailedReason.CasterAurastate); } var spells = caster.Spells; // check cooldown and power cost if (spells != null && caster.CastingTill > System.DateTime.Now && !spells.IsReady(this)) { return(SpellFailedReason.NotReady); } if (caster is NPC && caster.Target != null && Range.MaxDist < caster.GetDistance(caster.Target)) { return(SpellFailedReason.OutOfRange); } if (!IsPassive) { if (!caster.HasEnoughPowerToCast(this, null)) { return(SpellFailedReason.NoPower); } } return(SpellFailedReason.Ok); }
/// <summary> /// Checks whether the given spell can be casted by the casting Unit. /// Does not do range checks. /// </summary> public SpellFailedReason CheckCasterConstraints(Unit caster) { // check for combat if (caster.IsInCombat && RequiresCasterOutOfCombat) { return(SpellFailedReason.AffectingCombat); } // Power Type if (CostsPower && PowerType != caster.PowerType && PowerType != PowerType.Health && !AttributesExB.HasFlag(SpellAttributesExB.DoesNotNeedShapeshift)) { return(SpellFailedReason.OnlyShapeshift); } if (!caster.CanDoHarm && HasHarmfulEffects) { return(SpellFailedReason.Pacified); } // Not while silenced if (InterruptFlags.HasFlag(InterruptFlags.OnSilence) && caster.IsUnderInfluenceOf(SpellMechanic.Silenced)) { return(SpellFailedReason.Silenced); } // Check if castable while stunned if (!AttributesExD.HasFlag(SpellAttributesExD.UsableWhileStunned) && !caster.CanInteract) { return(SpellFailedReason.CantDoThatRightNow); } // Combo points if (IsFinishingMove && caster.ComboPoints == 0) { return(SpellFailedReason.NoComboPoints); } // spell focus if (!CheckSpellFocus(caster)) { return(SpellFailedReason.RequiresSpellFocus); } // Not while silenced else if (!caster.CanCastSpells && (!IsPhysicalAbility || (InterruptFlags.HasFlag(InterruptFlags.OnSilence) && caster.IsUnderInfluenceOf(SpellMechanic.Silenced)))) { return(SpellFailedReason.Silenced); } // cannot use physical ability or not do harm at all else if ((!caster.CanDoPhysicalActivity && IsPhysicalAbility) || (!caster.CanDoHarm && HasHarmfulEffects)) { return(SpellFailedReason.Pacified); } else if (!AttributesExD.HasFlag(SpellAttributesExD.UsableWhileStunned) && !caster.CanInteract) { return(SpellFailedReason.Stunned); } // Combo points else if (IsFinishingMove && caster.ComboPoints == 0) { return(SpellFailedReason.NoComboPoints); } // AuraStates if (RequiredCasterAuraState != 0 || ExcludeCasterAuraState != 0) { // check AuraStates var state = caster.AuraState; if ((RequiredCasterAuraState != 0 && !state.HasAnyFlag(RequiredCasterAuraState)) || (ExcludeCasterAuraState != 0 && state.HasAnyFlag(ExcludeCasterAuraState))) { return(SpellFailedReason.CasterAurastate); } } // Required Auras if ((ExcludeCasterAuraId != 0 && caster.Auras.Contains(ExcludeCasterAuraId)) || (RequiredCasterAuraId != 0 && !caster.Auras.Contains(RequiredCasterAuraId))) { return(SpellFailedReason.CasterAurastate); } // Shapeshift var shapeshiftMask = caster.ShapeshiftMask; bool ignoreShapeshiftRequirement = false; // use this to allow for lazy requirement lookup if (ExcludeShapeshiftMask.HasAnyFlag(shapeshiftMask)) { if (!(ignoreShapeshiftRequirement = caster.Auras.IsShapeshiftRequirementIgnored(this))) { return(SpellFailedReason.NotShapeshift); } } else if (!RequiredShapeshiftMask.HasAnyFlag(shapeshiftMask)) { // our mask did not pass -> do the default checks var shapeshiftEntry = caster.ShapeshiftEntry; var shapeshifted = shapeshiftEntry != null && (shapeshiftEntry.Flags & ShapeshiftInfoFlags.NotActualShapeshift) == 0; if (shapeshifted) { if (RequiredShapeshiftMask != 0) { // When shapeshifted, can only use spells that allow this form if (!(ignoreShapeshiftRequirement = caster.Auras.IsShapeshiftRequirementIgnored(this))) { return(SpellFailedReason.OnlyShapeshift); } } else if (Attributes.HasAnyFlag(SpellAttributes.NotWhileShapeshifted)) { if (!(ignoreShapeshiftRequirement = caster.Auras.IsShapeshiftRequirementIgnored(this))) { // cannot cast this spell when shapeshifted return(SpellFailedReason.NotShapeshift); } } } if (Attributes.HasFlag(SpellAttributes.RequiresStealth) && caster.Stealthed < 1) { if (!caster.Auras.IsShapeshiftRequirementIgnored(this)) { // Stealth Required, but not stealthed and not ignored by a SPELL_AURA_MOD_IGNORE_SHAPESHIFT aura return(SpellFailedReason.OnlyStealthed); } } } var spells = caster.Spells as PlayerSpellCollection; // check cooldown and power cost if (spells != null && !spells.IsReady(this)) { return(SpellFailedReason.NotReady); } if (!IsPassive) { if (!caster.HasEnoughPowerToCast(this, null)) { return(SpellFailedReason.NoPower); } } return(SpellFailedReason.Ok); }