diff --git a/Dungeons/EclipseAscent/0GreatbladeoftheEntwinedEclipse.cs b/Dungeons/EclipseAscent/0GreatbladeoftheEntwinedEclipse.cs new file mode 100644 index 000000000..fbe5a9f15 --- /dev/null +++ b/Dungeons/EclipseAscent/0GreatbladeoftheEntwinedEclipse.cs @@ -0,0 +1,50 @@ +//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; + +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 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 = GetOptions(); + + public void ScriptMain(IScriptInterface Bot) + { + coreEclipse.BotStart(); + + templeMerge.BuyAllMerge("Greatblade of the Entwined Eclipse"); + + coreEclipse.BotStop(); + } + + private static List GetOptions() + { + 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 new file mode 100644 index 000000000..c66a4e4e7 --- /dev/null +++ b/Dungeons/EclipseAscent/CelestialTempleForgeMerge.cs @@ -0,0 +1,125 @@ +/* +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; + +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 static CoreEclipse coreEclipse + { + get => _coreEclipse; + set => _coreEclipse = value; + } + public static 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 = coreEclipse.Options; + + public void ScriptMain(IScriptInterface Bot) + { + coreEclipse.BotStart(); + + BuyAllMerge(); + + coreEclipse.BotStop(); + } + + 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), + }; +} diff --git a/Dungeons/EclipseAscent/CoreEclipse.cs b/Dungeons/EclipseAscent/CoreEclipse.cs new file mode 100644 index 000000000..03487d116 --- /dev/null +++ b/Dungeons/EclipseAscent/CoreEclipse.cs @@ -0,0 +1,698 @@ +//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; + +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 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") + { + C.Equip(item); + Bot.Wait.ForItemEquip(item); + Bot.Wait.ForActionCooldown(GameActions.EquipItem); + C.Sleep(); + } + + public void SetupParty() + { + if (!IsPlayer1) 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 (IsPlayer1 && 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 (IsPlayer2 && 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 (IsPlayer3 && 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 (IsPlayer4 && 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 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)) + 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 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; + 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()); + 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(); + + PotionsBug(); + + 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; + } + } + #endregion + + #region Dungeon Handlers + 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"); + Eclipse.PotionsBug(); + } + else + { + Kill(); + } + } + } + + private bool IsTaunter() + { + return Eclipse.IsPlayer3 || Eclipse.IsPlayer4; + } + + 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"); + Eclipse.PotionsBug(); + } + else + { + Kill(); + } + } + } + + private bool IsTaunter() + { + return Eclipse.IsPlayer1 || Eclipse.IsPlayer2; + } + + 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"); + Eclipse.PotionsBug(); + } + else + { + Kill(); + } + } + } + + private bool IsTeamSun() + { + return Eclipse.IsPlayer1 || Eclipse.IsPlayer2; + } + + 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 (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"); + 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 (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 (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); + 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%"); + } + } + #endregion +}