private void AddHandlerTargetsToTargets(SpellEffectHandler handler) { foreach (var target in handler.Targets) { Targets.Add(target); } }
/// <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); }
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); }
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); }
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); }
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); } }
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; }
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); }
/// <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); } }
/// <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; }
/// <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)); }
/// <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; }
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(); } }
/// <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; }
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); } }
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; }
/// <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; }
/// <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; }
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(); } } }