From f514890e3ebce21b2f11d74e0d9e96e28a1837fb Mon Sep 17 00:00:00 2001 From: Robmart <4825809+robmart@users.noreply.github.com> Date: Sun, 5 Apr 2026 10:15:26 +0200 Subject: [PATCH 1/5] Eclipse Ascent scripts --- .../0GreatbladeoftheEntwinedEclipse.cs | 103 ++++ .../CelestialTempleForgeMerge.cs | 187 ++++++ Dungeons/EclipseAscent/CoreEclipse.cs | 552 ++++++++++++++++++ 3 files changed, 842 insertions(+) create mode 100644 Dungeons/EclipseAscent/0GreatbladeoftheEntwinedEclipse.cs create mode 100644 Dungeons/EclipseAscent/CelestialTempleForgeMerge.cs create mode 100644 Dungeons/EclipseAscent/CoreEclipse.cs diff --git a/Dungeons/EclipseAscent/0GreatbladeoftheEntwinedEclipse.cs b/Dungeons/EclipseAscent/0GreatbladeoftheEntwinedEclipse.cs new file mode 100644 index 000000000..afd86c1ae --- /dev/null +++ b/Dungeons/EclipseAscent/0GreatbladeoftheEntwinedEclipse.cs @@ -0,0 +1,103 @@ +//cs_include Scripts/CoreBots.cs +//cs_include Scripts/CoreAdvanced.cs +//cs_include Scripts/Ultras/CoreEngine.cs +//cs_include Scripts/Ultras/CoreUltra.cs +//cs_include Scripts/Dungeons/EclipseAscent/CoreEclipse.cs +//cs_include Scripts/Dungeons/EclipseAscent/CelestialTempleForgeMerge.cs +//cs_include Scripts/Army/CoreArmyLite.cs + +using Skua.Core.Interfaces; +using Skua.Core.Models; +using Skua.Core.Options; + +namespace SkuaScripts.Scripts.Custom.EclipseAscent; + +public class GreatbladeoftheEntwinedEclipse { + private IScriptInterface Bot => IScriptInterface.Instance; + public CoreBots C => CoreBots.Instance; + private static CoreAdvanced Adv = new(); + public CoreUltra Ultra = new(); + private static CoreArmyLite sArmy = new(); + public CoreEclipse coreEclipse = new(); + public CelestialTempleForgeMerge templeMerge = new(); + + public bool DontPreconfigure = true; + public string OptionsStorage = "EclipseAscent"; + public List Options = new() + { + new Option( + "player1", + "Account #1", + "This character will be using Legion Revenant", + "" + ), + new Option( + "player2", + "Account #2", + "This character will be using StoneCrusher", + "" + ), + new Option( + "player3", + "Account #3", + "This character will be using ArchPaladin", + "" + ), + new Option( + "player4", + "Account #4", + "This character will be using Lord Of Order", + "" + ), + new Option( + "autoclass", + "Auto Equip Classes", + "This will auto equip all classes, if false it will use the classes already equipped.", + true + ), + CoreBots.Instance.SkipOptions, + }; + + public void ScriptMain(IScriptInterface Bot) { + Bot.Events.ScriptStopping += OnBotStopped; + Bot.Events.ExtensionPacketReceived += sArmy.PartyManagement; + + C.BankingBlackList.AddRange(new[] { "Sliver of Moonlight", "Sliver of Sunlight", "Victor of the Festival", "Ecliptic Offering"}); + + C.SetOptions(); + C.SendPackets($"%xt%zm%cmd%1%uopref%bParty%true%"); //To be able to join party + + while (!Bot.ShouldExit && sArmy.PartyMemberArray()!.Length < 4) + coreEclipse.SetupParty(); + + C.SendPackets($"%xt%zm%cmd%1%uopref%bParty%false%"); + + Adv.GearStore(EnhAfter: true); + + coreEclipse.EquipWait(); + coreEclipse.EquipClasses(true); + + templeMerge.BuyAllMerge(""); + + sArmy.PartyLeave(); + + Bot.Events.ScriptStopping -= OnBotStopped; + Bot.Events.ExtensionPacketReceived -= sArmy.PartyManagement; + + Adv.GearStore(true, EnhAfter: true); + + C.SetOptions(false); + } + + private bool OnBotStopped(Exception? exception) { + Bot.Events.ScriptStopping -= OnBotStopped; + Bot.Events.ExtensionPacketReceived -= sArmy.PartyManagement; + + C.JumpWait(); + sArmy.PartyLeave(); + + Adv.GearStore(true, EnhAfter: true); + + return true; + } +} \ No newline at end of file diff --git a/Dungeons/EclipseAscent/CelestialTempleForgeMerge.cs b/Dungeons/EclipseAscent/CelestialTempleForgeMerge.cs new file mode 100644 index 000000000..7d7877c2d --- /dev/null +++ b/Dungeons/EclipseAscent/CelestialTempleForgeMerge.cs @@ -0,0 +1,187 @@ +/* +name: Celestial Temple Forge Merge +description: This bot will farm the items belonging to the selected mode for the Celestial Temple Forge Merge [2303] in /templeshrine +tags: celestial, temple, forge, merge, templeshrine, rite, ascension, solarbrand, lunarbrand, umbrabrand, burning, sun, glowing, moon, bound, eclipse, greatblade, midnight, solstice, entwined +*/ +//cs_include Scripts/CoreBots.cs +//cs_include Scripts/CoreFarms.cs +//cs_include Scripts/CoreAdvanced.cs +//cs_include Scripts/Dungeons/EclipseAscent/CoreEclipse.cs +//cs_include Scripts/Army/CoreArmyLite.cs +//cs_include Scripts/Story/VictorMatsuri.cs +using Skua.Core.Interfaces; +using Skua.Core.Models.Items; +using Skua.Core.Options; +using SkuaScripts.Scripts.Custom.EclipseAscent; + +public class CelestialTempleForgeMerge +{ + private IScriptInterface Bot => IScriptInterface.Instance; + private CoreBots Core => CoreBots.Instance; + private static CoreFarms Farm { get => _Farm ??= new CoreFarms(); set => _Farm = value; } + private static CoreFarms _Farm; + private static CoreAdvanced Adv { get => _Adv ??= new CoreAdvanced(); set => _Adv = value; } + private static CoreAdvanced _Adv; + private static CoreAdvanced sAdv { get => _sAdv ??= new CoreAdvanced(); set => _sAdv = value; } + private static CoreAdvanced _sAdv; + public CoreEclipse coreEclipse = new(); + private static CoreArmyLite sArmy = new(); + private static VictorMatsuri VictorMatsuri = new(); + + + public bool DontPreconfigure = true; + public List Generic = sAdv.MergeOptions; + public string[] MultiOptions = { "Generic", "Select" }; + public string OptionsStorage = sAdv.OptionsStorage; + // [Can Change] This should only be changed by the author. + // If true, it will not stop the script if the default case triggers and the user chose to only get mats + private bool dontStopMissingIng = false; + public List Options = new() + { + new Option( + "player1", + "Account #1", + "This character will be using Legion Revenant", + "" + ), + new Option( + "player2", + "Account #2", + "This character will be using StoneCrusher", + "" + ), + new Option( + "player3", + "Account #3", + "This character will be using ArchPaladin", + "" + ), + new Option( + "player4", + "Account #4", + "This character will be using Lord Of Order", + "" + ), + new Option( + "autoclass", + "Auto Equip Classes", + "This will auto equip all classes, if false it will use the classes already equipped.", + true + ), + }; + + public void ScriptMain(IScriptInterface Bot) + { + Bot.Events.ScriptStopping += OnBotStopped; + Bot.Events.ExtensionPacketReceived += sArmy.PartyManagement; + + Core.BankingBlackList.AddRange(new[] { "Sliver of Moonlight", "Sliver of Sunlight", "Victor of the Festival", "Ecliptic Offering"}); + + Core.SetOptions(); + Core.SendPackets($"%xt%zm%cmd%1%uopref%bParty%true%"); //To be able to join party + + while (!Bot.ShouldExit && sArmy.PartyMemberArray()!.Length < 4) + coreEclipse.SetupParty(); + + Core.SendPackets($"%xt%zm%cmd%1%uopref%bParty%false%"); + + Adv.GearStore(EnhAfter: true); + + coreEclipse.EquipWait(); + coreEclipse.EquipClasses(true); + + BuyAllMerge(); + + sArmy.PartyLeave(); + + Bot.Events.ScriptStopping -= OnBotStopped; + Bot.Events.ExtensionPacketReceived -= sArmy.PartyManagement; + + Adv.GearStore(true, EnhAfter: true); + + Core.SetOptions(false); + } + + public void BuyAllMerge(string? buyOnlyThis = null, mergeOptionsEnum? buyMode = null) + { + //Only edit the map and shopID here + Adv.StartBuyAllMerge("templeshrine", 2303, findIngredients, buyOnlyThis, buyMode: buyMode); + + #region Dont edit this part + void findIngredients() + { + ItemBase req = Adv.externalItem; + int quant = Adv.externalQuant; + int currentQuant = req.Temp ? Bot.TempInv.GetQuantity(req.Name) : Bot.Inventory.GetQuantity(req.Name); + var sliverQuant = quant + (!Core.CheckInventory("Rite of Ascension") ? 1 : 0); + if (req == null) + { + Core.Logger("req is NULL"); + return; + } + + switch (req.Name) + { + default: + bool shouldStop = !Adv.matsOnly || !dontStopMissingIng; + Core.Logger($"The bot hasn't been taught how to get {req.Name}." + (shouldStop ? " Please report the issue." : " Skipping"), messageBox: shouldStop, stopBot: shouldStop); + break; + #endregion + + case "Sliver of Moonlight": + Core.FarmingLogger(req.Name, sliverQuant); + coreEclipse.GetSliverOfMoonlight(sliverQuant); + break; + + + case "Sliver of Sunlight": + Core.FarmingLogger(req.Name, sliverQuant); + coreEclipse.GetSliverOfSunlight(sliverQuant); + break; + + + case "Victor of the Festival": + VictorMatsuri.Storyline(); + if (!Core.CheckInventory("Victor of the Festival")) { + Core.Logger("Victor Matsuri questline didn't finish, exiting..."); + Bot.StopSync(true); + } + break; + + + case "Ecliptic Offering": + if (!Core.CheckInventory("Rite of Ascension")) + BuyAllMerge("Rite of Ascension"); + Core.FarmingLogger("Ecliptic Offering", quant); + coreEclipse.GetEclipticOffering(quant); + break; + } + } + } + + public List Select = new() + { + new Option("78809", "Rite of Ascension", "Mode: [select] only\nShould the bot buy \"Rite of Ascension\" ?", false), + new Option("78465", "Solarbrand", "Mode: [select] only\nShould the bot buy \"Solarbrand\" ?", false), + new Option("78460", "Lunarbrand", "Mode: [select] only\nShould the bot buy \"Lunarbrand\" ?", false), + new Option("78455", "Umbrabrand", "Mode: [select] only\nShould the bot buy \"Umbrabrand\" ?", false), + new Option("78466", "Blade of the Burning Sun", "Mode: [select] only\nShould the bot buy \"Blade of the Burning Sun\" ?", false), + new Option("78461", "Blade of the Glowing Moon", "Mode: [select] only\nShould the bot buy \"Blade of the Glowing Moon\" ?", false), + new Option("78456", "Blade of the Bound Eclipse", "Mode: [select] only\nShould the bot buy \"Blade of the Bound Eclipse\" ?", false), + new Option("78467", "Greatblade of the Midnight Sun", "Mode: [select] only\nShould the bot buy \"Greatblade of the Midnight Sun\" ?", false), + new Option("78462", "Greatblade of the Solstice Moon", "Mode: [select] only\nShould the bot buy \"Greatblade of the Solstice Moon\" ?", false), + new Option("78457", "Greatblade of the Entwined Eclipse", "Mode: [select] only\nShould the bot buy \"Greatblade of the Entwined Eclipse\" ?", false), + }; + + private bool OnBotStopped(Exception? exception) { + Bot.Events.ScriptStopping -= OnBotStopped; + Bot.Events.ExtensionPacketReceived -= sArmy.PartyManagement; + + Core.JumpWait(); + sArmy.PartyLeave(); + + Adv.GearStore(true, EnhAfter: true); + + return true; + } +} diff --git a/Dungeons/EclipseAscent/CoreEclipse.cs b/Dungeons/EclipseAscent/CoreEclipse.cs new file mode 100644 index 000000000..120b4075f --- /dev/null +++ b/Dungeons/EclipseAscent/CoreEclipse.cs @@ -0,0 +1,552 @@ +//cs_include Scripts/CoreBots.cs +//cs_include Scripts/Ultras/CoreEngine.cs +//cs_include Scripts/Ultras/CoreUltra.cs +//cs_include Scripts/CoreAdvanced.cs +//cs_include Scripts/Army/CoreArmyLite.cs + +using Newtonsoft.Json; +using Skua.Core.Interfaces; +using Skua.Core.Models; +using Skua.Core.Models.Monsters; +using Skua.Core.Models.Skills; +using Skua.Core.Options; +using Skua.Core.Scripts; + +namespace SkuaScripts.Scripts.Custom.EclipseAscent; + +public class CoreEclipse { + private IScriptInterface Bot => IScriptInterface.Instance; + private CoreBots C => CoreBots.Instance; + private CoreEngine Core = new(); + private CoreUltra Ultra = new(); + private static CoreAdvanced Adv = new(); + private static CoreArmyLite sArmy = new(); + + public void EquipWait(string item = "Scroll of Enrage") { + C.Equip(item); + Bot.Wait.ForItemEquip(item); + Bot.Wait.ForActionCooldown(GameActions.EquipItem); + C.Sleep(); + } + + public void SetupParty() { + if (!Bot.Player.Username.Equals(Bot.Config!.Get("player1").ToLower())) return; + + if (!sArmy.PartyMemberArray().Contains(Bot.Config!.Get("player2")!.ToLower())) { + sArmy.PartyInvite(Bot.Config!.Get("player2")!); + Bot.Sleep(2000); + } + if (!sArmy.PartyMemberArray().Contains(Bot.Config!.Get("player3")!.ToLower())) { + sArmy.PartyInvite(Bot.Config!.Get("player3")!); + Bot.Sleep(2000); + } + if (!sArmy.PartyMemberArray().Contains(Bot.Config!.Get("player4")!.ToLower())) { + sArmy.PartyInvite(Bot.Config!.Get("player4")!); + Bot.Sleep(2000); + } + + Bot.Sleep(10000); + } + + public void EquipClasses(bool autoEnhance) { + if (!Bot.Config!.Get("autoclass")) return; + if (Bot.Player.Username.Equals(Bot.Config!.Get("player1").ToLower()) && C.CheckInventory("Legion Revenant")) { + C.Equip("Legion Revenant"); + if (!autoEnhance) return; + Adv.EnhanceEquipped( + type: EnhancementType.Wizard, + hSpecial: HelmSpecial.Pneuma, + wSpecial: Adv.uRavenous() ? WeaponSpecial.Ravenous : WeaponSpecial.Awe_Blast, + cSpecial: CapeSpecial.Vainglory + ); + } + else if (Bot.Player.Username.Equals(Bot.Config!.Get("player2").ToLower()) && C.CheckInventory("StoneCrusher")) { + C.Equip("StoneCrusher"); + if (!autoEnhance) return; + Adv.EnhanceEquipped( + type: EnhancementType.Fighter, + hSpecial: HelmSpecial.Anima, + wSpecial: Adv.uRavenous() ? WeaponSpecial.Ravenous : WeaponSpecial.Valiance, + cSpecial: CapeSpecial.Absolution + ); + } + else if (Bot.Player.Username.Equals(Bot.Config!.Get("player3").ToLower()) && C.CheckInventory("ArchPaladin")) { + C.Equip("ArchPaladin"); + if (!autoEnhance) return; + Adv.EnhanceEquipped( + type: EnhancementType.Lucky, + hSpecial: HelmSpecial.Forge, + wSpecial: Adv.uRavenous() ? WeaponSpecial.Ravenous : WeaponSpecial.Awe_Blast, + cSpecial: CapeSpecial.Penitence + ); + } + else if (Bot.Player.Username.Equals(Bot.Config!.Get("player4").ToLower()) && C.CheckInventory("Lord Of Order")) { + C.Equip("Lord Of Order"); + if (!autoEnhance) return; + Adv.EnhanceEquipped( + type: EnhancementType.Lucky, + hSpecial: HelmSpecial.Forge, + wSpecial: Adv.uArcanasConcerto() + ? WeaponSpecial.Arcanas_Concerto + : WeaponSpecial.Awe_Blast, + cSpecial: CapeSpecial.Penitence + ); + } + else { + C.Logger("Valid class not found"); + Bot.StopSync(true); + } + } + + public void GetScrollOfEnrage(int count = 100) { + if (!Core.Faction("SpellCrafting", 5)) + return; + + const string parchment = "Mystic Parchment"; + const string ink = "Zealous Ink"; + const string scroll = "Scroll of Enrage"; + + while (!Bot.ShouldExit && !C.CheckInventory(scroll, count)) { + // Mats + Core.ForItem("Undead Infantry", "underworld", parchment, 2); + Core.BuyItem(ink, 549, "dragonrune", 5, calculateRemaining: false); + + // Craft + Core.Join("spellcraft"); + Bot.Drops.Add(scroll); + Bot.Send.Packet("%xt%zm%crafting%1%spellOnStart%7%1555%Spell%"); + Bot.Sleep(5000); + Bot.Send.Packet("%xt%zm%crafting%1%spellComplete%7%2330%Enrage%"); + + Core.WaitForDrop(scroll, 10000); + Core.Pickup(scroll); + } + } + + public void GetSliverOfMoonlight(int count = 221) { //220 for the sword, 1 for Rite of Ascension + new SolsticeMoon(this, count); + } + + public void GetSliverOfSunlight(int count = 221) { //220 for the sword, 1 for Rite of Ascension + new MidnightSun(this, count); + } + + public void GetEclipticOffering(int count = 155) { //155 for the sword + new AscendEclipse(this, count); + } + + private bool needsEnrage; + private bool usedEnrage; + private bool usedLastEnrage; + private DateTimeOffset tauntTime; + private int deathCount; + //This is mostly a copy of CoreAOR.ColdThunderBoss + public void EclipseBossHandler(string startingEnragePlayer, string bossName, string enrageMessage, bool alternateEnrage = true, string bossCell = "r3", int tauntOffset = 0, int deathResetCount = 0, params string[] deathMessages) { + needsEnrage = false; + usedEnrage = false; + usedLastEnrage = alternateEnrage + ? Bot.Player.Username.Equals(Bot.Config!.Get(startingEnragePlayer).ToLower()) + : false; + deathCount = 0; + + Bot.Events.ScriptStopping += OnBotStopped; + Bot.Flash.FlashCall += Listener; + + //TODO: startingEnragePlayer should start the fight by using a scroll? + //TODO: Skip the enrage if they missed it badly enough that the other player's enrage is up + + C.Logger( + $"About to attack {bossName} boss." + ); + + while (!Bot.ShouldExit && Bot.Player.Cell == bossCell && + Bot.Monsters.CurrentMonsters.Any(x => x.Alive && x.Name.Equals(bossName))) + { + if (needsEnrage && !usedEnrage && !usedLastEnrage && Bot.Player.HasTarget && (tauntOffset <= 0 || DateTimeOffset.Now > tauntTime)) + { + C.Logger( + $"Detected '{enrageMessage}' - applying Scroll of Enrage..." + ); + + Bot.Skills.Pause(); + + // Keep trying to use scroll until it's successfully applied + while (!Bot.ShouldExit && Bot.Player.HasTarget && Bot.Player.Cell == bossCell && + Bot.Monsters.CurrentMonsters.Any(x => x.Alive && x.Name.Equals(bossName)) && needsEnrage && !usedEnrage && !usedLastEnrage) + { + Bot.Combat.CancelAutoAttack(); + + C.UsePotion(); + C.Sleep(200); // Small delay to allow scroll to apply + + if (Bot.Player.HasTarget && (Bot.Target.Auras.Any(x => x.Name.Equals("Focus", StringComparison.OrdinalIgnoreCase) && x.RemainingTime > 4)) || + Bot.Target.Auras.Any(x => x.Name.Equals("Reckless", StringComparison.OrdinalIgnoreCase) && x.RemainingTime > 4)) + { + usedEnrage = true; + needsEnrage = false; + usedLastEnrage = alternateEnrage; + C.Logger("Enraged successfully!"); + } + else + { + C.Sleep(200); // Brief pause before retrying + } + } + } + else if (needsEnrage && !usedEnrage && usedLastEnrage) { + C.Logger( + $"Detected '{enrageMessage}' - other player enrages..." + ); + usedEnrage = true; + needsEnrage = false; + usedLastEnrage = false; + } + + // Only attack if no scroll is needed or scroll has been applied + if (!needsEnrage || usedEnrage || !Bot.Player.HasTarget) + { + Bot.Skills.Resume(); + Bot.Combat.Attack(bossName); + } + + if (deathResetCount > 0) { + if (deathCount >= deathResetCount) { + ResetFight(); + goto Stop; + } + } + + C.Sleep(); + } + + Stop: + + Bot.Events.ScriptStopping -= OnBotStopped; + Bot.Flash.FlashCall -= Listener; + + usedEnrage = false; + needsEnrage = false; + + #region Packet Listener + + void Listener(string name, object[] args) { + switch (name) { + case "pext": + var packet = JsonConvert.DeserializeObject((string)args[0])!; + if (packet["params"] is not null && packet["params"]["type"] is not null) { + string type = packet["params"]["type"]; + if (type is "json" && packet["params"]["dataObj"] is not null) { + DataHandler(packet["params"]["dataObj"]); + } + } + break; + case "packetFromServer": + packet = JsonConvert.DeserializeObject((string)args[0])!; + if (packet["b"] is not null && packet["b"]["o"] is not null) { + DataHandler(packet["b"]["o"]); + } + break; + } + } + + void DataHandler(dynamic data) { + if (data["cmd"] is null) return; + string cmd = data["cmd"].ToString(); + switch (cmd) + { + case "ct": + if (data["anims"] is not null) + { + foreach (var a in data.anims) + { + if (a is null) + continue; + + if (a.msg is not null) + { + if (((string)a.msg).ToLower().Contains(enrageMessage.ToLower())) + goto Enrage; + } + } + } + + if (data["a"] is not null) { + foreach (var a in data.a) + { + if (a is null || a["cmd"].ToString() is not "aura+") + continue; + if (a["auras"] is not null) { + foreach (var aura in a["auras"]) { + if ( + aura is not null + && aura["msgOn"] is not null + ) + { + if (((string)aura.msgOn).ToLower().Contains(enrageMessage.ToLower()) + && ((bool)aura.isNew)) + goto Enrage; + } + } + } + } + } + break; + case "umsg": + if (data["s"] is not null && deathResetCount > 0) + foreach (var deathMessage in deathMessages) { + if (!((string)data["s"]).ToLower().Contains(deathMessage.ToLower())) continue; + deathCount++; + C.Logger("Death detected, logging..."); + } + break; + } + + return; + + Enrage: + needsEnrage = true; + usedEnrage = false; + if (tauntOffset > 0) { + tauntTime = DateTimeOffset.Now.AddSeconds(tauntOffset); + C.Logger( + $"Event detected: {enrageMessage}. Prepare yourself! - Enrage needed in {tauntOffset} seconds." + ); + } + else { + C.Logger( + $"Event detected: {enrageMessage}. Prepare yourself! - Enrage needed." + ); + } + } + #endregion + + void ResetFight() { + C.Logger("Too many deaths, resetting the fight..."); + + Bot.Wait.ForTrue(() => Bot.Player.Alive, 20); + + C.JumpWait(); + + //Try to avoid potions bug + C.Unbank("Healer"); + C.Equip("Healer"); + EquipClasses(false); + + const string syncPath = "EclipseAscentReset"; + Ultra.ClearSyncFile(syncPath); + Bot.Sleep(2500); + Ultra.WaitForArmy(3, syncPath, timeoutMs: 10000); + } + + bool OnBotStopped(Exception? e) { + Bot.Events.ScriptStopping -= OnBotStopped; + Bot.Flash.FlashCall -= Listener; + + return true; + } + } + + private class EclipseBase { + protected CoreEclipse Eclipse; + protected IScriptInterface Bot => Eclipse.Bot; + protected CoreBots C => Eclipse.C; + protected CoreUltra Ultra => Eclipse.Ultra; + protected bool doGetEnrage = true; + + protected EclipseBase(CoreEclipse eclipse) { + Eclipse = eclipse; + } + + protected void Restart(string packet) { + if (doGetEnrage) { + doGetEnrage = false; + if (!C.CheckInventory("Scroll of Enrage", 250)) + Eclipse.GetScrollOfEnrage(1000); + + if (C.CheckInventory("Hallowed Remains", 400)) + C.SellItem("Hallowed Remains", all: true); + + const string syncPath = "EclipseAscentRestart"; + Ultra.ClearSyncFile(syncPath); + Ultra.WaitForArmy(3, syncPath); + } + + Bot.Sleep(2000); + if (sArmy.isPartyLeader()) { + Bot.Send.Packet(packet); + } + else if (sArmy.getPartyLeader() != null) { + Bot.Player?.Goto(sArmy.getPartyLeader()!); + } + } + + protected void Move(string packet) { + switch (Bot.Player?.Cell) { + case "Enter": + C.Jump("r1"); + doGetEnrage = true; + break; + case "r1": + C.Jump("r2"); + break; + case "r2": + C.Jump("r3"); + break; + case "r3a": + case "r3": + Restart(packet); + Bot.Wait.OverrideTimeout = true; + Bot.Wait.ForCellChange("Enter"); + Bot.Wait.OverrideTimeout = false; + //Try to avoid potions bug + C.Unbank("Healer"); + C.Equip("Healer"); + Eclipse.EquipClasses(false); + break; + } + } + } + + private class SolsticeMoon : EclipseBase { + public SolsticeMoon(CoreEclipse eclipse, int count) : base(eclipse) { + while (!Bot.ShouldExit && !C.CheckInventory("Sliver of Moonlight", count)) { + if (Bot.Map.Name != "solsticemoon") { + Restart("%xt%zm%dungeonQueue%24946%solsticemoon%"); + Bot.Wait.ForMapLoad("solsticemoon"); + //Try to avoid potions bug + C.Unbank("Healer"); + C.Equip("Healer"); + Eclipse.EquipClasses(false); + } + else { + Kill(); + } + } + } + + private bool IsTaunter() { + return Bot.Player.Username.Equals(Bot.Config!.Get("player3").ToLower()) || Bot.Player.Username.Equals(Bot.Config!.Get("player4").ToLower()); + } + + private void Kill() { + Bot.Sleep(1000); + if (Bot.Monsters.CurrentMonsters.Any(x => x.Alive)) + if (Bot.Player.Cell.Equals("r3") && IsTaunter()) + Eclipse.EclipseBossHandler("player4", "Hollow Midnight", "The Moon Converges"); + else + Bot.Combat.Attack("*"); + else + Move("%xt%zm%dungeonQueue%24946%solsticemoon%"); + } + } + + private class MidnightSun : EclipseBase { + public MidnightSun(CoreEclipse eclipse, int count) : base(eclipse) { + while (!Bot.ShouldExit && !C.CheckInventory("Sliver of Sunlight", count)) { + if (Bot.Map.Name != "midnightsun") { + Restart("%xt%zm%dungeonQueue%25127%midnightsun%"); + Bot.Wait.ForMapLoad("midnightsun"); + //Try to avoid potions bug + C.Unbank("Healer"); + C.Equip("Healer"); + Eclipse.EquipClasses(false); + } + else { + Kill(); + } + } + } + + private bool IsTaunter() { + return Bot.Player.Username.Equals(Bot.Config!.Get("player1").ToLower()) || Bot.Player.Username.Equals(Bot.Config!.Get("player2").ToLower()); + } + + private void Kill() { + Bot.Sleep(1000); + if (Bot.Monsters.CurrentMonsters.Any(x => x.Alive)) + if (Bot.Player.Cell.Equals("r3") && IsTaunter()) + Eclipse.EclipseBossHandler("player2", "Hollow Solstice", "The Sun Converges"); + else if (IsTaunter() && Bot.Monsters.CurrentMonsters.Any(x => x is { Alive: true, Name: "Dying Light" })) + Eclipse.EclipseBossHandler("player1", "Dying Light", "The Light Gathers", bossCell: Bot.Player.Cell); + else + Bot.Combat.Attack("*"); + else + Move("%xt%zm%dungeonQueue%25127%midnightsun%"); + } + } + + private class AscendEclipse : EclipseBase { + public AscendEclipse(CoreEclipse eclipse, int count) : base(eclipse) { + while (!Bot.ShouldExit && !C.CheckInventory("Ecliptic Offering", count)) { + if (Bot.Map.Name != "ascendeclipse") { + Restart("%xt%zm%dungeonQueue%15395%ascendeclipse%"); + Bot.Wait.ForMapLoad("ascendeclipse"); + //Try to avoid potions bug + C.Unbank("Healer"); + C.Equip("Healer"); + Eclipse.EquipClasses(false); + } + else { + Kill(); + } + } + } + + private bool IsTeamSun() { + return Bot.Player.Username.Equals(Bot.Config!.Get("player1").ToLower()) || Bot.Player.Username.Equals(Bot.Config!.Get("player2").ToLower()); + } + + private void Kill() { + Bot.Sleep(1000); + if (Bot.Monsters.CurrentMonsters.Any(x => x.Alive)) + switch (Bot.Player.Cell) { + case "Enter": + if (Bot.Monsters.CurrentMonsters.Any(x => x is { Alive: true, Name: "Fallen Star" })) + if (Bot.Player.Username.Equals(Bot.Config!.Get("player4").ToLower()) && Bot.Monsters.CurrentMonsters.Any(x => x is { Alive: true, Name: "Blessless Deer" })) + Bot.Combat.Attack("Blessless Deer"); + else + Bot.Combat.Attack("Fallen Star"); + else + Bot.Combat.Attack("*"); + break; + case "r1": + if (IsTeamSun() && Bot.Monsters.CurrentMonsters.Any(x => x is { Alive: true, Name: "Suffocated Light" })) + Eclipse.EclipseBossHandler("player1", "Suffocated Light", "The Light Gathers", bossCell: Bot.Player.Cell); + else + Bot.Combat.Attack("*"); + break; + case "r2": + if (Bot.Monsters.CurrentMonsters.Any(x => x is { Alive: true, Name: "Sunset Knight" })) { + if (Bot.Player.Username.Equals(Bot.Config!.Get("player4").ToLower()) && + Bot.Monsters.CurrentMonsters.Any(x => x is { Alive: true, Name: "Moon Haze" })) + Eclipse.EclipseBossHandler("player4", "Moon Haze", "You gaze into the moon", + bossCell: Bot.Player.Cell, alternateEnrage: false, tauntOffset: 6); + else if (Bot.Player.Username.Equals(Bot.Config!.Get("player3").ToLower()) && + Bot.Monsters.CurrentMonsters.Any(x => x is { Alive: true, Name: "Sunset Knight" })) + Eclipse.EclipseBossHandler("player3", "Sunset Knight", "You feel the warmth of the sun", + bossCell: Bot.Player.Cell, alternateEnrage: false, tauntOffset: 6); + else + Bot.Combat.Attack("Sunset Knight"); + } + else + Bot.Combat.Attack("*"); + break; + case "r3": + if(IsTeamSun() && Bot.Monsters.CurrentMonsters.Any(x => x is { Alive: true, Name: "Ascended Solstice" })) + Eclipse.EclipseBossHandler("player1", "Ascended Solstice", "The Sun Converges", deathResetCount: 2, deathMessages: + ["The Ascended Midnight glows brighter", "The Ascended Solstice burns hotter"]); + else if (Bot.Monsters.CurrentMonsters.Any(x => x is { Alive: true, Name: "Ascended Midnight" })) + Eclipse.EclipseBossHandler("player3", "Ascended Midnight", "The Moon Converges", deathResetCount: 2, deathMessages: + ["The Ascended Midnight glows brighter", "The Ascended Solstice burns hotter"]); + else + Bot.Combat.Attack("*"); + break; + default: + Bot.Combat.Attack("*"); + break; + } + else + Move("%xt%zm%dungeonQueue%15395%ascendeclipse%"); + } + } +} \ No newline at end of file From a550dc5e2b7c40d20f6c4b9e57bdac453e29d80a Mon Sep 17 00:00:00 2001 From: Robmart <4825809+robmart@users.noreply.github.com> Date: Sun, 5 Apr 2026 10:26:41 +0200 Subject: [PATCH 2/5] Auto format code to match repo --- .../0GreatbladeoftheEntwinedEclipse.cs | 183 +-- .../CelestialTempleForgeMerge.cs | 46 +- Dungeons/EclipseAscent/CoreEclipse.cs | 1131 +++++++++-------- 3 files changed, 716 insertions(+), 644 deletions(-) diff --git a/Dungeons/EclipseAscent/0GreatbladeoftheEntwinedEclipse.cs b/Dungeons/EclipseAscent/0GreatbladeoftheEntwinedEclipse.cs index afd86c1ae..015ffc2d1 100644 --- a/Dungeons/EclipseAscent/0GreatbladeoftheEntwinedEclipse.cs +++ b/Dungeons/EclipseAscent/0GreatbladeoftheEntwinedEclipse.cs @@ -12,92 +12,97 @@ namespace SkuaScripts.Scripts.Custom.EclipseAscent; -public class GreatbladeoftheEntwinedEclipse { - private IScriptInterface Bot => IScriptInterface.Instance; - public CoreBots C => CoreBots.Instance; - private static CoreAdvanced Adv = new(); - public CoreUltra Ultra = new(); - private static CoreArmyLite sArmy = new(); - public CoreEclipse coreEclipse = new(); - public CelestialTempleForgeMerge templeMerge = new(); - - public bool DontPreconfigure = true; - public string OptionsStorage = "EclipseAscent"; - public List Options = new() - { - new Option( - "player1", - "Account #1", - "This character will be using Legion Revenant", - "" - ), - new Option( - "player2", - "Account #2", - "This character will be using StoneCrusher", - "" - ), - new Option( - "player3", - "Account #3", - "This character will be using ArchPaladin", - "" - ), - new Option( - "player4", - "Account #4", - "This character will be using Lord Of Order", - "" - ), - new Option( - "autoclass", - "Auto Equip Classes", - "This will auto equip all classes, if false it will use the classes already equipped.", - true - ), - CoreBots.Instance.SkipOptions, - }; - - public void ScriptMain(IScriptInterface Bot) { - Bot.Events.ScriptStopping += OnBotStopped; - Bot.Events.ExtensionPacketReceived += sArmy.PartyManagement; - - C.BankingBlackList.AddRange(new[] { "Sliver of Moonlight", "Sliver of Sunlight", "Victor of the Festival", "Ecliptic Offering"}); - - C.SetOptions(); - C.SendPackets($"%xt%zm%cmd%1%uopref%bParty%true%"); //To be able to join party - - while (!Bot.ShouldExit && sArmy.PartyMemberArray()!.Length < 4) - coreEclipse.SetupParty(); - - C.SendPackets($"%xt%zm%cmd%1%uopref%bParty%false%"); - - Adv.GearStore(EnhAfter: true); - - coreEclipse.EquipWait(); - coreEclipse.EquipClasses(true); - - templeMerge.BuyAllMerge(""); - - sArmy.PartyLeave(); - - Bot.Events.ScriptStopping -= OnBotStopped; - Bot.Events.ExtensionPacketReceived -= sArmy.PartyManagement; - - Adv.GearStore(true, EnhAfter: true); - - C.SetOptions(false); - } - - private bool OnBotStopped(Exception? exception) { - Bot.Events.ScriptStopping -= OnBotStopped; - Bot.Events.ExtensionPacketReceived -= sArmy.PartyManagement; - - C.JumpWait(); - sArmy.PartyLeave(); - - Adv.GearStore(true, EnhAfter: true); - - return true; - } -} \ No newline at end of file +public class GreatbladeoftheEntwinedEclipse +{ + private IScriptInterface Bot => IScriptInterface.Instance; + public CoreBots C => CoreBots.Instance; + private static CoreAdvanced Adv = new(); + public CoreUltra Ultra = new(); + private static CoreArmyLite sArmy = new(); + public CoreEclipse coreEclipse = new(); + public CelestialTempleForgeMerge templeMerge = new(); + + public bool DontPreconfigure = true; + public string OptionsStorage = "EclipseAscent"; + + public List Options = new() + { + new Option( + "player1", + "Account #1", + "This character will be using Legion Revenant", + "" + ), + new Option( + "player2", + "Account #2", + "This character will be using StoneCrusher", + "" + ), + new Option( + "player3", + "Account #3", + "This character will be using ArchPaladin", + "" + ), + new Option( + "player4", + "Account #4", + "This character will be using Lord Of Order", + "" + ), + new Option( + "autoclass", + "Auto Equip Classes", + "This will auto equip all classes, if false it will use the classes already equipped.", + true + ), + CoreBots.Instance.SkipOptions, + }; + + public void ScriptMain(IScriptInterface Bot) + { + Bot.Events.ScriptStopping += OnBotStopped; + Bot.Events.ExtensionPacketReceived += sArmy.PartyManagement; + + C.BankingBlackList.AddRange(new[] + { "Sliver of Moonlight", "Sliver of Sunlight", "Victor of the Festival", "Ecliptic Offering" }); + + C.SetOptions(); + C.SendPackets($"%xt%zm%cmd%1%uopref%bParty%true%"); //To be able to join party + + while (!Bot.ShouldExit && sArmy.PartyMemberArray()!.Length < 4) + coreEclipse.SetupParty(); + + C.SendPackets($"%xt%zm%cmd%1%uopref%bParty%false%"); + + Adv.GearStore(EnhAfter: true); + + coreEclipse.EquipWait(); + coreEclipse.EquipClasses(true); + + templeMerge.BuyAllMerge(""); + + sArmy.PartyLeave(); + + Bot.Events.ScriptStopping -= OnBotStopped; + Bot.Events.ExtensionPacketReceived -= sArmy.PartyManagement; + + Adv.GearStore(true, EnhAfter: true); + + C.SetOptions(false); + } + + private bool OnBotStopped(Exception? exception) + { + Bot.Events.ScriptStopping -= OnBotStopped; + Bot.Events.ExtensionPacketReceived -= sArmy.PartyManagement; + + C.JumpWait(); + sArmy.PartyLeave(); + + Adv.GearStore(true, EnhAfter: true); + + return true; + } +} diff --git a/Dungeons/EclipseAscent/CelestialTempleForgeMerge.cs b/Dungeons/EclipseAscent/CelestialTempleForgeMerge.cs index 7d7877c2d..8ea406a09 100644 --- a/Dungeons/EclipseAscent/CelestialTempleForgeMerge.cs +++ b/Dungeons/EclipseAscent/CelestialTempleForgeMerge.cs @@ -63,8 +63,8 @@ public class CelestialTempleForgeMerge "" ), new Option( - "autoclass", - "Auto Equip Classes", + "autoclass", + "Auto Equip Classes", "This will auto equip all classes, if false it will use the classes already equipped.", true ), @@ -74,31 +74,31 @@ public void ScriptMain(IScriptInterface Bot) { Bot.Events.ScriptStopping += OnBotStopped; Bot.Events.ExtensionPacketReceived += sArmy.PartyManagement; - - Core.BankingBlackList.AddRange(new[] { "Sliver of Moonlight", "Sliver of Sunlight", "Victor of the Festival", "Ecliptic Offering"}); - + + Core.BankingBlackList.AddRange(new[] { "Sliver of Moonlight", "Sliver of Sunlight", "Victor of the Festival", "Ecliptic Offering" }); + Core.SetOptions(); Core.SendPackets($"%xt%zm%cmd%1%uopref%bParty%true%"); //To be able to join party - + while (!Bot.ShouldExit && sArmy.PartyMemberArray()!.Length < 4) coreEclipse.SetupParty(); - + Core.SendPackets($"%xt%zm%cmd%1%uopref%bParty%false%"); - + Adv.GearStore(EnhAfter: true); - + coreEclipse.EquipWait(); coreEclipse.EquipClasses(true); BuyAllMerge(); - + sArmy.PartyLeave(); - + Bot.Events.ScriptStopping -= OnBotStopped; Bot.Events.ExtensionPacketReceived -= sArmy.PartyManagement; - + Adv.GearStore(true, EnhAfter: true); - + Core.SetOptions(false); } @@ -132,27 +132,28 @@ void findIngredients() Core.FarmingLogger(req.Name, sliverQuant); coreEclipse.GetSliverOfMoonlight(sliverQuant); break; - + case "Sliver of Sunlight": Core.FarmingLogger(req.Name, sliverQuant); coreEclipse.GetSliverOfSunlight(sliverQuant); break; - + case "Victor of the Festival": VictorMatsuri.Storyline(); - if (!Core.CheckInventory("Victor of the Festival")) { + if (!Core.CheckInventory("Victor of the Festival")) + { Core.Logger("Victor Matsuri questline didn't finish, exiting..."); Bot.StopSync(true); } break; - + case "Ecliptic Offering": if (!Core.CheckInventory("Rite of Ascension")) BuyAllMerge("Rite of Ascension"); - Core.FarmingLogger("Ecliptic Offering", quant); + Core.FarmingLogger("Ecliptic Offering", quant); coreEclipse.GetEclipticOffering(quant); break; } @@ -171,15 +172,16 @@ void findIngredients() new Option("78467", "Greatblade of the Midnight Sun", "Mode: [select] only\nShould the bot buy \"Greatblade of the Midnight Sun\" ?", false), new Option("78462", "Greatblade of the Solstice Moon", "Mode: [select] only\nShould the bot buy \"Greatblade of the Solstice Moon\" ?", false), new Option("78457", "Greatblade of the Entwined Eclipse", "Mode: [select] only\nShould the bot buy \"Greatblade of the Entwined Eclipse\" ?", false), - }; + }; - private bool OnBotStopped(Exception? exception) { + private bool OnBotStopped(Exception? exception) + { Bot.Events.ScriptStopping -= OnBotStopped; Bot.Events.ExtensionPacketReceived -= sArmy.PartyManagement; - + Core.JumpWait(); sArmy.PartyLeave(); - + Adv.GearStore(true, EnhAfter: true); return true; diff --git a/Dungeons/EclipseAscent/CoreEclipse.cs b/Dungeons/EclipseAscent/CoreEclipse.cs index 120b4075f..f4d64738d 100644 --- a/Dungeons/EclipseAscent/CoreEclipse.cs +++ b/Dungeons/EclipseAscent/CoreEclipse.cs @@ -14,539 +14,604 @@ namespace SkuaScripts.Scripts.Custom.EclipseAscent; -public class CoreEclipse { - private IScriptInterface Bot => IScriptInterface.Instance; - private CoreBots C => CoreBots.Instance; - private CoreEngine Core = new(); - private CoreUltra Ultra = new(); - private static CoreAdvanced Adv = new(); - private static CoreArmyLite sArmy = new(); - - public void EquipWait(string item = "Scroll of Enrage") { - C.Equip(item); - Bot.Wait.ForItemEquip(item); - Bot.Wait.ForActionCooldown(GameActions.EquipItem); - C.Sleep(); - } - - public void SetupParty() { - if (!Bot.Player.Username.Equals(Bot.Config!.Get("player1").ToLower())) return; - - if (!sArmy.PartyMemberArray().Contains(Bot.Config!.Get("player2")!.ToLower())) { - sArmy.PartyInvite(Bot.Config!.Get("player2")!); - Bot.Sleep(2000); - } - if (!sArmy.PartyMemberArray().Contains(Bot.Config!.Get("player3")!.ToLower())) { - sArmy.PartyInvite(Bot.Config!.Get("player3")!); - Bot.Sleep(2000); - } - if (!sArmy.PartyMemberArray().Contains(Bot.Config!.Get("player4")!.ToLower())) { - sArmy.PartyInvite(Bot.Config!.Get("player4")!); - Bot.Sleep(2000); - } - - Bot.Sleep(10000); - } - - public void EquipClasses(bool autoEnhance) { - if (!Bot.Config!.Get("autoclass")) return; - if (Bot.Player.Username.Equals(Bot.Config!.Get("player1").ToLower()) && C.CheckInventory("Legion Revenant")) { - C.Equip("Legion Revenant"); - if (!autoEnhance) return; - Adv.EnhanceEquipped( - type: EnhancementType.Wizard, - hSpecial: HelmSpecial.Pneuma, - wSpecial: Adv.uRavenous() ? WeaponSpecial.Ravenous : WeaponSpecial.Awe_Blast, - cSpecial: CapeSpecial.Vainglory - ); - } - else if (Bot.Player.Username.Equals(Bot.Config!.Get("player2").ToLower()) && C.CheckInventory("StoneCrusher")) { - C.Equip("StoneCrusher"); - if (!autoEnhance) return; - Adv.EnhanceEquipped( - type: EnhancementType.Fighter, - hSpecial: HelmSpecial.Anima, - wSpecial: Adv.uRavenous() ? WeaponSpecial.Ravenous : WeaponSpecial.Valiance, - cSpecial: CapeSpecial.Absolution - ); - } - else if (Bot.Player.Username.Equals(Bot.Config!.Get("player3").ToLower()) && C.CheckInventory("ArchPaladin")) { - C.Equip("ArchPaladin"); - if (!autoEnhance) return; - Adv.EnhanceEquipped( - type: EnhancementType.Lucky, - hSpecial: HelmSpecial.Forge, - wSpecial: Adv.uRavenous() ? WeaponSpecial.Ravenous : WeaponSpecial.Awe_Blast, - cSpecial: CapeSpecial.Penitence - ); - } - else if (Bot.Player.Username.Equals(Bot.Config!.Get("player4").ToLower()) && C.CheckInventory("Lord Of Order")) { - C.Equip("Lord Of Order"); - if (!autoEnhance) return; - Adv.EnhanceEquipped( - type: EnhancementType.Lucky, - hSpecial: HelmSpecial.Forge, - wSpecial: Adv.uArcanasConcerto() - ? WeaponSpecial.Arcanas_Concerto - : WeaponSpecial.Awe_Blast, - cSpecial: CapeSpecial.Penitence - ); - } - else { - C.Logger("Valid class not found"); - Bot.StopSync(true); - } - } - - public void GetScrollOfEnrage(int count = 100) { - if (!Core.Faction("SpellCrafting", 5)) - return; - - const string parchment = "Mystic Parchment"; - const string ink = "Zealous Ink"; - const string scroll = "Scroll of Enrage"; - - while (!Bot.ShouldExit && !C.CheckInventory(scroll, count)) { - // Mats - Core.ForItem("Undead Infantry", "underworld", parchment, 2); - Core.BuyItem(ink, 549, "dragonrune", 5, calculateRemaining: false); - - // Craft - Core.Join("spellcraft"); - Bot.Drops.Add(scroll); - Bot.Send.Packet("%xt%zm%crafting%1%spellOnStart%7%1555%Spell%"); - Bot.Sleep(5000); - Bot.Send.Packet("%xt%zm%crafting%1%spellComplete%7%2330%Enrage%"); - - Core.WaitForDrop(scroll, 10000); - Core.Pickup(scroll); - } - } - - public void GetSliverOfMoonlight(int count = 221) { //220 for the sword, 1 for Rite of Ascension - new SolsticeMoon(this, count); - } - - public void GetSliverOfSunlight(int count = 221) { //220 for the sword, 1 for Rite of Ascension - new MidnightSun(this, count); - } - - public void GetEclipticOffering(int count = 155) { //155 for the sword - new AscendEclipse(this, count); - } - - private bool needsEnrage; - private bool usedEnrage; - private bool usedLastEnrage; - private DateTimeOffset tauntTime; - private int deathCount; - //This is mostly a copy of CoreAOR.ColdThunderBoss - public void EclipseBossHandler(string startingEnragePlayer, string bossName, string enrageMessage, bool alternateEnrage = true, string bossCell = "r3", int tauntOffset = 0, int deathResetCount = 0, params string[] deathMessages) { - needsEnrage = false; - usedEnrage = false; - usedLastEnrage = alternateEnrage - ? Bot.Player.Username.Equals(Bot.Config!.Get(startingEnragePlayer).ToLower()) - : false; - deathCount = 0; - - Bot.Events.ScriptStopping += OnBotStopped; - Bot.Flash.FlashCall += Listener; - - //TODO: startingEnragePlayer should start the fight by using a scroll? - //TODO: Skip the enrage if they missed it badly enough that the other player's enrage is up - - C.Logger( - $"About to attack {bossName} boss." - ); - - while (!Bot.ShouldExit && Bot.Player.Cell == bossCell && - Bot.Monsters.CurrentMonsters.Any(x => x.Alive && x.Name.Equals(bossName))) - { - if (needsEnrage && !usedEnrage && !usedLastEnrage && Bot.Player.HasTarget && (tauntOffset <= 0 || DateTimeOffset.Now > tauntTime)) - { - C.Logger( - $"Detected '{enrageMessage}' - applying Scroll of Enrage..." - ); - - Bot.Skills.Pause(); - - // Keep trying to use scroll until it's successfully applied - while (!Bot.ShouldExit && Bot.Player.HasTarget && Bot.Player.Cell == bossCell && - Bot.Monsters.CurrentMonsters.Any(x => x.Alive && x.Name.Equals(bossName)) && needsEnrage && !usedEnrage && !usedLastEnrage) - { - Bot.Combat.CancelAutoAttack(); - - C.UsePotion(); - C.Sleep(200); // Small delay to allow scroll to apply - - if (Bot.Player.HasTarget && (Bot.Target.Auras.Any(x => x.Name.Equals("Focus", StringComparison.OrdinalIgnoreCase) && x.RemainingTime > 4)) || - Bot.Target.Auras.Any(x => x.Name.Equals("Reckless", StringComparison.OrdinalIgnoreCase) && x.RemainingTime > 4)) - { - usedEnrage = true; - needsEnrage = false; - usedLastEnrage = alternateEnrage; - C.Logger("Enraged successfully!"); - } - else - { - C.Sleep(200); // Brief pause before retrying - } - } - } - else if (needsEnrage && !usedEnrage && usedLastEnrage) { - C.Logger( - $"Detected '{enrageMessage}' - other player enrages..." - ); - usedEnrage = true; - needsEnrage = false; - usedLastEnrage = false; - } - - // Only attack if no scroll is needed or scroll has been applied - if (!needsEnrage || usedEnrage || !Bot.Player.HasTarget) - { - Bot.Skills.Resume(); - Bot.Combat.Attack(bossName); - } - - if (deathResetCount > 0) { - if (deathCount >= deathResetCount) { - ResetFight(); - goto Stop; - } - } - - C.Sleep(); - } - - Stop: - - Bot.Events.ScriptStopping -= OnBotStopped; - Bot.Flash.FlashCall -= Listener; - - usedEnrage = false; - needsEnrage = false; - - #region Packet Listener +public class CoreEclipse +{ + private IScriptInterface Bot => IScriptInterface.Instance; + private CoreBots C => CoreBots.Instance; + private CoreEngine Core = new(); + private CoreUltra Ultra = new(); + private static CoreAdvanced Adv = new(); + private static CoreArmyLite sArmy = new(); + + public void EquipWait(string item = "Scroll of Enrage") + { + C.Equip(item); + Bot.Wait.ForItemEquip(item); + Bot.Wait.ForActionCooldown(GameActions.EquipItem); + C.Sleep(); + } + + public void SetupParty() + { + if (!Bot.Player.Username.Equals(Bot.Config!.Get("player1").ToLower())) return; + + if (!sArmy.PartyMemberArray().Contains(Bot.Config!.Get("player2")!.ToLower())) + { + sArmy.PartyInvite(Bot.Config!.Get("player2")!); + Bot.Sleep(2000); + } + if (!sArmy.PartyMemberArray().Contains(Bot.Config!.Get("player3")!.ToLower())) + { + sArmy.PartyInvite(Bot.Config!.Get("player3")!); + Bot.Sleep(2000); + } + if (!sArmy.PartyMemberArray().Contains(Bot.Config!.Get("player4")!.ToLower())) + { + sArmy.PartyInvite(Bot.Config!.Get("player4")!); + Bot.Sleep(2000); + } + + Bot.Sleep(10000); + } + + public void EquipClasses(bool autoEnhance) + { + if (!Bot.Config!.Get("autoclass")) return; + if (Bot.Player.Username.Equals(Bot.Config!.Get("player1").ToLower()) && C.CheckInventory("Legion Revenant")) + { + C.Equip("Legion Revenant"); + if (!autoEnhance) return; + Adv.EnhanceEquipped( + type: EnhancementType.Wizard, + hSpecial: HelmSpecial.Pneuma, + wSpecial: Adv.uRavenous() ? WeaponSpecial.Ravenous : WeaponSpecial.Awe_Blast, + cSpecial: CapeSpecial.Vainglory + ); + } + else if (Bot.Player.Username.Equals(Bot.Config!.Get("player2").ToLower()) && C.CheckInventory("StoneCrusher")) + { + C.Equip("StoneCrusher"); + if (!autoEnhance) return; + Adv.EnhanceEquipped( + type: EnhancementType.Fighter, + hSpecial: HelmSpecial.Anima, + wSpecial: Adv.uRavenous() ? WeaponSpecial.Ravenous : WeaponSpecial.Valiance, + cSpecial: CapeSpecial.Absolution + ); + } + else if (Bot.Player.Username.Equals(Bot.Config!.Get("player3").ToLower()) && C.CheckInventory("ArchPaladin")) + { + C.Equip("ArchPaladin"); + if (!autoEnhance) return; + Adv.EnhanceEquipped( + type: EnhancementType.Lucky, + hSpecial: HelmSpecial.Forge, + wSpecial: Adv.uRavenous() ? WeaponSpecial.Ravenous : WeaponSpecial.Awe_Blast, + cSpecial: CapeSpecial.Penitence + ); + } + else if (Bot.Player.Username.Equals(Bot.Config!.Get("player4").ToLower()) && C.CheckInventory("Lord Of Order")) + { + C.Equip("Lord Of Order"); + if (!autoEnhance) return; + Adv.EnhanceEquipped( + type: EnhancementType.Lucky, + hSpecial: HelmSpecial.Forge, + wSpecial: Adv.uArcanasConcerto() + ? WeaponSpecial.Arcanas_Concerto + : WeaponSpecial.Awe_Blast, + cSpecial: CapeSpecial.Penitence + ); + } + else + { + C.Logger("Valid class not found"); + Bot.StopSync(true); + } + } + + public void GetScrollOfEnrage(int count = 100) + { + if (!Core.Faction("SpellCrafting", 5)) + return; + + const string parchment = "Mystic Parchment"; + const string ink = "Zealous Ink"; + const string scroll = "Scroll of Enrage"; + + while (!Bot.ShouldExit && !C.CheckInventory(scroll, count)) + { + // Mats + Core.ForItem("Undead Infantry", "underworld", parchment, 2); + Core.BuyItem(ink, 549, "dragonrune", 5, calculateRemaining: false); + + // Craft + Core.Join("spellcraft"); + Bot.Drops.Add(scroll); + Bot.Send.Packet("%xt%zm%crafting%1%spellOnStart%7%1555%Spell%"); + Bot.Sleep(5000); + Bot.Send.Packet("%xt%zm%crafting%1%spellComplete%7%2330%Enrage%"); + + Core.WaitForDrop(scroll, 10000); + Core.Pickup(scroll); + } + } + + public void GetSliverOfMoonlight(int count = 221) + { //220 for the sword, 1 for Rite of Ascension + new SolsticeMoon(this, count); + } + + public void GetSliverOfSunlight(int count = 221) + { //220 for the sword, 1 for Rite of Ascension + new MidnightSun(this, count); + } + + public void GetEclipticOffering(int count = 155) + { //155 for the sword + new AscendEclipse(this, count); + } + + private bool needsEnrage; + private bool usedEnrage; + private bool usedLastEnrage; + private DateTimeOffset tauntTime; + private int deathCount; + //This is mostly a copy of CoreAOR.ColdThunderBoss + public void EclipseBossHandler(string startingEnragePlayer, string bossName, string enrageMessage, bool alternateEnrage = true, string bossCell = "r3", int tauntOffset = 0, int deathResetCount = 0, params string[] deathMessages) + { + needsEnrage = false; + usedEnrage = false; + usedLastEnrage = alternateEnrage + ? Bot.Player.Username.Equals(Bot.Config!.Get(startingEnragePlayer).ToLower()) + : false; + deathCount = 0; + + Bot.Events.ScriptStopping += OnBotStopped; + Bot.Flash.FlashCall += Listener; + + //TODO: startingEnragePlayer should start the fight by using a scroll? + //TODO: Skip the enrage if they missed it badly enough that the other player's enrage is up + + C.Logger( + $"About to attack {bossName} boss." + ); + + while (!Bot.ShouldExit && Bot.Player.Cell == bossCell && + Bot.Monsters.CurrentMonsters.Any(x => x.Alive && x.Name.Equals(bossName))) + { + if (needsEnrage && !usedEnrage && !usedLastEnrage && Bot.Player.HasTarget && (tauntOffset <= 0 || DateTimeOffset.Now > tauntTime)) + { + C.Logger( + $"Detected '{enrageMessage}' - applying Scroll of Enrage..." + ); + + Bot.Skills.Pause(); + + // Keep trying to use scroll until it's successfully applied + while (!Bot.ShouldExit && Bot.Player.HasTarget && Bot.Player.Cell == bossCell && + Bot.Monsters.CurrentMonsters.Any(x => x.Alive && x.Name.Equals(bossName)) && needsEnrage && !usedEnrage && !usedLastEnrage) + { + Bot.Combat.CancelAutoAttack(); + + C.UsePotion(); + C.Sleep(200); // Small delay to allow scroll to apply + + if (Bot.Player.HasTarget && (Bot.Target.Auras.Any(x => x.Name.Equals("Focus", StringComparison.OrdinalIgnoreCase) && x.RemainingTime > 4)) || + Bot.Target.Auras.Any(x => x.Name.Equals("Reckless", StringComparison.OrdinalIgnoreCase) && x.RemainingTime > 4)) + { + usedEnrage = true; + needsEnrage = false; + usedLastEnrage = alternateEnrage; + C.Logger("Enraged successfully!"); + } + else + { + C.Sleep(200); // Brief pause before retrying + } + } + } + else if (needsEnrage && !usedEnrage && usedLastEnrage) + { + C.Logger( + $"Detected '{enrageMessage}' - other player enrages..." + ); + usedEnrage = true; + needsEnrage = false; + usedLastEnrage = false; + } + + // Only attack if no scroll is needed or scroll has been applied + if (!needsEnrage || usedEnrage || !Bot.Player.HasTarget) + { + Bot.Skills.Resume(); + Bot.Combat.Attack(bossName); + } + + if (deathResetCount > 0) + { + if (deathCount >= deathResetCount) + { + ResetFight(); + goto Stop; + } + } + + C.Sleep(); + } + + Stop: + + Bot.Events.ScriptStopping -= OnBotStopped; + Bot.Flash.FlashCall -= Listener; + + usedEnrage = false; + needsEnrage = false; - void Listener(string name, object[] args) { - switch (name) { - case "pext": - var packet = JsonConvert.DeserializeObject((string)args[0])!; - if (packet["params"] is not null && packet["params"]["type"] is not null) { - string type = packet["params"]["type"]; - if (type is "json" && packet["params"]["dataObj"] is not null) { - DataHandler(packet["params"]["dataObj"]); - } - } - break; - case "packetFromServer": - packet = JsonConvert.DeserializeObject((string)args[0])!; - if (packet["b"] is not null && packet["b"]["o"] is not null) { - DataHandler(packet["b"]["o"]); - } - break; - } - } - - void DataHandler(dynamic data) { - if (data["cmd"] is null) return; - string cmd = data["cmd"].ToString(); - switch (cmd) - { - case "ct": - if (data["anims"] is not null) - { - foreach (var a in data.anims) - { - if (a is null) - continue; - - if (a.msg is not null) - { - if (((string)a.msg).ToLower().Contains(enrageMessage.ToLower())) - goto Enrage; - } - } - } - - if (data["a"] is not null) { - foreach (var a in data.a) - { - if (a is null || a["cmd"].ToString() is not "aura+") - continue; - if (a["auras"] is not null) { - foreach (var aura in a["auras"]) { - if ( - aura is not null - && aura["msgOn"] is not null - ) - { - if (((string)aura.msgOn).ToLower().Contains(enrageMessage.ToLower()) - && ((bool)aura.isNew)) - goto Enrage; - } - } - } - } - } - break; - case "umsg": - if (data["s"] is not null && deathResetCount > 0) - foreach (var deathMessage in deathMessages) { - if (!((string)data["s"]).ToLower().Contains(deathMessage.ToLower())) continue; - deathCount++; - C.Logger("Death detected, logging..."); - } - break; - } - - return; - - Enrage: - needsEnrage = true; - usedEnrage = false; - if (tauntOffset > 0) { - tauntTime = DateTimeOffset.Now.AddSeconds(tauntOffset); - C.Logger( - $"Event detected: {enrageMessage}. Prepare yourself! - Enrage needed in {tauntOffset} seconds." - ); - } - else { - C.Logger( - $"Event detected: {enrageMessage}. Prepare yourself! - Enrage needed." - ); - } - } + #region Packet Listener + void Listener(string name, object[] args) + { + switch (name) + { + case "pext": + var packet = JsonConvert.DeserializeObject((string)args[0])!; + if (packet["params"] is not null && packet["params"]["type"] is not null) + { + string type = packet["params"]["type"]; + if (type is "json" && packet["params"]["dataObj"] is not null) + { + DataHandler(packet["params"]["dataObj"]); + } + } + break; + case "packetFromServer": + packet = JsonConvert.DeserializeObject((string)args[0])!; + if (packet["b"] is not null && packet["b"]["o"] is not null) + { + DataHandler(packet["b"]["o"]); + } + break; + } + } + + void DataHandler(dynamic data) + { + if (data["cmd"] is null) return; + string cmd = data["cmd"].ToString(); + switch (cmd) + { + case "ct": + if (data["anims"] is not null) + { + foreach (var a in data.anims) + { + if (a is null) + continue; + + if (a.msg is not null) + { + if (((string)a.msg).ToLower().Contains(enrageMessage.ToLower())) + goto Enrage; + } + } + } + + if (data["a"] is not null) + { + foreach (var a in data.a) + { + if (a is null || a["cmd"].ToString() is not "aura+") + continue; + if (a["auras"] is not null) + { + foreach (var aura in a["auras"]) + { + if ( + aura is not null + && aura["msgOn"] is not null + ) + { + if (((string)aura.msgOn).ToLower().Contains(enrageMessage.ToLower()) + && ((bool)aura.isNew)) + goto Enrage; + } + } + } + } + } + break; + case "umsg": + if (data["s"] is not null && deathResetCount > 0) + foreach (var deathMessage in deathMessages) + { + if (!((string)data["s"]).ToLower().Contains(deathMessage.ToLower())) continue; + deathCount++; + C.Logger("Death detected, logging..."); + } + break; + } + + return; + + Enrage: + needsEnrage = true; + usedEnrage = false; + if (tauntOffset > 0) + { + tauntTime = DateTimeOffset.Now.AddSeconds(tauntOffset); + C.Logger( + $"Event detected: {enrageMessage}. Prepare yourself! - Enrage needed in {tauntOffset} seconds." + ); + } + else + { + C.Logger( + $"Event detected: {enrageMessage}. Prepare yourself! - Enrage needed." + ); + } + } #endregion - void ResetFight() { - C.Logger("Too many deaths, resetting the fight..."); - - Bot.Wait.ForTrue(() => Bot.Player.Alive, 20); - - C.JumpWait(); - - //Try to avoid potions bug - C.Unbank("Healer"); - C.Equip("Healer"); - EquipClasses(false); - - const string syncPath = "EclipseAscentReset"; - Ultra.ClearSyncFile(syncPath); - Bot.Sleep(2500); - Ultra.WaitForArmy(3, syncPath, timeoutMs: 10000); - } - - bool OnBotStopped(Exception? e) { - Bot.Events.ScriptStopping -= OnBotStopped; - Bot.Flash.FlashCall -= Listener; - - return true; - } - } - - private class EclipseBase { - protected CoreEclipse Eclipse; - protected IScriptInterface Bot => Eclipse.Bot; - protected CoreBots C => Eclipse.C; - protected CoreUltra Ultra => Eclipse.Ultra; - protected bool doGetEnrage = true; - - protected EclipseBase(CoreEclipse eclipse) { - Eclipse = eclipse; - } - - protected void Restart(string packet) { - if (doGetEnrage) { - doGetEnrage = false; - if (!C.CheckInventory("Scroll of Enrage", 250)) - Eclipse.GetScrollOfEnrage(1000); - - if (C.CheckInventory("Hallowed Remains", 400)) - C.SellItem("Hallowed Remains", all: true); - - const string syncPath = "EclipseAscentRestart"; - Ultra.ClearSyncFile(syncPath); - Ultra.WaitForArmy(3, syncPath); - } - - Bot.Sleep(2000); - if (sArmy.isPartyLeader()) { - Bot.Send.Packet(packet); - } - else if (sArmy.getPartyLeader() != null) { - Bot.Player?.Goto(sArmy.getPartyLeader()!); - } - } - - protected void Move(string packet) { - switch (Bot.Player?.Cell) { - case "Enter": - C.Jump("r1"); - doGetEnrage = true; - break; - case "r1": - C.Jump("r2"); - break; - case "r2": - C.Jump("r3"); - break; - case "r3a": - case "r3": - Restart(packet); - Bot.Wait.OverrideTimeout = true; - Bot.Wait.ForCellChange("Enter"); - Bot.Wait.OverrideTimeout = false; - //Try to avoid potions bug - C.Unbank("Healer"); - C.Equip("Healer"); - Eclipse.EquipClasses(false); - break; - } - } - } - - private class SolsticeMoon : EclipseBase { - public SolsticeMoon(CoreEclipse eclipse, int count) : base(eclipse) { - while (!Bot.ShouldExit && !C.CheckInventory("Sliver of Moonlight", count)) { - if (Bot.Map.Name != "solsticemoon") { - Restart("%xt%zm%dungeonQueue%24946%solsticemoon%"); - Bot.Wait.ForMapLoad("solsticemoon"); - //Try to avoid potions bug - C.Unbank("Healer"); - C.Equip("Healer"); - Eclipse.EquipClasses(false); - } - else { - Kill(); - } - } - } - - private bool IsTaunter() { - return Bot.Player.Username.Equals(Bot.Config!.Get("player3").ToLower()) || Bot.Player.Username.Equals(Bot.Config!.Get("player4").ToLower()); - } - - private void Kill() { - Bot.Sleep(1000); - if (Bot.Monsters.CurrentMonsters.Any(x => x.Alive)) - if (Bot.Player.Cell.Equals("r3") && IsTaunter()) - Eclipse.EclipseBossHandler("player4", "Hollow Midnight", "The Moon Converges"); - else - Bot.Combat.Attack("*"); - else - Move("%xt%zm%dungeonQueue%24946%solsticemoon%"); - } - } - - private class MidnightSun : EclipseBase { - public MidnightSun(CoreEclipse eclipse, int count) : base(eclipse) { - while (!Bot.ShouldExit && !C.CheckInventory("Sliver of Sunlight", count)) { - if (Bot.Map.Name != "midnightsun") { - Restart("%xt%zm%dungeonQueue%25127%midnightsun%"); - Bot.Wait.ForMapLoad("midnightsun"); - //Try to avoid potions bug - C.Unbank("Healer"); - C.Equip("Healer"); - Eclipse.EquipClasses(false); - } - else { - Kill(); - } - } - } - - private bool IsTaunter() { - return Bot.Player.Username.Equals(Bot.Config!.Get("player1").ToLower()) || Bot.Player.Username.Equals(Bot.Config!.Get("player2").ToLower()); - } - - private void Kill() { - Bot.Sleep(1000); - if (Bot.Monsters.CurrentMonsters.Any(x => x.Alive)) - if (Bot.Player.Cell.Equals("r3") && IsTaunter()) - Eclipse.EclipseBossHandler("player2", "Hollow Solstice", "The Sun Converges"); - else if (IsTaunter() && Bot.Monsters.CurrentMonsters.Any(x => x is { Alive: true, Name: "Dying Light" })) - Eclipse.EclipseBossHandler("player1", "Dying Light", "The Light Gathers", bossCell: Bot.Player.Cell); - else - Bot.Combat.Attack("*"); - else - Move("%xt%zm%dungeonQueue%25127%midnightsun%"); - } - } - - private class AscendEclipse : EclipseBase { - public AscendEclipse(CoreEclipse eclipse, int count) : base(eclipse) { - while (!Bot.ShouldExit && !C.CheckInventory("Ecliptic Offering", count)) { - if (Bot.Map.Name != "ascendeclipse") { - Restart("%xt%zm%dungeonQueue%15395%ascendeclipse%"); - Bot.Wait.ForMapLoad("ascendeclipse"); - //Try to avoid potions bug - C.Unbank("Healer"); - C.Equip("Healer"); - Eclipse.EquipClasses(false); - } - else { - Kill(); - } - } - } - - private bool IsTeamSun() { - return Bot.Player.Username.Equals(Bot.Config!.Get("player1").ToLower()) || Bot.Player.Username.Equals(Bot.Config!.Get("player2").ToLower()); - } - - private void Kill() { - Bot.Sleep(1000); - if (Bot.Monsters.CurrentMonsters.Any(x => x.Alive)) - switch (Bot.Player.Cell) { - case "Enter": - if (Bot.Monsters.CurrentMonsters.Any(x => x is { Alive: true, Name: "Fallen Star" })) - if (Bot.Player.Username.Equals(Bot.Config!.Get("player4").ToLower()) && Bot.Monsters.CurrentMonsters.Any(x => x is { Alive: true, Name: "Blessless Deer" })) - Bot.Combat.Attack("Blessless Deer"); - else - Bot.Combat.Attack("Fallen Star"); - else - Bot.Combat.Attack("*"); - break; - case "r1": - if (IsTeamSun() && Bot.Monsters.CurrentMonsters.Any(x => x is { Alive: true, Name: "Suffocated Light" })) - Eclipse.EclipseBossHandler("player1", "Suffocated Light", "The Light Gathers", bossCell: Bot.Player.Cell); - else - Bot.Combat.Attack("*"); - break; - case "r2": - if (Bot.Monsters.CurrentMonsters.Any(x => x is { Alive: true, Name: "Sunset Knight" })) { - if (Bot.Player.Username.Equals(Bot.Config!.Get("player4").ToLower()) && - Bot.Monsters.CurrentMonsters.Any(x => x is { Alive: true, Name: "Moon Haze" })) - Eclipse.EclipseBossHandler("player4", "Moon Haze", "You gaze into the moon", - bossCell: Bot.Player.Cell, alternateEnrage: false, tauntOffset: 6); - else if (Bot.Player.Username.Equals(Bot.Config!.Get("player3").ToLower()) && - Bot.Monsters.CurrentMonsters.Any(x => x is { Alive: true, Name: "Sunset Knight" })) - Eclipse.EclipseBossHandler("player3", "Sunset Knight", "You feel the warmth of the sun", - bossCell: Bot.Player.Cell, alternateEnrage: false, tauntOffset: 6); - else - Bot.Combat.Attack("Sunset Knight"); - } - else - Bot.Combat.Attack("*"); - break; - case "r3": - if(IsTeamSun() && Bot.Monsters.CurrentMonsters.Any(x => x is { Alive: true, Name: "Ascended Solstice" })) - Eclipse.EclipseBossHandler("player1", "Ascended Solstice", "The Sun Converges", deathResetCount: 2, deathMessages: - ["The Ascended Midnight glows brighter", "The Ascended Solstice burns hotter"]); - else if (Bot.Monsters.CurrentMonsters.Any(x => x is { Alive: true, Name: "Ascended Midnight" })) - Eclipse.EclipseBossHandler("player3", "Ascended Midnight", "The Moon Converges", deathResetCount: 2, deathMessages: - ["The Ascended Midnight glows brighter", "The Ascended Solstice burns hotter"]); - else - Bot.Combat.Attack("*"); - break; - default: - Bot.Combat.Attack("*"); - break; - } - else - Move("%xt%zm%dungeonQueue%15395%ascendeclipse%"); - } - } -} \ No newline at end of file + void ResetFight() + { + C.Logger("Too many deaths, resetting the fight..."); + + Bot.Wait.ForTrue(() => Bot.Player.Alive, 20); + + C.JumpWait(); + + //Try to avoid potions bug + C.Unbank("Healer"); + C.Equip("Healer"); + EquipClasses(false); + + const string syncPath = "EclipseAscentReset"; + Ultra.ClearSyncFile(syncPath); + Bot.Sleep(2500); + Ultra.WaitForArmy(3, syncPath, timeoutMs: 10000); + } + + bool OnBotStopped(Exception? e) + { + Bot.Events.ScriptStopping -= OnBotStopped; + Bot.Flash.FlashCall -= Listener; + + return true; + } + } + + private class EclipseBase + { + protected CoreEclipse Eclipse; + protected IScriptInterface Bot => Eclipse.Bot; + protected CoreBots C => Eclipse.C; + protected CoreUltra Ultra => Eclipse.Ultra; + protected bool doGetEnrage = true; + + protected EclipseBase(CoreEclipse eclipse) + { + Eclipse = eclipse; + } + + protected void Restart(string packet) + { + if (doGetEnrage) + { + doGetEnrage = false; + if (!C.CheckInventory("Scroll of Enrage", 250)) + Eclipse.GetScrollOfEnrage(1000); + + if (C.CheckInventory("Hallowed Remains", 400)) + C.SellItem("Hallowed Remains", all: true); + + const string syncPath = "EclipseAscentRestart"; + Ultra.ClearSyncFile(syncPath); + Ultra.WaitForArmy(3, syncPath); + } + + Bot.Sleep(2000); + if (sArmy.isPartyLeader()) + { + Bot.Send.Packet(packet); + } + else if (sArmy.getPartyLeader() != null) + { + Bot.Player?.Goto(sArmy.getPartyLeader()!); + } + } + + protected void Move(string packet) + { + switch (Bot.Player?.Cell) + { + case "Enter": + C.Jump("r1"); + doGetEnrage = true; + break; + case "r1": + C.Jump("r2"); + break; + case "r2": + C.Jump("r3"); + break; + case "r3a": + case "r3": + Restart(packet); + Bot.Wait.OverrideTimeout = true; + Bot.Wait.ForCellChange("Enter"); + Bot.Wait.OverrideTimeout = false; + //Try to avoid potions bug + C.Unbank("Healer"); + C.Equip("Healer"); + Eclipse.EquipClasses(false); + break; + } + } + } + + private class SolsticeMoon : EclipseBase + { + public SolsticeMoon(CoreEclipse eclipse, int count) : base(eclipse) + { + while (!Bot.ShouldExit && !C.CheckInventory("Sliver of Moonlight", count)) + { + if (Bot.Map.Name != "solsticemoon") + { + Restart("%xt%zm%dungeonQueue%24946%solsticemoon%"); + Bot.Wait.ForMapLoad("solsticemoon"); + //Try to avoid potions bug + C.Unbank("Healer"); + C.Equip("Healer"); + Eclipse.EquipClasses(false); + } + else + { + Kill(); + } + } + } + + private bool IsTaunter() + { + return Bot.Player.Username.Equals(Bot.Config!.Get("player3").ToLower()) || Bot.Player.Username.Equals(Bot.Config!.Get("player4").ToLower()); + } + + private void Kill() + { + Bot.Sleep(1000); + if (Bot.Monsters.CurrentMonsters.Any(x => x.Alive)) + if (Bot.Player.Cell.Equals("r3") && IsTaunter()) + Eclipse.EclipseBossHandler("player4", "Hollow Midnight", "The Moon Converges"); + else + Bot.Combat.Attack("*"); + else + Move("%xt%zm%dungeonQueue%24946%solsticemoon%"); + } + } + + private class MidnightSun : EclipseBase + { + public MidnightSun(CoreEclipse eclipse, int count) : base(eclipse) + { + while (!Bot.ShouldExit && !C.CheckInventory("Sliver of Sunlight", count)) + { + if (Bot.Map.Name != "midnightsun") + { + Restart("%xt%zm%dungeonQueue%25127%midnightsun%"); + Bot.Wait.ForMapLoad("midnightsun"); + //Try to avoid potions bug + C.Unbank("Healer"); + C.Equip("Healer"); + Eclipse.EquipClasses(false); + } + else + { + Kill(); + } + } + } + + private bool IsTaunter() + { + return Bot.Player.Username.Equals(Bot.Config!.Get("player1").ToLower()) || Bot.Player.Username.Equals(Bot.Config!.Get("player2").ToLower()); + } + + private void Kill() + { + Bot.Sleep(1000); + if (Bot.Monsters.CurrentMonsters.Any(x => x.Alive)) + if (Bot.Player.Cell.Equals("r3") && IsTaunter()) + Eclipse.EclipseBossHandler("player2", "Hollow Solstice", "The Sun Converges"); + else if (IsTaunter() && Bot.Monsters.CurrentMonsters.Any(x => x is { Alive: true, Name: "Dying Light" })) + Eclipse.EclipseBossHandler("player1", "Dying Light", "The Light Gathers", bossCell: Bot.Player.Cell); + else + Bot.Combat.Attack("*"); + else + Move("%xt%zm%dungeonQueue%25127%midnightsun%"); + } + } + + private class AscendEclipse : EclipseBase + { + public AscendEclipse(CoreEclipse eclipse, int count) : base(eclipse) + { + while (!Bot.ShouldExit && !C.CheckInventory("Ecliptic Offering", count)) + { + if (Bot.Map.Name != "ascendeclipse") + { + Restart("%xt%zm%dungeonQueue%15395%ascendeclipse%"); + Bot.Wait.ForMapLoad("ascendeclipse"); + //Try to avoid potions bug + C.Unbank("Healer"); + C.Equip("Healer"); + Eclipse.EquipClasses(false); + } + else + { + Kill(); + } + } + } + + private bool IsTeamSun() + { + return Bot.Player.Username.Equals(Bot.Config!.Get("player1").ToLower()) || Bot.Player.Username.Equals(Bot.Config!.Get("player2").ToLower()); + } + + private void Kill() + { + Bot.Sleep(1000); + if (Bot.Monsters.CurrentMonsters.Any(x => x.Alive)) + switch (Bot.Player.Cell) + { + case "Enter": + if (Bot.Monsters.CurrentMonsters.Any(x => x is { Alive: true, Name: "Fallen Star" })) + if (Bot.Player.Username.Equals(Bot.Config!.Get("player4").ToLower()) && Bot.Monsters.CurrentMonsters.Any(x => x is { Alive: true, Name: "Blessless Deer" })) + Bot.Combat.Attack("Blessless Deer"); + else + Bot.Combat.Attack("Fallen Star"); + else + Bot.Combat.Attack("*"); + break; + case "r1": + if (IsTeamSun() && Bot.Monsters.CurrentMonsters.Any(x => x is { Alive: true, Name: "Suffocated Light" })) + Eclipse.EclipseBossHandler("player1", "Suffocated Light", "The Light Gathers", bossCell: Bot.Player.Cell); + else + Bot.Combat.Attack("*"); + break; + case "r2": + if (Bot.Monsters.CurrentMonsters.Any(x => x is { Alive: true, Name: "Sunset Knight" })) + { + if (Bot.Player.Username.Equals(Bot.Config!.Get("player4").ToLower()) && + Bot.Monsters.CurrentMonsters.Any(x => x is { Alive: true, Name: "Moon Haze" })) + Eclipse.EclipseBossHandler("player4", "Moon Haze", "You gaze into the moon", + bossCell: Bot.Player.Cell, alternateEnrage: false, tauntOffset: 6); + else if (Bot.Player.Username.Equals(Bot.Config!.Get("player3").ToLower()) && + Bot.Monsters.CurrentMonsters.Any(x => x is { Alive: true, Name: "Sunset Knight" })) + Eclipse.EclipseBossHandler("player3", "Sunset Knight", "You feel the warmth of the sun", + bossCell: Bot.Player.Cell, alternateEnrage: false, tauntOffset: 6); + else + Bot.Combat.Attack("Sunset Knight"); + } + else + Bot.Combat.Attack("*"); + break; + case "r3": + if (IsTeamSun() && Bot.Monsters.CurrentMonsters.Any(x => x is { Alive: true, Name: "Ascended Solstice" })) + Eclipse.EclipseBossHandler("player1", "Ascended Solstice", "The Sun Converges", deathResetCount: 2, deathMessages: + ["The Ascended Midnight glows brighter", "The Ascended Solstice burns hotter"]); + else if (Bot.Monsters.CurrentMonsters.Any(x => x is { Alive: true, Name: "Ascended Midnight" })) + Eclipse.EclipseBossHandler("player3", "Ascended Midnight", "The Moon Converges", deathResetCount: 2, deathMessages: + ["The Ascended Midnight glows brighter", "The Ascended Solstice burns hotter"]); + else + Bot.Combat.Attack("*"); + break; + default: + Bot.Combat.Attack("*"); + break; + } + else + Move("%xt%zm%dungeonQueue%15395%ascendeclipse%"); + } + } +} From f8f4bea3c0d76f5e80d508350cf2665383c7163f Mon Sep 17 00:00:00 2001 From: Robmart <4825809+robmart@users.noreply.github.com> Date: Sun, 5 Apr 2026 10:31:05 +0200 Subject: [PATCH 3/5] Remove namespaces inserted by the IDE --- Dungeons/EclipseAscent/0GreatbladeoftheEntwinedEclipse.cs | 2 -- Dungeons/EclipseAscent/CelestialTempleForgeMerge.cs | 1 - Dungeons/EclipseAscent/CoreEclipse.cs | 2 -- 3 files changed, 5 deletions(-) diff --git a/Dungeons/EclipseAscent/0GreatbladeoftheEntwinedEclipse.cs b/Dungeons/EclipseAscent/0GreatbladeoftheEntwinedEclipse.cs index 015ffc2d1..26b65fda0 100644 --- a/Dungeons/EclipseAscent/0GreatbladeoftheEntwinedEclipse.cs +++ b/Dungeons/EclipseAscent/0GreatbladeoftheEntwinedEclipse.cs @@ -10,8 +10,6 @@ using Skua.Core.Models; using Skua.Core.Options; -namespace SkuaScripts.Scripts.Custom.EclipseAscent; - public class GreatbladeoftheEntwinedEclipse { private IScriptInterface Bot => IScriptInterface.Instance; diff --git a/Dungeons/EclipseAscent/CelestialTempleForgeMerge.cs b/Dungeons/EclipseAscent/CelestialTempleForgeMerge.cs index 8ea406a09..186f5db84 100644 --- a/Dungeons/EclipseAscent/CelestialTempleForgeMerge.cs +++ b/Dungeons/EclipseAscent/CelestialTempleForgeMerge.cs @@ -12,7 +12,6 @@ using Skua.Core.Interfaces; using Skua.Core.Models.Items; using Skua.Core.Options; -using SkuaScripts.Scripts.Custom.EclipseAscent; public class CelestialTempleForgeMerge { diff --git a/Dungeons/EclipseAscent/CoreEclipse.cs b/Dungeons/EclipseAscent/CoreEclipse.cs index f4d64738d..48c093350 100644 --- a/Dungeons/EclipseAscent/CoreEclipse.cs +++ b/Dungeons/EclipseAscent/CoreEclipse.cs @@ -12,8 +12,6 @@ using Skua.Core.Options; using Skua.Core.Scripts; -namespace SkuaScripts.Scripts.Custom.EclipseAscent; - public class CoreEclipse { private IScriptInterface Bot => IScriptInterface.Instance; From d2ae3b8fda39641f77692356b1b4fb8c2ce07ee8 Mon Sep 17 00:00:00 2001 From: Robmart <4825809+robmart@users.noreply.github.com> Date: Sun, 5 Apr 2026 10:35:19 +0200 Subject: [PATCH 4/5] Oops --- Dungeons/EclipseAscent/0GreatbladeoftheEntwinedEclipse.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dungeons/EclipseAscent/0GreatbladeoftheEntwinedEclipse.cs b/Dungeons/EclipseAscent/0GreatbladeoftheEntwinedEclipse.cs index 26b65fda0..221aec43b 100644 --- a/Dungeons/EclipseAscent/0GreatbladeoftheEntwinedEclipse.cs +++ b/Dungeons/EclipseAscent/0GreatbladeoftheEntwinedEclipse.cs @@ -79,7 +79,7 @@ public void ScriptMain(IScriptInterface Bot) coreEclipse.EquipWait(); coreEclipse.EquipClasses(true); - templeMerge.BuyAllMerge(""); + templeMerge.BuyAllMerge("Greatblade of the Entwined Eclipse"); sArmy.PartyLeave(); From 484129c759ea8ade14775711249500539b15dd69 Mon Sep 17 00:00:00 2001 From: Robmart <4825809+robmart@users.noreply.github.com> Date: Sun, 5 Apr 2026 12:17:10 +0200 Subject: [PATCH 5/5] Fix AI comments --- .../0GreatbladeoftheEntwinedEclipse.cs | 90 ++--------- .../CelestialTempleForgeMerge.cs | 83 ++-------- Dungeons/EclipseAscent/CoreEclipse.cs | 147 ++++++++++++++---- 3 files changed, 142 insertions(+), 178 deletions(-) diff --git a/Dungeons/EclipseAscent/0GreatbladeoftheEntwinedEclipse.cs b/Dungeons/EclipseAscent/0GreatbladeoftheEntwinedEclipse.cs index 221aec43b..fbe5a9f15 100644 --- a/Dungeons/EclipseAscent/0GreatbladeoftheEntwinedEclipse.cs +++ b/Dungeons/EclipseAscent/0GreatbladeoftheEntwinedEclipse.cs @@ -17,90 +17,34 @@ public class GreatbladeoftheEntwinedEclipse private static CoreAdvanced Adv = new(); public CoreUltra Ultra = new(); private static CoreArmyLite sArmy = new(); - public CoreEclipse coreEclipse = new(); + public static CoreEclipse coreEclipse + { + get => _coreEclipse; + set => _coreEclipse = value; + } + public static CoreEclipse _coreEclipse = new(); public CelestialTempleForgeMerge templeMerge = new(); public bool DontPreconfigure = true; public string OptionsStorage = "EclipseAscent"; - - public List Options = new() - { - new Option( - "player1", - "Account #1", - "This character will be using Legion Revenant", - "" - ), - new Option( - "player2", - "Account #2", - "This character will be using StoneCrusher", - "" - ), - new Option( - "player3", - "Account #3", - "This character will be using ArchPaladin", - "" - ), - new Option( - "player4", - "Account #4", - "This character will be using Lord Of Order", - "" - ), - new Option( - "autoclass", - "Auto Equip Classes", - "This will auto equip all classes, if false it will use the classes already equipped.", - true - ), - CoreBots.Instance.SkipOptions, - }; + public List Options = GetOptions(); public void ScriptMain(IScriptInterface Bot) { - Bot.Events.ScriptStopping += OnBotStopped; - Bot.Events.ExtensionPacketReceived += sArmy.PartyManagement; - - C.BankingBlackList.AddRange(new[] - { "Sliver of Moonlight", "Sliver of Sunlight", "Victor of the Festival", "Ecliptic Offering" }); - - C.SetOptions(); - C.SendPackets($"%xt%zm%cmd%1%uopref%bParty%true%"); //To be able to join party - - while (!Bot.ShouldExit && sArmy.PartyMemberArray()!.Length < 4) - coreEclipse.SetupParty(); - - C.SendPackets($"%xt%zm%cmd%1%uopref%bParty%false%"); - - Adv.GearStore(EnhAfter: true); - - coreEclipse.EquipWait(); - coreEclipse.EquipClasses(true); + coreEclipse.BotStart(); templeMerge.BuyAllMerge("Greatblade of the Entwined Eclipse"); - - sArmy.PartyLeave(); - - Bot.Events.ScriptStopping -= OnBotStopped; - Bot.Events.ExtensionPacketReceived -= sArmy.PartyManagement; - - Adv.GearStore(true, EnhAfter: true); - - C.SetOptions(false); + + coreEclipse.BotStop(); } - private bool OnBotStopped(Exception? exception) + private static List GetOptions() { - Bot.Events.ScriptStopping -= OnBotStopped; - Bot.Events.ExtensionPacketReceived -= sArmy.PartyManagement; - - C.JumpWait(); - sArmy.PartyLeave(); - - Adv.GearStore(true, EnhAfter: true); - - return true; + var list = new List + { + CoreBots.Instance.SkipOptions, + }; + list.AddRange(coreEclipse.Options); + return list; } } diff --git a/Dungeons/EclipseAscent/CelestialTempleForgeMerge.cs b/Dungeons/EclipseAscent/CelestialTempleForgeMerge.cs index 186f5db84..c66a4e4e7 100644 --- a/Dungeons/EclipseAscent/CelestialTempleForgeMerge.cs +++ b/Dungeons/EclipseAscent/CelestialTempleForgeMerge.cs @@ -23,7 +23,12 @@ public class CelestialTempleForgeMerge private static CoreAdvanced _Adv; private static CoreAdvanced sAdv { get => _sAdv ??= new CoreAdvanced(); set => _sAdv = value; } private static CoreAdvanced _sAdv; - public CoreEclipse coreEclipse = new(); + public static CoreEclipse coreEclipse + { + get => _coreEclipse; + set => _coreEclipse = value; + } + public static CoreEclipse _coreEclipse = new(); private static CoreArmyLite sArmy = new(); private static VictorMatsuri VictorMatsuri = new(); @@ -35,70 +40,15 @@ public class CelestialTempleForgeMerge // [Can Change] This should only be changed by the author. // If true, it will not stop the script if the default case triggers and the user chose to only get mats private bool dontStopMissingIng = false; - public List Options = new() - { - new Option( - "player1", - "Account #1", - "This character will be using Legion Revenant", - "" - ), - new Option( - "player2", - "Account #2", - "This character will be using StoneCrusher", - "" - ), - new Option( - "player3", - "Account #3", - "This character will be using ArchPaladin", - "" - ), - new Option( - "player4", - "Account #4", - "This character will be using Lord Of Order", - "" - ), - new Option( - "autoclass", - "Auto Equip Classes", - "This will auto equip all classes, if false it will use the classes already equipped.", - true - ), - }; + public List Options = coreEclipse.Options; public void ScriptMain(IScriptInterface Bot) { - Bot.Events.ScriptStopping += OnBotStopped; - Bot.Events.ExtensionPacketReceived += sArmy.PartyManagement; - - Core.BankingBlackList.AddRange(new[] { "Sliver of Moonlight", "Sliver of Sunlight", "Victor of the Festival", "Ecliptic Offering" }); - - Core.SetOptions(); - Core.SendPackets($"%xt%zm%cmd%1%uopref%bParty%true%"); //To be able to join party - - while (!Bot.ShouldExit && sArmy.PartyMemberArray()!.Length < 4) - coreEclipse.SetupParty(); - - Core.SendPackets($"%xt%zm%cmd%1%uopref%bParty%false%"); - - Adv.GearStore(EnhAfter: true); - - coreEclipse.EquipWait(); - coreEclipse.EquipClasses(true); + coreEclipse.BotStart(); BuyAllMerge(); - - sArmy.PartyLeave(); - - Bot.Events.ScriptStopping -= OnBotStopped; - Bot.Events.ExtensionPacketReceived -= sArmy.PartyManagement; - - Adv.GearStore(true, EnhAfter: true); - - Core.SetOptions(false); + + coreEclipse.BotStop(); } public void BuyAllMerge(string? buyOnlyThis = null, mergeOptionsEnum? buyMode = null) @@ -172,17 +122,4 @@ void findIngredients() new Option("78462", "Greatblade of the Solstice Moon", "Mode: [select] only\nShould the bot buy \"Greatblade of the Solstice Moon\" ?", false), new Option("78457", "Greatblade of the Entwined Eclipse", "Mode: [select] only\nShould the bot buy \"Greatblade of the Entwined Eclipse\" ?", false), }; - - private bool OnBotStopped(Exception? exception) - { - Bot.Events.ScriptStopping -= OnBotStopped; - Bot.Events.ExtensionPacketReceived -= sArmy.PartyManagement; - - Core.JumpWait(); - sArmy.PartyLeave(); - - Adv.GearStore(true, EnhAfter: true); - - return true; - } } diff --git a/Dungeons/EclipseAscent/CoreEclipse.cs b/Dungeons/EclipseAscent/CoreEclipse.cs index 48c093350..03487d116 100644 --- a/Dungeons/EclipseAscent/CoreEclipse.cs +++ b/Dungeons/EclipseAscent/CoreEclipse.cs @@ -20,6 +20,78 @@ public class CoreEclipse private CoreUltra Ultra = new(); private static CoreAdvanced Adv = new(); private static CoreArmyLite sArmy = new(); + + public List Options = new() + { + new Option( + "player1", + "Account #1", + "This character will be using Legion Revenant", + "" + ), + new Option( + "player2", + "Account #2", + "This character will be using StoneCrusher", + "" + ), + new Option( + "player3", + "Account #3", + "This character will be using ArchPaladin", + "" + ), + new Option( + "player4", + "Account #4", + "This character will be using Lord Of Order", + "" + ), + new Option( + "autoclass", + "Auto Equip Classes", + "This will auto equip all classes, if false it will use the classes already equipped.", + true + ), + }; + + public bool IsPlayer1 => Bot.Player.Username.Equals(Bot.Config!.Get("player1")?.ToLower()); + public bool IsPlayer2 => Bot.Player.Username.Equals(Bot.Config!.Get("player2")?.ToLower()); + public bool IsPlayer3 => Bot.Player.Username.Equals(Bot.Config!.Get("player3")?.ToLower()); + public bool IsPlayer4 => Bot.Player.Username.Equals(Bot.Config!.Get("player4")?.ToLower()); + + public void BotStart() + { + Bot.Events.ScriptStopping += OnBotStopped; + Bot.Events.ExtensionPacketReceived += sArmy.PartyManagement; + + C.BankingBlackList.AddRange(new[] { "Sliver of Moonlight", "Sliver of Sunlight", "Victor of the Festival", "Ecliptic Offering" }); + + C.SetOptions(); + C.SendPackets($"%xt%zm%cmd%1%uopref%bParty%true%"); //To be able to join party + + while (!Bot.ShouldExit && sArmy.PartyMemberArray()!.Length < 4) + SetupParty(); + + C.SendPackets($"%xt%zm%cmd%1%uopref%bParty%false%"); + + Adv.GearStore(EnhAfter: true); + + EquipWait(); + EquipClasses(true); + } + + public void BotStop() + { + sArmy.PartyLeave(); + + Bot.Events.ScriptStopping -= OnBotStopped; + Bot.Events.ExtensionPacketReceived -= sArmy.PartyManagement; + + Adv.GearStore(true, EnhAfter: true); + + C.SetOptions(false); + } public void EquipWait(string item = "Scroll of Enrage") { @@ -31,7 +103,7 @@ public void EquipWait(string item = "Scroll of Enrage") public void SetupParty() { - if (!Bot.Player.Username.Equals(Bot.Config!.Get("player1").ToLower())) return; + if (!IsPlayer1) return; if (!sArmy.PartyMemberArray().Contains(Bot.Config!.Get("player2")!.ToLower())) { @@ -55,7 +127,7 @@ public void SetupParty() public void EquipClasses(bool autoEnhance) { if (!Bot.Config!.Get("autoclass")) return; - if (Bot.Player.Username.Equals(Bot.Config!.Get("player1").ToLower()) && C.CheckInventory("Legion Revenant")) + if (IsPlayer1 && C.CheckInventory("Legion Revenant")) { C.Equip("Legion Revenant"); if (!autoEnhance) return; @@ -66,7 +138,7 @@ public void EquipClasses(bool autoEnhance) cSpecial: CapeSpecial.Vainglory ); } - else if (Bot.Player.Username.Equals(Bot.Config!.Get("player2").ToLower()) && C.CheckInventory("StoneCrusher")) + else if (IsPlayer2 && C.CheckInventory("StoneCrusher")) { C.Equip("StoneCrusher"); if (!autoEnhance) return; @@ -77,7 +149,7 @@ public void EquipClasses(bool autoEnhance) cSpecial: CapeSpecial.Absolution ); } - else if (Bot.Player.Username.Equals(Bot.Config!.Get("player3").ToLower()) && C.CheckInventory("ArchPaladin")) + else if (IsPlayer3 && C.CheckInventory("ArchPaladin")) { C.Equip("ArchPaladin"); if (!autoEnhance) return; @@ -88,7 +160,7 @@ public void EquipClasses(bool autoEnhance) cSpecial: CapeSpecial.Penitence ); } - else if (Bot.Player.Username.Equals(Bot.Config!.Get("player4").ToLower()) && C.CheckInventory("Lord Of Order")) + else if (IsPlayer4 && C.CheckInventory("Lord Of Order")) { C.Equip("Lord Of Order"); if (!autoEnhance) return; @@ -108,6 +180,14 @@ public void EquipClasses(bool autoEnhance) } } + public void PotionsBug() + { + //Try to avoid potions bug + C.Unbank("Healer"); + C.Equip("Healer"); + EquipClasses(false); + } + public void GetScrollOfEnrage(int count = 100) { if (!Core.Faction("SpellCrafting", 5)) @@ -150,6 +230,20 @@ public void GetEclipticOffering(int count = 155) new AscendEclipse(this, count); } + private bool OnBotStopped(Exception? exception) + { + Bot.Events.ScriptStopping -= OnBotStopped; + Bot.Events.ExtensionPacketReceived -= sArmy.PartyManagement; + + C.JumpWait(); + sArmy.PartyLeave(); + + Adv.GearStore(true, EnhAfter: true); + + return true; + } + + #region Boss Handler private bool needsEnrage; private bool usedEnrage; private bool usedLastEnrage; @@ -160,9 +254,7 @@ public void EclipseBossHandler(string startingEnragePlayer, string bossName, str { needsEnrage = false; usedEnrage = false; - usedLastEnrage = alternateEnrage - ? Bot.Player.Username.Equals(Bot.Config!.Get(startingEnragePlayer).ToLower()) - : false; + usedLastEnrage = alternateEnrage && Bot.Player.Username.Equals(Bot.Config!.Get(startingEnragePlayer)?.ToLower()); deathCount = 0; Bot.Events.ScriptStopping += OnBotStopped; @@ -195,8 +287,8 @@ public void EclipseBossHandler(string startingEnragePlayer, string bossName, str C.UsePotion(); C.Sleep(200); // Small delay to allow scroll to apply - if (Bot.Player.HasTarget && (Bot.Target.Auras.Any(x => x.Name.Equals("Focus", StringComparison.OrdinalIgnoreCase) && x.RemainingTime > 4)) || - Bot.Target.Auras.Any(x => x.Name.Equals("Reckless", StringComparison.OrdinalIgnoreCase) && x.RemainingTime > 4)) + if (Bot.Player.HasTarget && (Bot.Target.Auras.Any(x => x.Name.Equals("Focus", StringComparison.OrdinalIgnoreCase) && x.RemainingTime > 4) || + Bot.Target.Auras.Any(x => x.Name.Equals("Reckless", StringComparison.OrdinalIgnoreCase) && x.RemainingTime > 4))) { usedEnrage = true; needsEnrage = false; @@ -358,10 +450,7 @@ void ResetFight() C.JumpWait(); - //Try to avoid potions bug - C.Unbank("Healer"); - C.Equip("Healer"); - EquipClasses(false); + PotionsBug(); const string syncPath = "EclipseAscentReset"; Ultra.ClearSyncFile(syncPath); @@ -377,7 +466,9 @@ bool OnBotStopped(Exception? e) return true; } } + #endregion + #region Dungeon Handlers private class EclipseBase { protected CoreEclipse Eclipse; @@ -457,10 +548,7 @@ public SolsticeMoon(CoreEclipse eclipse, int count) : base(eclipse) { Restart("%xt%zm%dungeonQueue%24946%solsticemoon%"); Bot.Wait.ForMapLoad("solsticemoon"); - //Try to avoid potions bug - C.Unbank("Healer"); - C.Equip("Healer"); - Eclipse.EquipClasses(false); + Eclipse.PotionsBug(); } else { @@ -471,7 +559,7 @@ public SolsticeMoon(CoreEclipse eclipse, int count) : base(eclipse) private bool IsTaunter() { - return Bot.Player.Username.Equals(Bot.Config!.Get("player3").ToLower()) || Bot.Player.Username.Equals(Bot.Config!.Get("player4").ToLower()); + return Eclipse.IsPlayer3 || Eclipse.IsPlayer4; } private void Kill() @@ -497,10 +585,7 @@ public MidnightSun(CoreEclipse eclipse, int count) : base(eclipse) { Restart("%xt%zm%dungeonQueue%25127%midnightsun%"); Bot.Wait.ForMapLoad("midnightsun"); - //Try to avoid potions bug - C.Unbank("Healer"); - C.Equip("Healer"); - Eclipse.EquipClasses(false); + Eclipse.PotionsBug(); } else { @@ -511,7 +596,7 @@ public MidnightSun(CoreEclipse eclipse, int count) : base(eclipse) private bool IsTaunter() { - return Bot.Player.Username.Equals(Bot.Config!.Get("player1").ToLower()) || Bot.Player.Username.Equals(Bot.Config!.Get("player2").ToLower()); + return Eclipse.IsPlayer1 || Eclipse.IsPlayer2; } private void Kill() @@ -539,10 +624,7 @@ public AscendEclipse(CoreEclipse eclipse, int count) : base(eclipse) { Restart("%xt%zm%dungeonQueue%15395%ascendeclipse%"); Bot.Wait.ForMapLoad("ascendeclipse"); - //Try to avoid potions bug - C.Unbank("Healer"); - C.Equip("Healer"); - Eclipse.EquipClasses(false); + Eclipse.PotionsBug(); } else { @@ -553,7 +635,7 @@ public AscendEclipse(CoreEclipse eclipse, int count) : base(eclipse) private bool IsTeamSun() { - return Bot.Player.Username.Equals(Bot.Config!.Get("player1").ToLower()) || Bot.Player.Username.Equals(Bot.Config!.Get("player2").ToLower()); + return Eclipse.IsPlayer1 || Eclipse.IsPlayer2; } private void Kill() @@ -564,7 +646,7 @@ private void Kill() { case "Enter": if (Bot.Monsters.CurrentMonsters.Any(x => x is { Alive: true, Name: "Fallen Star" })) - if (Bot.Player.Username.Equals(Bot.Config!.Get("player4").ToLower()) && Bot.Monsters.CurrentMonsters.Any(x => x is { Alive: true, Name: "Blessless Deer" })) + if (Eclipse.IsPlayer4 && Bot.Monsters.CurrentMonsters.Any(x => x is { Alive: true, Name: "Blessless Deer" })) Bot.Combat.Attack("Blessless Deer"); else Bot.Combat.Attack("Fallen Star"); @@ -580,11 +662,11 @@ private void Kill() case "r2": if (Bot.Monsters.CurrentMonsters.Any(x => x is { Alive: true, Name: "Sunset Knight" })) { - if (Bot.Player.Username.Equals(Bot.Config!.Get("player4").ToLower()) && + if (Eclipse.IsPlayer4 && Bot.Monsters.CurrentMonsters.Any(x => x is { Alive: true, Name: "Moon Haze" })) Eclipse.EclipseBossHandler("player4", "Moon Haze", "You gaze into the moon", bossCell: Bot.Player.Cell, alternateEnrage: false, tauntOffset: 6); - else if (Bot.Player.Username.Equals(Bot.Config!.Get("player3").ToLower()) && + else if (Eclipse.IsPlayer3 && Bot.Monsters.CurrentMonsters.Any(x => x is { Alive: true, Name: "Sunset Knight" })) Eclipse.EclipseBossHandler("player3", "Sunset Knight", "You feel the warmth of the sun", bossCell: Bot.Player.Cell, alternateEnrage: false, tauntOffset: 6); @@ -612,4 +694,5 @@ private void Kill() Move("%xt%zm%dungeonQueue%15395%ascendeclipse%"); } } + #endregion }