Exemple #1
0
        private void InitAura()
        {
            // procs
            if (ProcTriggerFlags != ProcTriggerFlags.None || CasterProcSpells != null)
            {
                ProcTriggerEffects = Effects.Where(effect => effect.IsProc).ToArray();
                if (ProcTriggerEffects.Length == 0)
                {
                    // no proc-specific effects -> all effects are triggered on proc
                    ProcTriggerEffects = null;
                }
                //else if (ProcTriggerEffects.Length > 1)
                //{
                //    log.Warn("Spell {0} had more than one ProcTriggerEffect", this);
                //}

                IsProc = ProcTriggerEffects != null || ProcHandlers != null || CasterProcSpells != null ||
                         ProcCharges > 0;
            }

            IsAura = IsProc || HasEffectWith(effect =>
            {
                if (effect.AuraType != AuraType.None)
                {
                    return(true);
                }
                return(false);
            });

            ForeachEffect(effect =>
            {
                if (effect.IsAuraEffect)
                {
                    HasNonPeriodicAuraEffects = HasNonPeriodicAuraEffects || !effect.IsPeriodic;
                    HasPeriodicAuraEffects    = HasPeriodicAuraEffects || effect.IsPeriodic;
                }
            });

            IsAutoRepeating = AttributesExB.HasFlag(SpellAttributesExB.AutoRepeat);

            HasManaShield = HasEffectWith(effect => effect.AuraType == AuraType.ManaShield);

            AuraEffects     = GetEffectsWhere(effect => effect.AuraEffectHandlerCreator != null);
            AreaAuraEffects = GetEffectsWhere(effect => effect.IsAreaAuraEffect);

            IsAreaAura = AreaAuraEffects != null;
            IsPureAura = !IsDamageSpell && !HasEffectWith(effect => effect.EffectType != SpellEffectType.ApplyAura ||
                                                          effect.EffectType != SpellEffectType.ApplyAuraToMaster ||
                                                          effect.EffectType != SpellEffectType.ApplyStatAura ||
                                                          effect.EffectType != SpellEffectType.ApplyStatAuraPercent);

            IsPureBuff   = IsPureAura && HasBeneficialEffects && !HasHarmfulEffects;
            IsPureDebuff = IsPureAura && HasHarmfulEffects && !HasBeneficialEffects;

            IsVehicle    = HasEffectWith(effect => effect.AuraType == AuraType.Vehicle);
            IsShapeshift = HasEffectWith(effect =>
            {
                //if (effect.AuraType == AuraType.ModShapeshift)
                //{
                //    var info = SpellHandler.ShapeshiftEntries.Get((uint)effect.MiscValue);
                //    return info.CreatureType > 0;
                //}
                return(effect.AuraType == AuraType.ModShapeshift || effect.AuraType == AuraType.Transform);
            });

            // charges and stacks:
            CanStack = MaxStackCount > 0;
            if (ProcCharges > 0)
            {
                // applications will be used up by procs
                InitialStackCount = ProcCharges;
            }
            else
            {
                // applications can be added by re-applying
                InitialStackCount = 1;
            }

            IsGhost = HasEffectWith(effect => effect.AuraType == AuraType.Ghost);


            HasFlyEffect = HasEffectWith(effect => effect.AuraType == AuraType.Fly);

            IsFlyingMount = IsMount &&
                            HasEffectWith(effect => effect.AuraType == AuraType.ModSpeedMountedFlight);

            CanApplyMultipleTimes = Attributes == (SpellAttributes.InvisibleAura | SpellAttributes.Passive) &&
                                    Ability == null && Talent == null;

            HasShapeshiftDependentEffects  = HasEffectWith(effect => effect.RequiredShapeshiftMask != 0);
            IsModalShapeshiftDependentAura = IsPassive && (RequiredShapeshiftMask != 0 || HasShapeshiftDependentEffects);

            if (AuraUID == 0)
            {
                CreateAuraUID();
            }
        }
Exemple #2
0
        /// <summary>
        /// Checks whether the given target is valid for the given caster.
        /// Is called automatically when SpellCast selects Targets.
        /// Does not do maximum range check.
        /// </summary>
        public SpellFailedReason CheckValidTarget(WorldObject caster, WorldObject target)
        {
            if (AttributesEx.HasAnyFlag(SpellAttributesEx.CannotTargetSelf) && target == caster)
            {
                return(SpellFailedReason.NoValidTargets);
            }
            if (target is Unit)
            {
                // AuraState
                if (RequiredTargetAuraState != 0 || ExcludeTargetAuraState != 0)
                {
                    var state = ((Unit)target).AuraState;
                    if ((RequiredTargetAuraState != 0 && !state.HasAnyFlag(RequiredTargetAuraState)) ||
                        (ExcludeTargetAuraState != 0 && state.HasAnyFlag(ExcludeTargetAuraState)))
                    {
                        return(SpellFailedReason.TargetAurastate);
                    }
                }

                // Required Auras
                if ((ExcludeTargetAuraId != 0 && ((Unit)target).Auras.Contains(ExcludeTargetAuraId)) ||
                    (RequiredTargetAuraId != 0 && !((Unit)target).Auras.Contains(RequiredTargetAuraId)))
                {
                    return(SpellFailedReason.TargetAurastate);
                }
            }

            // Make sure that we have a GameObject if the Spell requires one
            if (TargetFlags.HasAnyFlag(SpellTargetFlags.UnkUnit_0x100) &&
                (!(target is GameObject) || !target.IsInWorld))
            {
                return(SpellFailedReason.BadTargets);
            }

            // CreatureTypes

            /*if (CreatureMask != CreatureMask.None &&
             *      (!(target is NPC) || !((NPC)target).CheckCreatureType(CreatureMask)))
             * {
             *      return SpellFailedReason.BadImplicitTargets;
             * }*/
            if (!CanCastOnPlayer && target is Character)
            {
                return(SpellFailedReason.BadImplicitTargets);
            }


            // Corpse target
            if (RequiresDeadTarget)
            {
                if (TargetFlags.HasAnyFlag(SpellTargetFlags.PvPCorpse | SpellTargetFlags.Corpse))
                {
                    if (!(target is Corpse) ||
                        (TargetFlags.HasAnyFlag(SpellTargetFlags.PvPCorpse) && caster != null && !caster.IsHostileWith(target)))
                    {
                        return(SpellFailedReason.BadImplicitTargets);
                    }
                }
                else if ((target is NPC))
                {
                    // need to be dead and looted empty
                    if (((NPC)target).IsAlive || target.Loot != null)
                    {
                        return(SpellFailedReason.TargetNotDead);
                    }
                }
                else if ((target is Character))
                {
                    if (((Character)target).IsAlive)
                    {
                        return(SpellFailedReason.TargetNotDead);
                    }
                }
            }
            else
            {
                if (target is Unit && !((Unit)target).IsAlive)
                {
                    return(SpellFailedReason.TargetsDead);
                }
            }

            // Rogues do it from behind
            if (AttributesExB.HasFlag(SpellAttributesExB.RequiresBehindTarget))
            {
                if (caster != null && !caster.IsBehind(target))
                {
                    return(SpellFailedReason.NotBehind);
                }
            }

            //if (AttributesExC.HasFlag(SpellAttributesExC.NoInitialAggro))
            //{
            //    if (target is Unit && ((Unit)target).IsInCombat)
            //    {
            //        return SpellFailedReason.TargetAffectingCombat;
            //    }
            //}

            if (Range.MinDist > 0 && caster != null &&
                //caster.IsInRadius(target, caster.GetSpellMinRange(Range.MinDist, target)))
                caster.IsInRadius(target, Range.MinDist))
            {
                return(SpellFailedReason.TooClose);
            }

            return(SpellFailedReason.Ok);
        }
Exemple #3
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);
        }