示例#1
0
 private void AddHandlerTargetsToTargets(SpellEffectHandler handler)
 {
     foreach (var target in handler.Targets)
     {
         Targets.Add(target);
     }
 }
示例#2
0
        /// <summary>
        /// Adds all chained units around the selected unit to the list
        /// </summary>
        public void FindChain(Unit first, TargetFilter filter, bool harmful, int limit)
        {
            SpellEffectHandler firstHandler = this.FirstHandler;
            WorldObject        caster       = firstHandler.Cast.CasterObject;
            Spell spell = firstHandler.Cast.Spell;

            first.IterateEnvironment(firstHandler.GetRadius(), (Func <WorldObject, bool>)(target =>
            {
                if ((spell.FacingFlags & SpellFacingFlags.RequiresInFront) != (SpellFacingFlags)0 && caster != null &&
                    !target.IsInFrontOf(caster) || (target == caster || target == first || caster == null) ||
                    (harmful && !caster.MayAttack((IFactionMember)target) ||
                     !harmful && !caster.IsInSameDivision((IFactionMember)target) ||
                     this.ValidateTarget(target, filter) != SpellFailedReason.Ok))
                {
                    return(true);
                }
                this.AddOrReplace(target, limit);
                return(true);
            }));
            if (this.TargetEvaluator != null)
            {
                return;
            }
            this.Sort((Comparison <WorldObject>)((a, b) =>
                                                 a.GetDistanceSq((WorldObject)first).CompareTo(b.GetDistanceSq((WorldObject)first))));
            if (this.Count <= limit)
            {
                return;
            }
            this.RemoveRange(limit, this.Count - limit);
        }
示例#3
0
        private int EvaluateTarget(WorldObject target)
        {
            SpellEffectHandler firstHandler = this.FirstHandler;
            SpellCast          cast         = firstHandler.Cast;
            int num = this.TargetEvaluator(firstHandler, target);

            if (cast.IsAICast && cast.Spell.IsAura && (target is Unit && ((Unit)target).Auras.Contains(cast.Spell)))
            {
                num += 1000000;
            }
            return(num);
        }
示例#4
0
        private SpellFailedReason PrepAuras()
        {
            // create Auras
            //m_auraApplicationInfos = AuraAppListPool.Obtain();
            m_auraApplicationInfos = new List <AuraApplicationInfo>(4);

            // check stacking
            SpellEffectHandler lastHandler = null;

            for (var i = 0; i < Handlers.Length; i++)
            {
                var spellHandler = Handlers[i];
                if (spellHandler.Effect.IsAuraEffect)
                {
                    if (lastHandler != null && lastHandler.Effect.SharesTargetsWith(spellHandler.Effect))
                    {
                        // same aura
                        continue;
                    }
                    lastHandler = spellHandler;

                    if (spellHandler.m_targets != null)
                    {
                        foreach (var target in spellHandler.m_targets)
                        {
                            if (target is Unit)
                            {
                                if (m_auraApplicationInfos.Any(info => info.Target == target))
                                {
                                    // target was already added
                                    continue;
                                }

                                var id         = Spell.GetAuraUID(CasterReference, target);
                                var failReason = SpellFailedReason.Ok;
                                if (((Unit)target).Auras.PrepareStackOrOverride(CasterReference, id, Spell, ref failReason, this))
                                {
                                    m_auraApplicationInfos.Add(new AuraApplicationInfo((Unit)target));
                                }
                                else if (failReason != SpellFailedReason.Ok && !IsAoE)
                                {
                                    // spell fails
                                    // m_auraApplicationInfos.Clear();
                                    // AuraAppListPool.Recycle(m_auraApplicationInfos);
                                    return(failReason);
                                }
                            }
                        }
                    }
                }
            }
            return(SpellFailedReason.Ok);
        }
示例#5
0
        private SpellFailedReason CollectHandlerTargets(SpellEffectHandler handler)
        {
            var failReason = InitialTargets != null?handler.Targets.AddAll(InitialTargets) : handler.Targets.FindAllTargets();

            if (failReason != SpellFailedReason.Ok)
            {
                return(failReason);
            }

            AddHandlerTargetsToTargets(handler);

            return(SpellFailedReason.Ok);
        }
示例#6
0
        private void CreateHandler(SpellEffect effect, int h, SpellEffectHandler[] handlers, ref SpellTargetCollection targets, ref SpellFailedReason failReason)
        {
            var handler = effect.SpellEffectHandlerCreator(this, effect);
            handlers[h] = handler;

            // make sure, we have the right Caster-Type
            handler.CheckCasterType(ref failReason);
            if (failReason != SpellFailedReason.Ok)
            {
                return;
            }

            // find targets and amount SpellTargetCollection if effects have same ImplicitTargetTypes
            if (InitialTargets != null)
            {
                // do we have given targets?
                if (targets == null)
                {
                    targets = CreateSpellTargetCollection();
                }
            }
            else if (handler.HasOwnTargets)
            {
                // see if targets are shared between effects
                targets = null;

                for (var j = 0; j < h; j++)
                {
                    var handler2 = handlers[j];
                    if (handler.Effect.SharesTargetsWith(handler2.Effect, IsAICast))
                    {
                        // same targets -> share target collection
                        targets = handler2.m_targets;
                        break;
                    }
                }

                if (targets == null)
                {
                    targets = CreateSpellTargetCollection();
                }
            }

            if (targets != null)
            {
                handler.m_targets = targets;
                targets.m_handlers.Add(handler);
            }
        }
示例#7
0
        private SpellEffectHandler[] CreateHandlers(ref SpellFailedReason failReason)
        {
            var handlers = new SpellEffectHandler[Spell.EffectHandlerCount];
            var h = 0;
            SpellTargetCollection targets = null;
            foreach (var effect in Spell.Effects.Where(effect => effect.SpellEffectHandlerCreator != null))
            {
                CreateHandler(effect, h, handlers, ref targets, ref failReason);
                if (failReason != SpellFailedReason.Ok)
                {
                    return null;
                }
                h++;
            }

            return handlers;
        }
示例#8
0
        private SpellEffectHandler[] CreateHandlers(ref SpellFailedReason failReason)
        {
            var handlers = new SpellEffectHandler[Spell.EffectHandlerCount];
            var h        = 0;
            SpellTargetCollection targets = null;

            foreach (var effect in Spell.Effects.Where(effect => effect.SpellEffectHandlerCreator != null))
            {
                CreateHandler(effect, h, handlers, ref targets, ref failReason);
                if (failReason != SpellFailedReason.Ok)
                {
                    return(null);
                }
                h++;
            }

            return(handlers);
        }
示例#9
0
        /// <summary>
        /// Removes all targets that don't satisfy the effects' constraints
        /// </summary>
        public void RevalidateAll()
        {
            SpellEffectHandler firstHandler = this.FirstHandler;
            SpellCast          cast         = firstHandler.Cast;

            for (int index = this.Count - 1; index >= 0; --index)
            {
                WorldObject target = this[index];
                if (target.IsInWorld)
                {
                    TargetDefinition targetDefinition = firstHandler.Effect.GetTargetDefinition();
                    if (targetDefinition != null)
                    {
                        if (this.ValidateTarget(target, targetDefinition.Filter) == SpellFailedReason.Ok)
                        {
                            continue;
                        }
                    }
                    else if (this.ValidateTarget(target,
                                                 DefaultTargetDefinitions.GetTargetFilter(firstHandler.Effect.ImplicitTargetA)) ==
                             SpellFailedReason.Ok)
                    {
                        TargetFilter targetFilter =
                            DefaultTargetDefinitions.GetTargetFilter(firstHandler.Effect.ImplicitTargetB);
                        if (targetFilter != null)
                        {
                            SpellFailedReason failReason = SpellFailedReason.Ok;
                            targetFilter(firstHandler, target, ref failReason);
                            if (failReason == SpellFailedReason.Ok)
                            {
                                continue;
                            }
                        }
                        else
                        {
                            continue;
                        }
                    }
                }

                this.RemoveAt(index);
            }
        }
示例#10
0
		/// <summary>
		/// Custom filter to ensure the given spell only targets a specific NPC
		/// </summary>
		public static void IsRunebladeTriggerNPC(SpellEffectHandler effectHandler, WorldObject target, ref SpellFailedReason failedReason)
		{
			if(!(target is NPC))
			{
				failedReason =  SpellFailedReason.OutOfRange;
				return;
			}

			var entryid = ((NPC) target).EntryId;
			if(entryid == (uint)NPCId.RuneforgeSE)
			{
				return;
			}

			if(entryid == (uint)NPCId.RuneforgeSW)
			{
				failedReason =  SpellFailedReason.Ok;
				return;
			}
			failedReason = SpellFailedReason.OutOfRange;
		}
示例#11
0
        /// <summary>
        /// Does default checks on whether the given Target is valid for the current SpellCast
        /// </summary>
        public SpellFailedReason ValidateTarget(WorldObject target, TargetFilter filter)
        {
            SpellEffectHandler firstHandler = this.FirstHandler;
            SpellCast          cast         = firstHandler.Cast;
            SpellFailedReason  failReason   = cast.Spell.CheckValidTarget(cast.CasterObject, target);

            if (failReason != SpellFailedReason.Ok)
            {
                return(failReason);
            }
            if (filter != null)
            {
                filter(firstHandler, target, ref failReason);
                if (failReason != SpellFailedReason.Ok)
                {
                    return(failReason);
                }
            }

            return(this.ValidateTargetForHandlers(target));
        }
示例#12
0
		/// <summary>
		/// Custom filter to ensure the given spell only targets specific NPCs
		/// </summary>
		public static void IsSiphonTriggerNPC(SpellEffectHandler effectHandler, WorldObject target, ref SpellFailedReason failedReason)
		{
			if (!(target is NPC))
			{
				failedReason = SpellFailedReason.OutOfRange;
				return;
			}
			var possibleIds = new List<NPCId>
			                  	{
			                  		NPCId.ScarletHold,
			                  		NPCId.NewAvalonForge,
			                  		NPCId.NewAvalonTownHall,
			                  		NPCId.ChapelOfTheCrimsonFlame
			                  	};
			var entryid = (NPCId)target.EntryId;
			if (possibleIds.Contains(entryid))
			{
				failedReason = SpellFailedReason.Ok;
				return;
			}
			failedReason = SpellFailedReason.OutOfRange;
		}
示例#13
0
文件: SpellCast.cs 项目: primax/WCell
		private void DoFinalCleanup(SpellEffectHandler[] handlers)
		{
			if (TriggerAction != null)
			{
				TriggerAction.ReferenceCount--;
				TriggerAction = null;
			}

			if (handlers != null)
			{
				foreach (var handler in handlers)
				{
					// can be null if spell is cancelled during initialization
					if (handler != null)
					{
						handler.Cleanup();
					}
				}
			}

			if (CasterObject == null || CasterObject.SpellCast != this)
			{
				// TODO: Improve dispose strategy
				Dispose();
			}
		}
示例#14
0
		/// <summary>
		/// Creates the SpellEffectHandlers and collects all initial targets
		/// </summary>
		protected SpellFailedReason InitHandlers()
		{
			var failReason = SpellFailedReason.Ok;

			if (m_targets == null)
			{
				//m_targets = WorldObject.WorldObjectSetPool.Obtain();
				m_targets = new HashSet<WorldObject>();
			}

			//var extraEffects = CasterUnit.Spells.GetExtraEffectsForSpell(m_spell.SpellId);
			//var hasExtraEffects = extraEffects != null;
			var handlers = new SpellEffectHandler[m_spell.EffectHandlerCount];// + (hasExtraEffects ? extraEffects.Count : 0)];
			var h = 0;
			SpellTargetCollection targets = null;
			foreach (var effect in m_spell.Effects)
			{
				if (effect.SpellEffectHandlerCreator == null)
				{
					continue;
				}

				CreateHandler(effect, h, handlers, ref targets, ref failReason);
				if (failReason != SpellFailedReason.Ok)
				{
					return failReason;
				}
				h++;
			}
			//if (hasExtraEffects)
			//{
			//    foreach (var effect in extraEffects)
			//    {
			//        if (effect.SpellEffectHandlerCreator == null)
			//        {
			//            continue;
			//        }

			//        InitHandler(effect, h, handlers, out targets, ref failReason);
			//        if (failReason != SpellFailedReason.Ok)
			//        {
			//            return failReason;
			//        }
			//        h++;
			//    }
			//}

			if (failReason == SpellFailedReason.Ok)
			{
				m_handlers = handlers;

				// initialize handlers
				foreach (var handler in m_handlers)
				{
					handler.Initialize(ref failReason);
					if (failReason != SpellFailedReason.Ok)
					{
						m_handlers = null;
						return failReason;
					}
				}

				// initialize targets
				foreach (var handler in m_handlers)
				{
					if (m_initialTargets != null)
					{
						// initialize forced targets
						for (var j = 0; j < m_initialTargets.Length; j++)
						{
							var target = m_initialTargets[j];
							if (target.IsInContext)
							{
								// must call ValidateTarget anyway
								var err = handler.ValidateTarget(target);
								if (err != SpellFailedReason.Ok)
								{
									LogManager.GetCurrentClassLogger().Warn(
										"{0} tried to cast spell \"{1}\" with forced target {2} which is not valid: {3}",
										CasterObject, Spell, target, err);
									if (!IsAoE)
									{
										m_handlers = null;
										return err;
									}
								}
								else if (handler.m_targets != null)
								{
									handler.m_targets.Add(target);
								}
								m_targets.Add(target);
							}
							else if (target.IsInWorld)
							{
								LogManager.GetCurrentClassLogger().Warn(
									"{0} tried to cast spell \"{1}\" with forced target {2} which is not in context",
									CasterObject, Spell, target);
							}
						}
					}
					else
					{
						// Initialize standard Targets
						if (handler.m_targets != null)
						{
							var handlerTargets = handler.m_targets;

							if (!handlerTargets.IsInitialized)
							{
								// find all targets and initialize them
								if ((failReason = handlerTargets.FindAllTargets()) != SpellFailedReason.Ok)
								{
									return failReason;
								}
							}

							foreach (var target in handlerTargets)
							{
								m_targets.Add(target);
							}
						}
					}
				}
			}

			return failReason;
		}
示例#15
0
		private void CreateHandler(SpellEffect effect, int h, SpellEffectHandler[] handlers, ref SpellTargetCollection targets, ref SpellFailedReason failReason)
		{
			var handler = effect.SpellEffectHandlerCreator(this, effect);
			handlers[h] = handler;

			// make sure, we have the right Caster-Type
			handler.CheckCasterType(ref failReason);
			if (failReason != SpellFailedReason.Ok)
			{
				return;
			}

			// find targets and amount SpellTargetCollection if effects have same ImplicitTargetTypes
			if (m_initialTargets != null)
			{
				// do we have given targets?
				//targets = SpellTargetCollection.SpellTargetCollectionPool.Obtain();
				if (targets == null)
				{
					targets = new SpellTargetCollection();
				}
			}
			else if (handler.HasOwnTargets)
			{
				targets = null;

				// check if we have same target-types, else collect targets specifically for this Effect
				for (var j = 0; j < h; j++)
				{
					var handler2 = handlers[j];
					if (handler.Effect.TargetsEqual(handler2.Effect))
					{
						targets = handler2.m_targets;
						break;
					}
				}

				if (targets == null)
				{
					//targets = SpellTargetCollection.SpellTargetCollectionPool.Obtain();
					targets = new SpellTargetCollection();
				}
			}

			if (targets != null)
			{
				handler.m_targets = targets;
				targets.m_handlers.Add(handler);
			}
		}
示例#16
0
        private SpellFailedReason CollectHandlerTargets(SpellEffectHandler handler)
        {
            var failReason = InitialTargets != null ? handler.Targets.AddAll(InitialTargets) : handler.Targets.FindAllTargets();

            if (failReason != SpellFailedReason.Ok)
                return failReason;

            AddHandlerTargetsToTargets(handler);

            return SpellFailedReason.Ok;
        }
示例#17
0
 private void AddHandlerTargetsToTargets(SpellEffectHandler handler)
 {
     foreach (var target in handler.Targets)
     {
         Targets.Add(target);
     }
 }
示例#18
0
		/// <summary>
		/// Creates the SpellEffectHandlers and collects all initial targets
		/// </summary>
		protected SpellFailedReason InitHandlers()
		{
			SpellTargetCollection targets;
			var failReason = SpellFailedReason.Ok;

			if (m_targets == null)
			{
				//m_targets = WorldObject.WorldObjectSetPool.Obtain();
				m_targets = new HashSet<WorldObject>();
			}

			//var extraEffects = CasterUnit.Spells.GetExtraEffectsForSpell(m_spell.SpellId);
			//var hasExtraEffects = extraEffects != null;
			var handlers = new SpellEffectHandler[m_spell.EffectHandlerCount];// + (hasExtraEffects ? extraEffects.Count : 0)];
			var h = 0;
			foreach (var effect in m_spell.Effects)
			{
				if (effect.SpellEffectHandlerCreator == null)
				{
					continue;
				}

				InitHandler(effect, h, handlers, out targets, ref failReason);
				if (failReason != SpellFailedReason.Ok)
				{
					return failReason;
				}
				h++;
			}
			//if (hasExtraEffects)
			//{
			//    foreach (var effect in extraEffects)
			//    {
			//        if (effect.SpellEffectHandlerCreator == null)
			//        {
			//            continue;
			//        }

			//        InitHandler(effect, h, handlers, out targets, ref failReason);
			//        if (failReason != SpellFailedReason.Ok)
			//        {
			//            return failReason;
			//        }
			//        h++;
			//    }
			//}

			// Initialize Targets
			for (var i = 0; i < h; i++)
			{
				var handler = handlers[i];
				if (handler.Targets != null)
				{
					var handlerTargets = handler.Targets;
					// find all targets and init
					if (m_initialTargets == null || m_initialTargets.Length == 0)
					{
						// only search if we don't have initial targets
						if ((failReason = handlerTargets.FindAllTargets()) != SpellFailedReason.Ok)
						{
							return failReason;
						}
					}

					foreach (var target in handlerTargets)
					{
						m_targets.Add(target);
					}
				}
			}
			if (failReason == SpellFailedReason.Ok)
			{
				m_handlers = handlers;
			}
			return failReason;
		}
示例#19
0
		/// <summary>
		/// Creates the SpellEffectHandlers and collects all initial targets
		/// </summary>
		protected SpellFailedReason InitHandlers()
		{
			var failReason = SpellFailedReason.Ok;

			if (Targets == null)
			{
				//m_targets = WorldObject.WorldObjectSetPool.Obtain();
				Targets = new HashSet<WorldObject>();
			}

			//var extraEffects = CasterUnit.Spells.GetExtraEffectsForSpell(m_spell.SpellId);
			//var hasExtraEffects = extraEffects != null;
			var handlers = new SpellEffectHandler[Spell.EffectHandlerCount];// + (hasExtraEffects ? extraEffects.Count : 0)];
			var h = 0;
			SpellTargetCollection targets = null;
			foreach (var effect in Spell.Effects)
			{
				if (effect.SpellEffectHandlerCreator == null)
				{
					continue;
				}

				CreateHandler(effect, h, handlers, ref targets, ref failReason);
				if (failReason != SpellFailedReason.Ok)
				{
					return failReason;
				}
				h++;
			}

			//if (hasExtraEffects)
			//{
			//    foreach (var effect in extraEffects)
			//    {
			//        if (effect.SpellEffectHandlerCreator == null)
			//        {
			//            continue;
			//        }

			//        InitHandler(effect, h, handlers, out targets, ref failReason);
			//        if (failReason != SpellFailedReason.Ok)
			//        {
			//            return failReason;
			//        }
			//        h++;
			//    }
			//}

			if (failReason == SpellFailedReason.Ok)
			{
				Handlers = handlers;

				// initialize handlers
				foreach (var handler in Handlers)
				{
					handler.Initialize(ref failReason);
					if (failReason != SpellFailedReason.Ok)
					{
						Handlers = null;
						return failReason;
					}
				}

				// initialize targets
				foreach (var handler in Handlers)
				{
					var handlerTargets = handler.m_targets;
					if (handlerTargets == null || handlerTargets.IsInitialized) continue;

					if (InitialTargets != null)
					{
						// initialize forced targets
						if ((failReason = handlerTargets.AddAll(InitialTargets)) != SpellFailedReason.Ok)
						{
							return failReason;
						}
					}
					else
					{
						// Initialize standard Targets
						if ((failReason = handlerTargets.FindAllTargets()) != SpellFailedReason.Ok)
						{
							return failReason;
						}
					}

					foreach (var target in handlerTargets)
					{
						Targets.Add(target);
					}
				}
			}
			return failReason;
		}
示例#20
0
		private void DisposeHandlers(SpellEffectHandler[] handlers)
		{
			if (handlers == null)
				return;

			foreach (var handler in handlers)
			{
				// can be null if spell is cancelled during initialization
				if (handler != null)
				{
					handler.Cleanup();
				}
			}
		}