From bad79cfa18b160ab45d85a17f051fdc495595a68 Mon Sep 17 00:00:00 2001 From: DreadedSlug Date: Fri, 20 Feb 2026 11:33:20 -0800 Subject: [PATCH 1/4] Trying to simplify taunts in Gramiel --- Ultras/UltraGramiel.cs | 169 +++++++++++++++-------------------------- 1 file changed, 63 insertions(+), 106 deletions(-) diff --git a/Ultras/UltraGramiel.cs b/Ultras/UltraGramiel.cs index 6361edb70..b3b211d8b 100644 --- a/Ultras/UltraGramiel.cs +++ b/Ultras/UltraGramiel.cs @@ -13,6 +13,8 @@ using System; using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; using Skua.Core.Interfaces; using Skua.Core.Options; @@ -207,6 +209,7 @@ void Prep(bool skipEnhancements = false) _ => throw new NotImplementedException(), }; + Core.EquipRandomClassAndReequip(); Ultra.EquipClassSync(classes, 4, "gramiel_class.sync"); } @@ -508,49 +511,11 @@ void AttackWithPriority() if (shouldExecuteTaunt) { shouldExecuteTaunt = false; - Core.DisableSkills(); - Bot.Sleep(500); - C.Logger($"{className} executing taunt #{tauntCounter}!"); + Bot.Log($"[GRAMIEL] {className} executing taunt #{tauntCounter}!"); + Ultra.UseTaunt(crystalMapId); + Bot.Log($"[GRAMIEL] Taunt #{tauntCounter} landed!"); - int attempts = 0; - bool tauntLanded = false; - while (!Bot.ShouldExit && attempts < 15) - { - if (!Bot.Player.Alive) - break; - - if (!Bot.Player.HasTarget) - Bot.Combat.Attack(crystalMapId); // Re-target crystal - - if (Bot.Skills.CanUseSkill(5)) - Bot.Skills.UseSkill(5); - - Bot.Sleep(500); - attempts++; - - // Check if Focus aura appeared (taunt landed) - if (Bot.Player.HasTarget && Bot.Target?.Auras?.Any(a => a?.Name == "Focus") == true) - { - C.Logger($"Taunt #{tauntCounter} landed after {attempts} attempts"); - tauntLanded = true; - Bot.Sleep(500); - break; - } - } - - if (!tauntLanded) - { - C.Logger($"WARNING: Taunt #{tauntCounter} FAILED after {attempts} attempts!"); - if (Bot.Player.HasTarget && Bot.Target?.Auras != null) - { - string auraNames = string.Join(", ", Bot.Target.Auras.Select(a => a?.Name ?? "null")); - C.Logger($"Target auras present: {auraNames}"); - } - } - - Core.EnableSkills(); - Bot.Sleep(300); return; } @@ -604,33 +569,9 @@ void AttackWithPriority() if (inTauntWindow && noFocusAura) { - Core.DisableSkills(); - Bot.Sleep(500); - C.Logger($"Gramiel taunt window ({currentTime:F1}s into fight, offset {tauntOffsetSeconds}s)"); - - int attempts = 0; - while (!Bot.ShouldExit && attempts < 15) - { - if (!Bot.Player.Alive) - break; - - if (!Bot.Player.HasTarget) - Bot.Combat.Attack(gramielMapId); - - if (Bot.Skills.CanUseSkill(5)) - Bot.Skills.UseSkill(5); - - Bot.Sleep(500); - attempts++; - - if (Bot.Player.HasTarget && Bot.Target?.Auras?.Any(a => a?.Name == "Focus") == true) - { - C.Logger("Gramiel taunt landed - Focus aura detected!"); - Bot.Sleep(500); - break; - } - } + Ultra.UseTaunt(gramielMapId); + C.Logger("Gramiel taunt landed!"); Core.EnableSkills(); Bot.Sleep(300); @@ -639,63 +580,79 @@ void AttackWithPriority() } // Packet Handler for Gramiel Warning Messages - private void GramielMessageListener(dynamic packet) + private async void GramielMessageListener(dynamic packet) { try { - string type = packet["params"].type; - if (type is not "json") - return; - - if (!Bot.Player.Alive) + if (packet?["params"]?.type?.ToString() != "json") return; dynamic data = packet["params"].dataObj; - string cmd = data.cmd.ToString(); - - if (cmd != "ct") + if (data?.cmd?.ToString() != "ct") return; - // Check for messages in anims array (boss messages appear here) - if (data.anims is null) + if (data?.anims is null) return; foreach (dynamic anim in data.anims) { - if (anim is null || anim.msg is null) + if (anim is null) continue; - string message = (string)anim.msg; - - // Check for crystal defense shattering attack warning - if (message.Contains("The Grace Crystal prepares a defense shattering attack!", StringComparison.OrdinalIgnoreCase)) + string? message = anim?.msg?.ToString(); + if (!string.IsNullOrEmpty(message) && + message.Contains("defense shattering attack", StringComparison.OrdinalIgnoreCase)) { - // Debounce: Ignore if we received this message within the last 2 seconds -- avoid double taunts - TimeSpan timeSinceLastWarning = DateTime.Now - lastTauntWarningTime; - if (timeSinceLastWarning.TotalSeconds < 2) - { - return; - } - - lastTauntWarningTime = DateTime.Now; - tauntCounter++; - C.Logger($"Crystal attack warning detected! (Taunt #{tauntCounter})"); - - // Determine if this player should taunt - // T1 taunters taunt on odd counts (1, 3, 5...) - // T2 taunters taunt on even counts (2, 4, 6...) - bool shouldTaunt = (isT1Taunter && tauntCounter % 2 == 1) || - (!isT1Taunter && tauntCounter % 2 == 0); - - if (shouldTaunt) - { - C.Logger($"Taunt #{tauntCounter} assigned to {(isT1Taunter ? "T1" : "T2")}"); - shouldExecuteTaunt = true; - } + Bot.Log($"[GRAMIEL] Crystal warning packet received"); + await HandleCrystalWarning(); + return; } } } - catch { } + catch (Exception ex) + { + Bot.Log($"[GRAMIEL] Listener exception: {ex.Message}"); + } + } + + private async Task HandleCrystalWarning() + { + try + { + // Debounce: Ignore if we received this message within the last 500ms -- avoid double taunts (AE sends dupes) + TimeSpan timeSinceLastWarning = DateTime.Now - lastTauntWarningTime; + if (timeSinceLastWarning.TotalMilliseconds < 500) + { + Bot.Log($"[GRAMIEL] Debounce: Ignoring duplicate ({timeSinceLastWarning.TotalMilliseconds:F0}ms ago)"); + return; + } + + lastTauntWarningTime = DateTime.Now; + int currentCount = Interlocked.Increment(ref tauntCounter); + + Bot.Log($"[GRAMIEL] Warning #{currentCount} | Role: {(isT1Taunter ? "T1" : "T2")} | Crystal: {crystalMapId}"); + + // T1 taunters taunt on odd counts (1, 3, 5...) + // T2 taunters taunt on even counts (2, 4, 6...) + bool shouldTaunt = (isT1Taunter && currentCount % 2 == 1) || + (!isT1Taunter && currentCount % 2 == 0); + + if (shouldTaunt) + { + Bot.Log($"[GRAMIEL] MY TURN - Setting shouldExecuteTaunt=true"); + shouldExecuteTaunt = true; + } + else + { + Bot.Log($"[GRAMIEL] Not my turn (counter={currentCount}, isT1={isT1Taunter})"); + } + } + catch (Exception ex) + { + Bot.Log($"[GRAMIEL] HandleCrystalWarning exception: {ex.Message}"); + } + + await Task.CompletedTask; } public enum GramielComp From 969d39f2e5b0021d0bb7b338828131cd6f1b1d9e Mon Sep 17 00:00:00 2001 From: DreadedSlug Date: Fri, 20 Feb 2026 11:47:25 -0800 Subject: [PATCH 2/4] bot fixes --- Ultras/UltraGramiel.cs | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/Ultras/UltraGramiel.cs b/Ultras/UltraGramiel.cs index b3b211d8b..a1a31ef48 100644 --- a/Ultras/UltraGramiel.cs +++ b/Ultras/UltraGramiel.cs @@ -14,7 +14,6 @@ using System; using System.Collections.Generic; using System.Threading; -using System.Threading.Tasks; using Skua.Core.Interfaces; using Skua.Core.Options; @@ -108,9 +107,9 @@ private static CoreAdvanced Adv public string OptionsStorage = "UltraGramiel"; // Gramiel warning tracking - private int tauntCounter = 0; + private volatile int tauntCounter = 0; private DateTime lastTauntWarningTime = DateTime.MinValue; - private bool shouldExecuteTaunt = false; + private volatile bool shouldExecuteTaunt = false; // Gramiel boss taunt timer (4 rotation, 5 seconds per taunt) private DateTime gramielFightStartTime = DateTime.MinValue; @@ -569,7 +568,14 @@ void AttackWithPriority() if (inTauntWindow && noFocusAura) { + // Stop all skill systems before taunting + Core.DisableSkills(); + Bot.Skills.Stop(); + Bot.Sleep(Core.D2); // Use standard delay (700ms) + C.Logger($"Gramiel taunt window ({currentTime:F1}s into fight, offset {tauntOffsetSeconds}s)"); + + // Use the proven UseTaunt pattern Ultra.UseTaunt(gramielMapId); C.Logger("Gramiel taunt landed!"); @@ -580,7 +586,7 @@ void AttackWithPriority() } // Packet Handler for Gramiel Warning Messages - private async void GramielMessageListener(dynamic packet) + private void GramielMessageListener(dynamic packet) { try { @@ -604,7 +610,7 @@ private async void GramielMessageListener(dynamic packet) message.Contains("defense shattering attack", StringComparison.OrdinalIgnoreCase)) { Bot.Log($"[GRAMIEL] Crystal warning packet received"); - await HandleCrystalWarning(); + HandleCrystalWarning(); return; } } @@ -615,7 +621,7 @@ private async void GramielMessageListener(dynamic packet) } } - private async Task HandleCrystalWarning() + private void HandleCrystalWarning() { try { @@ -651,8 +657,6 @@ private async Task HandleCrystalWarning() { Bot.Log($"[GRAMIEL] HandleCrystalWarning exception: {ex.Message}"); } - - await Task.CompletedTask; } public enum GramielComp From f6cf3a9c525549d432c81dea70be298b66ea34ad Mon Sep 17 00:00:00 2001 From: DreadedSlug Date: Fri, 20 Feb 2026 11:49:45 -0800 Subject: [PATCH 3/4] removing extras --- Ultras/UltraGramiel.cs | 7 ------- 1 file changed, 7 deletions(-) diff --git a/Ultras/UltraGramiel.cs b/Ultras/UltraGramiel.cs index a1a31ef48..68470b17a 100644 --- a/Ultras/UltraGramiel.cs +++ b/Ultras/UltraGramiel.cs @@ -568,14 +568,7 @@ void AttackWithPriority() if (inTauntWindow && noFocusAura) { - // Stop all skill systems before taunting - Core.DisableSkills(); - Bot.Skills.Stop(); - Bot.Sleep(Core.D2); // Use standard delay (700ms) - C.Logger($"Gramiel taunt window ({currentTime:F1}s into fight, offset {tauntOffsetSeconds}s)"); - - // Use the proven UseTaunt pattern Ultra.UseTaunt(gramielMapId); C.Logger("Gramiel taunt landed!"); From 45f99e5cab5c9c1d1c69805eee77b6f89cde1241 Mon Sep 17 00:00:00 2001 From: DreadedSlug Date: Fri, 20 Feb 2026 12:01:31 -0800 Subject: [PATCH 4/4] cleanup --- Ultras/UltraGramiel.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Ultras/UltraGramiel.cs b/Ultras/UltraGramiel.cs index 68470b17a..203db7246 100644 --- a/Ultras/UltraGramiel.cs +++ b/Ultras/UltraGramiel.cs @@ -107,9 +107,9 @@ private static CoreAdvanced Adv public string OptionsStorage = "UltraGramiel"; // Gramiel warning tracking - private volatile int tauntCounter = 0; + private int tauntCounter = 0; private DateTime lastTauntWarningTime = DateTime.MinValue; - private volatile bool shouldExecuteTaunt = false; + private bool shouldExecuteTaunt = false; // Gramiel boss taunt timer (4 rotation, 5 seconds per taunt) private DateTime gramielFightStartTime = DateTime.MinValue;