public static Composite CreateWarlockDestructionNormalPull() { return(new PrioritySelector( Helpers.Common.EnsureReadyToAttackFromLongRange(), Spell.WaitForCast(), new Decorator(ret => !Spell.IsGlobalCooldown(), new PrioritySelector( CreateWarlockDiagnosticOutputBehavior("Pull"), // grinding or questing, if target meets these cast Flame Shock if possible // 1. mob is less than 12 yds, so no benefit from delay in Lightning Bolt missile arrival // 2. area has another player competing for mobs (we want to tag the mob quickly) new Decorator( ret => { if (StyxWoW.Me.CurrentTarget.IsHostile && StyxWoW.Me.CurrentTarget.Distance < 12) { Logger.WriteDiagnostic("NormalPull: fast pull since hostile target is {0:F1} yds away", StyxWoW.Me.CurrentTarget.Distance); return true; } WoWPlayer nearby = ObjectManager.GetObjectsOfType <WoWPlayer>(true, false).FirstOrDefault(p => !p.IsMe && p.SpellDistance(Me.CurrentTarget) <= 40); if (nearby != null) { Logger.WriteDiagnostic("NormalPull: fast pull since player {0} targeting my target from @ {1:F1} yds", nearby.SafeName(), nearby.SpellDistance(Me.CurrentTarget)); return true; } return false; }, new PrioritySelector( // instant spells Spell.Cast("Conflagrate"), Spell.CastOnGround( "Rain of Fire", on => Me.CurrentTarget, req => Spell.UseAOE && !Unit.UnfriendlyUnitsNearTarget(8).Any(u => u.Guid != Me.CurrentTargetGuid && (!u.Aggro || u.IsCrowdControlled())), false ), new Action(r => { Logger.WriteDiagnostic("NormalPull: no instant cast spells were available -- using default Pull logic"); return RunStatus.Failure; }) ) ), Spell.Buff("Immolate", 3, on => Me.CurrentTarget, ret => true), Spell.Cast("Incinerate") ) ) )); }
public static Composite CreateMageFrostNormalPull() { return(new PrioritySelector( Safers.EnsureTarget(), Common.CreateStayAwayFromFrozenTargetsBehavior(), Helpers.Common.EnsureReadyToAttackFromLongRange(), Spell.WaitForCastOrChannel(), new Decorator( ret => !Spell.IsGlobalCooldown(), new PrioritySelector( Common.CreateMagePullBuffs(), Movement.WaitForFacing(), Movement.WaitForLineOfSpellSight(), #region TRIVIAL MOB FARM SUPPORT new Decorator( req => Me.CurrentTarget.IsTrivial(), new PrioritySelector( Spell.Cast("Cone of Cold", mov => false, on => Me.CurrentTarget, req => { IEnumerable <WoWUnit> coneUnits = Clusters.GetConeCluster(Unit.UnfriendlyUnits(12), 12); int count = coneUnits.Count(); if (count > 1 && Spell.CanCastHack("Cone of Cold", Me.CurrentTarget) && coneUnits.Any(u => u.Guid == Me.CurrentTargetGuid)) { if (coneUnits.All(u => u.IsTrivial())) { Logger.Write("^AOE Trivial Pull: casting Cone of Cold"); return true; } } return false; }), CreateIceLanceBehavior(on => Me.CurrentTarget, req => { if (!Spell.CanCastHack("Ice Lance", Me.CurrentTarget)) { return false; } Logger.Write(LogColor.Hilite, "^Trivial Pull: casting Ice Lance"); return true; }) ) ), #endregion #region FAST PULL SUPPORT new Decorator( ret => { WoWPlayer nearby = ObjectManager.GetObjectsOfType <WoWPlayer>(true, false).FirstOrDefault(p => !p.IsMe && p.DistanceSqr <= 40 * 40); if (nearby != null) { Logger.WriteDiagnostic("NormalPull: doing fast pull since player {0} nearby @ {1:F1} yds", nearby.SafeName(), nearby.Distance); return true; } return false; }, new PrioritySelector( Spell.Buff("Nether Tempest", 1, on => Me.CurrentTarget, req => true), Spell.Buff("Living Bomb", 0, on => Me.CurrentTarget, req => true), Spell.Cast("Ice Lance", ret => { if (Me.GotTarget && Me.CurrentTarget.IsImmune(WoWSpellSchool.Frost)) { return false; } if (!Spell.CanCastHack("Ice Lance", Me.CurrentTarget)) { return false; } Logger.Write(LogColor.Hilite, "^Fast Pull: casting Ice Lance for instant pull"); return true; }) ) ), #endregion // Pull with Ice Lance if trivial or FoF built up CreateIceLanceFoFBehavior(), // Otherwise.... lets set a Bomb first new Decorator( req => !Me.CurrentTarget.IsTrivial(), new PrioritySelector( Spell.Buff("Ice Nova", 0, on => Me.CurrentTarget, req => true), Spell.Buff("Frost Bomb", 0, on => Me.CurrentTarget, req => true) ) ), Spell.Cast("Frostbolt", ret => Me.GotTarget() && !Me.CurrentTarget.IsImmune(WoWSpellSchool.Frost)), Spell.Cast("Ice Lance", ret => { if (Me.GotTarget && Me.CurrentTarget.IsImmune(WoWSpellSchool.Frost)) { return false; } if (!Spell.CanCastHack("Ice Lance", Me.CurrentTarget)) { return false; } if (!Me.IsMoving) { return false; } Logger.Write(LogColor.Hilite, "^Cast on the Move: Ice Lance"); return true; }) ) ), Movement.CreateMoveToUnitBehavior(on => StyxWoW.Me.CurrentTarget, 38f, 33f) )); }
protected Composite CreateEnsurePVPTargetRanged() { return(new Action(ret => { unitsAt40Range = ObjectManager.GetObjectsOfType <WoWPlayer>(false, false).Where( p => p.IsHostile && !p.Dead && p.DistanceSqr <= (40 * 40)).ToList(); if (unitsAt40Range == null) { return RunStatus.Failure; } if (Me.CurrentTarget == null || Me.CurrentTarget.DistanceSqr > (45 * 45) || !Me.CurrentTarget.IsAlive) { // Pick up closes one WoWPlayer unit = unitsAt40Range.OrderBy(u => u.DistanceSqr).FirstOrDefault(); if (unit != null) { targetSwitchTimer.Reset(); TargetUnit(unit); Logger.Write("[Invalid target] Found new target: " + unit.SafeName()); return RunStatus.Success; } else { return RunStatus.Failure; } } if (!targetSwitchTimer.IsFinished || Me.IsCasting) { return RunStatus.Failure; } double currentTargetDistanceSqr = Me.CurrentTarget != null ? Me.CurrentTarget.DistanceSqr : 40 * 40; for (uint i = 2; i < 8; i++) { double rangeSqr = (i * 5) * (i * 5); if (rangeSqr > currentTargetDistanceSqr) { return RunStatus.Failure; } List <WoWPlayer> unitsAtRange = unitsAt40Range.Where(p => p.DistanceSqr <= rangeSqr).ToList(); if (unitsAtRange.Count > 0) { WoWPlayer unit = unitsAtRange.OrderBy(u => u.HealthPercent).FirstOrDefault(); if (unit != null) { targetSwitchTimer.Reset(); TargetUnit(unit); Logger.Write("[Invalid target] Found new target: " + unit.SafeName() + " I: " + i); return RunStatus.Success; } else { return RunStatus.Failure; } } } return RunStatus.Failure; })); }
protected Composite CreateEnsurePVPTargetMelee() { return (new PrioritySelector( // check if timer elapsed.. try to find closer target within melee range new Decorator( ret => Me.CurrentTarget != null && targetAwayFromMeleeTimer.IsFinished && Me.CurrentTarget.Guid == targetAwayFromMeleeGuid && !(Me.CurrentTarget.HealthPercent <= 20 && Me.CurrentTarget.DistanceSqr <= 30 * 30), new Action( ret => { // try to find any target within melee range WoWPlayer unit = ObjectManager.GetObjectsOfType <WoWPlayer>(false, false).Where( p => p.IsHostile && !p.Dead && p.DistanceSqr <= (10 * 10)).OrderBy( u => u.HealthPercent).FirstOrDefault(); if (unit != null) { Logger.Write("[Melee timer timeout] Found more suitable unit: " + unit.SafeName()); TargetUnit(unit); targetAwayFromMeleeGuid = unit.Guid; targetAwayFromMeleeTimer.Reset(); return RunStatus.Success; } else { Logger.Write("[Melee timer timeout] Didn't find any suitable unit."); return RunStatus.Failure; } })), // Make sure we have correct, target, if we don't find new target within range. new Decorator( ret => Me.CurrentTarget == null || Me.CurrentTarget.DistanceSqr > (35 * 35) || !Me.CurrentTarget.IsAlive, new Action( ret => { //get nearest one WoWPlayer unit = ObjectManager.GetObjectsOfType <WoWPlayer>(false, false).Where( p => p.IsHostile && !p.Dead && p.DistanceSqr <= (35 * 35)).OrderBy( u => u.DistanceSqr).FirstOrDefault(); if (unit != null) { Logger.Write("[Invalid target] Found new target: " + unit.SafeName()); TargetUnit(unit); targetAwayFromMeleeGuid = unit.Guid; targetAwayFromMeleeTimer.Reset(); return RunStatus.Success; } else { Logger.Write("[Invalid target] Didn't find any targets"); return RunStatus.Failure; } })), new Decorator( ret => Me.CurrentTarget != null && Me.CurrentTarget.DistanceSqr <= (10 * 10), new Action(ret => { if (targetAwayFromMeleeGuid != Me.CurrentTarget.Guid) { targetAwayFromMeleeGuid = Me.CurrentTarget.Guid; } targetAwayFromMeleeTimer.Reset(); return RunStatus.Failure; })), new Action(ret => { return RunStatus.Failure; }))); }
public static Composite CreatePriestShadowNormalPull() { return(new PrioritySelector( Helpers.Common.EnsureReadyToAttackFromLongRange(), Spell.WaitForCastOrChannel(), new Decorator( ret => !Spell.IsGlobalCooldown(), new PrioritySelector( // grinding or questing, if target meets either of these cast instant if possible // 1. mob is less than 12 yds, so no benefit from delay in Lightning Bolt missile arrival // 2. area has another player competing for mobs (we want to tag the mob quickly) new Decorator( ret => { if (StyxWoW.Me.CurrentTarget.IsHostile && StyxWoW.Me.CurrentTarget.Distance < 12) { Logger.Write(LogColor.Hilite, "Pull with Instant since hostile target is {0:F1} yds away", StyxWoW.Me.CurrentTarget.Distance); return true; } WoWPlayer nearby = ObjectManager.GetObjectsOfType <WoWPlayer>(true, false).FirstOrDefault(p => !p.IsMe && p.SpellDistance(Me.CurrentTarget) <= 40); if (nearby != null) { Logger.Write(LogColor.Hilite, "Pull with Instant since player {0} nearby @ {1:F1} yds", nearby.SafeName(), nearby.Distance); return true; } Logger.WriteDiagnostic("Pull with normal rotation since no urgency"); return false; }, new PrioritySelector( Spell.Buff("Shadow Word: Pain", true) ) ), Spell.BuffSelf("Power Word: Shield", ret => PriestSettings.UseShieldPrePull && !Me.HasAura("Weakened Soul")), Movement.WaitForFacing(), Movement.WaitForLineOfSpellSight(), Spell.Buff("Vampiric Touch", true), Spell.Buff("Shadow Word: Pain", true) // Spell.Cast("Holy Fire", ctx => Me.CurrentTarget.IsImmune(WoWSpellSchool.Shadow)) ) ) )); }
public static Composite CreateElementalNormalPull() { return(new PrioritySelector( Helpers.Common.EnsureReadyToAttackFromLongRange(), Spell.WaitForCastOrChannel(), new Decorator( ret => !Spell.IsGlobalCooldown(), new PrioritySelector( Common.CreateShamanDpsShieldBehavior(), Totems.CreateTotemsBehavior(), Spell.BuffSelf("Totem Mastery", req => !Me.HasAura("Ember Totem")), // Only one buff should need to be checked. Movement.WaitForFacing(), Movement.WaitForLineOfSpellSight(), // grinding or questing, if target meets these cast Flame Shock if possible // 1. mob is less than 12 yds, so no benefit from delay in Lightning Bolt missile arrival // 2. area has another player competing for mobs (we want to tag the mob quickly) new Decorator( ret => { if (StyxWoW.Me.CurrentTarget.IsHostile && StyxWoW.Me.CurrentTarget.Distance < 12) { Logger.WriteDiagnostic("NormalPull: fast pull since hostile target is {0:F1} yds away", StyxWoW.Me.CurrentTarget.Distance); return true; } WoWPlayer nearby = ObjectManager.GetObjectsOfType <WoWPlayer>(true, false).FirstOrDefault(p => !p.IsMe && p.DistanceSqr <= 40 * 40); if (nearby != null) { Logger.WriteDiagnostic("NormalPull: fast pull since player {0} nearby @ {1:F1} yds", nearby.SafeName(), nearby.Distance); return true; } return false; }, new PrioritySelector( // have a big attack loaded up, so don't waste it Spell.Cast("Earth Shock", ret => StyxWoW.Me.HasAura("Lightning Shield", 5)), Spell.Buff("Flame Shock", true, req => SpellManager.HasSpell("Lava Burst")), Spell.Cast("Earth Shock", ret => !SpellManager.HasSpell("Flame Shock")) ) ), // have a big attack loaded up, so don't waste it Spell.Cast("Earth Shock", ret => StyxWoW.Me.HasAura("Lightning Shield", 5)), // otherwise, start with Lightning Bolt so we can follow with an instant // to maximize damage at initial aggro Spell.Cast("Lightning Bolt"), // we are moving so throw an instant of some type Spell.Buff("Flame Shock", true, req => SpellManager.HasSpell("Lava Burst")), Spell.Buff("Lava Burst", true, req => Me.GotTarget() && Me.CurrentTarget.HasMyAura("Flame Shock")), Spell.Cast("Earth Shock") ) ) // Movement.CreateMoveToUnitBehavior( on => StyxWoW.Me.CurrentTarget, 38f, 33f) )); }