示例#1
0
        void CreateAuras(ref List <MissedTarget> missedTargets, ref List <IAura> auras, DynamicObject dynObj)
        {
            auras = AuraListPool.Obtain();

            var allowDead = Spell.PersistsThroughDeath;

            // create AreaAura
            if (Spell.IsAreaAura)
            {
                if (dynObj != null || (CasterObject != null && (allowDead || !(CasterObject is Unit) || ((Unit)CasterObject).IsAlive)))
                {
                    // AreaAura is created at the target location if it is a DynamicObject, else its applied to the caster
                    var aaura = new AreaAura(dynObj ?? CasterObject, Spell);
                    if (dynObj != null)
                    {
                        // also start the area aura
                        auras.Add(aaura);
                    }
                    // else: Is coupled to an Aura instance
                }
                else
                {
                    LogManager.GetCurrentClassLogger().Warn(
                        "Tried to cast Spell {0} with invalid dynObj or Caster - dynObj: {1}, CasterObject: {2}, CasterUnit: {3}",
                        Spell, dynObj, CasterObject, CasterUnit);
                }
            }

            // remove missed targets
            for (var i = m_auraApplicationInfos.Count - 1; i >= 0; i--)
            {
                var app = m_auraApplicationInfos[i];
                if (!Targets.Contains(app.Target))
                {
                    m_auraApplicationInfos.RemoveAt(i);
                }
            }
            if (m_auraApplicationInfos.Count == 0)
            {
                return;
            }

            // create Aura-Handlers
            for (var i = 0; i < Handlers.Length; i++)
            {
                var spellHandler = Handlers[i];
                if (spellHandler is ApplyAuraEffectHandler)
                {
                    ((ApplyAuraEffectHandler)spellHandler).AddAuraHandlers(m_auraApplicationInfos);
                }
            }
            if (missedTargets == null)
            {
                missedTargets = CastMissListPool.Obtain();
            }

            // apply all new Auras
            for (var i = 0; i < m_auraApplicationInfos.Count; i++)
            {
                var info   = m_auraApplicationInfos[i];
                var target = info.Target;

                if (!target.IsInContext)
                {
                    continue;
                }

                if (info.Handlers == null || (!allowDead && !target.IsAlive))
                {
                    continue;
                }

                // check for immunities and resistances
                CastMissReason missReason;
                var            hostile = Spell.IsHarmfulFor(CasterReference, target);

                if (!IsPassive && !Spell.IsPreventionDebuff &&
                    (missReason = CheckDebuffResist(target, Spell, CasterReference.Level, hostile)) != CastMissReason.None)
                {
                    // debuff miss
                    missedTargets.Add(new MissedTarget(target, missReason));
                }
                else
                {
                    // create aura
                    var newAura = target.Auras.CreateAura(CasterReference, Spell, info.Handlers, TargetItem, !Spell.IsPreventionDebuff && !hostile);
                    if (newAura != null)
                    {
                        // check for debuff and if the spell causes no threat we aren't put in combat
                        if (!Spell.IsPreventionDebuff && !((Spell.AttributesExC & SpellAttributesExC.NoInitialAggro) != 0) && hostile && target.IsInWorld && target.IsAlive)
                        {
                            // force combat mode
                            target.IsInCombat = true;
                            if (target is NPC && CasterUnit != null)
                            {
                                ((NPC)target).ThreatCollection.AddNewIfNotExisted(CasterUnit);
                            }
                        }
                        // add Aura now
                        auras.Add(newAura);
                    }
                }
            }

            //m_auraApplicationInfos.Clear();
            //AuraAppListPool.Recycle(m_auraApplicationInfos);
            m_auraApplicationInfos = null;
        }
示例#2
0
        /// <summary>
        /// Validates targets and applies all SpellEffects
        /// </summary>
        public SpellFailedReason Impact()
        {
            if (!IsCasting)
            {
                return(SpellFailedReason.Ok);
            }

            // apply effects
            foreach (var handler in Handlers)
            {
                if (handler.Effect.IsPeriodic || handler.Effect.IsStrikeEffect)
                {
                    // weapon ability or handled by Aura or Channel
                    continue;
                }

                handler.Apply();
                if (!IsCasting)
                {
                    // the last handler cancelled the SpellCast
                    return(SpellFailedReason.DontReport);
                }
            }

            if (CasterObject is Unit && Spell.IsPhysicalAbility)
            {
                // strike at everyone
                foreach (var target in UnitTargets)
                {
                    ProcHitFlags hitFlags = CasterUnit.Strike(GetWeapon(), target, this);
                    m_hitInfoByTarget[target] = hitFlags;
                }
            }

            // open Channel and spawn DynamicObject
            DynamicObject dynObj = null;

            if (Spell.DOEffect != null)
            {
                dynObj = new DynamicObject(this, Spell.DOEffect.GetRadius(CasterReference));
            }

            if (!IsCasting)
            {
                return(SpellFailedReason.Ok);
            }

            List <MissedTarget> missedTargets = null;
            // create auras
            List <IAura> auras = null;

            if (m_auraApplicationInfos != null)
            {
                CreateAuras(ref missedTargets, ref auras, dynObj);
            }

            // check for missed targets
            if (missedTargets != null)
            {
                if (missedTargets.Count > 0)
                {
                    // TODO: Flash message ontop of missed heads when impact is delayed
                    CombatLogHandler.SendSpellMiss(this, true, missedTargets);
                    missedTargets.Clear();
                }

                CastMissListPool.Recycle(missedTargets);
            }

            // open channel
            if (Spell.IsChanneled && CasterObject != null)
            {
                Channel        = SpellChannel.SpellChannelPool.Obtain();
                Channel.m_cast = this;

                if (CasterObject is Unit)
                {
                    if (dynObj != null)
                    {
                        CasterUnit.ChannelObject = dynObj;
                    }
                    else if (SelectedTarget != null)
                    {
                        CasterUnit.ChannelObject = SelectedTarget;
                        if (SelectedTarget is NPC && Spell.IsTame)
                        {
                            ((NPC)SelectedTarget).CurrentTamer = CasterObject as Character;
                        }
                    }
                }

                var len = Handlers.Length;
                var channelEffectHandlers = SpellEffectHandlerListPool.Obtain();
                //var channelEffectHandlers = new List<SpellEffectHandler>(6);
                for (var i = 0; i < len; i++)
                {
                    var handler = Handlers[i];
                    if (handler.Effect.IsPeriodic)
                    {
                        channelEffectHandlers.Add(handler);
                    }
                }
                Channel.Open(channelEffectHandlers, auras);
            }

            // start Auras
            if (auras != null)
            {
                for (var i = 0; i < auras.Count; i++)
                {
                    var aura = auras[i];
                    aura.Start(Spell.IsChanneled ? Channel : null, false);
                }

                if (!IsChanneling)
                {
                    auras.Clear();
                    AuraListPool.Recycle(auras);
                    auras = null;
                }
            }

            // applying debuffs might cancel other Auras
            if (Spell.HasHarmfulEffects && !Spell.IsPreventionDebuff)
            {
                foreach (var target in Targets)
                {
                    if (target is Unit && Spell.IsHarmfulFor(CasterReference, target))
                    {
                        ((Unit)target).Auras.RemoveByFlag(AuraInterruptFlags.OnHostileSpellInflicted);
                    }
                }
            }

            //if (CasterChar != null)
            //{
            //    CasterChar.SendSystemMessage("SpellCast (Impact): {0} ms", sw1.ElapsedTicks / 10000d);
            //}

            return(SpellFailedReason.Ok);
        }