public static Composite CreateAssaRogueNormalCombat() { return(new PrioritySelector( Common.RogueEnsureWeKillSappedMobs(), Common.CreateRogueMoveBehindTarget(), Helpers.Common.EnsureReadyToAttackFromMelee(), Spell.WaitForCastOrChannel(), new Decorator( ret => !Spell.IsGlobalCooldown(), new PrioritySelector( SingularRoutine.MoveBehaviorInlineToCombat(BehaviorType.Heal), SingularRoutine.MoveBehaviorInlineToCombat(BehaviorType.CombatBuffs), // updated time to death tracking values before we need them new Action(ret => { Me.CurrentTarget.TimeToDeath(); return RunStatus.Failure; }), Helpers.Common.CreateInterruptBehavior(), Common.CreateDismantleBehavior(), Spell.Buff("Rupture", req => Me.ComboPoints >= 5), Spell.Buff("Vendetta", ret => Me.CurrentTarget.IsPlayer || Me.CurrentTarget.Elite || Me.CurrentTarget.IsBoss() || Common.AoeCount > 1), Spell.Buff("Hemorrhage"), Spell.Buff("Garrote"), Spell.Cast("Exsanguinate"), Spell.Cast("Kingsbane", ret => !RogueSettings.UseArtifactOnlyInAoE && RogueSettings.UseDPSArtifactWeaponWhen != UseDPSArtifactWeaponWhen.None), Spell.Cast("Envenom", req => Me.ComboPoints >= 5), Spell.Cast("Mutilate"), new Decorator( ret => Spell.UseAOE && Common.AoeCount > 1, new PrioritySelector( ctx => Common.AoeCount >= RogueSettings.AoeSpellPriorityCount, Spell.Cast("Kingsbane", ret => RogueSettings.UseDPSArtifactWeaponWhen != UseDPSArtifactWeaponWhen.None), Spell.Buff( "Rupture", 3, on => Unit.UnfriendlyUnits(5) .FirstOrDefault(u => !u.HasMyAura("Rupture") && u.IsWithinMeleeRange && Me.IsSafelyFacing(u) && u.InLineOfSpellSight), req => !(bool)req ), Spell.BuffSelf( "Fan of Knives", req => !Me.CurrentTarget.IsPlayer && Common.AoeCount >= RogueSettings.FanOfKnivesCount ), Spell.Cast("Mutilate", ret => !SpellManager.HasSpell("Fan of Knives") && Common.HasTwoDaggers), AssaCastSinisterStrike(), Movement.CreateMoveToMeleeBehavior(true) ) ), Common.CheckThatDaggersAreEquippedIfNeeded(), AssaCastSinisterStrike() ) ) )); }
// save list to xml file public void Save(string sFilename = null) { if (string.IsNullOrEmpty(sFilename)) { sFilename = Filename; } try { if (!Directory.Exists(Path.GetDirectoryName(sFilename))) { Directory.CreateDirectory(Path.GetDirectoryName(sFilename)); } XmlSerializer ser = new XmlSerializer(typeof(SpellList), new Type[] { typeof(SpellEntry) }); using (StreamWriter writer = new StreamWriter(sFilename)) { Version = SingularRoutine.GetSingularVersion().ToString(); ser.Serialize(writer, this); } } catch (Exception ex) { Styx.Common.Logging.WriteException(ex); } }
public static Composite CreatePurgeEnemyBehavior(string spellName) { if (SingularSettings.Instance.PurgeTargets == CheckTargets.None || SingularSettings.Instance.PurgeBuffs == PurgeAuraFilter.None) { return(new ActionAlwaysFail()); } return(Spell.Cast(spellName, mov => false, on => { if (!SingularRoutine.IsAllowed(Styx.CommonBot.Routines.CapabilityFlags.DefensiveDispel)) { return null; } WoWUnit unit = GetPurgeEnemyTarget(spellName); if (unit != null) { Logger.WriteDebug("PurgeEnemy[{0}]: found {1} has triggering aura, cancast={2}", spellName, unit.SafeName(), Spell.CanCastHack(spellName, unit)); } return unit; }, ret => SingularSettings.Instance.PurgeTargets != CheckTargets.None )); }
public static Composite CreateBrewmasterMonkCombat() { TankManager.NeedTankTargeting = (SingularRoutine.CurrentWoWContext == WoWContext.Instances); return(new PrioritySelector( Common.CreateAttackFlyingOrUnreachableMobs(), Helpers.Common.EnsureReadyToAttackFromMelee(), Spell.WaitForCastOrChannel(), new Decorator( req => !Spell.IsGlobalCooldown(), new PrioritySelector( ctx => TankManager.Instance.TargetList.FirstOrDefault(u => u.IsWithinMeleeRange) ?? Me.CurrentTarget, Helpers.Common.CreateInterruptBehavior(), SingularRoutine.MoveBehaviorInlineToCombat(BehaviorType.CombatBuffs), Movement.WaitForFacing(), Movement.WaitForLineOfSpellSight(), new Decorator( ret => SingularRoutine.CurrentWoWContext == WoWContext.Instances && Unit.NearbyUnfriendlyUnits.Count(u => !u.IsBoss) > 2, new PrioritySelector( CreateSummonBlackOxStatueBehavior(on => Me.CurrentTarget), Spell.Cast("Provoke", on => FindStatue(), ret => TankManager.Instance.NeedToTaunt.Count >= 2)) ), // taunt if needed Spell.Cast("Provoke", ret => TankManager.Instance.NeedToTaunt.FirstOrDefault(), ret => SingularSettings.Instance.EnableTaunting), new Decorator(ret => Unit.UnfriendlyUnits(8).Count() >= 2, new PrioritySelector( Spell.CastOnGround("Exploding Keg", on => (WoWUnit)on, ret => Me.CurrentTarget.IsWithinMeleeRange && (Me.HealthPercent <= MonkSettings.ArtifactHealthPercent || Unit.NearbyUnfriendlyUnits.Count(u => !u.IsBoss) > 2)), Spell.Cast("Keg Smash", on => (WoWUnit)on), Spell.Cast("Breath of Fire", on => (WoWUnit)on), Spell.Cast("Blackout Strike", on => (WoWUnit)on, req => Common.HasTalent(MonkTalents.BlackoutCombo)), Spell.Cast("Chi Burst", on => (WoWUnit)on), Spell.Cast("Breath of Fire", on => (WoWUnit)on), Spell.Cast("Rushing Jade Wind", on => (WoWUnit)on), Spell.Cast("Tiger Palm", on => (WoWUnit)on, req => Me.CurrentEnergy >= 65), Spell.Cast("Leg Sweep", on => (WoWUnit)on, ret => ((WoWUnit)ret).IsWithinMeleeRange), Spell.Cast("Blackout Strike", on => (WoWUnit)on) ) ), Spell.Cast("Blackout Strike", on => (WoWUnit)on), Spell.Cast("Tiger Palm", on => (WoWUnit)on, req => Me.CurrentEnergy >= 65), Spell.Cast("Rushing Jade Wind", on => (WoWUnit)on), Spell.Cast("Chi Wave", on => (WoWUnit)on), Spell.Cast("Leg Sweep", on => (WoWUnit)on, ret => ((WoWUnit)ret).IsWithinMeleeRange), Spell.Cast("Breath of Fire", on => (WoWUnit)on, req => (Me.CurrentTarget.IsPlayer || Me.CurrentTarget.IsBoss || Me.CurrentTarget.Elite) && Me.IsSafelyFacing(Me.CurrentTarget, 90f) && Me.CurrentTarget.SpellDistance() < 12), Spell.Cast("Breath of Fire", on => (WoWUnit)on, req => Clusters.GetConeClusterCount(90f, Unit.UnfriendlyUnits(12), 100f) > 1), SingularRoutine.MoveBehaviorInlineToCombat(BehaviorType.Heal), Common.CreateCloseDistanceBehavior() ) ) )); }
public bool IsCombatRoutineMovementAllowed() { if (AllowMovement != AllowMovementType.Auto) { return(AllowMovement >= AllowMovementType.ClassSpecificOnly); } return(!SingularRoutine.IsBotInUse("LazyRaider") || !SingularRoutine.IsBotInUse("Raid Bot") || !SingularRoutine.IsBotInUse("Combat Bot")); }
public void UpdateCapabilitiesFlags() { if (!this.Visible) { return; } SendMessage(lblPoi.Handle, WM_SETREDRAW, false, (IntPtr)0); SendMessage(chkCFInterrupt.Handle, WM_SETREDRAW, false, (IntPtr)0); SendMessage(chkCFTaunt.Handle, WM_SETREDRAW, false, (IntPtr)0); SendMessage(chkCFMultiMobPull.Handle, WM_SETREDRAW, false, (IntPtr)0); SendMessage(chkCFDefDispel.Handle, WM_SETREDRAW, false, (IntPtr)0); SendMessage(chkCFOffDispel.Handle, WM_SETREDRAW, false, (IntPtr)0); SendMessage(chkCFKiting.Handle, WM_SETREDRAW, false, (IntPtr)0); SendMessage(chkCFSpecialAttacks.Handle, WM_SETREDRAW, false, (IntPtr)0); SendMessage(chkCFPetUse.Handle, WM_SETREDRAW, false, (IntPtr)0); SendMessage(chkCFPetSummon.Handle, WM_SETREDRAW, false, (IntPtr)0); SendMessage(chkCFTargeting.Handle, WM_SETREDRAW, false, (IntPtr)0); SendMessage(chkCFAOE.Handle, WM_SETREDRAW, false, (IntPtr)0); SendMessage(chkCFGapCloser.Handle, WM_SETREDRAW, false, (IntPtr)0); SendMessage(chkCFFacing.Handle, WM_SETREDRAW, false, (IntPtr)0); SendMessage(chkCFMoveBehind.Handle, WM_SETREDRAW, false, (IntPtr)0); SendMessage(chkCFMovement.Handle, WM_SETREDRAW, false, (IntPtr)0); chkCFInterrupt.Checked = SingularRoutine.IsAllowed(CapabilityFlags.Interrupting); chkCFTaunt.Checked = SingularRoutine.IsAllowed(CapabilityFlags.Taunting); chkCFMultiMobPull.Checked = SingularRoutine.IsAllowed(CapabilityFlags.MultiMobPull); chkCFDefDispel.Checked = SingularRoutine.IsAllowed(CapabilityFlags.DefensiveDispel); chkCFOffDispel.Checked = SingularRoutine.IsAllowed(CapabilityFlags.OffensiveDispel); chkCFKiting.Checked = SingularRoutine.IsAllowed(CapabilityFlags.Kiting); chkCFSpecialAttacks.Checked = SingularRoutine.IsAllowed(CapabilityFlags.SpecialAttacks); chkCFPetUse.Checked = SingularRoutine.IsAllowed(CapabilityFlags.PetUse); chkCFPetSummon.Checked = SingularRoutine.IsAllowed(CapabilityFlags.PetSummoning); chkCFTargeting.Checked = SingularRoutine.IsAllowed(CapabilityFlags.Targeting); chkCFAOE.Checked = SingularRoutine.IsAllowed(CapabilityFlags.Aoe); chkCFGapCloser.Checked = SingularRoutine.IsAllowed(CapabilityFlags.GapCloser); chkCFFacing.Checked = SingularRoutine.IsAllowed(CapabilityFlags.Facing); chkCFMoveBehind.Checked = SingularRoutine.IsAllowed(CapabilityFlags.MoveBehind); chkCFMovement.Checked = SingularRoutine.IsAllowed(CapabilityFlags.Movement); SendMessage(lblPoi.Handle, WM_SETREDRAW, true, (IntPtr)0); SendMessage(chkCFInterrupt.Handle, WM_SETREDRAW, true, (IntPtr)0); SendMessage(chkCFTaunt.Handle, WM_SETREDRAW, true, (IntPtr)0); SendMessage(chkCFMultiMobPull.Handle, WM_SETREDRAW, true, (IntPtr)0); SendMessage(chkCFDefDispel.Handle, WM_SETREDRAW, true, (IntPtr)0); SendMessage(chkCFOffDispel.Handle, WM_SETREDRAW, true, (IntPtr)0); SendMessage(chkCFKiting.Handle, WM_SETREDRAW, true, (IntPtr)0); SendMessage(chkCFSpecialAttacks.Handle, WM_SETREDRAW, true, (IntPtr)0); SendMessage(chkCFPetUse.Handle, WM_SETREDRAW, true, (IntPtr)0); SendMessage(chkCFPetSummon.Handle, WM_SETREDRAW, true, (IntPtr)0); SendMessage(chkCFTargeting.Handle, WM_SETREDRAW, true, (IntPtr)0); SendMessage(chkCFAOE.Handle, WM_SETREDRAW, true, (IntPtr)0); SendMessage(chkCFGapCloser.Handle, WM_SETREDRAW, true, (IntPtr)0); SendMessage(chkCFFacing.Handle, WM_SETREDRAW, true, (IntPtr)0); SendMessage(chkCFMoveBehind.Handle, WM_SETREDRAW, true, (IntPtr)0); SendMessage(chkCFMovement.Handle, WM_SETREDRAW, true, (IntPtr)0); }
public static Composite CreateRogueCombatNormalCombat() { return(new PrioritySelector( Common.RogueEnsureWeKillSappedMobs(), Common.CreateRogueMoveBehindTarget(), Helpers.Common.EnsureReadyToAttackFromMelee(), Spell.WaitForCastOrChannel(), new Decorator( ret => !Spell.IsGlobalCooldown(), new PrioritySelector( SingularRoutine.MoveBehaviorInlineToCombat(BehaviorType.Heal), SingularRoutine.MoveBehaviorInlineToCombat(BehaviorType.CombatBuffs), // updated time to death tracking values before we need them new Action(ret => { Me.CurrentTarget.TimeToDeath(); return RunStatus.Failure; }), CreateBladeFlurryBehavior(), Helpers.Common.CreateInterruptBehavior(), Common.CreateDismantleBehavior(), Common.CreateRogueOpenerBehavior() ) ), Spell.Cast("Vanish", when => Me.TimeToDeath() < 2 && Me.TimeToDeath() < Me.CurrentTarget.TimeToDeath()), new Decorator( ret => Me.HasActiveAura("Curse of the Dreadblades"), CreateDreadbladeRotation() ), new Decorator( ret => !Common.HaveTalent(RogueTalents.SliceAndDice), CreateRollTheBonesRotation() ), new Decorator( ret => Common.HaveTalent(RogueTalents.SliceAndDice), CreateSliceAndDiceRotation() ) )); }
protected override void OnClosing(System.ComponentModel.CancelEventArgs e) { if (DialogResult == DialogResult.OK || DialogResult == DialogResult.Yes) { Logger.WriteDebug(Color.LightGreen, "Settings saved, rebuilding behaviors..."); // in case bot not running when config change occurs SingularRoutine.OnPlayerTargetChange(StyxWoW.Me.CurrentTarget); HotkeyDirector.Update(); MovementManager.Update(); SingularRoutine.DescribeContext(); SingularRoutine.Instance.RebuildBehaviors(); SingularSettings.Instance.LogSettings(); } base.OnClosing(e); }
public static Composite CreateRogueSubtletyNormalCombat() { return(new PrioritySelector( Common.RogueEnsureWeKillSappedMobs(), Common.CreateRogueMoveBehindTarget(), Helpers.Common.EnsureReadyToAttackFromMelee(), Spell.WaitForCastOrChannel(), new Decorator( ret => !Spell.IsGlobalCooldown(), new PrioritySelector( SingularRoutine.MoveBehaviorInlineToCombat(BehaviorType.Heal), SingularRoutine.MoveBehaviorInlineToCombat(BehaviorType.CombatBuffs), // updated time to death tracking values before we need them new Action(ret => { Me.CurrentTarget.TimeToDeath(); return RunStatus.Failure; }), Helpers.Common.CreateInterruptBehavior(), Common.CreateDismantleBehavior(), Common.CreateRogueOpenerBehavior(), Spell.HandleOffGCD(Spell.Cast("Symbols of Death")), Spell.Cast("Shadow Blades"), Spell.Cast("Shadowstrike"), Spell.Buff("Nightblade", req => Me.ComboPoints >= 5), Spell.Cast("Shadow Dance", ret => !Common.AreStealthAbilitiesAvailable && Spell.GetCharges("Shadow Dance") >= 2), Spell.Cast("Goremaw's Bite", ret => RogueSettings.UseDPSArtifactWeaponWhen != UseDPSArtifactWeaponWhen.None), Spell.Cast("Eviscerate", req => Me.ComboPoints >= 5), Spell.Cast("Shuriken Storm", req => Common.AoeCount >= 2), Spell.Cast("Backstab"), // lets try a big hit if stealthed and behind before anything Spell.Cast(sp => "Ambush", chkMov => false, on => Me.CurrentTarget, req => Common.IsAmbushNeeded(), canCast: Common.RogueCanCastOpener), Common.CheckThatDaggersAreEquippedIfNeeded() ) ) )); }
internal static void Init() { SingularRoutine.OnBotEvent += (src, arg) => { IsManualMovementBotActive = SingularRoutine.IsBotInUse("LazyRaider", "Raid Bot", "Tyrael", "Enyo", "HazzNyo"); if (arg.Event == SingularBotEvent.BotStarted) { MovementManager.Start(); } else if (arg.Event == SingularBotEvent.BotStopped) { MovementManager.Stop(); } else if (arg.Event == SingularBotEvent.BotChanged) { MovementManager.Change(); } }; }
public static Composite CreateGuardianCombat() { TankManager.NeedTankTargeting = (SingularRoutine.CurrentWoWContext == WoWContext.Instances); return(new PrioritySelector( //Some profiles have problems pulling. Having this here reduces somewhat the delay to enter Bear Form this profiles cause. Common.CastForm(ShapeshiftForm.Bear, req => !Utilities.EventHandlers.IsShapeshiftSuppressed && Me.Shapeshift != ShapeshiftForm.Bear), Helpers.Common.EnsureReadyToAttackFromMelee(), CreateGuardianWildChargeBehavior(), Spell.WaitForCast(), new Decorator( ret => !Spell.IsGlobalCooldown(), new PrioritySelector( ctx => TankManager.Instance.TargetList.FirstOrDefault(u => u.IsWithinMeleeRange) ?? Me.CurrentTarget, SingularRoutine.MoveBehaviorInlineToCombat(BehaviorType.Heal), SingularRoutine.MoveBehaviorInlineToCombat(BehaviorType.CombatBuffs), Helpers.Common.CreateInterruptBehavior(), CreateGuardianTauntBehavior(), Spell.HandleOffGCD(Spell.Cast("Rage of the Sleeper", ret => Settings.UseDPSArtifactWeaponWhen != UseDPSArtifactWeaponWhen.None && Me.HealthPercent <= Settings.ArtifactHealthPercent)), Spell.BuffSelf("Incarnation: Guardian of Ursoc", ret => Me.CurrentRage <= 20), Spell.Cast("Moonfire", on => (WoWUnit)on, ret => Me.HasActiveAura("Galactic Guardian")), // thrash is slightly higher priority when mob count >= 3. Spell.Cast("Thrash", on => (WoWUnit)on, req => Unit.UnitsInCombatWithMe(8).Count() >= 3), Spell.Cast("Mangle", on => (WoWUnit)on), Spell.Cast("Thrash", on => (WoWUnit)on, req => Unit.UnitsInCombatWithMe(8).Any()), Spell.Cast("Moonfire", on => Unit.NearbyUnitsInCombatWithUsOrOurStuff.FirstOrDefault(u => u.GetAuraTimeLeft("Moonfire").TotalSeconds < 2.5)), Spell.Cast("Swipe", on => (WoWUnit)on, req => Unit.UnitsInCombatWithMe(8).Any()), Spell.HandleOffGCD(Spell.Cast("Maul", on => (WoWUnit)on, ret => (!Me.HasActiveAura("Ironfur") && !Me.HasActiveAura("Mark of Ursol") && RageDeficit < 10))), Movement.WaitForFacing(), Movement.WaitForLineOfSpellSight(), CreateGuardianWildChargeBehavior() ) ) )); }
public static Composite CreateProtectionCombat() { TankManager.NeedTankTargeting = SingularRoutine.CurrentWoWContext == WoWContext.Instances; EventHandlers.TrackDamage = true; return(new PrioritySelector( // set context to current target ctx => { if (TankManager.NeedTankTargeting && TankManager.Instance.FirstUnit != null) { return TankManager.Instance.FirstUnit; } return Me.CurrentTarget; }, Helpers.Common.EnsureReadyToAttackFromMelee(), Spell.WaitForCast(), Common.CheckIfWeShouldCancelBladestorm(), new Decorator( ret => !Spell.IsGlobalCooldown(), new PrioritySelector( SingularRoutine.MoveBehaviorInlineToCombat(BehaviorType.Heal), SingularRoutine.MoveBehaviorInlineToCombat(BehaviorType.CombatBuffs), Movement.WaitForFacing(), Movement.WaitForLineOfSpellSight(), new Decorator( req => Me.GotTarget(), CreateProtectionDefensiveCombat() ) ) ) )); }
public static bool Pulse() { if (SpecChangeTestTimer.IsFinished) { if (StyxWoW.Me.Level >= 10 && StyxWoW.Me.Specialization != CurrentSpec) { CurrentSpec = StyxWoW.Me.Specialization; RebuildNeeded = true; Logger.Write(LogColor.Hilite, "TalentManager: spec is now to {0}", SingularRoutine.SpecName()); } } if (RebuildNeeded && EventRebuildTimer.IsFinished) { RebuildNeeded = false; Logger.Write(LogColor.Hilite, "TalentManager: Rebuilding behaviors due to changes detected."); Update(); // reload talents just in case SingularRoutine.DescribeContext(); SingularRoutine.Instance.RebuildBehaviors(); return(true); } return(false); }
public static Composite CreateFeralNormalCombat() { return(new PrioritySelector( Helpers.Common.EnsureReadyToAttackFromMelee(req => !Me.HasAura("Prowl")), Spell.WaitForCast(), new Decorator( ret => !Spell.IsGlobalCooldown(), new PrioritySelector( SingularRoutine.MoveBehaviorInlineToCombat(BehaviorType.Heal), SingularRoutine.MoveBehaviorInlineToCombat(BehaviorType.CombatBuffs), // updated time to death tracking values before we need them new Action(ret => { Me.CurrentTarget.TimeToDeath(); return RunStatus.Failure; }), Helpers.Common.CreateInterruptBehavior(), Movement.WaitForFacing(), Movement.WaitForLineOfSpellSight(), //High Priorty Artifact Weapon Ashamane's Frenzy new Decorator( ret => DruidSettings.UseArtifactOnlyInAoE && Unit.NearbyUnfriendlyUnits.Count(u => u.IsWithinMeleeRange) > 1, new PrioritySelector( Spell.Cast("Ashamane's Frenzy", ret => DruidSettings.UseDPSArtifactWeaponWhen == UseDPSArtifactWeaponWhen.OnCooldown || (DruidSettings.UseDPSArtifactWeaponWhen == UseDPSArtifactWeaponWhen.AtHighestDPSOpportunity && Me.HasActiveAura("Tiger's Fury")) ) ) ), Spell.Cast("Ashamane's Frenzy", ret => !DruidSettings.UseArtifactOnlyInAoE && (DruidSettings.UseDPSArtifactWeaponWhen == UseDPSArtifactWeaponWhen.OnCooldown || (DruidSettings.UseDPSArtifactWeaponWhen == UseDPSArtifactWeaponWhen.AtHighestDPSOpportunity && Me.HasActiveAura("Tiger's Fury"))) ), Spell.Cast("Regrowth", on => Me, ret => Me.HasActiveAura("Predatory Swiftness") && (Me.HealthPercent < 90 || (Me.HealthPercent >= 90 && !Me.HasActiveAura("Regrowth")))), Spell.HandleOffGCD(Spell.Cast("Tiger's Fury", ret => Common.HasTalent(DruidTalents.Predator) && Me.CurrentTarget.HasBleedDebuff() && Me.CurrentTarget.TimeToDeath() < 3 && (!Me.HasActiveAura("Tiger's Fury") || Me.CurrentEnergy < 70))), // AoE new Decorator( ret => Spell.UseAOE && Unit.UnfriendlyUnits(8).Count() > 2, new PrioritySelector( Spell.Cast("Thrash", on => Unit.UnfriendlyUnits(8).FirstOrDefault(u => u.GetAuraTimeLeft("Thrash").TotalSeconds < RakeAndThrashRefresh)), Spell.Cast("Rake", on => Unit.UnfriendlyUnits(8).OrderBy(u => u.GetAuraTimeLeft("Rake")). FirstOrDefault(u => Me.IsSafelyFacing(u) && (Me.HasActiveAura("Bloodtalons") || u.GetAuraTimeLeft("Rake").TotalSeconds < RakeAndThrashRefresh))), Spell.Cast("Rip", on => Unit.UnfriendlyUnits(8).FirstOrDefault( u => u.HealthPercent >= 25 && Me.IsSafelyFacing(u) && u.TimeToDeath(int.MaxValue) > 18 && u.GetAuraTimeLeft("Rip").TotalSeconds < RipRefresh), ret => Me.ComboPoints >= 4), Spell.Cast("Swipe"), Spell.HandleOffGCD(Spell.BuffSelf("Tiger's Fury")), Spell.BuffSelf("Berserk") ) ), //Single target CreateFeralFaerieFireBehavior(), Spell.Cast("Elune's Guidance", ret => Me.ComboPoints <= 0 && Me.CurrentEnergy >= 50), new Decorator(ret => Me.ComboPoints >= 5 || (Me.ComboPoints >= 3 && Me.CurrentTarget.IsTrivial()), new PrioritySelector( Spell.Cast("Ferocious Bite", on => Unit.UnfriendlyUnits(8).FirstOrDefault( u => Me.IsSafelyFacing(u) && ((u.HealthPercent < 25 || Common.HasTalent(DruidTalents.Sabertooth)) && u.HasMyAura("Rip") || u.TimeToDeath(int.MaxValue) < 18 || u.GetAuraTimeLeft("Rip").TotalSeconds >= RipRefresh)), ret => (!Common.HasTalent(DruidTalents.SavageRoar) || Me.GetAuraTimeLeft("Savage Roar").TotalSeconds > 12) && Me.CurrentEnergy >= 50), Spell.Cast("Rip", on => Unit.UnfriendlyUnits(8).FirstOrDefault( u => Me.IsSafelyFacing(u) && u.HealthPercent >= 25 && u.TimeToDeath(int.MaxValue) > 18 && u.GetAuraTimeLeft("Rip").TotalSeconds < RipRefresh)), Spell.Cast("Savage Roar"))), Spell.Cast("Moonfire", on => Unit.NearbyUnitsInCombatWithUsOrOurStuff.FirstOrDefault(u => u.GetAuraTimeLeft("Moonfire").TotalSeconds < 2.5), ret => Common.HasTalent(DruidTalents.LunarInspiration)), Spell.HandleOffGCD(Spell.Cast("Tiger's Fury", ret => EnergyDecifit > 65)), Spell.Cast("Berserk", ret => Me.HasActiveAura("Tiger's Fury") && Me.CurrentTarget.IsStressful()), Spell.Cast("Rake", on => Unit.UnfriendlyUnits(8).OrderBy(u => u.GetAuraTimeLeft("Rake")). FirstOrDefault( u => Me.IsSafelyFacing(u) && (Me.HasActiveAura("Bloodtalons") || u.GetAuraTimeLeft("Rake").TotalSeconds < RakeAndThrashRefresh))), Spell.Cast("Brutal Slash"), Spell.Cast("Shred", ret => Unit.UnfriendlyUnitsNearTarget(8).Count() <= 1), Spell.Cast("Swipe"), new Decorator( ret => MovementManager.IsClassMovementAllowed && Me.IsMoving && Me.CurrentTarget.Distance > (Me.CurrentTarget.IsPlayer ? 10 : 15), new PrioritySelector( CreateFeralWildChargeBehavior(), Spell.BuffSelf("Dash", ret => MovementManager.IsClassMovementAllowed && Spell.GetSpellCooldown("Wild Charge", 0).TotalSeconds < 13) ) ) ) ), Movement.CreateMoveToMeleeBehavior(true) )); }
public static Composite CheckThatShieldIsEquippedIfNeeded() { if (_checkShield == null) { _checkShield = new ThrottlePasses(60, new Sequence( new DecoratorContinue( ret => !Me.Disarmed && !HasShieldInOffHand && SpellManager.HasSpell("Shield Slam"), new Action(ret => Logger.Write(Color.HotPink, "User Error: a{0} requires a Shield in offhand to cast Shield Slam", SingularRoutine.SpecAndClassName())) ), new ActionAlwaysFail() ) ); } return(_checkShield); }
private static Composite CreateProtectionDefensiveCombat() { return(new PrioritySelector( CreateProtectionDiagnosticOutput(), Common.CreateVictoryRushBehavior(), new Decorator( ret => SingularSettings.Instance.EnableTaunting && SingularRoutine.CurrentWoWContext == WoWContext.Instances, CreateProtectionTauntBehavior() ), new Sequence( new Decorator( ret => Common.IsSlowNeeded(Me.CurrentTarget), new PrioritySelector( Spell.Buff("Hamstring") ) ), new Wait(TimeSpan.FromMilliseconds(500), until => !Common.IsSlowNeeded(Me.CurrentTarget), new ActionAlwaysSucceed()) ), CreateProtectionInterrupt(), Common.CreateSpellReflectBehavior(), // special "in combat" pull logic for mobs not tagged and out of melee range Common.CreateWarriorCombatPullMore(), // Multi-target? get the debuff on them new Decorator( ret => Unit.NearbyUnitsInCombatWithMeOrMyStuff.Count() > 1, new PrioritySelector( Spell.BuffSelf("Avatar", ret => WarriorSettings.AvatarOnCooldownAOE), Spell.Cast("Thunder Clap", on => Unit.UnfriendlyUnits(Common.DistanceWindAndThunder(8)).FirstOrDefault()), Spell.Cast("Shockwave", on => Unit.UnfriendlyUnits(8).FirstOrDefault(u => Me.IsSafelyFacing(u)), ret => Clusters.GetClusterCount(StyxWoW.Me, Unit.NearbyUnfriendlyUnits, ClusterType.Cone, 10f) >= 3)) ), Spell.BuffSelf("Avatar", ret => WarriorSettings.AvatarOnCooldownSingleTarget), Spell.HandleOffGCD(Spell.Cast("Focused Rage", ret => Me.HasAura(ULTIMATUM_PROC) || Me.RagePercent > 45 && Me.HasAura(FOCUSED_PROC) && !Me.HasAura("Focused Rage") || Me.RagePercent > 90)), Spell.HandleOffGCD(Spell.Cast("Ignore Pain", ret => Me.RagePercent > 70 && Me.HasAura(IGNORE_PROC) || (Me.RagePercent > 40 && Me.HasAura(IGNORE_PROC) && !Me.HasAura("Ignore Pain")) || (Me.RagePercent > 70 && !Me.HasAura("Ignore Pain"))) ), Spell.Cast("Shield Block", ret => Spell.GetCharges("Shield Block") > 1), // Generate Rage SingularRoutine.MoveBehaviorInlineToCombat(BehaviorType.Heal), SingularRoutine.MoveBehaviorInlineToCombat(BehaviorType.CombatBuffs), Movement.WaitForFacing(), Movement.WaitForLineOfSpellSight(), Spell.Cast("Shield Slam", ret => Me.CurrentRage < RageBuild && HasShieldInOffHand), Spell.Cast("Revenge"), // Artifact Weapon new Decorator( ret => WarriorSettings.UseArtifactOnlyInAoE && Clusters.GetConeClusterCount(90f, Unit.UnfriendlyUnits(12), 100f) > 1, new PrioritySelector( Spell.HandleOffGCD(Spell.BuffSelf("Battle Cry", req => true, 0, HasGcd.No)), Spell.Cast("Neltharion's Fury", movement => false, target => Me.CurrentTarget, ret => WarriorSettings.UseDPSArtifactWeaponWhen != UseDPSArtifactWeaponWhen.None) ) ), Spell.HandleOffGCD(Spell.BuffSelf("Battle Cry", req => true, 0, HasGcd.No)), Spell.Cast("Neltharion's Fury", movement => false, target => Me.CurrentTarget, ret => !WarriorSettings.UseArtifactOnlyInAoE && WarriorSettings.UseDPSArtifactWeaponWhen != UseDPSArtifactWeaponWhen.None && Clusters.GetConeClusterCount(90f, Unit.UnfriendlyUnits(12), 100f) >= 1 ), // Filler Spell.Cast("Devastate"), //Charge Common.CreateChargeBehavior(), Common.CreateAttackFlyingOrUnreachableMobs(), new Action(ret => { if (Me.GotTarget() && Me.CurrentTarget.IsWithinMeleeRange && Me.IsSafelyFacing(Me.CurrentTarget)) { Logger.WriteDebug("--- we did nothing!"); } return RunStatus.Failure; }) )); }
public static Composite CreateBeastMasterHunterNormalPullAndCombat() { return(new PrioritySelector( Common.CreateHunterEnsureReadyToAttackFromLongRange(), Spell.WaitForCastOrChannel(), new Decorator( ret => !Spell.IsGlobalCooldown(), new PrioritySelector( SingularRoutine.MoveBehaviorInlineToCombat(BehaviorType.Heal), SingularRoutine.MoveBehaviorInlineToCombat(BehaviorType.CombatBuffs), CreateBeastMasteryDiagnosticOutputBehavior(), Common.CreateMisdirectionBehavior(), Common.CreateHunterAvoidanceBehavior(null, null), Movement.WaitForFacing(), Movement.WaitForLineOfSpellSight(), Helpers.Common.CreateInterruptBehavior(), Common.CreateHunterNormalCrowdControl(), Spell.Buff("Concussive Shot", ret => Me.CurrentTarget.CurrentTargetGuid == Me.Guid && Me.CurrentTarget.Distance > Spell.MeleeRange), // Defensive Stuff Spell.Cast("Intimidation", ret => Me.GotTarget() && Me.CurrentTarget.IsAlive && Me.GotAlivePet && (!Me.CurrentTarget.GotTarget() || Me.CurrentTarget.CurrentTarget == Me)), // Cooldowns - should be used as much as possible. Spell.Cast("Bestial Wrath", ret => Spell.GetSpellCooldown("Kill Command").TotalSeconds < 3), Spell.Cast("Aspect of the Wild", ret => Me.HasAura("Bestial Wrath")), Spell.Cast("A Murder of Crows", ret => Me.CurrentTarget.TimeToDeath(int.MaxValue) < 14), Spell.Cast("Stampede", ret => Me.CurrentTarget.TimeToDeath(int.MaxValue) > 6), new Decorator( ret => Unit.NearbyUnitsInCombatWithUsOrOurStuff.Count() > 1, new PrioritySelector( new Throttle(1, Spell.BuffSelf("Volley")), Spell.Cast("Multi-Shot", ret => Me.GotAlivePet && Me.Pet.GetAuraTimeLeft("Beast Cleave", false).TotalSeconds < 1.5), Spell.Cast("Kill Command"), new Decorator(ret => Spell.GetSpellCooldown("Bestial Wrath").TotalSeconds > 15, new PrioritySelector( Spell.Cast("Dire Beast", ret => !Common.HasTalent(HunterTalents.DireFrenzy)), Spell.Cast("Dire Frenzy", ret => Me.GotAlivePet) )), Spell.Cast("Cobra Shot", ret => Me.CurrentFocus > 90 && Me.GotAlivePet && Me.Pet.GetAuraTimeLeft("Beast Cleave", false).TotalSeconds > 1.5), Spell.Cast("Multi-Shot") )), new Decorator( ret => Me.HasActiveAura("Volley"), new Throttle(1, new Action(ret => Me.CancelAura("Volley")))), Spell.Cast("Kill Command"), Spell.Cast("Chimaera Shot"), Spell.Cast("Dire Beast", ret => Spell.GetSpellCooldown("Bestial Wrath").TotalSeconds > 15), Spell.Cast("Cobra Shot", ret => Me.CurrentFocus > 90) ) ) )); }
public static Composite CreateDispelBehavior() { if (SingularSettings.Instance.DispelDebuffs == RelativePriority.None) { return(new ActionAlwaysFail()); } PrioritySelector prio = new PrioritySelector(); switch (StyxWoW.Me.Class) { case WoWClass.Paladin: prio.AddChild(Spell.Cast("Cleanse", on => _unitDispel)); break; case WoWClass.Monk: prio.AddChild(Spell.Cast("Detox", on => _unitDispel)); break; case WoWClass.Priest: if (TalentManager.CurrentSpec == WoWSpec.PriestHoly || TalentManager.CurrentSpec == WoWSpec.PriestDiscipline) { prio.AddChild(Spell.Cast("Purify", on => _unitDispel)); } break; case WoWClass.Druid: if (TalentManager.CurrentSpec == WoWSpec.DruidRestoration) { prio.AddChild(Spell.Cast("Nature's Cure", on => _unitDispel)); } else { prio.AddChild(Spell.Cast("Remove Corruption", on => _unitDispel)); } break; case WoWClass.Shaman: if (TalentManager.CurrentSpec == WoWSpec.ShamanRestoration) { prio.AddChild(Spell.Cast("Purify Spirit", on => _unitDispel)); } else { prio.AddChild(Spell.Cast("Cleanse Spirit", on => _unitDispel)); } break; case WoWClass.Mage: prio.AddChild(Spell.Cast("Remove Curse", on => _unitDispel)); break; } return(new Decorator( req => SingularRoutine.IsAllowed(Styx.CommonBot.Routines.CapabilityFlags.DefensiveDispel), new Sequence( new Action(r => _unitDispel = HealerManager.Instance.TargetList.FirstOrDefault(u => u.IsAlive && CanDispel(u))), prio ) )); }
/// <summary> /// This behavior SHOULD be called at top of the combat behavior. This behavior won't let the rest of the combat behavior to be called /// if you don't have a target. Also it will find a proper target, if the current target is dead or you don't have a target and still in combat. /// Tank targeting is also dealed in this behavior. /// </summary> /// <returns></returns> public static Composite EnsureTarget() { return (new Decorator( ret => !SingularSettings.DisableAllTargeting, new PrioritySelector( #region Switch from Current Target if a more important one exists! new PrioritySelector( #region Validate our CurrentTarget - ctx set to null if we need a new one, non-null if ok! ctx => { #region Tank Targeting // Handle tank targeting - only if in Combat, otherwise we'll choose based upon Targeting list if (TankManager.NeedTankTargeting && !SingularSettings.Instance.DisableTankTargetSwitching && Group.MeIsTank && StyxWoW.Me.Combat && TankManager.Instance.FirstUnit != null) { if (Me.CurrentTarget != TankManager.Instance.FirstUnit) { if (TankManager.TargetingTimer.IsFinished) { Logger.Write(targetColor, "TankTarget: switching to first unit of TankTargeting"); return TankManager.Instance.FirstUnit; } if (!Unit.ValidUnit(Me.CurrentTarget, showReason: false)) { Logger.Write(targetColor, "TankTarget: CurrentTarget invalid, switching to first unit of TankTargeting"); return TankManager.Instance.FirstUnit; } } return Me.CurrentTarget; // pass our currenttarget to skip setting or switching } #endregion #region WORLD_PVP_FIRST_AND_FOREMOST if (SingularRoutine.CurrentWoWContext == WoWContext.Normal && SingularSettings.Instance.TargetWorldPvpRegardless) { // if on an enemy player, stay there if (Me.GotTarget() && Me.CurrentTarget.IsPlayer && Unit.ValidUnit(Me.CurrentTarget)) { return Me.CurrentTarget; } // if attacked in last 15 seconds, go after them if (EventHandlers.TimeSinceAttackedByEnemyPlayer.TotalSeconds < 15) { WoWUnit ganker = EventHandlers.AttackingEnemyPlayer; if (Unit.ValidUnit(ganker)) { if (!Me.GotTarget() || !Me.CurrentTarget.IsPlayer || !Unit.ValidUnit(Me.CurrentTarget)) { if (ganker != Me.CurrentTarget) { Logger.Write(targetColor, "Switching to Ganker: " + ganker.SafeName() + " who attacked us first!"); Logger.WriteDebug("Setting BotPoi to Kill {0}", ganker.SafeName()); BotPoi.Current = new BotPoi(ganker, PoiType.Kill); } return ganker; } } } } #endregion #region TOTEM KILLER if (SingularRoutine.CurrentWoWContext == WoWContext.Normal && SingularSettings.Instance.TargetCurrentTargetTotems) { if (Me.GotTarget() && !Me.CurrentTarget.IsPlayer && Unit.ValidUnit(Me.CurrentTarget)) { if (Me.CurrentTarget.IsTotem) { if (Me.CurrentTarget.SummonedByUnit != null && !Me.CurrentTarget.SummonedByUnit.IsPlayer) { return Me.CurrentTarget; } } else if ((DateTime.UtcNow - timePrevTotem).TotalSeconds > 15) { float range = Me.IsMelee() ? 15 : 39; WoWUnit totem = ObjectManager.GetObjectsOfType <WoWUnit>(false, false) .FirstOrDefault(t => t.IsTotem && guidPrevTotem != t.Guid && t.SummonedByUnitGuid == Me.CurrentTargetGuid && Unit.ValidUnit(t) && t.SpellDistance() < range); if (totem != null) { guidPrevTotem = totem.Guid; timePrevTotem = DateTime.UtcNow; Logger.Write(targetColor, "Switching to Totem: {0} set by {1}", totem.Name, totem.SummonedUnit.SafeName()); return totem; } } } } #endregion #if ALWAYS_SWITCH_TO_BOTPOI WoWUnit unit; // Check botpoi (our top priority.) we switch to BotPoi if a kill type exists and not blacklisted // .. if blacklisted, clear the poi to give bot a chance to do something smarter // .. if we are already fighting it, we keep fighting it, end of story if (BotPoi.Current.Type == PoiType.Kill) { if (BotPoi.Current.AsObject == null) { Logger.Write(targetColor, "BotPOI is (null) --- clearing"); BotPoi.Clear(string.Format("Singular: (null) object was target (possibly another components error)")); } else { unit = BotPoi.Current.AsObject.ToUnit(); if (unit != null && !unit.IsAlive) { Logger.WriteDiagnostic(targetColor, "BotPOI " + unit.SafeName() + " is dead --- clearing"); BotPoi.Clear(string.Format("Singular: {0} is dead", unit.SafeName())); } else if (!Unit.ValidUnit(unit, showReason: true)) { Logger.Write(targetColor, "BotPOI " + unit.SafeName() + " not valid --- clearing"); BotPoi.Clear(string.Format("Singular: {0} invalid target", unit.SafeName())); } else { if (StyxWoW.Me.CurrentTargetGuid != unit.Guid) { Logger.Write(targetColor, "Switching to BotPoi: " + unit.SafeName() + "!"); } return unit; } } } #endif // Go below if current target is null or dead. We have other checks to deal with that if (!StyxWoW.Me.GotTarget() || StyxWoW.Me.CurrentTarget.IsDead) { return null; } // target not aggroed yet or out of range? check for adds in melee pounding us if (!Me.IsInGroup() && Me.Combat && ((!StyxWoW.Me.CurrentTarget.Combat && !StyxWoW.Me.CurrentTarget.Aggro && !StyxWoW.Me.CurrentTarget.PetAggro) || StyxWoW.Me.SpellDistance() > 30 || !StyxWoW.Me.CurrentTarget.InLineOfSpellSight)) { // Look for agrroed mobs next. prioritize by IsPlayer, Relative Distance, then Health var target = ObjectManager.GetObjectsOfType <WoWUnit>(false, false) .Where( p => p.SpellDistance() < 10 && Unit.ValidUnit(p) && (p.Aggro || p.PetAggro) && p.InLineOfSpellSight ) // .OrderBy(u => CalcDistancePriority(u)).ThenBy(u => u.HealthPercent) .OrderBy(u => u.HealthPercent) .FirstOrDefault(); if (target != null && target.Guid != Me.CurrentTargetGuid) { // Return the closest one to us Logger.Write(targetColor, "Switching to aggroed mob pounding on me " + target.SafeName() + "!"); return target; } } // check if current target is owned by a player WoWUnit pOwner = Unit.GetPlayerParent(Me.CurrentTarget); if (pOwner != null) { if (!Me.CurrentTarget.CanWeAttack()) { Logger.Write(targetColor, "CurrentTarget " + Me.CurrentTarget.SafeName() + " is a non-attackable enemy player pet so clearing target!"); Blacklist.Add(Me.CurrentTargetGuid, BlacklistFlags.Pull | BlacklistFlags.Combat, TimeSpan.FromSeconds(60), "Unattackable Enemy Player Pet is CurrentTarget"); Me.ClearTarget(); return null; } else if (Unit.ValidUnit(pOwner) && !Blacklist.Contains(pOwner, BlacklistFlags.Combat)) { Logger.Write(targetColor, "Current target owned by a player. Switching to " + pOwner.SafeName() + "!"); if (BotPoi.Current.Type == PoiType.Kill && BotPoi.Current.Guid == Me.CurrentTarget.Guid) { BotPoi.Clear(string.Format("Singular detected {0} as Player Owned Pet", Me.CurrentTarget.SafeName())); } return pOwner; } } // no valid BotPoi, so let's check Targeting.FirstUnit which is Bots #1 choice #if IGNORE_TARGETING_UNLESS_SEARCHING_FOR_NEW_TARGET #elif BOT_FIRSTUNIT_GETS_PRIORITY unit = Targeting.Instance.FirstUnit; if (unit != null && unit.IsAlive) { if (Blacklist.Contains(unit.Guid, BlacklistFlags.Combat)) { Logger.Write(targetColor, "Targeting.FirstUnit " + unit.SafeName() + " is blacklisted!"); if (unit == Me.CurrentTarget && (Me.CurrentTarget.Combat && Me.CurrentTarget.IsTargetingMeOrPet)) { return unit; } return null; } if (StyxWoW.Me.CurrentTarget != unit) { Logger.Write(targetColor, "Current target is not Bots first choice. Switching to " + unit.SafeName() + "!"); } return unit; } #else foreach (var unit in Targeting.Instance.TargetList) { if (StyxWoW.Me.CurrentTargetGuid != unit.Guid && unit.IsAlive && !Blacklist.Contains(unit.Guid, BlacklistFlags.Combat)) { Logger.Write(targetColor, "Bot has a higher priority target available. Switching to " + unit.SafeName() + "!"); return unit; } } #endif // at this point, just check its okay to kill currenttarget if (Blacklist.Contains(StyxWoW.Me.CurrentTargetGuid, BlacklistFlags.Combat)) { Logger.Write(targetColor, "CurrentTarget " + Me.CurrentTarget.SafeName() + " blacklisted and not in combat with so clearing target!"); Me.ClearTarget(); return null; } // valid unit? keep it then if (Unit.ValidUnit(Me.CurrentTarget, showReason: true)) { return Me.CurrentTarget; } if (Me.CurrentTarget.IsPlayer && !Battlegrounds.IsInsideBattleground && Me.CurrentTarget.IsHostile && !Me.CurrentTarget.CanWeAttack()) { Logger.Write(targetColor, "CurrentTarget " + Me.CurrentTarget.SafeName() + " is a non-attackable enemy player so clearing target!"); Blacklist.Add(Me.CurrentTargetGuid, BlacklistFlags.Pull | BlacklistFlags.Combat, TimeSpan.FromSeconds(15), "Unattackable Enemy Player is CurrentTarget"); Me.ClearTarget(); } // otherwise, let's get a new one Logger.WriteDebug(targetColor, "EnsureTarget: invalid target {0}, so forcing selection of a new one...", !Me.GotTarget() ? "(null)" : Me.CurrentTarget.SafeName()); return null; }, #endregion #region Target was selected -- change target if needed, or do nothing if already current target new Decorator( ret => ret != null, new Sequence( CreateClearPendingCursorSpell(RunStatus.Success), new Decorator( req => ((WoWUnit)req).Guid != StyxWoW.Me.CurrentTargetGuid, new Sequence( new Action(ret => { if (SingularSettings.Debug) { Logger.WriteDebug(targetColor, "EnsureTarget: switching to target {0}", ((WoWUnit)ret).SafeName()); } }), new Action(ret => ((WoWUnit)ret).Target()), new WaitContinue(2, ret => StyxWoW.Me.GotTarget() && StyxWoW.Me.CurrentTarget == (WoWUnit)ret, new ActionAlwaysSucceed()), new Action(ret => TankManager.TargetingTimer.Reset()) // cheaper to just reset than to check if we need Tank Targeting ) ), // fall through to spell priority at this point as we have our target and its valid new ActionAlwaysFail() ) ), #endregion #endregion #region Target Invalid (none or dead) - Find a New one if possible new Decorator( ret => ret == null, new PrioritySelector( ctx => { // If we have a RaF leader, then use its target. var rafLeader = RaFHelper.Leader; if (rafLeader != null && rafLeader.IsValid && !rafLeader.IsMe && rafLeader.Combat && rafLeader.GotTarget() && rafLeader.CurrentTarget.IsAlive && !Blacklist.Contains(rafLeader.CurrentTarget, BlacklistFlags.Combat)) { Logger.Write(targetColor, "Current target invalid. Switching to Tanks target " + rafLeader.CurrentTarget.SafeName() + "!"); return rafLeader.CurrentTarget; } /* * // if we have BotPoi then try it * if (SingularRoutine.CurrentWoWContext != WoWContext.Normal && BotPoi.Current.Type == PoiType.Kill) * { * var unit = BotPoi.Current.AsObject as WoWUnit; * if (unit == null) * { * Logger.Write(targetColor, "Current Kill POI invalid. Clearing POI!"); * BotPoi.Clear("Singular detected null POI"); * } * else if (!unit.IsAlive) * { * Logger.Write(targetColor, "Current Kill POI dead. Clearing POI " + unit.SafeName() + "!"); * BotPoi.Clear("Singular detected Unit is dead"); * } * else if (Blacklist.Contains(unit, BlacklistFlags.Combat)) * { * Logger.Write(targetColor, "Current Kill POI is blacklisted. Clearing POI " + unit.SafeName() + "!"); * BotPoi.Clear("Singular detected Unit is Blacklisted"); * } * else * { * Logger.Write(targetColor, "Current target invalid. Switching to POI " + unit.SafeName() + "!"); * return unit; * } * } */ // Look for agrroed mobs next. prioritize by IsPlayer, Relative Distance, then Health var target = Targeting.Instance.TargetList .Where( p => !Blacklist.Contains(p, BlacklistFlags.Combat) && Unit.ValidUnit(p) // && p.DistanceSqr <= 40 * 40 // dont restrict check to 40 yds && (p.Aggro || p.PetAggro || (p.Combat && p.GotTarget() && (p.IsTargetingMeOrPet || p.IsTargetingMyRaidMember)))) .OrderBy(u => u.IsPlayer) .ThenBy(u => CalcDistancePriority(u)) .ThenBy(u => u.HealthPercent) .FirstOrDefault(); if (target != null) { // Return the closest one to us Logger.Write(targetColor, "Current target invalid. Switching to aggroed mob " + target.SafeName() + "!"); return target; } /* * // if we have BotPoi then try it * if (SingularRoutine.CurrentWoWContext == WoWContext.Normal && BotPoi.Current.Type == PoiType.Kill) * { * var unit = BotPoi.Current.AsObject as WoWUnit; * if (unit == null) * { * Logger.Write(targetColor, "Current Kill POI invalid. Clearing POI!"); * BotPoi.Clear("Singular detected null POI"); * } * else if (!unit.IsAlive) * { * Logger.Write(targetColor, "Current Kill POI dead. Clearing POI " + unit.SafeName() + "!"); * BotPoi.Clear("Singular detected Unit is dead"); * } * else if (Blacklist.Contains(unit, BlacklistFlags.Combat)) * { * Logger.Write(targetColor, "Current Kill POI is blacklisted. Clearing POI " + unit.SafeName() + "!"); * BotPoi.Clear("Singular detected Unit is Blacklisted"); * } * } */ // now anything in the target list or a Player target = Targeting.Instance.TargetList .Where( p => !Blacklist.Contains(p, BlacklistFlags.Combat) && p.IsAlive // && p.DistanceSqr <= 40 * 40 // don't restrict check to 40 yds ) .OrderBy(u => u.IsPlayer) .ThenBy(u => u.DistanceSqr) .FirstOrDefault(); if (target != null) { // Return the closest one to us Logger.Write(targetColor, "Current target invalid. Switching to TargetList mob " + target.SafeName() + "!"); return target; } /* * // Cache this query, since we'll be using it for 2 checks. No need to re-query it. * var agroMob = * ObjectManager.GetObjectsOfType<WoWUnit>(false, false) * .Where(p => !Blacklist.Contains(p, BlacklistFlags.Combat) && p.IsHostile && !p.IsDead * && !p.Mounted && p.DistanceSqr <= 70 * 70 && p.IsPlayer && p.Combat && (p.IsTargetingMeOrPet || p.IsTargetingMyRaidMember)) * .OrderBy(u => u.DistanceSqr) * .FirstOrDefault(); * * if (agroMob != null) * { * if (!agroMob.IsPet || agroMob.SummonedByUnit == null) * { * Logger.Write(targetColor, "Current target invalid. Switching to player attacking us " + agroMob.SafeName() + "!"); * } * else * { * Logger.Write(targetColor, "Current target invalid. Enemy player pet {0} attacking us, switching to player {1}!", agroMob.SafeName(), agroMob.SummonedByUnit.SafeName()); * agroMob = agroMob.SummonedByUnit; * } * * return agroMob; * } */ // Look for agrroed mobs not in targetlist for some reason next. prioritize by IsPlayer, Relative Distance, then Health target = Unit.UnfriendlyUnits() .Where( p => !Blacklist.Contains(p, BlacklistFlags.Combat) && Unit.ValidUnit(p) // && p.DistanceSqr <= 40 * 40 // dont restrict check to 40 yds && (p.Aggro || p.PetAggro || (p.Combat && p.GotTarget() && (p.IsTargetingMeOrPet || p.IsTargetingMyRaidMember)))) .OrderBy(u => u.IsPlayer) .ThenBy(u => CalcDistancePriority(u)) .ThenBy(u => u.HealthPercent) .FirstOrDefault(); if (target != null) { // Return the closest one to us Logger.Write(targetColor, "Current target invalid. Switching to Unfriendly mob " + target.SafeName() + " attacking us!"); return target; } // And there's nothing left, so just return null, kthx. // ... but show a message about botbase still calling our Combat behavior with nothing to kill if (DateTime.UtcNow >= _timeNextInvalidTargetMessage) { _timeNextInvalidTargetMessage = DateTime.UtcNow + TimeSpan.FromSeconds(5); Logger.Write(targetColor, "Bot TargetList is empty, no targets available"); } return null; }, // Make sure the target is VALID. If not, then ignore this next part. (Resolves some silly issues!) new Decorator( ret => ret != null && ((WoWUnit)ret).Guid != StyxWoW.Me.CurrentTargetGuid, new Sequence( CreateClearPendingCursorSpell(RunStatus.Success), new Action(ret => Logger.WriteDebug(targetColor, "EnsureTarget: set target to chosen target {0}", ((WoWUnit)ret).SafeName())), new Action(ret => ((WoWUnit)ret).Target()), new WaitContinue(2, ret => StyxWoW.Me.GotTarget() && StyxWoW.Me.CurrentTargetGuid == ((WoWUnit)ret).Guid, new ActionAlwaysSucceed()) ) ), // fall through... we'll catch whether we targeted or not in next check new ActionAlwaysFail() ) ) ), #endregion new Decorator( req => !Me.GotTarget() || !Unit.ValidUnit(Me.CurrentTarget), new Action(r => { if (_lastTargetMessageGuid != Me.CurrentTargetGuid || _nextTargetMessageTimer.IsFinished) { Logger.Write(targetColor, "EnsureTarget: no valid target set by " + SingularRoutine.GetBotName() + " -- skipping " + Dynamics.CompositeBuilder.CurrentBehaviorType.ToString() + " spell priority"); _nextTargetMessageTimer.Reset(); } _lastTargetMessageGuid = Me.CurrentTargetGuid; return RunStatus.Success; }) ) ) )); }
public static Composite CreateDeathKnightUnholyCombat() { return(new PrioritySelector( UnholyCastRaiseDead(), Helpers.Common.EnsureReadyToAttackFromMelee(), Spell.WaitForCastOrChannel(), new Decorator( req => !Spell.IsGlobalCooldown(), new PrioritySelector( SingularRoutine.MoveBehaviorInlineToCombat(BehaviorType.Heal), SingularRoutine.MoveBehaviorInlineToCombat(BehaviorType.CombatBuffs), Helpers.Common.CreateInterruptBehavior(), Movement.WaitForFacing(), Movement.WaitForLineOfSpellSight(), Common.CreateDeathKnightPullMore(), Common.CreateDeathGripBehavior(), Common.CreateAntiMagicShellBehavior(), Spell.Cast("Death Strike", ret => (Me.HasActiveAura("Dark Succor") && Me.HealthPercent <= DeathKnightSettings.DeathStrikeSuccorPercent) || Me.HealthPercent <= DeathKnightSettings.DeathStrikePercent ), Spell.Cast("Icebound Fortitude", ret => Me.HealthPercent <= DeathKnightSettings.IceboundFortitudePercent), //Corpse Shield new Decorator( ret => Common.HasTalent(DeathKnightTalents.CorpseShield) && Me.HealthPercent <= DeathKnightSettings.CorpseShieldPercent && Me.GotAlivePet, new PrioritySelector( PetManager.CastAction("Protective Bile", on => Me.Pet), Spell.Cast("Corpse Shield") ) ), // Artifact Weapon new Decorator( ret => DeathKnightSettings.UseArtifactOnlyInAoE && Unit.NearbyUnfriendlyUnits.Count(u => u.IsWithinMeleeRange) > 1, new PrioritySelector( Spell.Cast("Apocalypse", ret => DeathKnightSettings.UseDPSArtifactWeaponWhen != UseDPSArtifactWeaponWhen.None && !DeathKnightSettings.UseArtifactOnlyInAoE && ((DeathKnightSettings.UseDPSArtifactWeaponWhen == UseDPSArtifactWeaponWhen.AtHighestDPSOpportunity && Me.CurrentTarget.GetAuraStacks("Festering Wound") >= 8) || (DeathKnightSettings.UseDPSArtifactWeaponWhen == UseDPSArtifactWeaponWhen.OnCooldown && Me.CurrentTarget.GetAuraStacks("Festering Wound") >= DeathKnightSettings.FesteringWoundsCount) ) ) ) ), Spell.Cast("Apocalypse", ret => DeathKnightSettings.UseDPSArtifactWeaponWhen != UseDPSArtifactWeaponWhen.None && !DeathKnightSettings.UseArtifactOnlyInAoE && ((DeathKnightSettings.UseDPSArtifactWeaponWhen == UseDPSArtifactWeaponWhen.AtHighestDPSOpportunity && Me.CurrentTarget.GetAuraStacks("Festering Wound") >= 8) || (DeathKnightSettings.UseDPSArtifactWeaponWhen == UseDPSArtifactWeaponWhen.OnCooldown && Me.CurrentTarget.GetAuraStacks("Festering Wound") >= DeathKnightSettings.FesteringWoundsCount) ) ), new Decorator( ret => Unit.NearbyUnfriendlyUnits.Count(u => u.IsWithinMeleeRange) >= DeathKnightSettings.DeathAndDecayCount || Common.HasTalent(DeathKnightTalents.Epidemic) && Unit.NearbyUnfriendlyUnits.Count() >= DeathKnightSettings.EpidemicCount, new PrioritySelector( Spell.Cast("Summon Gargoyle", ret => Me.CurrentTarget.IsStressful() && DeathKnightSettings.UseSummonGargoyle), Spell.Cast("Outbreak", ret => Unit.NearbyUnfriendlyUnits.Any(u => u.IsWithinMeleeRange && u.GetAuraTimeLeft("Virulent Plague").TotalSeconds < 1.8)), Spell.BuffSelf("Dark Transformation", ret => Me.GotAlivePet), Spell.CastOnGround("Death and Decay", on => Clusters.GetBestUnitForCluster(Unit.NearbyUnfriendlyUnits, ClusterType.Radius, 8f).Location), Spell.Cast("Scourge Strike"), Spell.Cast("Epidemic", ret => Spell.IsSpellOnCooldown("Death and Decay") || Spell.IsSpellOnCooldown("Defile") || Unit.NearbyUnfriendlyUnits.Count() >= DeathKnightSettings.EpidemicCount && Unit.NearbyUnfriendlyUnits.Count(u => u.IsWithinMeleeRange) < DeathKnightSettings.DeathAndDecayCount), Spell.Cast("Festering Strike", ret => Me.CurrentTarget.GetAuraStacks("Festering Wound") < 5), Spell.Cast("Death Coil", ret => Me.RunicPowerPercent > 90 || Me.HasActiveAura("Sudden Doom")) ) ), new Decorator( ret => Me.Level < 100, CreateLowLevelRotation() ), new Decorator( ret => Common.HasTalent(DeathKnightTalents.DarkArbiter), CreateDarkArbiterRotation() ), new Decorator( ret => Common.HasTalent(DeathKnightTalents.Defile), CreateDefileRotation() ), new Decorator( ret => Common.HasTalent(DeathKnightTalents.SoulReaper), CreateSoulReaperRotation() ) ) ), Movement.CreateMoveToMeleeBehavior(true) )); }
public static Composite CreateFuryCombatNormal() { return(new PrioritySelector( Helpers.Common.EnsureReadyToAttackFromMelee(), Spell.WaitForCast(), Common.CheckIfWeShouldCancelBladestorm(), new Decorator( ret => !Spell.IsGlobalCooldown() && !StyxWoW.Me.HasAura("Bladestorm"), new PrioritySelector( SingularRoutine.MoveBehaviorInlineToCombat(BehaviorType.Heal), SingularRoutine.MoveBehaviorInlineToCombat(BehaviorType.CombatBuffs), CreateDiagnosticOutputBehavior("Combat"), Movement.WaitForFacing(), Movement.WaitForLineOfSpellSight(), // special "in combat" pull logic for mobs not tagged and out of melee range Common.CreateWarriorCombatPullMore(), // Dispel Bubbles new Decorator( ret => StyxWoW.Me.CurrentTarget.IsPlayer && (StyxWoW.Me.CurrentTarget.ActiveAuras.ContainsKey("Ice Block") || StyxWoW.Me.CurrentTarget.ActiveAuras.ContainsKey("Hand of Protection") || StyxWoW.Me.CurrentTarget.ActiveAuras.ContainsKey("Divine Shield")), new PrioritySelector( Spell.WaitForCast(), Movement.CreateEnsureMovementStoppedBehavior(30, on => StyxWoW.Me.CurrentTarget, reason: "for shattering throw"), Spell.Cast("Shattering Throw"), Movement.CreateMoveToUnitBehavior(on => StyxWoW.Me.CurrentTarget, 30f, 25f) ) ), //Heroic Leap Common.CreateHeroicLeapCloser(), new Throttle( TimeSpan.FromSeconds(0.5), new Sequence( new Decorator( ret => Common.IsSlowNeeded(Me.CurrentTarget), new PrioritySelector( Spell.Buff("Piercing Howl", ret => Me.CurrentTarget.SpellDistance().Between(8, 15)), Spell.Buff("Hamstring") ) ), new Wait(TimeSpan.FromMilliseconds(500), until => !Common.IsSlowNeeded(Me.CurrentTarget), new ActionAlwaysSucceed()) ) ), //Interupts Helpers.Common.CreateInterruptBehavior(), Common.CreateSpellReflectBehavior(), // Heal up in melee Common.CreateVictoryRushBehavior(), Common.CreateExecuteOnSuddenDeath(), // AOE // -- check melee dist+3 rather than 8 so works for large hitboxes (8 is range of DR and WW) // Artifact Weapon new Decorator( // Clusters.GetClusterCount(StyxWoW.Me, Unit.NearbyUnfriendlyUnits, ClusterType.Radius, 6f) >= 3, ret => Spell.UseAOE && Unit.NearbyUnfriendlyUnits.Count(u => u.SpellDistance() < Common.DistanceWindAndThunder(8)) >= 3, new PrioritySelector( new Decorator( ret => WarriorSettings.UseArtifactOnlyInAoE, new PrioritySelector( Spell.Cast("Odyn's Fury", ret => WarriorSettings.UseDPSArtifactWeaponWhen != UseDPSArtifactWeaponWhen.None && Me.CurrentTarget.IsWithinMeleeRange) ) ), Spell.BuffSelf("Avatar", ret => WarriorSettings.AvatarOnCooldownAOE), Spell.BuffSelf("Bladestorm"), Spell.Cast("Shockwave"), Spell.Cast("Whirlwind", ret => !Me.HasAura("Meat Cleaver") && Me.CurrentTarget.SpellDistance() < Common.DistanceWindAndThunder(8)), Spell.Cast("Rampage", ret => !Me.HasAura("Enrage")), Spell.Cast("Bloodthirst"), Spell.Cast("Raging Blow", ret => Scenario.MobCount < 3 && Me.HasAura("Raging Blow", 1)), Spell.Cast("Bloodthirst"), Spell.Cast("Whirlwind", ret => Me.CurrentTarget.SpellDistance() < Common.DistanceWindAndThunder(8)), // do some AOE prior to learning BT Spell.Cast("Thunder Clap", req => !SpellManager.HasSpell("Whirlwind")) ) ), // Use the single target rotation! SingleTarget(), // Charge if we can Common.CreateChargeBehavior(), Common.CreateAttackFlyingOrUnreachableMobs() ) ) )); }
public static Composite CreateDemonHunterHavocCombat() { return(new PrioritySelector( new Decorator( ret => DemonHunterSettings.HavocUseSoulFragments && (Me.HealthPercent <= DemonHunterSettings.HavocSoulFragmentHealthPercent || CurrentFury <= DemonHunterSettings.HavocSoulFragmentFuryPercent), Common.CreateCollectFragmentsBehavior(DemonHunterSettings.HavocSoulFragmentRange) ), Helpers.Common.EnsureReadyToAttackFromMelee(), Spell.WaitForCastOrChannel(), new Decorator( req => !Spell.IsGlobalCooldown(), new PrioritySelector( SingularRoutine.MoveBehaviorInlineToCombat(BehaviorType.Heal), SingularRoutine.MoveBehaviorInlineToCombat(BehaviorType.CombatBuffs), Helpers.Common.CreateInterruptBehavior(), Movement.WaitForFacing(), Movement.WaitForLineOfSpellSight(), Common.CreateDemonHunterPullMore(), // Buffs + Mitigation Spell.CastOnGround("Metamorphosis", on => Me.CurrentTarget, ret => Me.HealthPercent <= DemonHunterSettings.HavocMetamorphosisHealthPercent), Spell.BuffSelf("Blur", ret => Me.HealthPercent <= DemonHunterSettings.BlurHealthPercent), Spell.BuffSelf("Darkness", ret => Me.HealthPercent <= DemonHunterSettings.HavocDarknessHealthPercent), Spell.BuffSelf("Chaos Blades", ret => Me.CurrentTarget.IsWithinMeleeRange), // Out of Range Common.CreateThrowGlaiveBehavior(), // Artifact Weapon new Decorator( ret => DemonHunterSettings.UseArtifactOnlyInAoE && Unit.NearbyUnfriendlyUnits.Count(u => u.Distance <= 6) > 1, new PrioritySelector( Spell.Cast("Fury of the Illidari", ret => DemonHunterSettings.UseDPSArtifactWeaponWhen == UseDPSArtifactWeaponWhen.OnCooldown || (DemonHunterSettings.UseDPSArtifactWeaponWhen == UseDPSArtifactWeaponWhen.AtHighestDPSOpportunity && Me.HasActiveAura("Momentum")) ) ) ), Spell.Cast("Fury of the Illidari", ret => !DemonHunterSettings.UseArtifactOnlyInAoE && (DemonHunterSettings.UseDPSArtifactWeaponWhen == UseDPSArtifactWeaponWhen.OnCooldown || (DemonHunterSettings.UseDPSArtifactWeaponWhen == UseDPSArtifactWeaponWhen.AtHighestDPSOpportunity && Me.HasActiveAura("Momentum"))) ), // AoE Rotation new Decorator( ret => Spell.UseAOE && Unit.NearbyUnfriendlyUnits.Count(u => u.MeleeDistance() < 10) > 1, new PrioritySelector( Spell.Cast("Nemesis"), Spell.Cast("Chaos Nova", ret => Common.HasTalent(DemonHunterTalents.UnleashedPower) || Me.HealthPercent <= 75), Spell.Cast("Fel Rush", ret => DemonHunterSettings.DPSWithFelRush && Me.CurrentTarget.Distance <= 15 && Me.IsSafelyFacing(Me.CurrentTarget, 5f) && ((Common.HasTalent(DemonHunterTalents.FelMastery) && CurrentFury <= 70) || (Unit.NearbyUnfriendlyUnits.Count() >= 3 && Spell.GetCharges("Fel Rush") > 1))), Spell.Cast("Vengeful Retreat", ret => DemonHunterSettings.UseVengefulRetreat && Me.CurrentTarget.IsWithinMeleeRange && (Common.HasTalent(DemonHunterTalents.Prepared) || CurrentFury <= 85)), Spell.Cast("Fel Barrage", ret => (Common.HasTalent(DemonHunterTalents.Momentum) && Me.HasActiveAura("Momentum") && Spell.GetCharges("Fel Barrage") >= 4) || (!Common.HasTalent(DemonHunterTalents.Momentum) && Spell.GetCharges("Fel Barrage") >= 4) ), Spell.Cast("Eye Beam", ret => (!Common.HasTalent(DemonHunterTalents.Momentum) || Me.HasActiveAura("Momentum"))), // WaitForFacing will rotate us around for this. Spell.Cast("Chaos Strike", ret => Common.HasTalent(DemonHunterTalents.ChaosCleave) && Unit.NearbyUnfriendlyUnits.Count() <= 3), Spell.Cast("Blade Dance", ret => Unit.UnfriendlyUnits(8).Count() >= 3), Spell.Cast("Throw Glaive", ret => (!Common.HasTalent(DemonHunterTalents.Momentum) && Common.HasTalent(DemonHunterTalents.Bloodlet)) || Me.HasActiveAura("Momentum") ), Spell.Cast("Chaos Strike", ret => CurrentFury >= 70), Spell.Cast("Throw Glaive"), Spell.Cast("Chaos Strike", ret => (!Common.HasTalent(DemonHunterTalents.DemonBlades) && CurrentFury >= 70) || (Common.HasTalent(DemonHunterTalents.DemonBlades) && CurrentFury >= 60) ), Spell.Cast("Demon's Bite", ret => !Common.HasTalent(DemonHunterTalents.DemonBlades)) ) ), // Single Target Rotation Spell.Cast("Vengeful Retreat", ret => DemonHunterSettings.UseVengefulRetreat && Me.CurrentTarget.IsWithinMeleeRange && (CurrentFury <= 85 || Common.HasTalent(DemonHunterTalents.Prepared))), Spell.Cast("Fel Rush", ret => DemonHunterSettings.DPSWithFelRush && Me.CurrentTarget.Distance <= 15 && Me.IsSafelyFacing(Me.CurrentTarget, 5f) && ((Common.HasTalent(DemonHunterTalents.FelMastery) && CurrentFury <= 70) || Common.HasTalent(DemonHunterTalents.Momentum) && !Me.HasActiveAura("Momentum") || Spell.GetCharges("Fel Rush") > 1) ), Spell.Cast("Eye Beam", ret => Common.HasTalent(DemonHunterTalents.Demonic)), Spell.Cast("Fel Eruption"), Spell.Cast("Blade Dance", ret => (!Common.HasTalent(DemonHunterTalents.Momentum) && Common.HasTalent(DemonHunterTalents.FirstBlood)) || Me.HasActiveAura("Momentum") ), Spell.Cast("Felblade", ret => FuryDeficit >= 30), Spell.Cast("Throw Glaive", ret => (!Common.HasTalent(DemonHunterTalents.Momentum) && Common.HasTalent(DemonHunterTalents.Bloodlet)) || Me.HasActiveAura("Momentum") ), Spell.Cast("Fel Barrage", ret => (!Common.HasTalent(DemonHunterTalents.Momentum) && Spell.GetCharges("Fel Barrage") >= 5) || (Me.HasActiveAura("Momentum") && Spell.GetCharges("Fel Barrage") >= 5) ), Spell.Cast("Annihilation", ret => FuryDeficit <= 30), Spell.Cast("Chaos Strike", ret => CurrentFury >= 70), Spell.Cast("Fel Barrage", ret => (!Common.HasTalent(DemonHunterTalents.Momentum) && Spell.GetCharges("Fel Barrage") >= 4) || (Me.HasActiveAura("Momentum") && Spell.GetCharges("Fel Barrage") >= 4) ), Spell.Cast("Demon's Bite", ret => !Common.HasTalent(DemonHunterTalents.DemonBlades)) ) ), Movement.CreateMoveToMeleeBehavior(true) )); }
public static Composite CreateArmsCombatNormal() { return(new PrioritySelector( Helpers.Common.EnsureReadyToAttackFromMelee(), Spell.WaitForCast(), Common.CheckIfWeShouldCancelBladestorm(), new Decorator( ret => !Spell.IsGlobalCooldown(), new PrioritySelector( SingularRoutine.MoveBehaviorInlineToCombat(BehaviorType.Heal), SingularRoutine.MoveBehaviorInlineToCombat(BehaviorType.CombatBuffs), CreateDiagnosticOutputBehavior("Combat"), Movement.WaitForFacing(), Movement.WaitForLineOfSpellSight(), Helpers.Common.CreateInterruptBehavior(), Common.CreateSpellReflectBehavior(), Common.CreateVictoryRushBehavior(), // special "in combat" pull logic for mobs not tagged and out of melee range Common.CreateWarriorCombatPullMore(), Common.CreateExecuteOnSuddenDeath(), CreateArmsAoeCombat(ret => Unit.NearbyUnfriendlyUnits.Count(u => u.SpellDistance() < (Common.DistanceWindAndThunder(8)))), // Noxxic //---------------- new Decorator( ret => Me.GotTarget(), // execute new PrioritySelector( new Decorator( ret => Target.HealthPercent < 20 && Unit.UnfriendlyUnits(8).Count() < 5, new PrioritySelector( Spell.Cast("BladeStorm", ret => Spell.UseAOE && Me.HasAura("Battle Cry") && (NumTier20Pieces >= 4 || StyxWoW.Me.Inventory.Equipped.Head.ItemInfo.Guid == 151823)), Spell.Cast("Colossus Smash", ret => !Me.HasAura("Shattered Defenses") && !Me.HasAura("Battle Cry")), Spell.Cast("Warbreaker", ret => Spell.UseAOE && Spell.GetSpellCooldown("Mortal Strike").TotalSeconds < 1 && !Me.HasAura("Shattered Defenses") && Target.GetAuraByName("Executioner's Precision").stackCount == 2), Spell.Cast("Rend", ret => Spell.UseAOE && DebuffRend < 5 && Spell.GetSpellCooldown("Battle Cry").TotalSeconds < 2 && Spell.GetSpellCooldown("Bladestorm").TotalSeconds < 2), Spell.Cast("Ravager", ret => Spell.UseAOE && Spell.GetSpellCooldown("Battle Cry").TotalSeconds < 1 && DebuffColossusSmash >= 6), Spell.Cast("Mortal Strike", ret => Target.GetAuraByName("Executioner's Precision").stackCount == 2 && Me.HasAura("Shattered Defenses")), Spell.Cast("Execute", ret => !Me.HasAura("Shattered Defenses") || Me.CurrentRage >= 40 || Common.HasTalent(WarriorTalents.Dauntless) && Me.CurrentRage >= 36), Spell.Cast("BladeStorm", ret => Spell.UseAOE && NumTier20Pieces <= 4), new ActionAlwaysFail() ) ), new PrioritySelector( //normal Spell.Cast("Bladestorm", ret => Spell.UseAOE && Me.HasAura("Battle Cry") && (NumTier20Pieces >= 4 || StyxWoW.Me.Inventory.Equipped.Head.ItemInfo.Guid == 151823)), Spell.Cast("Colossus Smash", ret => !Me.HasAura("Shattered Defenses")), Spell.Cast("Warbreaker", ret => Spell.UseAOE && (Common.HasTalent(WarriorTalents.FervorOfBattle) && DebuffColossusSmash < 1) || (!Common.HasTalent(WarriorTalents.FervorOfBattle) && (Me.HasAura("Stone Heart") || CooldownMortalStrike < 1) && !Me.HasAura("Shattered Defenses"))), Spell.Cast("Rend", ret => DebuffRend <= 1 || Spell.UseAOE && DebuffRend < 5 && Spell.GetSpellCooldown("Battle Cry").TotalSeconds < 2 && Spell.GetSpellCooldown("Bladestorm").TotalSeconds < 2), Spell.Cast("Ravager", ret => Spell.UseAOE && Spell.GetSpellCooldown("Battle Cry").TotalSeconds < 1 && (DebuffColossusSmash >= 6)), Spell.Cast("Execute", ret => Me.HasAura("Stone Heart")), Spell.Cast("Mortal Strike", ret => Target.GetAuraByName("Executioner's Precision").stackCount == 0 || Me.HasAura("Shattered Defenses")), Spell.Cast("Rend", ret => Target.GetAuraByName("Rend").TimeLeft() < Target.GetAuraByName("Rend").Duration * .3), Spell.Cast("Whirlwind", ret => Unit.UnfriendlyUnits(8).Count() > 1 || Common.HasTalent(WarriorTalents.FervorOfBattle)), Spell.Cast("Slam", ret => !Common.HasTalent(WarriorTalents.FervorOfBattle) && (Me.CurrentRage >= 52 || !Common.HasTalent(WarriorTalents.Rend) || !Common.HasTalent(WarriorTalents.Ravager))), Spell.Cast("BladeStorm", ret => Spell.UseAOE && NumTier20Pieces <= 4) ) ) ), Common.CreateChargeBehavior(), Common.CreateAttackFlyingOrUnreachableMobs() ) ) )); }
public static Composite CreateShamanEnhancementNormalCombat() { return(new PrioritySelector( Helpers.Common.EnsureReadyToAttackFromMelee(), Spell.WaitForCastOrChannel(), new Decorator( ret => !Spell.IsGlobalCooldown(), new PrioritySelector( SingularRoutine.MoveBehaviorInlineToCombat(BehaviorType.Heal), SingularRoutine.MoveBehaviorInlineToCombat(BehaviorType.CombatBuffs), CreateEnhanceDiagnosticOutputBehavior(), Helpers.Common.CreateInterruptBehavior(), Totems.CreateTotemsBehavior(), Movement.WaitForFacing(), Movement.WaitForLineOfSpellSight(), Spell.BuffSelf("Feral Spirit", ret => !Me.CurrentTarget.IsTrivial() && NeedFeralSpirit), // Artifact Weapon new Decorator( ret => ShamanSettings.UseArtifactOnlyInAoE && Unit.NearbyUnitsInCombatWithMeOrMyStuff.Count() > 1, new PrioritySelector( Spell.Cast("Doom Winds", ret => ShamanSettings.UseDPSArtifactWeaponWhen == UseDPSArtifactWeaponWhen.OnCooldown) ) ), Spell.Cast("Doom Winds", ret => !ShamanSettings.UseArtifactOnlyInAoE && ShamanSettings.UseDPSArtifactWeaponWhen == UseDPSArtifactWeaponWhen.OnCooldown), new Decorator( req => AttackEvenIfGhostWolf, new PrioritySelector( Dispelling.CreatePurgeEnemyBehavior("Purge"), Common.CreateShamanDpsShieldBehavior(), // Spell.BuffSelf("Spiritwalker's Grace", ret => StyxWoW.Me.IsMoving && StyxWoW.Me.Combat), // pull more logic (use instants first, then ranged pulls if possible) Spell.CastOnGround("Lightning Surge Totem", on => Clusters.GetBestUnitForCluster(Unit.NearbyUnfriendlyUnits, ClusterType.Radius, 8f).Location, ret => ShamanSettings.UseLightningSurgeTotem && SingularRoutine.CurrentWoWContext == WoWContext.Normal && Unit.UnfriendlyUnits(8).Count() >= ShamanSettings.LightningSurgeTotemCount), Spell.Cast("Ascendance", req => Me.HealthPercent <= ShamanSettings.AscendanceHealthPercent), Spell.Cast("Lava Lash", req => Me.HasActiveAura("Hot Hand")), Spell.Cast("Windsong"), Spell.Cast("Rockbiter", req => (Common.HasTalent(ShamanTalents.Boulderfist) && !Me.HasActiveAura("Boulderfist")) || (Common.HasTalent(ShamanTalents.Landslide) && !Me.HasActiveAura("Landslide"))), Spell.Cast("Frostbrand", req => Common.HasTalent(ShamanTalents.Hailstorm) && !Me.HasActiveAura("Frostbrand")), Spell.Cast("Boulderfist", req => Me.CurrentMaelstrom < 130 && Spell.GetCharges("Boulderfist") >= 2), Spell.Cast("Flametongue", req => !Me.HasActiveAura("Flametongue")), Spell.Cast("Feral Spirit", ret => NeedFeralSpirit), Spell.Cast("Earthen Spike"), Spell.Cast("Crash Lightning", when => Unit.UnfriendlyUnitsNearTarget(10).Count(u => u.TaggedByMe || !u.TaggedByOther) >= 2), Spell.Cast("Stormstrike"), Spell.Cast("Crash Ligthning", req => Common.HasTalent(ShamanTalents.CrashingStorm)), Spell.Cast("Lava Lash", req => Me.CurrentMaelstrom > 110), Spell.Cast("Sundering", req => SingularRoutine.CurrentWoWContext != WoWContext.Instances), Spell.Cast("Rockbiter"), Spell.Cast("Lightning Bolt", req => !Me.CurrentTarget.IsWithinMeleeRange), // won't happen often, but if at range and no abilities enter ghost wolf CreateInCombatGapCloser() ) ) ) ), Movement.CreateMoveToMeleeBehavior(true) )); }
public static Composite CreatePaladinRetributionNormalPullAndCombat() { return(new PrioritySelector( Helpers.Common.EnsureReadyToAttackFromMelee(), Spell.WaitForCastOrChannel(), new Decorator( ret => !Spell.IsGlobalCooldown() && Me.GotTarget(), new PrioritySelector( SingularRoutine.MoveBehaviorInlineToCombat(BehaviorType.Heal), SingularRoutine.MoveBehaviorInlineToCombat(BehaviorType.CombatBuffs), // aoe count ActionAoeCount(), CreateRetDiagnosticOutputBehavior(), Helpers.Common.CreateInterruptBehavior(), Movement.WaitForFacing(), Movement.WaitForLineOfSpellSight(), Common.CreatePaladinPullMore(), //Survive! Spell.BuffSelf("Word of Glory", req => Me.HealthPercent <= PaladinSettings.SelfWordOfGloryHealth && (SingularRoutine.CurrentWoWContext != WoWContext.Instances || !Me.GroupInfo.IsInParty)), Spell.BuffSelf("Eye for an Eye", req => Me.HealthPercent <= PaladinSettings.EyeForAndEyeHealth), Spell.BuffSelf("Shield of Vengeance", req => Me.HealthPercent <= PaladinSettings.ShieldOfVengeanceHealth), Spell.Cast("Blessing of Freedom", on => Me, ret => Me.HasAuraWithMechanic(WoWSpellMechanic.Rooted, WoWSpellMechanic.Slowed, WoWSpellMechanic.Snared) || Me.HasAuraWithEffect(WoWApplyAuraType.ModRoot, WoWApplyAuraType.ModDecreaseSpeed) && !Me.HasAuraWithMechanic(WoWSpellMechanic.Dazed) ), Spell.BuffSelf("Cleanse Toxins", ret => StyxWoW.Me.GetAllAuras().Any(a => a.Spell.DispelType == WoWDispelType.Disease || a.Spell.DispelType == WoWDispelType.Poison)), //Changed: WoWContext.ALL (was not casting in dungeons) and added Player for BGs Spell.Cast("Hammer of Justice", ret => PaladinSettings.StunMobsWhileSolo || Me.CurrentTarget.IsPlayer), Spell.Cast( "War Stomp", req => PaladinSettings.StunMobsWhileSolo && Me.Race == WoWRace.Tauren && EventHandlers.TimeSinceAttackedByEnemyPlayer.TotalSeconds < 5 && EventHandlers.AttackingEnemyPlayer != null && EventHandlers.AttackingEnemyPlayer.SpellDistance() < 8 ), //7 Blow buffs seperatly. No reason for stacking while grinding. Spell.BuffSelf( "Holy Avenger", req => PaladinSettings.RetAvengAndGoatK && Me.GotTarget() && Me.CurrentTarget.IsWithinMeleeRange && !Me.CurrentTarget.IsTrivial() && (_mobCount > 1 || Me.CurrentTarget.TimeToDeath() > 25) && (!Me.HasAura("Avenging Wrath") && Spell.GetSpellCooldown("Avenging Wrath").TotalSeconds > 1) ), Spell.BuffSelf( "Avenging Wrath", req => PaladinSettings.RetAvengAndGoatK && Me.GotTarget() && Me.CurrentTarget.IsWithinMeleeRange && !Me.CurrentTarget.IsTrivial() && (_mobCount > 1 || Me.CurrentTarget.TimeToDeath() > 25) && (!Me.HasAura("Holy Avenger") && Spell.GetSpellCooldown("Holy Avenger").TotalSeconds > 1) ), Spell.Cast("Execution Sentence", ret => Me.CurrentTarget.TimeToDeath() > 15), Spell.Cast("Holy Prism", on => Group.Tanks.FirstOrDefault(t => t.IsAlive && t.Distance < 40)), // lowbie farming priority new Decorator( ret => _mobCount > 1 && Spell.UseAOE && Me.CurrentTarget.IsTrivial(), new PrioritySelector( // Bobby53: Inq > 5HP DS > Exo > HotR > 3-4HP DS Spell.Cast("Divine Storm", ret => Me.CurrentHolyPower == 5 && Spell.UseAOE), Spell.Cast("Hammer of the Righteous"), Spell.Cast("Divine Storm", ret => Me.CurrentHolyPower >= 3 && Spell.UseAOE) ) ), Common.CreatePaladinBlindingLightBehavior(), // Wake of Ashes notes: UseDPSArtifactWeaponWhen.AtHighestDPSOpportunity would be good if the player has the Ashes to Ashes artifact trait and if the player needs Holy Power. new Decorator( ret => _mobCount >= 3 && Spell.UseAOE && !Me.CurrentTarget.IsPlayer, new PrioritySelector( // was EJ: Inq > 5HP DS > LH > HoW > Exo > HotR > Judge > 3-4HP DS (> SS) // now EJ: Inq > 5HP DS > LH > HoW (> T16 Free DS) > HotR > Judge > Exo > 3-4HP DS (> SS) Spell.Cast("Wake of Ashes", ret => (PaladinSettings.UseDPSArtifactWeaponWhen == UseDPSArtifactWeaponWhen.OnCooldown || (PaladinSettings.UseDPSArtifactWeaponWhen == UseDPSArtifactWeaponWhen.AtHighestDPSOpportunity && Me.CurrentHolyPower <= 1)) && Clusters.GetConeClusterCount(90f, Unit.UnfriendlyUnits(10), 100f) > 1), Spell.Cast("Judgment", ret => Me.CurrentHolyPower >= 3), new Decorator(ret => Common.HasTalent(PaladinTalents.JusticarsVengeance), new PrioritySelector( Spell.Cast("Justicar's Vengeance", ret => Me.HealthPercent <= 50), Spell.Cast("Divine Storm", ret => Spell.UseAOE && Me.HealthPercent > 50 && (Me.CurrentTarget.HasAura(J_DEBUFF) || Me.CurrentHolyPower == 5)) ) ), Spell.Cast("Divine Storm", ret => !Common.HasTalent(PaladinTalents.JusticarsVengeance) && Spell.UseAOE && (Me.CurrentTarget.HasAura(J_DEBUFF) || Me.CurrentHolyPower == 5)), Spell.Cast("Blade of Justice", ret => Me.CurrentHolyPower < 5), Spell.Cast("Consecration", req => Unit.UnfriendlyUnits(8).Any()), Spell.Cast("Holy Wrath", ret => Me.HealthPercent <= 55), Spell.CastOnGround("Light's Hammer", on => Me.CurrentTarget, ret => 2 <= Clusters.GetClusterCount(Me.CurrentTarget, Unit.NearbyUnfriendlyUnits, ClusterType.Radius, 10f)), Spell.Cast("Crusader Strike"), // Can be replaced by Zeal - casts both ways. Movement.CreateMoveToMeleeBehavior(true), new ActionAlwaysSucceed() ) ), //No need to specify Holy Power, bot will cast anyway if it can. Spell.BuffSelf("Divine Steed", req => !Me.Mounted && Me.IsMoving && Me.CurrentTarget.SpellDistance().Between(20, 60)), Spell.Cast("Hand of Hindrance", req => Me.CurrentTarget.SpellDistance().Between(3, 27) && Me.CurrentTarget.IsMovingAway()), Spell.Cast("Wake of Ashes", ret => !PaladinSettings.UseArtifactOnlyInAoE && ((PaladinSettings.UseDPSArtifactWeaponWhen != UseDPSArtifactWeaponWhen.None && PaladinSettings.UseDPSArtifactWeaponWhen != UseDPSArtifactWeaponWhen.AtHighestDPSOpportunity) || (PaladinSettings.UseDPSArtifactWeaponWhen == UseDPSArtifactWeaponWhen.AtHighestDPSOpportunity && Me.CurrentHolyPower <= 1)) && Clusters.GetConeClusterCount(90f, Unit.UnfriendlyUnits(10), 100f) >= 1), Spell.Cast("Judgment", ret => Me.CurrentHolyPower >= 3 || Me.CurrentTarget.Distance > 20d), new Decorator(ret => Common.HasTalent(PaladinTalents.JusticarsVengeance), new PrioritySelector( Spell.Cast("Justicar's Vengeance", ret => Me.HasAura(DP_PROC) && Me.CurrentTarget.HasAura(J_DEBUFF) || Me.HealthPercent <= 50), Spell.Cast("Templar's Verdict", ret => Me.HealthPercent > 50 && (Me.CurrentTarget.HasAura(J_DEBUFF) || Me.CurrentHolyPower == 5)) ) ), Spell.Cast("Templar's Verdict", ret => !Common.HasTalent(PaladinTalents.JusticarsVengeance) && (Me.CurrentTarget.HasAura(J_DEBUFF) || Me.CurrentHolyPower == 5)), Spell.Cast("Blade of Justice", ret => Me.CurrentHolyPower < 5), Spell.Cast("Execution Sentence", when => Me.CurrentTarget.TimeToDeath() > 8), Spell.Cast("Crusader Strike") // Can be replaced by Zeal - casts both ways. ) ), // Move to melee is LAST. Period. Movement.CreateMoveToMeleeBehavior(true) )); }
public static Composite CreateArmsCombatNormal() { return(new PrioritySelector( Helpers.Common.EnsureReadyToAttackFromMelee(), Spell.WaitForCast(), Common.CheckIfWeShouldCancelBladestorm(), new Decorator( ret => !Spell.IsGlobalCooldown(), new PrioritySelector( SingularRoutine.MoveBehaviorInlineToCombat(BehaviorType.Heal), SingularRoutine.MoveBehaviorInlineToCombat(BehaviorType.CombatBuffs), CreateDiagnosticOutputBehavior("Combat"), Movement.WaitForFacing(), Movement.WaitForLineOfSpellSight(), Helpers.Common.CreateInterruptBehavior(), Common.CreateSpellReflectBehavior(), Common.CreateVictoryRushBehavior(), // special "in combat" pull logic for mobs not tagged and out of melee range Common.CreateWarriorCombatPullMore(), Common.CreateExecuteOnSuddenDeath(), new Sequence( new Decorator( req => Common.IsSlowNeeded(Me.CurrentTarget), new PrioritySelector( Spell.Buff("Hamstring") ) ), new Wait(TimeSpan.FromMilliseconds(500), until => !Common.IsSlowNeeded(Me.CurrentTarget), new ActionAlwaysSucceed()) ), CreateArmsAoeCombat(ret => Unit.NearbyUnfriendlyUnits.Count(u => u.SpellDistance() < (Common.DistanceWindAndThunder(8)))), // Noxxic //---------------- new Decorator( ret => Me.GotTarget(), // WarriorSettings.ArmsSpellPriority == WarriorSettings.SpellPriority.Noxxic, new PrioritySelector( Spell.BuffSelf("Avatar", ret => WarriorSettings.AvatarOnCooldownSingleTarget), new Decorator( ret => Spell.UseAOE && Me.GotTarget() && (Me.CurrentTarget.IsPlayer || Me.CurrentTarget.IsBoss()) && Me.CurrentTarget.SpellDistance() < 8, new PrioritySelector( Spell.Cast("Storm Bolt"), Spell.BuffSelf("Bladestorm"), Spell.Cast("Shockwave") ) ), new Decorator( new PrioritySelector( Spell.Cast("Colossus Smash"), // Artifact Weapon new Decorator( ret => WarriorSettings.UseArtifactOnlyInAoE && Unit.UnfriendlyUnits(8).Count() > 1, new PrioritySelector( Spell.Cast("Warbreaker", ret => WarriorSettings.UseDPSArtifactWeaponWhen == UseDPSArtifactWeaponWhen.OnCooldown || (WarriorSettings.UseDPSArtifactWeaponWhen == UseDPSArtifactWeaponWhen.AtHighestDPSOpportunity && !Me.CurrentTarget.HasActiveAura("Colossus Smash")) ) ) ), Spell.Cast("Warbreaker", ret => !WarriorSettings.UseArtifactOnlyInAoE && Me.CurrentTarget.IsWithinMeleeRange && (WarriorSettings.UseDPSArtifactWeaponWhen == UseDPSArtifactWeaponWhen.OnCooldown || (WarriorSettings.UseDPSArtifactWeaponWhen == UseDPSArtifactWeaponWhen.AtHighestDPSOpportunity && !Me.CurrentTarget.HasActiveAura("Colossus Smash"))) ), Spell.Cast("Execute", ret => Me.CurrentTarget.HasAura("Colossus Smash") && Me.CurrentTarget.HealthPercent < 20), Spell.Cast("Overpower"), Spell.Cast("Mortal Strike", ret => Spell.GetSpellCooldown("Colossus Smash") > TimeSpan.FromSeconds(2)), Spell.Cast("Slam"), new ActionAlwaysFail() )), new Decorator( req => Me.CurrentTarget.HasAura("Colossus Smash"), new PrioritySelector( // 1 Execute on cooldown when target is below 20% health. Spell.Cast("Execute", req => Me.CurrentTarget.HealthPercent <= 20), // 2 Mortal Strike on cooldown when target is above 20% health. Spell.Cast("Mortal Strike", req => Me.CurrentTarget.HealthPercent > 20 || Common.HasTalent(WarriorTalents.InForTheKill) && Me.RagePercent < 40), // 3 Whirlwind as a filler ability when target is above 20% health. Spell.Cast("Whirlwind", req => Me.CurrentTarget.HealthPercent > 20 && Me.CurrentTarget.SpellDistance() < Common.DistanceWindAndThunder(8)), // Done here new ActionAlwaysFail() ) ), Spell.Cast("Storm Bolt"), // if we are low-level with low rage regen, do any damage we can new Decorator( req => !SpellManager.HasSpell("Whirlwind"), new PrioritySelector( Spell.Cast("Rend"), Spell.Cast("Thunder Clap", req => Spell.UseAOE && Me.CurrentTarget.SpellDistance() < 8) ) ) ) ), Common.CreateChargeBehavior(), Common.CreateAttackFlyingOrUnreachableMobs() ) ) )); }
private void ConfigurationForm_Load(object sender, EventArgs e) { // lblVersion.Text = string.Format("Version {0}", Assembly.GetExecutingAssembly().GetName().Version); lblVersion.Text = string.Format("Version {0}", SingularRoutine.GetSingularVersion()); lblBuildTime.Text = SingularRoutine.GetSingularBuildTime(); //HealTargeting.Instance.OnTargetListUpdateFinished += new Styx.Logic.TargetListUpdateFinishedDelegate(Instance_OnTargetListUpdateFinished); pgGeneral.SelectedObject = SingularSettings.Instance; tabClass.Text = SingularRoutine.ClassName().Substring(1) + " Specific"; Styx.Helpers.Settings toSelect = null; switch (StyxWoW.Me.Class) { case WoWClass.Warrior: toSelect = SingularSettings.Instance.Warrior(); break; case WoWClass.Paladin: toSelect = SingularSettings.Instance.Paladin(); break; case WoWClass.Hunter: toSelect = SingularSettings.Instance.Hunter(); break; case WoWClass.Rogue: toSelect = SingularSettings.Instance.Rogue(); break; case WoWClass.Priest: toSelect = SingularSettings.Instance.Priest(); break; case WoWClass.DeathKnight: toSelect = SingularSettings.Instance.DeathKnight(); break; case WoWClass.Shaman: toSelect = SingularSettings.Instance.Shaman(); break; case WoWClass.Mage: toSelect = SingularSettings.Instance.Mage(); break; case WoWClass.Warlock: toSelect = SingularSettings.Instance.Warlock(); break; case WoWClass.Druid: toSelect = SingularSettings.Instance.Druid(); break; case WoWClass.Monk: toSelect = SingularSettings.Instance.Monk(); break; case WoWClass.DemonHunter: toSelect = SingularSettings.Instance.DemonHunter(); break; default: break; } if (toSelect != null) { pgClass.SelectedObject = toSelect; } pgHotkeys.SelectedObject = SingularSettings.Instance.Hotkeys(); InitializeDebugOutputDropdown(); chkDebugCasting.Checked = SingularSettings.Instance.EnableDebugSpellCasting; chkShowBehaviorFlags.Checked = SingularSettings.Instance.EnableShowBehaviorFlagChanges; chkDebugTrace.Checked = SingularSettings.Instance.EnableDebugTrace; chkDebugTraceHeal.Checked = SingularSettings.Instance.EnableDebugHealTrace; chkTraceBuffs.Checked = SingularSettings.Instance.EnableDebugTraceBuffPresence; chkDebugLogging_CheckedChanged(this, new EventArgs()); InitializeHealContextDropdown(StyxWoW.Me.Class); InitializeForceBehaviorsDropdown(); Screen screen = Screen.FromHandle(this.Handle); if (this.Left.Between(0, screen.WorkingArea.Width) && this.Top.Between(0, screen.WorkingArea.Height)) { int height = screen.WorkingArea.Height - this.Top; if (height > 200) { this.Height = height; } } if (Logger.LogMarkIndex > 0) { btnLogMark.Text = "LOGMARK! " + Logger.LogMarkIndex; } tabControl1_SelectedIndexChanged(this, new EventArgs()); }
public static Composite CheckThatWeaponIsEquipped() { if (_checkWeapons == null) { _checkWeapons = new ThrottlePasses(60, new Sequence( new DecoratorContinue( ret => !Me.Disarmed && !IsWeapon2H(Me.Inventory.Equipped.MainHand), new Action(ret => Logger.Write(Color.HotPink, "User Error: a {0} requires a Two Handed Weapon equipped to be effective", SingularRoutine.SpecAndClassName())) ), new ActionAlwaysFail() ) ); } return(_checkWeapons); }
public static Composite CreateDeathKnightFrostCombat() { return(new PrioritySelector( Helpers.Common.EnsureReadyToAttackFromMelee(), Spell.WaitForCastOrChannel(), new Decorator( req => !Spell.IsGlobalCooldown(), new PrioritySelector( SingularRoutine.MoveBehaviorInlineToCombat(BehaviorType.Heal), SingularRoutine.MoveBehaviorInlineToCombat(BehaviorType.CombatBuffs), Helpers.Common.CreateInterruptBehavior(), Movement.WaitForFacing(), Movement.WaitForLineOfSpellSight(), Common.CreateDeathKnightPullMore(), Common.CreateDeathGripBehavior(), Common.CreateAntiMagicShellBehavior(), // Cooldowns Spell.BuffSelf("Pillar of Frost", req => Me.GotTarget() && Me.CurrentTarget.IsWithinMeleeRange && Me.CurrentTarget.IsStressful()), Spell.Cast("Empower Rune Weapon", ret => Me.CurrentRunes <= 0 && Common.RunicPowerDeficit >= 35 && (!Common.HasTalent(DeathKnightTalents.BreathOfSindragosa) || Me.HasActiveAura("Breath of Sindragosa"))), Spell.Cast("Death Strike", ret => (Me.HasActiveAura("Dark Succor") && Me.HealthPercent <= DeathKnightSettings.DeathStrikeSuccorPercent) || Me.HealthPercent <= DeathKnightSettings.DeathStrikePercent ), Spell.Cast("Icebound Fortitude", ret => Me.HealthPercent <= DeathKnightSettings.IceboundFortitudePercent), new Decorator(ret => Me.Level < 100, CreateLowLevelRotation() ), new Decorator( ret => Common.HasTalent(DeathKnightTalents.Obliteration), CreateObliterationRotation() ), new Decorator( ret => Common.HasTalent(DeathKnightTalents.BreathOfSindragosa), CreateBreathOfSindragosaRotation() ), new Decorator( ret => Common.HasTalent(DeathKnightTalents.GlacialAdvance), CreateGlacialAdvanceRotation() ) ) ), Movement.CreateMoveToMeleeBehavior(true) )); }
public static bool CanDispel(WoWUnit unit, DispelCapabilities chk) { return(SingularRoutine.IsAllowed(CapabilityFlags.DefensiveDispel) && (chk & GetDispellableTypesOnUnit(unit)) != 0); }