Hi stewiethecat, Which botbase are you using? I'm trying with Mud assist. Basic rotation seems to work, but I'm having trouble switching rotations. I get the message that special hotkey was pressed but no change in behaviour. Is aoe rotation supposed to kick in when enabled to Auto in settings? It doesn't seem to. Perhaps related to the above.
Out of curiosity, would it be possible to write 2 seperate rotations that run at once. Such as for Dragoon, there's an opener and an actual rotation. The opener runs once then the rotation runs. http://forum.square-enix.com/ffxiv/...DPS-Paragdim?p=3036770&viewfull=1#post3036770 I am familiar with Java but not so much C so I am looking into how I would do this.
Look at Behavior.cs you can get when the bot rest there. Then you can process on how to handle stuff at the beginning of the combat.
This one should be more tuned. Did Bismark Ex and Ravana Ex with this. Code: // By HeinzSkies using System.Drawing; using System.Threading.Tasks; using System.Windows.Forms; using ff14bot; using ff14bot.Enums; using ff14bot.Managers; using ff14bot.Objects; using YourRaidingBuddy.Books; using YourRaidingBuddy.Helpers; using HotkeyManager = YourRaidingBuddy.Managers.HotkeyManager; namespace YourRaidingBuddy.Rotations { public class DarkKnight : Root { private static LocalPlayer Me { get { return Core.Player; } } public override ClassJobType[] Class { get { return new[] { ClassJobType.DarkKnight }; } } public override void OnInitialize() { ; } public static async Task<bool> AutoMode() { if (!Me.CurrentTarget.IsViable()) { return false; } Unit.UpdatePriorities(0, 15); return await AutoRotation(); } public static async Task<bool> HotkeyMode() { if (!Me.CurrentTarget.IsViable()) { return false; } Unit.UpdatePriorities(0, 10); return await HotkeyRotation(); } public static async Task<bool> AutoRotation() { if (await Darkside()) return true; if (await Aoe()) return true; if (await DotRotation()) return true; if (await FinishedRotation()) return true; if (HotkeyManager.IsKeyDown(Keys.LShiftKey)) { if (await EnmityRotation()) return true; } else { if (await DpsRotation()) return true; } if (await OffGcdRotation()) return true; if (await MpGeneratorRotation()) return true; return false; } public static async Task<bool> HotkeyRotation() { if (await Darkside()) return true; if (await Aoe()) return true; if (await DotRotation()) return true; if (await FinishedRotation()) return true; if (HotkeyManager.IsKeyDown(Keys.LShiftKey)) { if (await EnmityRotation()) return true; } else { if (await DpsRotation()) return true; } if (await OffGcdRotation()) return true; if (await MpGeneratorRotation()) return true; return false; } public static async Task<bool> Darkside() { if (await Spell.NoneGcdCast("Darkside", Me, () => !Me.HasAura("Darkside") && Me.CurrentManaPercent > 90)) return true; return false; } public static async Task<bool> DpsRotation() { if (await Spell.CastSpell("Syphon Strike", () => Actionmanager.LastSpell.Name == "Hard Slash")) return true; if (await Spell.CastSpell("Hard Slash", () => true)) return true; return false; } // We always want to finished out combo. public static async Task<bool> FinishedRotation() { await DarkArts(); if ( await Spell.CastSpell("Souleater", () => Actionmanager.LastSpell.Name == "Syphon Strike" && ((!ShouldApplyDelirium() && (Me.CurrentHealthPercent < 70 && Me.HasAura("Grit"))) || Me.HasAura("Dark Arts")))) return true; if ( await Spell.ApplyCast("Delirium", Me.CurrentTarget, () => Actionmanager.LastSpell.Name == "Syphon Strike")) return true; return await Spell.CastSpell("Power Slash", () => Actionmanager.LastSpell.Name == "Spinning Slash"); } public static async Task<bool> DarkArts() { // Using it at Mana > 70% means that we never interrupt more important stuff like Power Slash or Unleash. Which both trigger at 50%. await Spell.NoneGcdCast("Dark Arts", Me, () => Actionmanager.LastSpell.Name == "Syphon Strike" && Me.CurrentManaPercent > 70 && !ShouldApplyDelirium() && !Me.HasAura("Dark Arts")); await Spell.NoneGcdCast("Dark Arts", Me, () => Actionmanager.LastSpell.Name == "Spinning Slash" && Me.CurrentManaPercent > 50 && !Me.HasAura("Dark Arts")); return false; } public static bool ShouldApplyDelirium() { return !Me.CurrentTarget.HasAura("Delirium", false, 4000) && !Me.CurrentTarget.HasAura("Dragon Kick") && Me.ClassLevel >= 50; } public static async Task<bool> Aoe() { return await Spell.CastSpell("Unleash", Me, () => ((Me.CurrentManaPercent > 50 && VariableBook.HostileUnitsCount > 2) || Me.HasAura("Enhanced Unleash"))); } public static async Task<bool> DotRotation() { if (await Spell.ApplyCast("Scourge", Me.CurrentTarget, () => !Me.CurrentTarget.HasAura("Scourge", true, 4000) && Actionmanager.LastSpell.Name != "Syphon Strike" && Actionmanager.LastSpell.Name != "Hard Slash" && Actionmanager.LastSpell.Name != "Spinning Slash" && Me.CurrentTarget.CurrentHealth > 3000)) return true; return false; } // Currently without a way to detect enmity, we will use hotkey to trigger this. public static async Task<bool> EnmityRotation() { if (await Spell.CastSpell("Spinning Slash", () => Actionmanager.LastSpell.Name == "Hard Slash")) return true; if (await Spell.CastSpell("Hard Slash", () => true)) return true; return false; } public static async Task<bool> OffGcdRotation() { // Offensive await Spell.CastLocation("Salted Earth", Me.CurrentTarget, () => true); await Spell.NoneGcdCast("Reprisal", Me.CurrentTarget, () => true); await Spell.NoneGcdCast("Low Blow", Me.CurrentTarget, () => true); // Defensive await Spell.NoneGcdCast("Dark Dance", Me, () => Me.CurrentTarget.Distance(Me) < 3); return false; } public static async Task<bool> MpGeneratorRotation() { await Spell.NoneGcdCast("Blood Weapon", Me, () => Me.CurrentManaPercent < 90 && Me.CurrentTarget.Distance(Me) < 3); await Spell.NoneGcdCast("Blood Price", Me, () => Me.CurrentManaPercent < 70 && VariableBook.HostileUnitsTargettingMeCount > 0); await Spell.NoneGcdCast("Carve and Spit", Me.CurrentTarget, () => !Me.HasAura("Dark Arts") && Actionmanager.LastSpell.Name != "Syphon Strike" && Actionmanager.LastSpell.Name != "Spinning Slash" && Me.CurrentManaPercent < 50 && Me.CurrentTarget.Distance(Me) < 3); await Spell.NoneGcdCast("Sole Survivor", Me.CurrentTarget, () => (Me.CurrentManaPercent < 70 || Me.CurrentHealthPercent < 70) && Me.CurrentTarget.Distance(Me) < 3 && Me.CurrentTarget.CurrentHealth < 5000); return false; } } } Change log:
would also love a blm_60 routine, a lot of people play this job and dont have a decent 60 routine. this job is a lot asked for raids, and they must do old rotations cuz no 60 routines .
made some minor updates to Warrior routine. - If player is using deliverance rotation, the routine will now use equilibrium when below 500 tp - Fracture now works properly with default rotation, and Deliverance rotation. - Removed Berserk for now in Deliverance rotation. I will post update here until Xcesius gets a chance to update...
New update out --> Updated DarkKnight -- https://www.thebuddyforum.com/rebor...uddy-coming-soon-post1999060.html#post1999060 Updated Warrior -- https://www.thebuddyforum.com/rebor...uddy-coming-soon-post1999218.html#post1999218 Added new function :: CombatTime This will trigger when player enters combat. It will reset when player is not longer in combat. Usage :: Unit.CombatTime.ElapsedMilliseconds > X Where X is amount of Milliseconds.
I'm unable to get this to work at all for dark knight or whm. It just stands there in combat and sometimes says its going to use abilities in buddy chat but it never does. Anything I need to do?
Updated Ninja Fixed an issue where shadow fang, mutilate, and Duality would not cast if you had a war in group that puts on storm's eye. Code: using System; using System.Linq; using System.Threading.Tasks; using System.Windows.Media; using Buddy.Coroutines; using ff14bot; using ff14bot.Enums; using ff14bot.Helpers; using ff14bot.Managers; using ff14bot.Objects; using YourRaidingBuddy.Helpers; using YourRaidingBuddy.Settings; using TreeSharp; using System.Collections.Generic; using YourRaidingBuddy.Books; using YourRaidingBuddy.Interfaces.Settings; namespace YourRaidingBuddy.Rotations { public class Ninja : Root { private static LocalPlayer Me { get { return Core.Player; } } //Core.Player.CurrentTarget as BattleCharacter public override ClassJobType[] Class { get { return new[] { ClassJobType.Ninja, ClassJobType.Rogue }; } } private const int MobHp = 3000; private const int BuffHp = 8000; public override void OnInitialize() { ; } #region NewRotation public static async Task<bool> AutoMode() { if (!Me.CurrentTarget.IsViable()) return false; return await NinjaRotation(); } public static async Task<bool> HotkeyMode() { if (!Me.CurrentTarget.IsViable()) return false; if (VariableBook.HkmMultiTarget) await NinjaAoE(); return await NinjaRotation(); } public static async Task<bool> NinjaRotation() { if (Managers.HotkeyManager.IsKeyDown(System.Windows.Forms.Keys.LShiftKey)) { await EmergHuton(); } await DoNinjutsu(); await HutonRefresh(); await DancingEdge(); await Shadow(); await SingleTarget(); await NoneGCD(); return false; } public static async Task<bool> NinjaAoE() { if (VariableBook.HostileUnitsCount >= 3 && Core.Me.CurrentTarget.CurrentHealthPercent >= 60) { await CastDoton(); } if (VariableBook.HostileUnitsCount >= 5) { await Spell.CastSpell("Death Blossom", Me, () => true); } return false; } public static async Task<bool> EmergHuton() { await Spell.CastSpell("Armor Crush", () => Actionmanager.LastSpell.Name == "Gust Slash"); await Spell.CastSpell("Gust Slash", () => Actionmanager.LastSpell.Name == "Spinning Edge"); await Spell.CastSpell("Spinning Edge", () => true); return false; } public static async Task<bool> HutonRefresh() { if (!Me.HasAura("Duality") && !Core.Me.HasAura("Huton", true, 24000) && Actionmanager.LastSpell.Name == "Gust Slash") { return await Spell.CastSpell("Armor Crush", () => true); } return false; } public static async Task<bool> DancingEdge() { if (!Me.HasAura("Duality") && !Me.CurrentTarget.HasAura("Dancing Edge", true, 4000) && !Me.CurrentTarget.HasAura("Dancing Edge", false, 4000) && !Me.CurrentTarget.HasAura("Storm's Eye", false) && Actionmanager.LastSpell.Name == "Gust Slash") { return await Spell.CastSpell("Dancing Edge", () => true); } return false; } public static async Task<bool> Shadow() { if ((!Me.CurrentTarget.HasAura("Shadow Fang", true, 4000) || !Me.CurrentTarget.HasAura("Shadow Fang", true)) && await Spell.NoneGcdCast("Duality", Me, () => Actionmanager.LastSpell.Name == "Gust Slash" && Me.CurrentTarget.HasAura(AuraBook.ShadowFang, true, 5000) && (Me.CurrentTarget.HasAura("Dancing Edge") || Me.CurrentTarget.HasAura("Storm's Eye"))); && Actionmanager.LastSpell.Name == "Spinning Edge"); { return await Spell.CastSpell("Shadow Fang", () => true); } return false; } public static async Task<bool> SingleTarget() { await Spell.CastSpell("Aeolian Edge", () => Me.HasAura("Duality") || Actionmanager.LastSpell.Name == "Gust Slash"); await Spell.CastSpell("Gust Slash", () => Actionmanager.LastSpell.Name == "Spinning Edge"); await Spell.CastSpell("Mutilate", () => Me.CurrentTarget.HasAura(AuraBook.ShadowFang) && (!Me.CurrentTarget.HasAura(AuraBook.Mutilate, true, 4000) || !Me.CurrentTarget.HasAura(AuraBook.Mutilate)) && Core.Me.CurrentTarget.CurrentHealthPercent >= 25); await Spell.CastSpell("Spinning Edge", () => true); return false; } public static async Task<bool> NoneGCD() { await Spell.NoneGcdCast("Trick Attack", Me.CurrentTarget, () => Me.HasAura(AuraBook.Suiton) && Me.CurrentTarget.IsBehind); await Spell.NoneGcdCast("Internal Release", Me, () => !Me.HasAura(AuraBook.InternalRelease) && Core.Me.CurrentTarget.CurrentHealthPercent >= 25); await Spell.NoneGcdCast("Blood for Blood", Me, () => !Me.HasAura("Blood for Blood") && Core.Me.CurrentTarget.CurrentHealthPercent >= 25); await Spell.NoneGcdCast("Invigorate", Me, () => Me.CurrentTP < 550); await Spell.NoneGcdCast("Second Wind", Me, () => Me.CurrentHealthPercent <= 30); await Spell.NoneGcdCast("Jugulate", Me.CurrentTarget, () => Me.CurrentTarget.HasAura(AuraBook.Mutilate)); await Spell.NoneGcdCast("Mug", Me.CurrentTarget, () => Me.CurrentTarget.HasAura(AuraBook.ShadowFang)); await Spell.NoneGcdCast("Duality", Me, () => Actionmanager.LastSpell.Name == "Gust Slash" && Me.CurrentTarget.HasAura(AuraBook.ShadowFang, true, 5000) && (Me.CurrentTarget.HasAura("Dancing Edge", true, 5000) || Me.CurrentTarget.HasAura("Storm's Eye"))); await Spell.NoneGcdCast("Dream Within a Dream", Me.CurrentTarget, () => Me.CurrentTarget.HasAura("Vulnerability Up")); await Spell.NoneGcdCast("Assassinate", Me.CurrentTarget, () => true); return false; } #endregion #region Ninjatsu Copied From Kupo Credits Masta private static bool HasBleedingDebuff() { return Me.CurrentTarget.HasAura("Storm's Eye", false, 2000) || Me.CurrentTarget.HasAura("Dancing Edge"); } private static readonly SpellData Jin = DataManager.GetSpellData(2263); private static readonly SpellData Chi = DataManager.GetSpellData(2261); private static readonly SpellData Ten = DataManager.GetSpellData(2259); private static readonly SpellData Ninjutsu = DataManager.GetSpellData(2260); private static readonly SpellData Jugulate = DataManager.GetSpellData(2251); private static readonly SpellData Kassatsu = DataManager.GetSpellData(2264); private static readonly SpellData Trick_Attack = DataManager.GetSpellData(2258); private static readonly SpellData Sneak_Attack = DataManager.GetSpellData(2250); public static HashSet<uint> OverrideBackstabIds = new HashSet<uint>() { 3240//Cloud of darkness }; private const int HutonRecast = 8000; internal static async Task<bool> DoNinjutsu() { //Exit early if player was inputting something if (Core.Player.HasAura("Mudra")) return true; if (Actionmanager.CanCastOrQueue(Jin, null)) { if (!Core.Player.HasAura("Huton", true, HutonRecast)) { Logger.Write("YourRaidingBuddy Casting " + "Huton" + "Chi Combo!"); await CastHuton(); return false; } var curTarget = Core.Target as BattleCharacter; if (curTarget == null) return false; // if (curTarget.TimeToDeath() <= 3) // return false; //Suiton var taCD = Trick_Attack.Cooldown; //We can start casting suiton before trick attack is ready cause its going to take some time if (taCD.TotalMilliseconds <= 1300) { if (!await CastSuiton()) return false; if (!(Kassatsu.Cooldown.TotalMilliseconds <= 0) || !Core.Player.HasTarget) return false; if (await Coroutine.Wait(2000, () => Actionmanager.DoAction(Kassatsu, null) && Me.CurrentTarget.HasAura("Shadow Fang") && Me.CurrentTarget.HasAura(492))) { Logger.Write("YourRaidingBuddy Casting " + "Raiton"); if (Me.CurrentTarget.HasAura(492)) await CastRaiton(); } return false; } if (taCD.TotalSeconds >= 5) { await CastRaiton(); } return false; } if (Actionmanager.CanCastOrQueue(Chi, null) && Me.CurrentTarget.HasAura("Shadow Fang")) { Logger.Write("YourRaidingBuddy Casting " + "Raiton"); await CastRaiton(); return false; } if (Actionmanager.CanCastOrQueue(Ten, null)) { Logger.Write("YourRaidingBuddy Casting " + "Ten" + "Ninjutsu!"); { await Coroutine.Wait(2000, () => Actionmanager.DoAction(Ten, null)); await CastNinjutsu(); return false; } } return false; } private static async Task CastHuton() { if (await Coroutine.Wait(2000, () => Actionmanager.DoAction(Jin, null))) { if (await Coroutine.Wait(2000, () => Actionmanager.DoAction(Chi, null))) { if (await Coroutine.Wait(2000, () => Actionmanager.DoAction(Ten, null))) { await CastNinjutsu(); } } } } private static async Task<bool> CastDoton() { if (Actionmanager.CanCastOrQueue(Jin, null)) { if (await Coroutine.Wait(2000, () => Actionmanager.DoAction(Jin, null))) { if (await Coroutine.Wait(2000, () => Actionmanager.DoAction(Ten, null))) { if (await Coroutine.Wait(2000, () => Actionmanager.DoAction(Chi, null))) { return await CastNinjutsu(); } } } } return false; } private static async Task<bool> CastRaiton() { if (!await Coroutine.Wait(2000, () => Actionmanager.DoAction(Ten, null))) return false; if (await Coroutine.Wait(2000, () => Actionmanager.DoAction(Chi, null))) { return await CastNinjutsu(); } return false; } private static async Task<bool> CastSuiton() { if (!await Coroutine.Wait(2000, () => Actionmanager.DoAction(Ten, null))) return false; if (!await Coroutine.Wait(2000, () => Actionmanager.DoAction(Chi, null))) return false; if (!await Coroutine.Wait(2000, () => Actionmanager.DoAction(Jin, null))) return false; if (await CastNinjutsu()) { return await Coroutine.Wait(2000, () => Core.Player.HasAura("Suiton")); } return false; } private static async Task<bool> CastNinjutsu() { if (await Coroutine.Wait(2000, () => Core.Player.HasAura("Mudra"))) { bool possibly = false; while (Core.Player.HasAura("Mudra")) { if (Core.Player.HasTarget) { if (Actionmanager.DoAction(Ninjutsu, Core.Target)) { possibly = true; } } if (!Core.Player.InCombat) return false; await Coroutine.Yield(); } await Coroutine.Wait(2000, () => Ninjutsu.Cooldown.TotalSeconds > 10); return possibly; } return false; } #endregion } }
Can you post some logs? The Dark Knight profile doesn't any pulling logic in as I used it for raiding. So you have to pull / get up close by yourself.
Hi Everyone, I have now a "Update" system in place, if you create a rotation or modify. Please PM me with what class / job it is so I can give you the details where to upload the changes thanks!
[18:33:46.563 N] Compiler Error: c:\Users\Carlos\Desktop\Rebornbuddy 1.0.240.0\BotBases\YourRaidingBuddy\Root.cs(30,46) : warning CS0109: The member 'YourRaidingBuddy.Root.Revision' does not hide an inherited member. The new keyword is not required. [18:33:46.563 N] Compiler Error: c:\Users\Carlos\Desktop\Rebornbuddy 1.0.240.0\BotBases\YourRaidingBuddy\Root.cs(158,40) : warning CS1998: This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread. [18:33:46.563 N] Compiler Error: c:\Users\Carlos\Desktop\Rebornbuddy 1.0.240.0\BotBases\YourRaidingBuddy\Core\Helpers\Movement.cs(133,13) : warning CS0162: Unreachable code detected [18:33:46.563 N] Compiler Error: c:\Users\Carlos\Desktop\Rebornbuddy 1.0.240.0\BotBases\YourRaidingBuddy\Rotations\Jobs\Bard.cs(36,40) : warning CS1998: This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread. [18:33:46.563 N] Compiler Error: c:\Users\Carlos\Desktop\Rebornbuddy 1.0.240.0\BotBases\YourRaidingBuddy\Rotations\Jobs\Ninja.cs(114,365) : error CS1026: ) expected [18:33:46.563 N] Compiler Error: c:\Users\Carlos\Desktop\Rebornbuddy 1.0.240.0\BotBases\YourRaidingBuddy\Rotations\Jobs\Ninja.cs(114,367) : error CS1525: Invalid expression term '&&' [18:33:46.563 N] Compiler Error: c:\Users\Carlos\Desktop\Rebornbuddy 1.0.240.0\BotBases\YourRaidingBuddy\Rotations\Jobs\Ninja.cs(114,370) : error CS1002: ; expected [18:33:46.563 N] Compiler Error: c:\Users\Carlos\Desktop\Rebornbuddy 1.0.240.0\BotBases\YourRaidingBuddy\Rotations\Jobs\Ninja.cs(114,417) : error CS1002: ; expected [18:33:46.563 N] Compiler Error: c:\Users\Carlos\Desktop\Rebornbuddy 1.0.240.0\BotBases\YourRaidingBuddy\Rotations\Jobs\Ninja.cs(114,417) : error CS1525: Invalid expression term ')'