using System; using System.CodeDom; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms.VisualStyles; using ff14bot; using ff14bot.Behavior; using ff14bot.Enums; using ff14bot.Managers; using ff14bot.Navigation; using ff14bot.Objects; using ff14bot.Helpers; using Kupper; using Kupper.Helpers; using Kupper.Settings; using Pathfinding; using TreeSharp; using Action = TreeSharp.Action; using Clio.Common; using Clio.Utilities; using System.Windows.Input; using System.Windows.Forms; namespace Kupper.Rotations { public class ArcherBard : KupperRoutine { //DEVELOPERS REPLACE GetType().Name WITH YOUR CR'S NAME. public override string Name { get { return "Kupper [" + GetType().Name + "]"; } } public override void OnInitialize() { WindowSettings = new ArcherSettings(); ff14bot.TreeRoot.TicksPerSecond = 255; HotkeyManager.Register("AOE Toggle", Keys.Z, ModifierKeys.Shift, r => settings.AutoAOE = !settings.AutoAOE); } private ArcherSettings settings { get { return WindowSettings as ArcherSettings; } } public override float PullRange { get { return 23; } } public override ClassJobType[] Class { get { return new ClassJobType[] {ClassJobType.Archer, ClassJobType.Bard,}; } } public SpellData SkillBlocker; public SpellData BarrageCooldown; public SpellData EmpyrealCooldown; public SpellData GCDLength; public int ScaledDOT; public bool Opener = false; public bool RefreshWindbite = false; public bool RefreshVenomousBite = false; public bool IronJaws = false; public override void OnPulse() { Actionmanager.CurrentActions.TryGetValue("Heavy Shot", out SkillBlocker); Actionmanager.CurrentActions.TryGetValue("Heavy Shot", out GCDLength); Actionmanager.CurrentActions.TryGetValue("Barrage", out BarrageCooldown); Actionmanager.CurrentActions.TryGetValue("Empyreal Arrow", out EmpyrealCooldown); ScaledDOT = settings.DOTLimit * Core.Me.ClassLevel/60; Logging.Write("lastspellused = " + Kupper.Settings.ArcherSettings.lastspellused); if(settings.UseOpener) { if (Core.Me.HasAura("Internal Release", true, settings.DOTRefresh) && Core.Me.HasAura("Raging Strikes", true, settings.DOTRefresh) && Core.Me.HasAura("Hawk's Eye", true, settings.DOTRefresh) && Core.Me.HasAura("Blood for Blood", true, settings.DOTRefresh)) { Opener = true; } if (!Core.Me.HasAura("Internal Release") || !Core.Me.HasAura("Raging Strikes") || !Core.Me.HasAura("Hawk's Eye") || !Core.Me.HasAura("Blood for Blood")) { Opener = false; } if ((Opener == true) && (!Core.Me.HasAura("Internal Release", true, settings.DOTRefresh) || !Core.Me.HasAura("Raging Strikes", true, settings.DOTRefresh) || !Core.Me.HasAura("Hawk's Eye", true, settings.DOTRefresh) || !Core.Me.HasAura("Blood for Blood", true, settings.DOTRefresh))) { if(Core.Me.CurrentTarget.HasAura("Windbite", true)) RefreshWindbite = true; if(Core.Me.CurrentTarget.HasAura("Venomous Bite", true)) RefreshVenomousBite = true; Opener = false; } if (Core.Me.CurrentTarget.HasAura("Windbite", true, 17500)) RefreshWindbite = false; if (Core.Me.CurrentTarget.HasAura("Venomous Bite", true, 17500)) RefreshVenomousBite = false; } if ((Core.Me.CurrentTarget.HasAura("Venomous Bite", true, 1000) && Core.Me.CurrentTarget.HasAura("Windbite", true, 1000)) && (!Core.Me.CurrentTarget.HasAura("Venomous Bite", true, 5000) || !Core.Me.CurrentTarget.HasAura("Windbite", true, 5000))) IronJaws = true; else IronJaws = false; if (settings.UseSwiftsong && !MovementManager.IsMoving && !Core.Player.InCombat && !Core.Player.IsDead && !Core.Player.IsMounted && !Core.Me.HasAura("Swiftsong") && ((!Core.Me.HasAura("Foe Requiem") && !Core.Me.HasAura("Mage's Ballad") && !Core.Me.HasAura("Army's Paeon")) || settings.SwiftsongOverride)) Actionmanager.DoAction("Swiftsong", Core.Me); ChocoboStanceCheck(); } /* public Composite UsePotion(string PotName, GameObject onTarget) { var pot = InventoryManager.FilledSlots.FirstOrDefault(a => a.Name.Equals(PotName) && a.IsHighQuality); return new Decorator(r => pot != null && onTarget == Core.Me && pot.IsValid && pot.CanUse(onTarget) && settings.UseBuffPotions && ((settings.UseOpenerPotion && Opener) || !settings.UseOpenerPotion), new Action(r => { pot.UseItem(onTarget); })); return new Decorator(r => pot != null && onTarget != Core.Me && pot.IsValid && pot.CanUse(onTarget) && settings.UsePoisonPotions, new Action(r => { pot.UseItem(onTarget); })); } */ [Behavior(BehaviorType.PreCombatBuffs)] public Composite CreateBasicPreCombatBuffs() { return SummonChocobo(); } [Behavior(BehaviorType.Rest)] public Composite CreateBasicRest() { return DefaultRestBehavior(r => Core.Me.CurrentTPPercent); } [Behavior(BehaviorType.Pull)] public Composite CreateBasicPull() { return new PrioritySelector(ctx => Core.Me.CurrentTarget as BattleCharacter, new Decorator(ctx => ctx != null && BotManager.Current.IsAutonomous, new PrioritySelector( CommonBehaviors.MoveToLos(ctx => ctx as GameObject), CommonBehaviors.MoveAndStop(ctx => (ctx as GameObject).Location, ctx => PullRange + (ctx as GameObject).CombatReach, true, "Moving to unit") ) ), BardCombat() ); } [Behavior(BehaviorType.Combat)] public Composite CreateBasicCombat() { return new PrioritySelector(ctx => Core.Me.CurrentTarget as BattleCharacter, new Decorator(ctx => ctx != null && BotManager.Current.IsAutonomous, new PrioritySelector( CommonBehaviors.MoveToLos(ctx => ctx as GameObject), CommonBehaviors.MoveAndStop(ctx => (ctx as GameObject).Location, ctx => PullRange + (ctx as GameObject).CombatReach, true, "Moving to unit") ) ), BardCombat() ); } public Composite BardCombat() { return new PrioritySelector( //Interrupts new Decorator(r => settings.UseInterrupt && settings.Interrupt.Contains((Core.Me.CurrentTarget as BattleCharacter).SpellCastInfo.Name), new PrioritySelector( Spell.Cast("Blunt Arrow") ) ), new Decorator(r => Core.Me.HasAura("Barrage") || Kupper.Settings.ArcherSettings.lastspellused == "Barrage", new PrioritySelector( Spell.Cast("Heavy Shot", r => (!Core.Me.HasAura("The Wanderer's Minuet"))), Spell.Cast("Empyreal Arrow", r => (Core.Me.HasAura("The Wanderer's Minuet"))) ) ), new Decorator(r => Core.Me.HasAura("The Wanderer's Minuet") && (Core.Me.CurrentTP >= settings.AOETPLimit) && KeyboardPolling.IsKeyDown(Keys.R) && !KeyboardPolling.IsKeyDown(Keys.LShiftKey) && !KeyboardPolling.IsKeyDown(Keys.LMenu), new PrioritySelector( Spell.Cast("Straight Shot", r => (Actionmanager.LastSpell.Name != "Straight Shot" && Core.Me.CurrentTarget.CurrentHealth >= ScaledDOT*1.2 && (!Core.Me.CurrentTarget.HasAura("Windbite", true, (settings.DOTClip + (int)GCDLength.BaseCooldown.TotalMilliseconds)) || !Core.Me.CurrentTarget.HasAura("Venomous Bite", true, (settings.DOTClip + (int)GCDLength.BaseCooldown.TotalMilliseconds))) && !Core.Me.HasAura("Straight Shot", true, (settings.DOTClip + (int)GCDLength.BaseCooldown.TotalMilliseconds)))), Spell.Cast("Quick Nock", r => Core.Player.CurrentTarget.Location.Distance(Core.Player.Location) < 10), Spell.Cast("Wide Volley", r => Core.Player.CurrentTarget.Location.Distance(Core.Player.Location) >= 10), Spell.Cast("Rain of Death") ) ), new Decorator(r => Core.Me.HasAura("The Wanderer's Minuet"), new PrioritySelector( Spell.Cast("Iron Jaws", r => IronJaws), Spell.Cast("Straight Shot", r => (Kupper.Settings.ArcherSettings.lastspellused != "Straight Shot" && Actionmanager.LastSpell.Name != "Straight Shot" && !Core.Me.HasAura("Straight Shot", true, (settings.DOTClip + (int)GCDLength.BaseCooldown.TotalMilliseconds)))), Spell.Cast("Windbite", r => Kupper.Settings.ArcherSettings.lastspellused != "Windbite" && Core.Me.CurrentTarget.CurrentHealth >= ScaledDOT*1.2 && !Core.Me.HasAura("Barrage", true) && !Core.Me.CurrentTarget.HasAura("Windbite", true, (settings.DOTClip + (int)GCDLength.BaseCooldown.TotalMilliseconds)) && !settings.DontDOT.Contains(Core.Me.CurrentTarget.Name)), Spell.Cast("Venomous Bite", r => Kupper.Settings.ArcherSettings.lastspellused != "Venomous Bite" && Core.Me.CurrentTarget.CurrentHealth >= ScaledDOT*1.2 && !Core.Me.HasAura("Barrage", true) && !Core.Me.CurrentTarget.HasAura("Venomous Bite", true, (settings.DOTClip + (int)GCDLength.BaseCooldown.TotalMilliseconds)) && !settings.DontVB.Contains(Core.Me.CurrentTarget.Name) && !settings.DontDOT.Contains(Core.Me.CurrentTarget.Name)), Spell.Cast("Straight Shot", r => Core.Me.HasAura("Straighter Shot")), Spell.Cast("Heavy Shot", r => (Core.Me.CurrentTP >= 80) || (Core.Me.CurrentTP < 80 && ((Core.Me.CurrentTarget.HasAura("Windbite", true) && Core.Me.CurrentTarget.HasAura("Venomous Bite", true)) || Core.Me.CurrentTarget.CurrentHealth <= ScaledDOT) && Core.Me.HasAura("Straight Shot") && !Core.Me.HasAura("Straighter Shot"))) ) ), //Refresh DOTs for opener new Decorator(r => settings.UseOpener, new PrioritySelector( Spell.Cast("Windbite", r => Core.Me.CurrentTarget.CurrentHealth >= ScaledDOT && !Core.Me.HasAura("Barrage", true) && RefreshWindbite && !settings.DontDOT.Contains(Core.Me.CurrentTarget.Name)), Spell.Cast("Venomous Bite", r => Core.Me.CurrentTarget.CurrentHealth >= ScaledDOT && !Core.Me.HasAura("Barrage", true) && RefreshVenomousBite && !settings.DontVB.Contains(Core.Me.CurrentTarget.Name) && !settings.DontDOT.Contains(Core.Me.CurrentTarget.Name)) ) ), //Buffs (no opener) new Decorator( r => (settings.UseSongBuffs || (!settings.UseSongBuffs && (!Core.Me.HasAura("Army's Paeon", true) && !Core.Me.HasAura("Mage's Ballad", true)))) && !settings.UseOpener && settings.UseBuffs && Core.Me.CurrentTarget.CurrentHealth >= settings.BuffHPLimit && (SkillBlocker.Cooldown.TotalMilliseconds >= 1000 || (SkillBlocker.Cooldown.TotalMilliseconds >= 500 && Core.Me.HasAura("The Wanderer's Minuet"))), new PrioritySelector( Spell.Cast("Internal Release", r => settings.UseInternalRelease, r => Core.Me), Spell.Cast("Raging Strikes", r => settings.UseRagingStrikes, r => Core.Me), Spell.Cast("Hawk's Eye", r => settings.UseHawksEye, r => Core.Me), Spell.Cast("Blood for Blood", r => settings.UseBloodForBlood && (settings.AlignB4B && (/*BarrageCooldown.Cooldown.TotalMilliseconds == null ||*/ (BarrageCooldown.Cooldown.TotalMilliseconds <= 9000 || BarrageCooldown.Cooldown.TotalMilliseconds >= 25000 || Core.Me.HasAura("Barrage"))) || !settings.AlignB4B), r => Core.Me), // UsePotion("X-Potion of Dexterity", Core.Me), Spell.Cast("Barrage", r => settings.UseBarrage && !Core.Me.HasAura("Straighter Shot", true) && (EmpyrealCooldown.Cooldown.TotalMilliseconds < 1 || !Core.Me.HasAura("Wanderer's Minuet")), r => Core.Me), Spell.Cast("Quelling Strikes", r => settings.UseQuellingStrikes, r => Core.Me) ) ), //Buffs (opener) new Decorator(r => (settings.UseSongBuffs || (!settings.UseSongBuffs && (!Core.Me.HasAura("Army's Paeon", true) && !Core.Me.HasAura("Mage's Ballad", true)))) && settings.UseOpener && settings.UseBuffs && Core.Me.CurrentTarget.CurrentHealth >= settings.BuffHPLimit && SkillBlocker.Cooldown.TotalMilliseconds >= 1000, new PrioritySelector( Spell.Cast("Hawk's Eye", r => settings.UseHawksEye, r => Core.Me), Spell.Cast("Raging Strikes", r => settings.UseRagingStrikes, r => Core.Me), Spell.Cast("Blood for Blood", r => settings.UseBloodForBlood && (settings.AlignB4B && (/*BarrageCooldown.Cooldown.TotalMilliseconds == null || */(BarrageCooldown.Cooldown.TotalMilliseconds <= 9000 || BarrageCooldown.Cooldown.TotalMilliseconds >= 25000 || Core.Me.HasAura("Barrage"))) || !settings.AlignB4B), r => Core.Me), Spell.Cast("Internal Release", r => settings.UseInternalRelease, r => Core.Me), // UsePotion("X-Potion of Dexterity", Core.Me), Spell.Cast("Barrage", ret => settings.UseBarrage && (Core.Me.ClassLevel < 54 || EmpyrealCooldown.Cooldown.TotalMilliseconds < 1) && !IronJaws && Core.Me.HasAura("The Wanderer's Minuet", true) && !Core.Me.HasAura("Straighter Shot", true), r => Core.Me), Spell.Cast("Quelling Strikes", r => settings.UseQuellingStrikes, r => Core.Me) ) ), //AOE new Decorator(r => (settings.AutoAOE || settings.AOEOverride) && (Core.Me.CurrentTP >= settings.AOETPLimit || Core.Me.HasAura("Quicker Nock") || Core.Me.HasAura("Downpour of Death")), new PrioritySelector( Spell.Cast("Quick Nock", r => (((settings.AutoAOE && EnemiesNearTarget(10) >= settings.AOELimit && !settings.DontAOE.Contains(Core.Me.CurrentTarget.Name)) || settings.AOEOverride) && (Core.Me.HasAura("Quicker Nock") || Core.Me.ClassLevel < 45))), Spell.Cast("Rain of Death", r => (((settings.AutoAOE && EnemiesNearTarget(8) >= settings.AOELimit && !settings.DontAOE.Contains(Core.Me.CurrentTarget.Name)) || settings.AOEOverride) && (Core.Me.HasAura("Downpour of Death") || Core.Me.ClassLevel < 50 || EnemiesNearTarget(5) < settings.AOELimit))), Spell.Cast("Wide Volley", r => (((settings.AutoAOE && EnemiesNearTarget(5) >= settings.AOELimit && !settings.DontAOE.Contains(Core.Me.CurrentTarget.Name)) || settings.AOEOverride))) ) ), //AOE new Decorator(r => (Core.Me.CurrentTP >= settings.AOETPLimit) && KeyboardPolling.IsKeyDown(Keys.R) && !KeyboardPolling.IsKeyDown(Keys.LShiftKey) && !KeyboardPolling.IsKeyDown(Keys.LMenu), new PrioritySelector( Spell.Cast("Quick Nock", r => Core.Player.CurrentTarget.Location.Distance(Core.Player.Location) < 10), Spell.Cast("Wide Volley", r => Core.Player.CurrentTarget.Location.Distance(Core.Player.Location) >= 10), Spell.Cast("Rain of Death") ) ), //GCDs new Decorator(new PrioritySelector( Spell.Cast("Straight Shot", r => !Core.Me.HasAura("Straight Shot", true, settings.SSClip) || ((Core.Me.CurrentTarget.CurrentHealth >= ScaledDOT && (!Core.Me.CurrentTarget.HasAura("Windbite", true, (settings.DOTClip + (int)GCDLength.BaseCooldown.TotalMilliseconds)) || !Core.Me.CurrentTarget.HasAura("Venomous Bite", true, (settings.DOTClip + (int)GCDLength.BaseCooldown.TotalMilliseconds))) && !Core.Me.HasAura("Straight Shot", true, (settings.DOTClip + (int)GCDLength.BaseCooldown.TotalMilliseconds)))) ), Spell.Cast("Windbite", r => Core.Me.CurrentTarget.CurrentHealth >= ScaledDOT && !Core.Me.HasAura("Barrage", true) && !Core.Me.CurrentTarget.HasAura("Windbite", true, settings.DOTClip) && !settings.DontDOT.Contains(Core.Me.CurrentTarget.Name)), Spell.Cast("Venomous Bite", r => Core.Me.CurrentTarget.CurrentHealth >= ScaledDOT && !Core.Me.HasAura("Barrage", true) && !Core.Me.CurrentTarget.HasAura("Venomous Bite", true, settings.DOTClip) && !settings.DontVB.Contains(Core.Me.CurrentTarget.Name) && !settings.DontDOT.Contains(Core.Me.CurrentTarget.Name)), Spell.Cast("Straight Shot", r => Core.Me.HasAura("Straighter Shot")), Spell.Cast("Heavy Shot", r => (Core.Me.CurrentTP >= 80) || (Core.Me.CurrentTP < 80 && ((Core.Me.CurrentTarget.HasAura("Windbite", true) && Core.Me.CurrentTarget.HasAura("Venomous Bite", true)) || Core.Me.CurrentTarget.CurrentHealth <= ScaledDOT) && Core.Me.HasAura("Straight Shot") && !Core.Me.HasAura("Straighter Shot"))) ) ), //Defensives new Decorator(r => SkillBlocker.Cooldown.TotalMilliseconds >= 500 || Core.Me.CurrentTP < 80, new PrioritySelector( Spell.Cast("Invigorate", r => Core.Me.CurrentTPPercent <= settings.UseInvigorateTP && settings.UseBuffs, r => Core.Me), Spell.Cast("Second Wind", r => Core.Me.CurrentHealthPercent <= settings.UseSecondWindHP, r => Core.Me), Spell.Cast("Featherfoot", r => Core.Me.CurrentHealthPercent <= settings.UseFeatherfootHP, r => Core.Me), Spell.Cast("Keen Flurry", r => Core.Me.CurrentHealthPercent <= settings.UseKeenFlurryHP, r => Core.Me) ) ), //Flaming Arrow new Decorator(r => settings.UseFlamingArrow && Actionmanager.CanCast("Flaming Arrow", Core.Me.CurrentTarget) && (SkillBlocker.Cooldown.TotalMilliseconds >= 500 || Core.Me.CurrentTP <= 50) && Core.Me.CurrentTarget.CurrentHealth >= ScaledDOT, new Action(r => Actionmanager.DoActionLocation("Flaming Arrow", Core.Me.CurrentTarget.Location + new Vector3((float)MathEx.Random(-.75,.75),0,(float)MathEx.Random(-.75,.75)))) ), //OffGCDs new Decorator(r => (Core.Me.HasAura("The Wanderer's Minuet") && SkillBlocker.Cooldown.TotalMilliseconds >= 500) || SkillBlocker.Cooldown.TotalMilliseconds >= 1000 || Core.Me.CurrentTP < 60, new PrioritySelector( Spell.Cast("Sidewinder", r => Core.Me.CurrentTarget.HasAura("Windbite", true, 1000) && Core.Me.CurrentTarget.HasAura("Venomous Bite", true, 1000)), Spell.Cast("Empyreal Arrow", r => BarrageCooldown.Cooldown.TotalMilliseconds >= 10000 && !IronJaws), Spell.Cast("Rain of Death", r => ((settings.AutoAOE || settings.AOEOverride) && EnemiesNearTarget(8) >= 2 && !settings.DontAOE.Contains(Core.Me.CurrentTarget.Name))), Spell.Cast("Misery's End"), Spell.Cast("Bloodletter"), Spell.Cast("Repelling Shot", r => settings.UseRepellingShot), Spell.Cast("Blunt Arrow", r => settings.UseBluntArrow && !settings.UseInterrupt) // UsePotion("Potent Poisoning Potion", Core.Me.CurrentTarget) ) ) ); } } }