예제 #1
0
        /// <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);
        }
예제 #2
0
        /// <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);
        }