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);
            }
        }
Example #3
0
        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
                              ));
        }
Example #4
0
        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()
                               )
                           )
                       ));
        }
Example #5
0
        public bool IsCombatRoutineMovementAllowed()
        {
            if (AllowMovement != AllowMovementType.Auto)
            {
                return(AllowMovement >= AllowMovementType.ClassSpecificOnly);
            }

            return(!SingularRoutine.IsBotInUse("LazyRaider") || !SingularRoutine.IsBotInUse("Raid Bot") || !SingularRoutine.IsBotInUse("Combat Bot"));
        }
Example #6
0
        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);
        }
Example #7
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()
                           )
                       ));
        }
Example #8
0
        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);
        }
Example #9
0
        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()
                               )
                           )
                       ));
        }
Example #10
0
 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();
         }
     };
 }
Example #11
0
        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()
                                   )
                               )
                           )
                       ));
        }
Example #13
0
        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);
        }
Example #14
0
        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;
            })


                       ));
        }
Example #17
0
        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)
                               )
                           )
                       ));
        }
Example #18
0
        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
                           )
                       ));
        }
Example #19
0
        /// <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;
            })
                             )

                         )
                     ));
        }
Example #20
0
        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)
                       ));
        }
Example #21
0
        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()

                               )
                           )
                       ));
        }
Example #22
0
        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)
                       ));
        }
Example #23
0
        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()
                               )
                           )
                       ));
        }
Example #24
0
        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)
                       ));
        }
Example #26
0
        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()

                               )
                           )
                       ));
        }
Example #27
0
        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());
        }
Example #28
0
 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);
 }
Example #29
0
        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)
                       ));
        }
Example #30
0
 public static bool CanDispel(WoWUnit unit, DispelCapabilities chk)
 {
     return(SingularRoutine.IsAllowed(CapabilityFlags.DefensiveDispel) && (chk & GetDispellableTypesOnUnit(unit)) != 0);
 }