/// <summary> /// Checks whether the given spell can be casted by the casting Unit /// </summary> public SpellFailedReason CheckCasterConstraints(Unit caster) { // check for combat if (caster.IsInCombat && RequiresCasterOutOfCombat) { return SpellFailedReason.AffectingCombat; } // Power Type if (CostsMana && PowerType != caster.PowerType && PowerType != PowerType.Health) { return SpellFailedReason.NoPower; } // Stealth Required if (Attributes.HasAnyFlag(SpellAttributes.RequiresStealth) && caster.Stealthed < 1) { return SpellFailedReason.OnlyStealthed; } 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; } // shapeshift if (Attributes.HasFlag(SpellAttributes.NotWhileShapeshifted) && caster.ShapeshiftForm != ShapeshiftForm.Normal) { //return SpellFailedReason.NotShapeshift; } // Stealth Required else if (Attributes.HasFlag(SpellAttributes.RequiresStealth) && caster.Stealthed < 1) { return SpellFailedReason.OnlyStealthed; } // Not while silenced else if (InterruptFlags.HasFlag(InterruptFlags.OnSilence) && caster.IsUnderInfluenceOf(SpellMechanic.Silenced)) { return SpellFailedReason.Silenced; } else if (!caster.CanDoHarm && HasHarmfulEffects) { return SpellFailedReason.Pacified; } else if (!AttributesExD.HasFlag(SpellAttributesExD.UsableWhileStunned) && !caster.CanInteract) { return SpellFailedReason.Stunned; } else if (!caster.CanCastSpells) { return SpellFailedReason.Interrupted; } // Combo points else if (IsFinishingMove && caster.ComboPoints == 0) { return SpellFailedReason.NoComboPoints; } // spell focus if (!CheckSpellFocus(caster)) { return SpellFailedReason.RequiresSpellFocus; } // shapeshift //if (Attributes.Has(SpellAttributes.NotWhileShapeshifted) && caster.ShapeShiftForm != ShapeShiftForm.Normal) { //return SpellFailedReason.NotShapeshift; } // 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 as PlayerSpellCollection; // check cooldown and power cost if (spells != null && !spells.CheckCooldown(this)) { return SpellFailedReason.NotReady; } 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; } // Stealth Required if (Attributes.HasAnyFlag(SpellAttributes.RequiresStealth) && caster.Stealthed < 1) { return SpellFailedReason.OnlyStealthed; } 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; } // spell focus if (!CheckSpellFocus(caster)) { return SpellFailedReason.RequiresSpellFocus; } // 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 (ignoreShapeshiftRequirement || caster.Auras.IsShapeshiftRequirementIgnored(this)) { // Stealth Required, but not stealthed 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; }