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() ) ) )); }
public static Composite CreateBrewmasterMonkCombat() { TankManager.NeedTankTargeting = (SingularRoutine.CurrentWoWContext == WoWContext.Instances); return(new PrioritySelector( Common.CreateAttackFlyingOrUnreachableMobs(), Helpers.Common.EnsureReadyToAttackFromMelee(), Spell.WaitForCastOrChannel(), new Decorator( req => !Spell.IsGlobalCooldown(), new PrioritySelector( ctx => TankManager.Instance.TargetList.FirstOrDefault(u => u.IsWithinMeleeRange) ?? Me.CurrentTarget, Helpers.Common.CreateInterruptBehavior(), SingularRoutine.MoveBehaviorInlineToCombat(BehaviorType.CombatBuffs), Movement.WaitForFacing(), Movement.WaitForLineOfSpellSight(), new Decorator( ret => SingularRoutine.CurrentWoWContext == WoWContext.Instances && Unit.NearbyUnfriendlyUnits.Count(u => !u.IsBoss) > 2, new PrioritySelector( CreateSummonBlackOxStatueBehavior(on => Me.CurrentTarget), Spell.Cast("Provoke", on => FindStatue(), ret => TankManager.Instance.NeedToTaunt.Count >= 2)) ), // taunt if needed Spell.Cast("Provoke", ret => TankManager.Instance.NeedToTaunt.FirstOrDefault(), ret => SingularSettings.Instance.EnableTaunting), new Decorator(ret => Unit.UnfriendlyUnits(8).Count() >= 2, new PrioritySelector( Spell.CastOnGround("Exploding Keg", on => (WoWUnit)on, ret => Me.CurrentTarget.IsWithinMeleeRange && (Me.HealthPercent <= MonkSettings.ArtifactHealthPercent || Unit.NearbyUnfriendlyUnits.Count(u => !u.IsBoss) > 2)), Spell.Cast("Keg Smash", on => (WoWUnit)on), Spell.Cast("Breath of Fire", on => (WoWUnit)on), Spell.Cast("Blackout Strike", on => (WoWUnit)on, req => Common.HasTalent(MonkTalents.BlackoutCombo)), Spell.Cast("Chi Burst", on => (WoWUnit)on), Spell.Cast("Breath of Fire", on => (WoWUnit)on), Spell.Cast("Rushing Jade Wind", on => (WoWUnit)on), Spell.Cast("Tiger Palm", on => (WoWUnit)on, req => Me.CurrentEnergy >= 65), Spell.Cast("Leg Sweep", on => (WoWUnit)on, ret => ((WoWUnit)ret).IsWithinMeleeRange), Spell.Cast("Blackout Strike", on => (WoWUnit)on) ) ), Spell.Cast("Blackout Strike", on => (WoWUnit)on), Spell.Cast("Tiger Palm", on => (WoWUnit)on, req => Me.CurrentEnergy >= 65), Spell.Cast("Rushing Jade Wind", on => (WoWUnit)on), Spell.Cast("Chi Wave", on => (WoWUnit)on), Spell.Cast("Leg Sweep", on => (WoWUnit)on, ret => ((WoWUnit)ret).IsWithinMeleeRange), Spell.Cast("Breath of Fire", on => (WoWUnit)on, req => (Me.CurrentTarget.IsPlayer || Me.CurrentTarget.IsBoss || Me.CurrentTarget.Elite) && Me.IsSafelyFacing(Me.CurrentTarget, 90f) && Me.CurrentTarget.SpellDistance() < 12), Spell.Cast("Breath of Fire", on => (WoWUnit)on, req => Clusters.GetConeClusterCount(90f, Unit.UnfriendlyUnits(12), 100f) > 1), SingularRoutine.MoveBehaviorInlineToCombat(BehaviorType.Heal), Common.CreateCloseDistanceBehavior() ) ) )); }
public 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() ) )); }
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() ) ) )); }
public static Composite CreateGuardianCombat() { TankManager.NeedTankTargeting = (SingularRoutine.CurrentWoWContext == WoWContext.Instances); return(new PrioritySelector( //Some profiles have problems pulling. Having this here reduces somewhat the delay to enter Bear Form this profiles cause. Common.CastForm(ShapeshiftForm.Bear, req => !Utilities.EventHandlers.IsShapeshiftSuppressed && Me.Shapeshift != ShapeshiftForm.Bear), Helpers.Common.EnsureReadyToAttackFromMelee(), CreateGuardianWildChargeBehavior(), Spell.WaitForCast(), new Decorator( ret => !Spell.IsGlobalCooldown(), new PrioritySelector( ctx => TankManager.Instance.TargetList.FirstOrDefault(u => u.IsWithinMeleeRange) ?? Me.CurrentTarget, SingularRoutine.MoveBehaviorInlineToCombat(BehaviorType.Heal), SingularRoutine.MoveBehaviorInlineToCombat(BehaviorType.CombatBuffs), Helpers.Common.CreateInterruptBehavior(), CreateGuardianTauntBehavior(), Spell.HandleOffGCD(Spell.Cast("Rage of the Sleeper", ret => Settings.UseDPSArtifactWeaponWhen != UseDPSArtifactWeaponWhen.None && Me.HealthPercent <= Settings.ArtifactHealthPercent)), Spell.BuffSelf("Incarnation: Guardian of Ursoc", ret => Me.CurrentRage <= 20), Spell.Cast("Moonfire", on => (WoWUnit)on, ret => Me.HasActiveAura("Galactic Guardian")), // thrash is slightly higher priority when mob count >= 3. Spell.Cast("Thrash", on => (WoWUnit)on, req => Unit.UnitsInCombatWithMe(8).Count() >= 3), Spell.Cast("Mangle", on => (WoWUnit)on), Spell.Cast("Thrash", on => (WoWUnit)on, req => Unit.UnitsInCombatWithMe(8).Any()), Spell.Cast("Moonfire", on => Unit.NearbyUnitsInCombatWithUsOrOurStuff.FirstOrDefault(u => u.GetAuraTimeLeft("Moonfire").TotalSeconds < 2.5)), Spell.Cast("Swipe", on => (WoWUnit)on, req => Unit.UnitsInCombatWithMe(8).Any()), Spell.HandleOffGCD(Spell.Cast("Maul", on => (WoWUnit)on, ret => (!Me.HasActiveAura("Ironfur") && !Me.HasActiveAura("Mark of Ursol") && RageDeficit < 10))), Movement.WaitForFacing(), Movement.WaitForLineOfSpellSight(), CreateGuardianWildChargeBehavior() ) ) )); }
public static Composite CreateProtectionCombat() { TankManager.NeedTankTargeting = SingularRoutine.CurrentWoWContext == WoWContext.Instances; EventHandlers.TrackDamage = true; return(new PrioritySelector( // set context to current target ctx => { if (TankManager.NeedTankTargeting && TankManager.Instance.FirstUnit != null) { return TankManager.Instance.FirstUnit; } return Me.CurrentTarget; }, Helpers.Common.EnsureReadyToAttackFromMelee(), Spell.WaitForCast(), Common.CheckIfWeShouldCancelBladestorm(), new Decorator( ret => !Spell.IsGlobalCooldown(), new PrioritySelector( SingularRoutine.MoveBehaviorInlineToCombat(BehaviorType.Heal), SingularRoutine.MoveBehaviorInlineToCombat(BehaviorType.CombatBuffs), Movement.WaitForFacing(), Movement.WaitForLineOfSpellSight(), new Decorator( req => Me.GotTarget(), CreateProtectionDefensiveCombat() ) ) ) )); }
public static Composite CreateDemonHunterHavocCombat() { return(new PrioritySelector( new Decorator( ret => DemonHunterSettings.HavocUseSoulFragments && (Me.HealthPercent <= DemonHunterSettings.HavocSoulFragmentHealthPercent || CurrentFury <= DemonHunterSettings.HavocSoulFragmentFuryPercent), Common.CreateCollectFragmentsBehavior(DemonHunterSettings.HavocSoulFragmentRange) ), Helpers.Common.EnsureReadyToAttackFromMelee(), Spell.WaitForCastOrChannel(), new Decorator( req => !Spell.IsGlobalCooldown(), new PrioritySelector( SingularRoutine.MoveBehaviorInlineToCombat(BehaviorType.Heal), SingularRoutine.MoveBehaviorInlineToCombat(BehaviorType.CombatBuffs), Helpers.Common.CreateInterruptBehavior(), Movement.WaitForFacing(), Movement.WaitForLineOfSpellSight(), Common.CreateDemonHunterPullMore(), // Buffs + Mitigation Spell.CastOnGround("Metamorphosis", on => Me.CurrentTarget, ret => Me.HealthPercent <= DemonHunterSettings.HavocMetamorphosisHealthPercent), Spell.BuffSelf("Blur", ret => Me.HealthPercent <= DemonHunterSettings.BlurHealthPercent), Spell.BuffSelf("Darkness", ret => Me.HealthPercent <= DemonHunterSettings.HavocDarknessHealthPercent), Spell.BuffSelf("Chaos Blades", ret => Me.CurrentTarget.IsWithinMeleeRange), // Out of Range Common.CreateThrowGlaiveBehavior(), // Artifact Weapon new Decorator( ret => DemonHunterSettings.UseArtifactOnlyInAoE && Unit.NearbyUnfriendlyUnits.Count(u => u.Distance <= 6) > 1, new PrioritySelector( Spell.Cast("Fury of the Illidari", ret => DemonHunterSettings.UseDPSArtifactWeaponWhen == UseDPSArtifactWeaponWhen.OnCooldown || (DemonHunterSettings.UseDPSArtifactWeaponWhen == UseDPSArtifactWeaponWhen.AtHighestDPSOpportunity && Me.HasActiveAura("Momentum")) ) ) ), Spell.Cast("Fury of the Illidari", ret => !DemonHunterSettings.UseArtifactOnlyInAoE && (DemonHunterSettings.UseDPSArtifactWeaponWhen == UseDPSArtifactWeaponWhen.OnCooldown || (DemonHunterSettings.UseDPSArtifactWeaponWhen == UseDPSArtifactWeaponWhen.AtHighestDPSOpportunity && Me.HasActiveAura("Momentum"))) ), // AoE Rotation new Decorator( ret => Spell.UseAOE && Unit.NearbyUnfriendlyUnits.Count(u => u.MeleeDistance() < 10) > 1, new PrioritySelector( Spell.Cast("Nemesis"), Spell.Cast("Chaos Nova", ret => Common.HasTalent(DemonHunterTalents.UnleashedPower) || Me.HealthPercent <= 75), Spell.Cast("Fel Rush", ret => DemonHunterSettings.DPSWithFelRush && Me.CurrentTarget.Distance <= 15 && Me.IsSafelyFacing(Me.CurrentTarget, 5f) && ((Common.HasTalent(DemonHunterTalents.FelMastery) && CurrentFury <= 70) || (Unit.NearbyUnfriendlyUnits.Count() >= 3 && Spell.GetCharges("Fel Rush") > 1))), Spell.Cast("Vengeful Retreat", ret => DemonHunterSettings.UseVengefulRetreat && Me.CurrentTarget.IsWithinMeleeRange && (Common.HasTalent(DemonHunterTalents.Prepared) || CurrentFury <= 85)), Spell.Cast("Fel Barrage", ret => (Common.HasTalent(DemonHunterTalents.Momentum) && Me.HasActiveAura("Momentum") && Spell.GetCharges("Fel Barrage") >= 4) || (!Common.HasTalent(DemonHunterTalents.Momentum) && Spell.GetCharges("Fel Barrage") >= 4) ), Spell.Cast("Eye Beam", ret => (!Common.HasTalent(DemonHunterTalents.Momentum) || Me.HasActiveAura("Momentum"))), // WaitForFacing will rotate us around for this. Spell.Cast("Chaos Strike", ret => Common.HasTalent(DemonHunterTalents.ChaosCleave) && Unit.NearbyUnfriendlyUnits.Count() <= 3), Spell.Cast("Blade Dance", ret => Unit.UnfriendlyUnits(8).Count() >= 3), Spell.Cast("Throw Glaive", ret => (!Common.HasTalent(DemonHunterTalents.Momentum) && Common.HasTalent(DemonHunterTalents.Bloodlet)) || Me.HasActiveAura("Momentum") ), Spell.Cast("Chaos Strike", ret => CurrentFury >= 70), Spell.Cast("Throw Glaive"), Spell.Cast("Chaos Strike", ret => (!Common.HasTalent(DemonHunterTalents.DemonBlades) && CurrentFury >= 70) || (Common.HasTalent(DemonHunterTalents.DemonBlades) && CurrentFury >= 60) ), Spell.Cast("Demon's Bite", ret => !Common.HasTalent(DemonHunterTalents.DemonBlades)) ) ), // Single Target Rotation Spell.Cast("Vengeful Retreat", ret => DemonHunterSettings.UseVengefulRetreat && Me.CurrentTarget.IsWithinMeleeRange && (CurrentFury <= 85 || Common.HasTalent(DemonHunterTalents.Prepared))), Spell.Cast("Fel Rush", ret => DemonHunterSettings.DPSWithFelRush && Me.CurrentTarget.Distance <= 15 && Me.IsSafelyFacing(Me.CurrentTarget, 5f) && ((Common.HasTalent(DemonHunterTalents.FelMastery) && CurrentFury <= 70) || Common.HasTalent(DemonHunterTalents.Momentum) && !Me.HasActiveAura("Momentum") || Spell.GetCharges("Fel Rush") > 1) ), Spell.Cast("Eye Beam", ret => Common.HasTalent(DemonHunterTalents.Demonic)), Spell.Cast("Fel Eruption"), Spell.Cast("Blade Dance", ret => (!Common.HasTalent(DemonHunterTalents.Momentum) && Common.HasTalent(DemonHunterTalents.FirstBlood)) || Me.HasActiveAura("Momentum") ), Spell.Cast("Felblade", ret => FuryDeficit >= 30), Spell.Cast("Throw Glaive", ret => (!Common.HasTalent(DemonHunterTalents.Momentum) && Common.HasTalent(DemonHunterTalents.Bloodlet)) || Me.HasActiveAura("Momentum") ), Spell.Cast("Fel Barrage", ret => (!Common.HasTalent(DemonHunterTalents.Momentum) && Spell.GetCharges("Fel Barrage") >= 5) || (Me.HasActiveAura("Momentum") && Spell.GetCharges("Fel Barrage") >= 5) ), Spell.Cast("Annihilation", ret => FuryDeficit <= 30), Spell.Cast("Chaos Strike", ret => CurrentFury >= 70), Spell.Cast("Fel Barrage", ret => (!Common.HasTalent(DemonHunterTalents.Momentum) && Spell.GetCharges("Fel Barrage") >= 4) || (Me.HasActiveAura("Momentum") && Spell.GetCharges("Fel Barrage") >= 4) ), Spell.Cast("Demon's Bite", ret => !Common.HasTalent(DemonHunterTalents.DemonBlades)) ) ), Movement.CreateMoveToMeleeBehavior(true) )); }
public static Composite CreateFuryCombatNormal() { return(new PrioritySelector( Helpers.Common.EnsureReadyToAttackFromMelee(), Spell.WaitForCast(), Common.CheckIfWeShouldCancelBladestorm(), new Decorator( ret => !Spell.IsGlobalCooldown() && !StyxWoW.Me.HasAura("Bladestorm"), new PrioritySelector( SingularRoutine.MoveBehaviorInlineToCombat(BehaviorType.Heal), SingularRoutine.MoveBehaviorInlineToCombat(BehaviorType.CombatBuffs), CreateDiagnosticOutputBehavior("Combat"), Movement.WaitForFacing(), Movement.WaitForLineOfSpellSight(), // special "in combat" pull logic for mobs not tagged and out of melee range Common.CreateWarriorCombatPullMore(), // Dispel Bubbles new Decorator( ret => StyxWoW.Me.CurrentTarget.IsPlayer && (StyxWoW.Me.CurrentTarget.ActiveAuras.ContainsKey("Ice Block") || StyxWoW.Me.CurrentTarget.ActiveAuras.ContainsKey("Hand of Protection") || StyxWoW.Me.CurrentTarget.ActiveAuras.ContainsKey("Divine Shield")), new PrioritySelector( Spell.WaitForCast(), Movement.CreateEnsureMovementStoppedBehavior(30, on => StyxWoW.Me.CurrentTarget, reason: "for shattering throw"), Spell.Cast("Shattering Throw"), Movement.CreateMoveToUnitBehavior(on => StyxWoW.Me.CurrentTarget, 30f, 25f) ) ), //Heroic Leap Common.CreateHeroicLeapCloser(), new Throttle( TimeSpan.FromSeconds(0.5), new Sequence( new Decorator( ret => Common.IsSlowNeeded(Me.CurrentTarget), new PrioritySelector( Spell.Buff("Piercing Howl", ret => Me.CurrentTarget.SpellDistance().Between(8, 15)), Spell.Buff("Hamstring") ) ), new Wait(TimeSpan.FromMilliseconds(500), until => !Common.IsSlowNeeded(Me.CurrentTarget), new ActionAlwaysSucceed()) ) ), //Interupts Helpers.Common.CreateInterruptBehavior(), Common.CreateSpellReflectBehavior(), // Heal up in melee Common.CreateVictoryRushBehavior(), Common.CreateExecuteOnSuddenDeath(), // AOE // -- check melee dist+3 rather than 8 so works for large hitboxes (8 is range of DR and WW) // Artifact Weapon new Decorator( // Clusters.GetClusterCount(StyxWoW.Me, Unit.NearbyUnfriendlyUnits, ClusterType.Radius, 6f) >= 3, ret => Spell.UseAOE && Unit.NearbyUnfriendlyUnits.Count(u => u.SpellDistance() < Common.DistanceWindAndThunder(8)) >= 3, new PrioritySelector( new Decorator( ret => WarriorSettings.UseArtifactOnlyInAoE, new PrioritySelector( Spell.Cast("Odyn's Fury", ret => WarriorSettings.UseDPSArtifactWeaponWhen != UseDPSArtifactWeaponWhen.None && Me.CurrentTarget.IsWithinMeleeRange) ) ), Spell.BuffSelf("Avatar", ret => WarriorSettings.AvatarOnCooldownAOE), Spell.BuffSelf("Bladestorm"), Spell.Cast("Shockwave"), Spell.Cast("Whirlwind", ret => !Me.HasAura("Meat Cleaver") && Me.CurrentTarget.SpellDistance() < Common.DistanceWindAndThunder(8)), Spell.Cast("Rampage", ret => !Me.HasAura("Enrage")), Spell.Cast("Bloodthirst"), Spell.Cast("Raging Blow", ret => Scenario.MobCount < 3 && Me.HasAura("Raging Blow", 1)), Spell.Cast("Bloodthirst"), Spell.Cast("Whirlwind", ret => Me.CurrentTarget.SpellDistance() < Common.DistanceWindAndThunder(8)), // do some AOE prior to learning BT Spell.Cast("Thunder Clap", req => !SpellManager.HasSpell("Whirlwind")) ) ), // Use the single target rotation! SingleTarget(), // Charge if we can Common.CreateChargeBehavior(), Common.CreateAttackFlyingOrUnreachableMobs() ) ) )); }
public static Composite CreateDeathKnightUnholyCombat() { return(new PrioritySelector( UnholyCastRaiseDead(), Helpers.Common.EnsureReadyToAttackFromMelee(), Spell.WaitForCastOrChannel(), new Decorator( req => !Spell.IsGlobalCooldown(), new PrioritySelector( SingularRoutine.MoveBehaviorInlineToCombat(BehaviorType.Heal), SingularRoutine.MoveBehaviorInlineToCombat(BehaviorType.CombatBuffs), Helpers.Common.CreateInterruptBehavior(), Movement.WaitForFacing(), Movement.WaitForLineOfSpellSight(), Common.CreateDeathKnightPullMore(), Common.CreateDeathGripBehavior(), Common.CreateAntiMagicShellBehavior(), Spell.Cast("Death Strike", ret => (Me.HasActiveAura("Dark Succor") && Me.HealthPercent <= DeathKnightSettings.DeathStrikeSuccorPercent) || Me.HealthPercent <= DeathKnightSettings.DeathStrikePercent ), Spell.Cast("Icebound Fortitude", ret => Me.HealthPercent <= DeathKnightSettings.IceboundFortitudePercent), //Corpse Shield new Decorator( ret => Common.HasTalent(DeathKnightTalents.CorpseShield) && Me.HealthPercent <= DeathKnightSettings.CorpseShieldPercent && Me.GotAlivePet, new PrioritySelector( PetManager.CastAction("Protective Bile", on => Me.Pet), Spell.Cast("Corpse Shield") ) ), // Artifact Weapon new Decorator( ret => DeathKnightSettings.UseArtifactOnlyInAoE && Unit.NearbyUnfriendlyUnits.Count(u => u.IsWithinMeleeRange) > 1, new PrioritySelector( Spell.Cast("Apocalypse", ret => DeathKnightSettings.UseDPSArtifactWeaponWhen != UseDPSArtifactWeaponWhen.None && !DeathKnightSettings.UseArtifactOnlyInAoE && ((DeathKnightSettings.UseDPSArtifactWeaponWhen == UseDPSArtifactWeaponWhen.AtHighestDPSOpportunity && Me.CurrentTarget.GetAuraStacks("Festering Wound") >= 8) || (DeathKnightSettings.UseDPSArtifactWeaponWhen == UseDPSArtifactWeaponWhen.OnCooldown && Me.CurrentTarget.GetAuraStacks("Festering Wound") >= DeathKnightSettings.FesteringWoundsCount) ) ) ) ), Spell.Cast("Apocalypse", ret => DeathKnightSettings.UseDPSArtifactWeaponWhen != UseDPSArtifactWeaponWhen.None && !DeathKnightSettings.UseArtifactOnlyInAoE && ((DeathKnightSettings.UseDPSArtifactWeaponWhen == UseDPSArtifactWeaponWhen.AtHighestDPSOpportunity && Me.CurrentTarget.GetAuraStacks("Festering Wound") >= 8) || (DeathKnightSettings.UseDPSArtifactWeaponWhen == UseDPSArtifactWeaponWhen.OnCooldown && Me.CurrentTarget.GetAuraStacks("Festering Wound") >= DeathKnightSettings.FesteringWoundsCount) ) ), new Decorator( ret => Unit.NearbyUnfriendlyUnits.Count(u => u.IsWithinMeleeRange) >= DeathKnightSettings.DeathAndDecayCount || Common.HasTalent(DeathKnightTalents.Epidemic) && Unit.NearbyUnfriendlyUnits.Count() >= DeathKnightSettings.EpidemicCount, new PrioritySelector( Spell.Cast("Summon Gargoyle", ret => Me.CurrentTarget.IsStressful() && DeathKnightSettings.UseSummonGargoyle), Spell.Cast("Outbreak", ret => Unit.NearbyUnfriendlyUnits.Any(u => u.IsWithinMeleeRange && u.GetAuraTimeLeft("Virulent Plague").TotalSeconds < 1.8)), Spell.BuffSelf("Dark Transformation", ret => Me.GotAlivePet), Spell.CastOnGround("Death and Decay", on => Clusters.GetBestUnitForCluster(Unit.NearbyUnfriendlyUnits, ClusterType.Radius, 8f).Location), Spell.Cast("Scourge Strike"), Spell.Cast("Epidemic", ret => Spell.IsSpellOnCooldown("Death and Decay") || Spell.IsSpellOnCooldown("Defile") || Unit.NearbyUnfriendlyUnits.Count() >= DeathKnightSettings.EpidemicCount && Unit.NearbyUnfriendlyUnits.Count(u => u.IsWithinMeleeRange) < DeathKnightSettings.DeathAndDecayCount), Spell.Cast("Festering Strike", ret => Me.CurrentTarget.GetAuraStacks("Festering Wound") < 5), Spell.Cast("Death Coil", ret => Me.RunicPowerPercent > 90 || Me.HasActiveAura("Sudden Doom")) ) ), new Decorator( ret => Me.Level < 100, CreateLowLevelRotation() ), new Decorator( ret => Common.HasTalent(DeathKnightTalents.DarkArbiter), CreateDarkArbiterRotation() ), new Decorator( ret => Common.HasTalent(DeathKnightTalents.Defile), CreateDefileRotation() ), new Decorator( ret => Common.HasTalent(DeathKnightTalents.SoulReaper), CreateSoulReaperRotation() ) ) ), Movement.CreateMoveToMeleeBehavior(true) )); }
public static Composite 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() ) ) )); }
public static Composite CreatePaladinRetributionNormalPullAndCombat() { return(new PrioritySelector( Helpers.Common.EnsureReadyToAttackFromMelee(), Spell.WaitForCastOrChannel(), new Decorator( ret => !Spell.IsGlobalCooldown() && Me.GotTarget(), new PrioritySelector( SingularRoutine.MoveBehaviorInlineToCombat(BehaviorType.Heal), SingularRoutine.MoveBehaviorInlineToCombat(BehaviorType.CombatBuffs), // aoe count ActionAoeCount(), CreateRetDiagnosticOutputBehavior(), Helpers.Common.CreateInterruptBehavior(), Movement.WaitForFacing(), Movement.WaitForLineOfSpellSight(), Common.CreatePaladinPullMore(), //Survive! Spell.BuffSelf("Word of Glory", req => Me.HealthPercent <= PaladinSettings.SelfWordOfGloryHealth && (SingularRoutine.CurrentWoWContext != WoWContext.Instances || !Me.GroupInfo.IsInParty)), Spell.BuffSelf("Eye for an Eye", req => Me.HealthPercent <= PaladinSettings.EyeForAndEyeHealth), Spell.BuffSelf("Shield of Vengeance", req => Me.HealthPercent <= PaladinSettings.ShieldOfVengeanceHealth), Spell.Cast("Blessing of Freedom", on => Me, ret => Me.HasAuraWithMechanic(WoWSpellMechanic.Rooted, WoWSpellMechanic.Slowed, WoWSpellMechanic.Snared) || Me.HasAuraWithEffect(WoWApplyAuraType.ModRoot, WoWApplyAuraType.ModDecreaseSpeed) && !Me.HasAuraWithMechanic(WoWSpellMechanic.Dazed) ), Spell.BuffSelf("Cleanse Toxins", ret => StyxWoW.Me.GetAllAuras().Any(a => a.Spell.DispelType == WoWDispelType.Disease || a.Spell.DispelType == WoWDispelType.Poison)), //Changed: WoWContext.ALL (was not casting in dungeons) and added Player for BGs Spell.Cast("Hammer of Justice", ret => PaladinSettings.StunMobsWhileSolo || Me.CurrentTarget.IsPlayer), Spell.Cast( "War Stomp", req => PaladinSettings.StunMobsWhileSolo && Me.Race == WoWRace.Tauren && EventHandlers.TimeSinceAttackedByEnemyPlayer.TotalSeconds < 5 && EventHandlers.AttackingEnemyPlayer != null && EventHandlers.AttackingEnemyPlayer.SpellDistance() < 8 ), //7 Blow buffs seperatly. No reason for stacking while grinding. Spell.BuffSelf( "Holy Avenger", req => PaladinSettings.RetAvengAndGoatK && Me.GotTarget() && Me.CurrentTarget.IsWithinMeleeRange && !Me.CurrentTarget.IsTrivial() && (_mobCount > 1 || Me.CurrentTarget.TimeToDeath() > 25) && (!Me.HasAura("Avenging Wrath") && Spell.GetSpellCooldown("Avenging Wrath").TotalSeconds > 1) ), Spell.BuffSelf( "Avenging Wrath", req => PaladinSettings.RetAvengAndGoatK && Me.GotTarget() && Me.CurrentTarget.IsWithinMeleeRange && !Me.CurrentTarget.IsTrivial() && (_mobCount > 1 || Me.CurrentTarget.TimeToDeath() > 25) && (!Me.HasAura("Holy Avenger") && Spell.GetSpellCooldown("Holy Avenger").TotalSeconds > 1) ), Spell.Cast("Execution Sentence", ret => Me.CurrentTarget.TimeToDeath() > 15), Spell.Cast("Holy Prism", on => Group.Tanks.FirstOrDefault(t => t.IsAlive && t.Distance < 40)), // lowbie farming priority new Decorator( ret => _mobCount > 1 && Spell.UseAOE && Me.CurrentTarget.IsTrivial(), new PrioritySelector( // Bobby53: Inq > 5HP DS > Exo > HotR > 3-4HP DS Spell.Cast("Divine Storm", ret => Me.CurrentHolyPower == 5 && Spell.UseAOE), Spell.Cast("Hammer of the Righteous"), Spell.Cast("Divine Storm", ret => Me.CurrentHolyPower >= 3 && Spell.UseAOE) ) ), Common.CreatePaladinBlindingLightBehavior(), // Wake of Ashes notes: UseDPSArtifactWeaponWhen.AtHighestDPSOpportunity would be good if the player has the Ashes to Ashes artifact trait and if the player needs Holy Power. new Decorator( ret => _mobCount >= 3 && Spell.UseAOE && !Me.CurrentTarget.IsPlayer, new PrioritySelector( // was EJ: Inq > 5HP DS > LH > HoW > Exo > HotR > Judge > 3-4HP DS (> SS) // now EJ: Inq > 5HP DS > LH > HoW (> T16 Free DS) > HotR > Judge > Exo > 3-4HP DS (> SS) Spell.Cast("Wake of Ashes", ret => (PaladinSettings.UseDPSArtifactWeaponWhen == UseDPSArtifactWeaponWhen.OnCooldown || (PaladinSettings.UseDPSArtifactWeaponWhen == UseDPSArtifactWeaponWhen.AtHighestDPSOpportunity && Me.CurrentHolyPower <= 1)) && Clusters.GetConeClusterCount(90f, Unit.UnfriendlyUnits(10), 100f) > 1), Spell.Cast("Judgment", ret => Me.CurrentHolyPower >= 3), new Decorator(ret => Common.HasTalent(PaladinTalents.JusticarsVengeance), new PrioritySelector( Spell.Cast("Justicar's Vengeance", ret => Me.HealthPercent <= 50), Spell.Cast("Divine Storm", ret => Spell.UseAOE && Me.HealthPercent > 50 && (Me.CurrentTarget.HasAura(J_DEBUFF) || Me.CurrentHolyPower == 5)) ) ), Spell.Cast("Divine Storm", ret => !Common.HasTalent(PaladinTalents.JusticarsVengeance) && Spell.UseAOE && (Me.CurrentTarget.HasAura(J_DEBUFF) || Me.CurrentHolyPower == 5)), Spell.Cast("Blade of Justice", ret => Me.CurrentHolyPower < 5), Spell.Cast("Consecration", req => Unit.UnfriendlyUnits(8).Any()), Spell.Cast("Holy Wrath", ret => Me.HealthPercent <= 55), Spell.CastOnGround("Light's Hammer", on => Me.CurrentTarget, ret => 2 <= Clusters.GetClusterCount(Me.CurrentTarget, Unit.NearbyUnfriendlyUnits, ClusterType.Radius, 10f)), Spell.Cast("Crusader Strike"), // Can be replaced by Zeal - casts both ways. Movement.CreateMoveToMeleeBehavior(true), new ActionAlwaysSucceed() ) ), //No need to specify Holy Power, bot will cast anyway if it can. Spell.BuffSelf("Divine Steed", req => !Me.Mounted && Me.IsMoving && Me.CurrentTarget.SpellDistance().Between(20, 60)), Spell.Cast("Hand of Hindrance", req => Me.CurrentTarget.SpellDistance().Between(3, 27) && Me.CurrentTarget.IsMovingAway()), Spell.Cast("Wake of Ashes", ret => !PaladinSettings.UseArtifactOnlyInAoE && ((PaladinSettings.UseDPSArtifactWeaponWhen != UseDPSArtifactWeaponWhen.None && PaladinSettings.UseDPSArtifactWeaponWhen != UseDPSArtifactWeaponWhen.AtHighestDPSOpportunity) || (PaladinSettings.UseDPSArtifactWeaponWhen == UseDPSArtifactWeaponWhen.AtHighestDPSOpportunity && Me.CurrentHolyPower <= 1)) && Clusters.GetConeClusterCount(90f, Unit.UnfriendlyUnits(10), 100f) >= 1), Spell.Cast("Judgment", ret => Me.CurrentHolyPower >= 3 || Me.CurrentTarget.Distance > 20d), new Decorator(ret => Common.HasTalent(PaladinTalents.JusticarsVengeance), new PrioritySelector( Spell.Cast("Justicar's Vengeance", ret => Me.HasAura(DP_PROC) && Me.CurrentTarget.HasAura(J_DEBUFF) || Me.HealthPercent <= 50), Spell.Cast("Templar's Verdict", ret => Me.HealthPercent > 50 && (Me.CurrentTarget.HasAura(J_DEBUFF) || Me.CurrentHolyPower == 5)) ) ), Spell.Cast("Templar's Verdict", ret => !Common.HasTalent(PaladinTalents.JusticarsVengeance) && (Me.CurrentTarget.HasAura(J_DEBUFF) || Me.CurrentHolyPower == 5)), Spell.Cast("Blade of Justice", ret => Me.CurrentHolyPower < 5), Spell.Cast("Execution Sentence", when => Me.CurrentTarget.TimeToDeath() > 8), Spell.Cast("Crusader Strike") // Can be replaced by Zeal - casts both ways. ) ), // Move to melee is LAST. Period. Movement.CreateMoveToMeleeBehavior(true) )); }
public static Composite CreateDeathKnightFrostCombat() { return(new PrioritySelector( Helpers.Common.EnsureReadyToAttackFromMelee(), Spell.WaitForCastOrChannel(), new Decorator( req => !Spell.IsGlobalCooldown(), new PrioritySelector( SingularRoutine.MoveBehaviorInlineToCombat(BehaviorType.Heal), SingularRoutine.MoveBehaviorInlineToCombat(BehaviorType.CombatBuffs), Helpers.Common.CreateInterruptBehavior(), Movement.WaitForFacing(), Movement.WaitForLineOfSpellSight(), Common.CreateDeathKnightPullMore(), Common.CreateDeathGripBehavior(), Common.CreateAntiMagicShellBehavior(), // Cooldowns Spell.BuffSelf("Pillar of Frost", req => Me.GotTarget() && Me.CurrentTarget.IsWithinMeleeRange && Me.CurrentTarget.IsStressful()), Spell.Cast("Empower Rune Weapon", ret => Me.CurrentRunes <= 0 && Common.RunicPowerDeficit >= 35 && (!Common.HasTalent(DeathKnightTalents.BreathOfSindragosa) || Me.HasActiveAura("Breath of Sindragosa"))), Spell.Cast("Death Strike", ret => (Me.HasActiveAura("Dark Succor") && Me.HealthPercent <= DeathKnightSettings.DeathStrikeSuccorPercent) || Me.HealthPercent <= DeathKnightSettings.DeathStrikePercent ), Spell.Cast("Icebound Fortitude", ret => Me.HealthPercent <= DeathKnightSettings.IceboundFortitudePercent), new Decorator(ret => Me.Level < 100, CreateLowLevelRotation() ), new Decorator( ret => Common.HasTalent(DeathKnightTalents.Obliteration), CreateObliterationRotation() ), new Decorator( ret => Common.HasTalent(DeathKnightTalents.BreathOfSindragosa), CreateBreathOfSindragosaRotation() ), new Decorator( ret => Common.HasTalent(DeathKnightTalents.GlacialAdvance), CreateGlacialAdvanceRotation() ) ) ), Movement.CreateMoveToMeleeBehavior(true) )); }
public static 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 CreatePriestShadowNormalCombat() { return(new PrioritySelector( Helpers.Common.EnsureReadyToAttackFromLongRange(), Spell.WaitForCastOrChannel(), CreateFightAssessment(), new Decorator( ret => !Spell.IsGlobalCooldown(), new PrioritySelector( SingularRoutine.MoveBehaviorInlineToCombat(BehaviorType.Heal), SingularRoutine.MoveBehaviorInlineToCombat(BehaviorType.CombatBuffs), Helpers.Common.CreateInterruptBehavior(), Movement.WaitForFacing(), Movement.WaitForLineOfSpellSight(), new Decorator( req => !Me.CurrentTarget.IsTrivial(), new PrioritySelector( Dispelling.CreatePurgeEnemyBehavior("Dispel Magic"), // Mana Management stuff - send in the fiends Common.CreateShadowfiendBehavior(), // Defensive stuff Spell.BuffSelf("Dispersion", ret => Me.ManaPercent < PriestSettings.DispersionMana || Me.HealthPercent < 40 || (Me.ManaPercent < SingularSettings.Instance.MinMana && Me.IsSwimming) || Unit.NearbyUnfriendlyUnits.Count(t => t.GotTarget() && t.CurrentTarget.IsTargetingMyStuff()) >= 3), Common.CreatePriestShackleUndeadAddBehavior(), Common.CreatePsychicScreamBehavior(), Spell.HandleOffGCD( new PrioritySelector( ctx => Me.CurrentTarget.TimeToDeath() > 15 || cntAoeTargets > 1, new Sequence( Spell.BuffSelfAndWait(sp => "Vampiric Embrace", req => ((bool)req) && Me.HealthPercent < PriestSettings.VampiricEmbracePct), Spell.BuffSelf("Power Infusion") ), Spell.Cast("Power Infusion", req => ((bool)req) || Me.HasAura("Vampiric Embrace")) ) ) ) ), // Shadow immune npcs. // Spell.Cast("Holy Fire", req => Me.CurrentTarget.IsImmune(WoWSpellSchool.Shadow)), // AoE Rotation new Decorator( ret => Spell.UseAOE && cntAoeTargets > 1, new PrioritySelector( ctx => AoeTargets.FirstOrDefault(u => Me.IsSafelyFacing(u) && u.InLineOfSpellSight), Spell.Cast("Void Eruption", when => !InVoidform), Spell.Cast( "Mind Sear", mov => true, on => { IEnumerable <WoWUnit> aoeTargetsFacing = AoeTargets.Where(u => Me.IsSafelyFacing(u) && u.InLineOfSpellSight && u.IsTrivial()); WoWUnit unit = Clusters.GetBestUnitForCluster(aoeTargetsFacing, ClusterType.Radius, 10); if (unit == null) { return null; } if (3 > Clusters.GetClusterCount(unit, AoeTargets, ClusterType.Radius, 10)) { return null; } if (Unit.UnfriendlyUnits(50).Any(u => !u.IsTrivial() && unit.SpellDistance(u) < 12)) { return null; } Logger.Write(LogColor.Hilite, "^Trivial Farming: all trivial mobs within 12 yds of {0}", unit.SafeName()); return unit; }, cancel => Me.HealthPercent < PriestSettings.ShadowHeal ), Spell.Buff("Shadow Word: Pain", true), // no multi message for current target Spell.Buff("Vampiric Touch", true), // no multi message for current target Spell.Buff( // multi-dot others w/ message "Vampiric Touch", true, on => { WoWUnit dotTarget = AoeTargets.FirstOrDefault(u => u != Me.CurrentTarget && !u.HasMyAura("Vampiric Touch") && u.InLineOfSpellSight && !Spell.DoubleCastContains(u, "Vampiric Touch")); if (dotTarget != null && Spell.CanCastHack("Vampiric Touch", dotTarget)) { Logger.Write(LogColor.Hilite, "^Multi-DoT: cast Vampiric Touch on {0}", dotTarget.SafeName()); return dotTarget; } return null; }, req => true ), Spell.Buff( // multi-dot others w/ message "Shadow Word: Pain", true, on => { WoWUnit dotTarget = AoeTargets.FirstOrDefault(u => u != Me.CurrentTarget && !u.HasMyAura("Shadow Word: Pain") && u.InLineOfSpellSight && !Spell.DoubleCastContains(u, "Shadow Word: Pain")); if (dotTarget != null && Spell.CanCastHack("Shadow Word: Pain", dotTarget)) { Logger.Write(LogColor.Hilite, "^Multi-DoT: cast Shadow Word: Pain on {0}", dotTarget.SafeName()); return dotTarget; } return null; }, req => true ), // When we enter void form, even if AOE, we use our single target rotation after maintaining debuffs. new Decorator(ret => InVoidform, CreateMaintainVoidformBehaviour()), // filler spell Spell.Cast( "Mind Sear", mov => true, on => { IEnumerable <WoWUnit> AoeTargetsFacing = AoeTargets.Where(u => Me.IsSafelyFacing(u) && u.InLineOfSpellSight); WoWUnit unit = Clusters.GetBestUnitForCluster(AoeTargetsFacing, ClusterType.Radius, 10); if (unit == null) { return null; } if (4 > Clusters.GetClusterCount(unit, AoeTargets, ClusterType.Radius, 10)) { return null; } return unit; }, cancel => Me.HealthPercent < PriestSettings.ShadowHeal ), CastMindFlay(on => (WoWUnit)on, req => cntAoeTargets < 4) ) ), new Decorator(ret => InVoidform, CreateMaintainVoidformBehaviour()), CreateBuildVoidformBehaviour() ) ) )); }
private static Composite CreateProtectionDefensiveCombat() { return(new PrioritySelector( CreateProtectionDiagnosticOutput(), Common.CreateVictoryRushBehavior(), new Decorator( ret => SingularSettings.Instance.EnableTaunting && SingularRoutine.CurrentWoWContext == WoWContext.Instances, CreateProtectionTauntBehavior() ), new Sequence( new Decorator( ret => Common.IsSlowNeeded(Me.CurrentTarget), new PrioritySelector( Spell.Buff("Hamstring") ) ), new Wait(TimeSpan.FromMilliseconds(500), until => !Common.IsSlowNeeded(Me.CurrentTarget), new ActionAlwaysSucceed()) ), CreateProtectionInterrupt(), Common.CreateSpellReflectBehavior(), // special "in combat" pull logic for mobs not tagged and out of melee range Common.CreateWarriorCombatPullMore(), // Multi-target? get the debuff on them new Decorator( ret => Unit.NearbyUnitsInCombatWithMeOrMyStuff.Count() > 1, new PrioritySelector( Spell.BuffSelf("Avatar", ret => WarriorSettings.AvatarOnCooldownAOE), Spell.Cast("Thunder Clap", on => Unit.UnfriendlyUnits(Common.DistanceWindAndThunder(8)).FirstOrDefault()), Spell.Cast("Shockwave", on => Unit.UnfriendlyUnits(8).FirstOrDefault(u => Me.IsSafelyFacing(u)), ret => Clusters.GetClusterCount(StyxWoW.Me, Unit.NearbyUnfriendlyUnits, ClusterType.Cone, 10f) >= 3)) ), Spell.BuffSelf("Avatar", ret => WarriorSettings.AvatarOnCooldownSingleTarget), Spell.HandleOffGCD(Spell.Cast("Focused Rage", ret => Me.HasAura(ULTIMATUM_PROC) || Me.RagePercent > 45 && Me.HasAura(FOCUSED_PROC) && !Me.HasAura("Focused Rage") || Me.RagePercent > 90)), Spell.HandleOffGCD(Spell.Cast("Ignore Pain", ret => Me.RagePercent > 70 && Me.HasAura(IGNORE_PROC) || (Me.RagePercent > 40 && Me.HasAura(IGNORE_PROC) && !Me.HasAura("Ignore Pain")) || (Me.RagePercent > 70 && !Me.HasAura("Ignore Pain"))) ), Spell.Cast("Shield Block", ret => Spell.GetCharges("Shield Block") > 1), // Generate Rage SingularRoutine.MoveBehaviorInlineToCombat(BehaviorType.Heal), SingularRoutine.MoveBehaviorInlineToCombat(BehaviorType.CombatBuffs), Movement.WaitForFacing(), Movement.WaitForLineOfSpellSight(), Spell.Cast("Shield Slam", ret => Me.CurrentRage < RageBuild && HasShieldInOffHand), Spell.Cast("Revenge"), // Artifact Weapon new Decorator( ret => WarriorSettings.UseArtifactOnlyInAoE && Clusters.GetConeClusterCount(90f, Unit.UnfriendlyUnits(12), 100f) > 1, new PrioritySelector( Spell.HandleOffGCD(Spell.BuffSelf("Battle Cry", req => true, 0, HasGcd.No)), Spell.Cast("Neltharion's Fury", movement => false, target => Me.CurrentTarget, ret => WarriorSettings.UseDPSArtifactWeaponWhen != UseDPSArtifactWeaponWhen.None) ) ), Spell.HandleOffGCD(Spell.BuffSelf("Battle Cry", req => true, 0, HasGcd.No)), Spell.Cast("Neltharion's Fury", movement => false, target => Me.CurrentTarget, ret => !WarriorSettings.UseArtifactOnlyInAoE && WarriorSettings.UseDPSArtifactWeaponWhen != UseDPSArtifactWeaponWhen.None && Clusters.GetConeClusterCount(90f, Unit.UnfriendlyUnits(12), 100f) >= 1 ), // Filler Spell.Cast("Devastate"), //Charge Common.CreateChargeBehavior(), Common.CreateAttackFlyingOrUnreachableMobs(), new Action(ret => { if (Me.GotTarget() && Me.CurrentTarget.IsWithinMeleeRange && Me.IsSafelyFacing(Me.CurrentTarget)) { Logger.WriteDebug("--- we did nothing!"); } return RunStatus.Failure; }) )); }
public static Composite 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 CreateBeastMasterHunterNormalPullAndCombat() { return(new PrioritySelector( Common.CreateHunterEnsureReadyToAttackFromLongRange(), Spell.WaitForCastOrChannel(), new Decorator( ret => !Spell.IsGlobalCooldown(), new PrioritySelector( SingularRoutine.MoveBehaviorInlineToCombat(BehaviorType.Heal), SingularRoutine.MoveBehaviorInlineToCombat(BehaviorType.CombatBuffs), CreateBeastMasteryDiagnosticOutputBehavior(), Common.CreateMisdirectionBehavior(), Common.CreateHunterAvoidanceBehavior(null, null), Movement.WaitForFacing(), Movement.WaitForLineOfSpellSight(), Helpers.Common.CreateInterruptBehavior(), Common.CreateHunterNormalCrowdControl(), Spell.Buff("Concussive Shot", ret => Me.CurrentTarget.CurrentTargetGuid == Me.Guid && Me.CurrentTarget.Distance > Spell.MeleeRange), // Defensive Stuff Spell.Cast("Intimidation", ret => Me.GotTarget() && Me.CurrentTarget.IsAlive && Me.GotAlivePet && (!Me.CurrentTarget.GotTarget() || Me.CurrentTarget.CurrentTarget == Me)), // Cooldowns - should be used as much as possible. Spell.Cast("Bestial Wrath", ret => Spell.GetSpellCooldown("Kill Command").TotalSeconds < 3), Spell.Cast("Aspect of the Wild", ret => Me.HasAura("Bestial Wrath")), Spell.Cast("A Murder of Crows", ret => Me.CurrentTarget.TimeToDeath(int.MaxValue) < 14), Spell.Cast("Stampede", ret => Me.CurrentTarget.TimeToDeath(int.MaxValue) > 6), new Decorator( ret => Unit.NearbyUnitsInCombatWithUsOrOurStuff.Count() > 1, new PrioritySelector( new Throttle(1, Spell.BuffSelf("Volley")), Spell.Cast("Multi-Shot", ret => Me.GotAlivePet && Me.Pet.GetAuraTimeLeft("Beast Cleave", false).TotalSeconds < 1.5), Spell.Cast("Kill Command"), new Decorator(ret => Spell.GetSpellCooldown("Bestial Wrath").TotalSeconds > 15, new PrioritySelector( Spell.Cast("Dire Beast", ret => !Common.HasTalent(HunterTalents.DireFrenzy)), Spell.Cast("Dire Frenzy", ret => Me.GotAlivePet) )), Spell.Cast("Cobra Shot", ret => Me.CurrentFocus > 90 && Me.GotAlivePet && Me.Pet.GetAuraTimeLeft("Beast Cleave", false).TotalSeconds > 1.5), Spell.Cast("Multi-Shot") )), new Decorator( ret => Me.HasActiveAura("Volley"), new Throttle(1, new Action(ret => Me.CancelAura("Volley")))), Spell.Cast("Kill Command"), Spell.Cast("Chimaera Shot"), Spell.Cast("Dire Beast", ret => Spell.GetSpellCooldown("Bestial Wrath").TotalSeconds > 15), Spell.Cast("Cobra Shot", ret => Me.CurrentFocus > 90) ) ) )); }
public static Composite CreateArmsCombatNormal() { return(new PrioritySelector( Helpers.Common.EnsureReadyToAttackFromMelee(), Spell.WaitForCast(), Common.CheckIfWeShouldCancelBladestorm(), new Decorator( ret => !Spell.IsGlobalCooldown(), new PrioritySelector( SingularRoutine.MoveBehaviorInlineToCombat(BehaviorType.Heal), SingularRoutine.MoveBehaviorInlineToCombat(BehaviorType.CombatBuffs), CreateDiagnosticOutputBehavior("Combat"), Movement.WaitForFacing(), Movement.WaitForLineOfSpellSight(), Helpers.Common.CreateInterruptBehavior(), Common.CreateSpellReflectBehavior(), Common.CreateVictoryRushBehavior(), // special "in combat" pull logic for mobs not tagged and out of melee range Common.CreateWarriorCombatPullMore(), Common.CreateExecuteOnSuddenDeath(), CreateArmsAoeCombat(ret => Unit.NearbyUnfriendlyUnits.Count(u => u.SpellDistance() < (Common.DistanceWindAndThunder(8)))), // Noxxic //---------------- new Decorator( ret => Me.GotTarget(), // execute new PrioritySelector( new Decorator( ret => Target.HealthPercent < 20 && Unit.UnfriendlyUnits(8).Count() < 5, new PrioritySelector( Spell.Cast("BladeStorm", ret => Spell.UseAOE && Me.HasAura("Battle Cry") && (NumTier20Pieces >= 4 || StyxWoW.Me.Inventory.Equipped.Head.ItemInfo.Guid == 151823)), Spell.Cast("Colossus Smash", ret => !Me.HasAura("Shattered Defenses") && !Me.HasAura("Battle Cry")), Spell.Cast("Warbreaker", ret => Spell.UseAOE && Spell.GetSpellCooldown("Mortal Strike").TotalSeconds < 1 && !Me.HasAura("Shattered Defenses") && Target.GetAuraByName("Executioner's Precision").stackCount == 2), Spell.Cast("Rend", ret => Spell.UseAOE && DebuffRend < 5 && Spell.GetSpellCooldown("Battle Cry").TotalSeconds < 2 && Spell.GetSpellCooldown("Bladestorm").TotalSeconds < 2), Spell.Cast("Ravager", ret => Spell.UseAOE && Spell.GetSpellCooldown("Battle Cry").TotalSeconds < 1 && DebuffColossusSmash >= 6), Spell.Cast("Mortal Strike", ret => Target.GetAuraByName("Executioner's Precision").stackCount == 2 && Me.HasAura("Shattered Defenses")), Spell.Cast("Execute", ret => !Me.HasAura("Shattered Defenses") || Me.CurrentRage >= 40 || Common.HasTalent(WarriorTalents.Dauntless) && Me.CurrentRage >= 36), Spell.Cast("BladeStorm", ret => Spell.UseAOE && NumTier20Pieces <= 4), new ActionAlwaysFail() ) ), new PrioritySelector( //normal Spell.Cast("Bladestorm", ret => Spell.UseAOE && Me.HasAura("Battle Cry") && (NumTier20Pieces >= 4 || StyxWoW.Me.Inventory.Equipped.Head.ItemInfo.Guid == 151823)), Spell.Cast("Colossus Smash", ret => !Me.HasAura("Shattered Defenses")), Spell.Cast("Warbreaker", ret => Spell.UseAOE && (Common.HasTalent(WarriorTalents.FervorOfBattle) && DebuffColossusSmash < 1) || (!Common.HasTalent(WarriorTalents.FervorOfBattle) && (Me.HasAura("Stone Heart") || CooldownMortalStrike < 1) && !Me.HasAura("Shattered Defenses"))), Spell.Cast("Rend", ret => DebuffRend <= 1 || Spell.UseAOE && DebuffRend < 5 && Spell.GetSpellCooldown("Battle Cry").TotalSeconds < 2 && Spell.GetSpellCooldown("Bladestorm").TotalSeconds < 2), Spell.Cast("Ravager", ret => Spell.UseAOE && Spell.GetSpellCooldown("Battle Cry").TotalSeconds < 1 && (DebuffColossusSmash >= 6)), Spell.Cast("Execute", ret => Me.HasAura("Stone Heart")), Spell.Cast("Mortal Strike", ret => Target.GetAuraByName("Executioner's Precision").stackCount == 0 || Me.HasAura("Shattered Defenses")), Spell.Cast("Rend", ret => Target.GetAuraByName("Rend").TimeLeft() < Target.GetAuraByName("Rend").Duration * .3), Spell.Cast("Whirlwind", ret => Unit.UnfriendlyUnits(8).Count() > 1 || Common.HasTalent(WarriorTalents.FervorOfBattle)), Spell.Cast("Slam", ret => !Common.HasTalent(WarriorTalents.FervorOfBattle) && (Me.CurrentRage >= 52 || !Common.HasTalent(WarriorTalents.Rend) || !Common.HasTalent(WarriorTalents.Ravager))), Spell.Cast("BladeStorm", ret => Spell.UseAOE && NumTier20Pieces <= 4) ) ) ), Common.CreateChargeBehavior(), Common.CreateAttackFlyingOrUnreachableMobs() ) ) )); }
public static Composite CreateProtectionCombat() { TankManager.NeedTankTargeting = (SingularRoutine.CurrentWoWContext == WoWContext.Instances); return(new PrioritySelector( Helpers.Common.EnsureReadyToAttackFromMelee(), Spell.WaitForCastOrChannel(), new Decorator( ret => !Spell.IsGlobalCooldown(), new PrioritySelector( SingularRoutine.MoveBehaviorInlineToCombat(BehaviorType.Heal), SingularRoutine.MoveBehaviorInlineToCombat(BehaviorType.CombatBuffs), new Action(r => { // Paladin AOE count should be those near paladin (consecrate, holy wrath) and those near target (avenger's shield) _aoeCount = TankManager.Instance.TargetList.Count( u => u.SpellDistance() < 10 || u.Location.Distance(Me.CurrentTarget.Location) < 10); return RunStatus.Failure; }), CreateProtDiagnosticOutputBehavior(), Helpers.Common.CreateInterruptBehavior(), Movement.WaitForFacing(), Movement.WaitForLineOfSpellSight(), Common.CreatePaladinPullMore(), Common.CreatePaladinBlindingLightBehavior(), // Taunts - if reckoning on cooldown, throw some damage at them new Decorator( ret => SingularSettings.Instance.EnableTaunting && TankManager.Instance.NeedToTaunt.Any() && TankManager.Instance.NeedToTaunt.FirstOrDefault().InLineOfSpellSight, new Throttle(TimeSpan.FromMilliseconds(1500), new PrioritySelector( ctx => TankManager.Instance.NeedToTaunt.FirstOrDefault(e => e.SpellDistance() < 30), Spell.Cast("Reckoning", ctx => (WoWUnit)ctx), Spell.Cast("Avenger's Shield", ctx => (WoWUnit)ctx, req => Spell.UseAOE), Spell.Cast("Judgment", ctx => (WoWUnit)ctx) ) ) ), // Soloing move - open with stun to reduce incoming damage (best to take Fist of Justice talent if doing this Spell.Cast("Hammer of Justice", ret => PaladinSettings.StunMobsWhileSolo && SingularRoutine.CurrentWoWContext == WoWContext.Normal), //Multi target new Decorator( ret => _aoeCount >= 3 && Spell.UseAOE, new PrioritySelector( Spell.Cast("Avenger's Shield"), Spell.Cast("Consecration", req => Unit.UnfriendlyUnits(8).Any()), Spell.Cast("Blessed Hammer"), Spell.Cast("Judgment"), Movement.CreateMoveToMeleeBehavior(true) ) ), Spell.Cast("Blessed Hammer"), //Single target // The buff below gives us a 20% damage reduction if we have KnightTemplar talent. // However, something is removing the buff as soon as its cast as it believes the player is using a mount. // Spell.BuffSelf("Divine Steed", req => Common.HasTalent(PaladinTalents.KnightTemplar)), Spell.HandleOffGCD(Spell.Cast("Shield of the Righteous", req => !Me.HasAura(ShieldOfTheRighteous))), Spell.HandleOffGCD(Spell.Cast("Light of the Protector", req => Me.HealthPercent <= 85)), Spell.Cast("Consecration", req => Unit.UnfriendlyUnits(8).Any()), Spell.Cast("Avenger's Shield", req => Spell.UseAOE), Spell.Cast("Bastion of Light", req => Spell.GetCharges("Shield of the Righteous") == 0 && !Me.HasAura(ShieldOfTheRighteous) && Me.HealthPercent <= 80), Spell.Cast("Judgment"), Spell.Cast("Hammer of the Righteous") ) ), Movement.CreateMoveToMeleeBehavior(true))); }