Few comments about Ninja routine: Bot does Suiton->Kassatsu->Suiton - should Suiton->Kassatsu->SneakAttack/TrickAttack->cast ninjutsu buffed with Kassatsu. Yuo can do it by adding a condition to not cast ninjustu if Suiton_buff is active Bot starts fight with ninjutsu then breaks ninjustu spell casting chain with attack ability Overlay doesn't dissapear when game window loses focus
Hi Mathikk, Apologies, I forgot to run and see if the code compiled. Should be fixed now though! Please update to latest
When it gets uploaded new ninja update Changelong: 1. Better Off GCD weaving (Still needs a lil bit more work) 2. Fixed Shadowfang 3. Duality is now much more reliably casted alongside AE.
I have not ran across this happening with me. The only time it would double cast Sution is if i was not behind the target to use trick attack but I can try to look into it. As for it breaking ninjutsu I have no idea how it did that for you. When it starts the cast of ninjutsu the bot does not allow any inputs besides the mudras. You could literally manually spam spinning edge but it would not go off until the ninjutsu is casted.
Ninja Update: Changed from using Raiton to Fuma because of mudra lag. Optimized Armor Crush Instead of using AC only when huton drops below 25sec these are the changes 1. Will use AC if huton is below 40sec and has DE/Storm's, SF, and Mut up for atlease 4 sec. (This prioritizes dots up before AC is used.) 2. Will prioritize AC if huton drops below 15 sec (This prioritizes AC instead of dots.)
Alternatively, you could add a simple setting to the Job Settings file, and add a conditional statement to the rotation for people who don't suffer from the lag. [HIDE] Code: [Setting] [DefaultValue(false)] [Category("Ninja")] public bool UseRaiton{ get; set; } [Setting] [DefaultValue(true)] [Category("Ninja")] public bool UseFuma{ get; set; } [/HIDE] Just a suggestion. Thank you for your hard work on this rotation! EDIT: More alternatively, you could add something like this to generate a list of mobs to prefer one or the other over. [HIDE] Code: private List<String> _FumaTargets; [Description("Targets to use Fuma Shuriken instead of Raiton (For targets that resist magic)")] [Editor(@"System.Windows.Forms.Design.StringCollectionEditor," + "System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(System.Drawing.Design.UITypeEditor))] [TypeConverter(typeof(CsvConverter))] [Category("Ninjutsu")] [DisplayName("Fuma Shuriken Targets")] public List<String> FumaTargets { get { if (_FumaTargets == null) _FumaTargets = new List<String>(); return _FumaTargets; } } [/HIDE] *NOTE* That csv converter comes out of the Kupper settings, and may or may not work in YRB. The rest of it will. The code for it is here: [HIDE] Code: public class CsvConverter : TypeConverter { // Overrides the ConvertTo method of TypeConverter. public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) { List<String> v = value as List<String>; if (destinationType == typeof(string)) { return String.Join(",", v.ToArray()); } return base.ConvertTo(context, culture, value, destinationType); } } [/HIDE]
I'm wondering how much of a pain in the ass it would be for the creator to make a GUI for making combat rotations as an alternative to having us make one in code. Would help us less versed users .
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; namespace YourRaidingBuddy.Rotations { public class Monk : Root { private static LocalPlayer Me { get { return Core.Player; } } //Core.Player.CurrentTarget as BattleCharacter public override ClassJobType[] Class { get { return new[] { ClassJobType.Monk }; } } public override void OnInitialize() { ; } #region NewRotation public static async Task<bool> AutoMode() { if (!Me.CurrentTarget.IsViable()) return false; return await MonkOpener(); } public static async Task<bool> HotkeyMode() { if (!Me.CurrentTarget.IsViable()) return false; // if (VariableBook.HkmMultiTarget) await MonkAoE(); return await MonkOpener(); } public static async Task<bool> MonkOpener() { if (await Spell.ApplyCast("Perfect Balance", Me, () => !Me.HasAura("Perfect Balance"))) return true; if (await Spell.ApplyCast("Internal Release", Me, () => !Me.HasAura("Internal Release"))) return true; if (await Spell.ApplyCast("Blood for Blood", Me, () => !Me.HasAura("Blood for Blood"))) return true; if (await Spell.ApplyCast("Demolish", Me.CurrentTarget, () => !Me.CurrentTarget.HasAura("Demolish") if (await Spell.CastSpell("Snap Punch", Me, () => !Me.HasAura("Greased Lightning II"))) return true; if (await Spell.CastSpell("Snap Punch", Me, () => !Me.HasAura("Greased Lightning III"))) return true; if (await Spell.NoneGcdCast("Elixir Field", Me, () => !Me.HasAura("Greased Lightning III"))) return true; if (await Spell.NoneGcdCast("Howling Fist", Me, () => !Me.HasAura("Greased Lightning III"))) return true; if (await Spell.NoneGcdCast("Steel Peak", Me, () => !Me.HasAura("Greased Lightning III"))) return true; return false;
what i have so far i havent been able to test due to patch but wondering if some of you better coders could look at the code and see if there is something wrong
also curious about the opener and if it will repeat itself or do i need to add cooldowns to the rotation as well
1. at the end of Demolish you do not have a return statement and your missing 2 more closing ). 2. after the return false; make sure to add your closing bracket } 3. Not sure what the mnk rotations is but based on this CR it will do this. 1. Pop your Cool Downs 2. Cast Demolish if your target does not have the debuff 3. Will cast 2 Snap punches witch gets you to GL3 4. Since your at GL3 it will never cast Elixir, howling, or Steel Peak you may want to delete the ! mark so it actually casts these skills. You also may want to change it to this. 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; namespace YourRaidingBuddy.Rotations { public class Monk : Root { private static LocalPlayer Me { get { return Core.Player; } } //Core.Player.CurrentTarget as BattleCharacter public override ClassJobType[] Class { get { return new[] { ClassJobType.Monk }; } } public override void OnInitialize() { ; } #region NewRotation public static async Task<bool> AutoMode() { if (!Me.CurrentTarget.IsViable()) return false; return await MonkRotation(); } public static async Task<bool> HotkeyMode() { if (!Me.CurrentTarget.IsViable()) return false; // if (VariableBook.HkmMultiTarget) await MonkAoE(); return await MonkRotation(); } public static async Task<bool> MonkRotation { await MonkOpener(); return false; } public static async Task<bool> MonkOpener() { if (await Spell.ApplyCast("Perfect Balance", Me, () => !Me.HasAura("Perfect Balance"))) return true; if (await Spell.ApplyCast("Internal Release", Me, () => !Me.HasAura("Internal Release"))) return true; if (await Spell.ApplyCast("Blood for Blood", Me, () => !Me.HasAura("Blood for Blood"))) return true; if (await Spell.ApplyCast("Demolish", Me.CurrentTarget, () => !Me.CurrentTarget.HasAura("Demolish"))) return true; if (await Spell.CastSpell("Snap Punch", Me, () => !Me.HasAura("Greased Lightning II"))) return true; if (await Spell.CastSpell("Snap Punch", Me, () => !Me.HasAura("Greased Lightning III"))) return true; if (await Spell.NoneGcdCast("Elixir Field", Me, () => !Me.HasAura("Greased Lightning III"))) return true; if (await Spell.NoneGcdCast("Howling Fist", Me, () => !Me.HasAura("Greased Lightning III"))) return true; if (await Spell.NoneGcdCast("Steel Peak", Me, () => !Me.HasAura("Greased Lightning III"))) return true; return false; } #endregion
ok i took your advice and made the changes it now looks like this public static async Task<bool> MonkOpener() { if (await Spell.ApplyCast("Perfect Balance", Me, () => !Me.HasAura("Perfect Balance"))) return true; if (await Spell.ApplyCast("Internal Release", Me, () => !Me.HasAura("Internal Release"))) return true; if (await Spell.ApplyCast("Blood for Blood", Me, () => !Me.HasAura("Blood for Blood"))) return true; if (await Spell.ApplyCast("Demolish", Me.CurrentTarget, () => !Me.CurrentTarget.HasAura("Demolish"))) return true; if (await Spell.CastSpell("Snap Punch", Me, () => !Me.HasAura("Greased Lightning II"))) return true; if (await Spell.CastSpell("Snap Punch", Me, () => !Me.HasAura("Greased Lightning III"))) return true; if (await Spell.NoneGcdCast("Elixir Field", Me, () => Me.HasAura("Greased Lightning III"))) return true; if (await Spell.NoneGcdCast("Howling Fist", Me, () => Me.HasAura("Greased Lightning III"))) return true; if (await Spell.NoneGcdCast("Steel Peak", Me, () => Me.HasAura("Greased Lightning III"))) return true; return false; }
As it is it will just repeat the opener over and over again but after it does the opener once since the condition of the skills are already met it will probably just auto attack.
i was kind of looking at yours and mirroring somewhat what you did and i saw that you split the ninja into an opener and then the rotation but i guess i could add the rest of my abilities underneath that and it would continue the chain?
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; namespace YourRaidingBuddy.Rotations { public class Monk : Root { private static LocalPlayer Me { get { return Core.Player; } } //Core.Player.CurrentTarget as BattleCharacter public override ClassJobType[] Class { get { return new[] { ClassJobType.Monk }; } } public override void OnInitialize() { ; } #region NewRotation public static async Task<bool> AutoMode() { if (!Me.CurrentTarget.IsViable()) return false; return await MonkOpener(); } public static async Task<bool> HotkeyMode() { if (!Me.CurrentTarget.IsViable()) return false; // if (VariableBook.HkmMultiTarget) await MonkAoE(); return await MonkOpener(); } public static async Task<bool> MonkOpener() { if (await Spell.ApplyCast("Perfect Balance", Me, () => !Me.HasAura("Perfect Balance"))) return true; if (await Spell.ApplyCast("Internal Release", Me, () => !Me.HasAura("Internal Release"))) return true; if (await Spell.ApplyCast("Blood for Blood", Me, () => !Me.HasAura("Blood for Blood"))) return true; if (await Spell.ApplyCast("Demolish", Me.CurrentTarget, () => !Me.CurrentTarget.HasAura("Demolish"))) return true; if (await Spell.CastSpell("Snap Punch", Me, () => !Me.HasAura("Greased Lightning II"))) return true; if (await Spell.CastSpell("Snap Punch", Me, () => !Me.HasAura("Greased Lightning III"))) return true; if (await Spell.NoneGcdCast("Elixir Field", Me, () => Me.HasAura("Greased Lightning III"))) return true; if (await Spell.NoneGcdCast("Howling Fist", Me, () => Me.HasAura("Greased Lightning III"))) return true; if (await Spell.NoneGcdCast("Steel Peak", Me, () => Me.HasAura("Greased Lightning III"))) return true; { if (await Spell.CastSpell("Bootshine", Me, () => Me.CurrentTarget.IsBehind))) return true; if (await Spell.CastSpell("Truestrike", Me, () => Me.HasAura("Raptor Form") && Me.CurrentTarget.IsBehind))) return true; if (await Spell.CastSpell("Demolish", Me, () => Me.HasAura("Coeurl Form") && Me.CurrentTarget.IsBehind))) return true; if (await Spell.CastSpell("Dragon Kick", Me, () => Me.CurrentTarget.IsFlanking))) return true; if (await Spell.CastSpell("Twin Snakes", Me, () => Me.HasAura("Raptor Form") && Me.CurrentTarget.IsFlanking))) return true; if (await Spell.CastSpell("Snap Punch", Me, () => Me.HasAura("Coeurl Form") && Me.CurrentTarget.IsBehind))) return true; return false; } #endregion } }
Soo after 9 hours of carefully testing i have gotten to the point where i get all the abilities in my list to work ONCE i am not sure why but it will correctly perform the rotation once and then just auto attack afterwards could use some help here is the code i am using 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; namespace YourRaidingBuddy.Rotations { public class Monk : Root { private static LocalPlayer Me { get { return Core.Player; } } //Core.Player.CurrentTarget as BattleCharacter public override ClassJobType[] Class { get { return new[] { ClassJobType.Monk }; } } public override void OnInitialize() { ; } #region NewRotation public static async Task<bool> AutoMode() { if (!Me.CurrentTarget.IsViable()) return false; return await MonkRotation(); } public static async Task<bool> HotkeyMode() { if (!Me.CurrentTarget.IsViable()) return false; // if (VariableBook.HkmMultiTarget) await NinjaAoE(); return await MonkRotation(); } public static async Task<bool> MonkRotation() { if (await Spell.ApplyCast("Perfect Balance", Me, () => !Me.HasAura("Perfect Balance"))) return true; if (await Spell.NoneGcdCast("Internal Release", Me, () => !Me.HasAura("Internal Release"))) return true; if (await Spell.NoneGcdCast("Blood for Blood", Me, () => !Me.HasAura("Blood for Blood"))) return true; if (await Spell.ApplyCast("Demolish", Me.CurrentTarget, () => !Me.CurrentTarget.HasAura("Demolish"))) return true; if (await Spell.CastSpell("Snap Punch", Me.CurrentTarget, () => !Me.HasAura(112))); if (await Spell.CastSpell("Snap Punch", Me.CurrentTarget, () => !Me.HasAura(113))); if (await Spell.NoneGcdCast("Elixir Field", Me.CurrentTarget, () => true)); if (await Spell.NoneGcdCast("Howling Fist", Me.CurrentTarget, () => true)); if (await Spell.NoneGcdCast("Steel Peak", Me.CurrentTarget, () => true)); if (await Spell.CastSpell("Demolish", Me.CurrentTarget, () => Me.HasAura("Coeurl Form") && Me.CurrentTarget.IsBehind)); if (await Spell.CastSpell("True Strike", Me.CurrentTarget, () => Me.HasAura("Raptor Form") && Me.CurrentTarget.IsBehind)); if (await Spell.CastSpell("Bootshine", Me.CurrentTarget, () => Me.CurrentTarget.IsBehind)); if (await Spell.CastSpell("Bootshine", Me.CurrentTarget, () => Me.HasAura("Opo-opo Form") && Me.CurrentTarget.IsBehind)); if (await Spell.CastSpell("Snap Punch", Me.CurrentTarget, () => Me.HasAura("Coeurl Form") && Me.CurrentTarget.IsFlanking)); if (await Spell.CastSpell("Twin Snakes", Me.CurrentTarget, () => Me.HasAura("Raptor Form") && Me.CurrentTarget.IsFlanking)); if (await Spell.CastSpell("Dragon Kick", Me.CurrentTarget, () => Me.CurrentTarget.IsFlanking)); if (await Spell.CastSpell("Dragon Kick", Me.CurrentTarget, () => Me.HasAura("Opo-opo Form") && Me.CurrentTarget.IsFlanking)); return false; } #endregion } }
[01:24:06.017 N] Compiler Error: c:\Users\Carlos\Desktop\Rebornbuddy 1.0.240.0\Routines\YourRaidingBuddy\Rotations\Jobs\Monk.cs(70,87) : error CS1010: Newline in constant [01:24:06.017 N] Compiler Error: c:\Users\Carlos\Desktop\Rebornbuddy 1.0.240.0\Routines\YourRaidingBuddy\Rotations\Jobs\Monk.cs(115,2) : error CS1056: Unexpected character '`' [01:24:06.017 N] Compiler Error: c:\Users\Carlos\Desktop\Rebornbuddy 1.0.240.0\Routines\YourRaidingBuddy\Rotations\Jobs\Monk.cs(122,26) : error CS1010: Newline in constant [01:24:06.017 N] Compiler Error: c:\Users\Carlos\Desktop\Rebornbuddy 1.0.240.0\Routines\YourRaidingBuddy\Rotations\Jobs\Monk.cs(137,26) : error CS1010: Newline in constant [01:24:06.017 N] Compiler Error: c:\Users\Carlos\Desktop\Rebornbuddy 1.0.240.0\Routines\YourRaidingBuddy\Rotations\Jobs\Monk.cs(128,22) : error CS1002: ; expected