From 6f5d0bcb013605781f9259980121a441004acd97 Mon Sep 17 00:00:00 2001
From: Jouramie <16137441+Jouramie@users.noreply.github.com>
Date: Sun, 26 Jul 2026 10:50:45 -0400
Subject: [PATCH] switch everything to file scoped namespace
---
APRandomizerMain.cs | 1549 ++++++++---------
Archipelago/ArchipelagoClient.cs | 849 +++++----
Archipelago/ArchipelagoData.cs | 223 ++-
Archipelago/DeathLinkInterface.cs | 317 ++--
Archipelago/ItemsAndLocationsHandler.cs | 989 ++++++-----
Archipelago/TrackerManager.cs | 51 +-
Exceptions/RandomizerException.cs | 33 +-
GameOverrideManagers/FlavorDialogManager.cs | 251 ++-
GameOverrideManagers/LostWoodsManager.cs | 63 +-
GameOverrideManagers/RandoBossManager.cs | 407 +++--
GameOverrideManagers/RandoMusicManager.cs | 99 +-
GameOverrideManagers/RandoPortalManager.cs | 813 +++++----
GameOverrideManagers/RandoPowerSealManager.cs | 101 +-
GameOverrideManagers/RandoRoomManager.cs | 197 ++-
GameOverrideManagers/RandoShopManager.cs | 371 ++--
GameOverrideManagers/RandoTimeShardManager.cs | 203 ++-
.../SkylandsGeneratorManager.cs | 357 ++--
GameOverrideManagers/TrapManager.cs | 336 ++--
Overrides/RandoCatacombLevelInitializer.cs | 49 +-
RO/LocationRO.cs | 55 +-
RO/RandoItemRO.cs | 105 +-
Utils/Constants/BossConstants.cs | 135 +-
Utils/Constants/LevelConstants.cs | 979 ++++++-----
Utils/Constants/RoomConstants.cs | 183 +-
Utils/DialogChanger.cs | 213 ++-
Utils/ItemRandomizerUtil.cs | 35 +-
Utils/Menus/ArchipelagoMenu.cs | 1185 +++++++------
Utils/Menus/HintMenu.cs | 814 +++++----
Utils/Menus/RandoMenu.cs | 971 ++++++-----
Utils/OptionsExporter.cs | 137 +-
Utils/RandoSave.cs | 105 +-
Utils/RandomizerConstants.cs | 83 +-
Utils/RandomizerOptions.cs | 466 +++--
Utils/RandomizerSaveMethod.cs | 0
Utils/RandomizerStateManager.cs | 663 ++++---
Utils/ReflectionHelpers.cs | 45 +-
Utils/SeedGenerator.cs | 253 ++-
Utils/UserConfig.cs | 707 ++++----
38 files changed, 7173 insertions(+), 7219 deletions(-)
delete mode 100644 Utils/RandomizerSaveMethod.cs
diff --git a/APRandomizerMain.cs b/APRandomizerMain.cs
index 9eb97fd..bf16a09 100644
--- a/APRandomizerMain.cs
+++ b/APRandomizerMain.cs
@@ -21,959 +21,958 @@
using static Mod.Courier.UI.TextEntryButtonInfo;
using Object = UnityEngine.Object;
-namespace MessengerRando
+namespace MessengerRando;
+
+///
+/// Where it all begins! This class defines and injects all the necessary for the mod.
+///
+// ReSharper disable once ClassNeverInstantiated.Global
+public class APRandomizerMain : CourierModule
{
- ///
- /// Where it all begins! This class defines and injects all the necessary for the mod.
- ///
- // ReSharper disable once ClassNeverInstantiated.Global
- public class APRandomizerMain : CourierModule
- {
- private float updateTimer;
- public static float UpdateTime = 3.0f;
-
- private RandomizerStateManager randoStateManager;
- private SkylandsGeneratorManager skylandsGeneratorManager;
- private TrackerManager trackerManager;
-
- private TextMeshProUGUI apTextDisplay8;
- private TextMeshProUGUI apTextDisplay16;
- private TextMeshProUGUI apMessagesDisplay8;
- private TextMeshProUGUI apMessagesDisplay16;
- public static string ModPath = Courier.ModsFolder.Replace("/Mods", "/");
-
- private TextEntryPopup closeLater;
- private float closeLaterTimer;
- //Set up save data
- public override Type ModuleSaveType => typeof(RandoSave);
- // ReSharper disable once MemberCanBePrivate.Global
- public RandoSave Save => (RandoSave)ModuleSave;
-
- public override void Load()
- {
- Console.WriteLine("Randomizer loading and ready to try things!");
-
- //Initialize the randomizer state manager
- skylandsGeneratorManager = new SkylandsGeneratorManager();
- RandomizerStateManager.skylandsGeneratorManager = skylandsGeneratorManager;
-
- randoStateManager = new RandomizerStateManager();
-
- trackerManager = new TrackerManager();
- ItemsAndLocationsHandler.TrackerManager = trackerManager;
- RandoPortalManager.TrackerManager = trackerManager;
- RandoLevelManager.TrackerManager = trackerManager;
-
- //Plug in my code :3
- On.InventoryManager.AddItem += InventoryManager_AddItem;
- On.ProgressionManager.SetChallengeRoomAsCompleted += ProgressionManager_SetChallengeRoomAsCompleted;
- On.HasItem.IsTrue += HasItem_IsTrue;
- On.AwardNoteCutscene.ShouldPlay += AwardNoteCutscene_ShouldPlay;
- On.CutsceneHasPlayed.IsTrue += CutsceneHasPlayed_IsTrue;
- On.SaveGameSelectionScreen.OnLoadGame += SaveGameSelectionScreen_OnLoadGame;
- On.SaveGameSelectionScreen.OnNewGame += SaveGameSelectionScreen_OnNewGame;
- On.SaveGameSelectionScreen.ConfirmSaveDelete += SaveGameSelectionScreen_ConfirmSaveDelete;
- On.SaveGameSelectionScreen.OnDeleteChoiceDone += SaveGameSelectionScreen_OnDelete;
- On.SaveGameSelectionScreen.Update += SaveSelectionScreen_OnUpdate;
- On.NameSavePopup.Update += OnNameSaveUpdate;
- On.BackToTitleScreen.GoBackToTitleScreen += PauseScreen_OnQuitToTitle;
- On.NecrophobicWorkerCutscene.Play += NecrophobicWorkerCutscene_Play;
- IL.RuxxtinNoteAndAwardAmuletCutscene.Play += RuxxtinNoteAndAwardAmuletCutscene_Play;
- On.DialogCutscene.Play += DialogCutscene_Play;
- On.CatacombLevelInitializer.OnBeforeInitDone += CatacombLevelInitializer_OnBeforeInitDone;
- On.DialogManager.LoadDialogs_ELanguage += DialogChanger.LoadDialogs_Elanguage;
- On.OptionScreen.OnEnable += OnOptionScreenEnable;
- On.LostWoods.SetAsSolved += LostWoodsManager.OnSetAsSolved;
- // shop management
- On.UpgradeButtonData.GetPrice += RandoShopManager.GetPrice;
- On.LocalizationManager.GetText += RandoShopManager.GetText;
- // On.UpgradeButton.Refresh += RandoShopManager.UpgradeButton_Refresh;
- On.BuyMoneyWrenchCutscene.OnBuyWrenchChoice += RandoShopManager.BuyMoneyWrench;
- On.BuyMoneyWrenchCutscene.EndCutsceneOnDialogDone += RandoShopManager.EndMoneyWrenchCutscene;
- On.MoneySinkUnclogCutscene.OnDialogOutDone += RandoShopManager.UnclogSink;
- On.GoToSousSolCutscene.EndCutScene += RandoShopManager.GoToSousSol;
- On.IronHoodShopScreen.GetFigurineData += RandoShopManager.GetFigurineData;
- On.SousSol.UnlockFigurine += RandoShopManager.UnlockFigurine;
- On.Shop.Init += RandoShopManager.ShopInit;
- On.JukeboxTrack.IsUnlocked += (orig, self) => true;
- On.UpgradeButtonData.IsStoryUnlocked += RandoShopManager.IsStoryUnlocked;
- On.AudioManager.PlayMusic += RandoMusicManager.OnPlayMusic;
- // boss management
- On.ProgressionManager.HasDefeatedBoss +=
- (orig, self, bossName) => RandoBossManager.HasBossDefeated(bossName);
- On.ProgressionManager.HasEverDefeatedBoss +=
- (orig, self, bossName) => RandoBossManager.HasBossDefeated(bossName);
- On.ProgressionManager.SetBossAsDefeated +=
- (orig, self, bossName) => RandoBossManager.SetBossAsDefeated(bossName);
- // level teleporting etc management
- On.Level.ChangeRoom += RandoRoomManager.Level_ChangeRoom;
- On.LevelManager.LoadLevel += RandoLevelManager.LoadLevel;
- On.LevelManager.EndLevelLoading += RandoLevelManager.EndLevelLoading;
- On.ElementalSkylandsLevelInitializer.OnBeforeInitDone += RandoLevelManager.ElementalSkylandsInit;
- // On.PortalOpeningCutscene.OnOpenPortalEvent += RandoPortalManager.OpenPortalEvent;
- On.TotHQ.LeaveToLevel += RandoPortalManager.LeaveHQ;
- // generator deactivation management
- skylandsGeneratorManager.ApplyHooks();
- //These functions let us override and manage power seals ourselves with 'fake' items
- On.ProgressionManager.TotalPowerSealCollected += ProgressionManager_TotalPowerSealCollected;
- On.ShopChestOpenCutscene.OnChestOpened += (orig, self) =>
- RandomizerStateManager.Instance.PowerSealManager?.OnShopChestOpen(orig, self);
- On.ShopChestChangeShurikenCutscene.Play += (orig, self) =>
- RandomizerStateManager.Instance.PowerSealManager?.OnShopChestOpen(orig, self);
- //update loops for Archipelago
- Courier.Events.PlayerController.OnUpdate += PlayerController_OnUpdate;
- On.InGameHud.OnGUI += InGameHud_OnGUI;
- On.SaveManager.DoActualSaving += SaveManager_DoActualSave;
- On.PlayerController.Die += OnPlayerDie;
- On.Quarble.OnDeathScreenDone += OnDeathScreenDone;
- // On.MegaTimeShard.NextState += RandoTimeShardManager.NextState;
- // On.MegaTimeShard.ReceiveHit += RandoTimeShardManager.ReceiveHit;
- On.MegaTimeShard.OnBreakDone += MegaTimeShard_OnBreakDone;
- On.DialogSequence.GetDialogList += DialogSequence_GetDialogList;
- On.Cutscene.Play += Cutscene_Play;
- On.PlayerController.Awake += OnPlayerController_Awake;
- //temp add
+ private float updateTimer;
+ public static float UpdateTime = 3.0f;
+
+ private RandomizerStateManager randoStateManager;
+ private SkylandsGeneratorManager skylandsGeneratorManager;
+ private TrackerManager trackerManager;
+
+ private TextMeshProUGUI apTextDisplay8;
+ private TextMeshProUGUI apTextDisplay16;
+ private TextMeshProUGUI apMessagesDisplay8;
+ private TextMeshProUGUI apMessagesDisplay16;
+ public static string ModPath = Courier.ModsFolder.Replace("/Mods", "/");
+
+ private TextEntryPopup closeLater;
+ private float closeLaterTimer;
+ //Set up save data
+ public override Type ModuleSaveType => typeof(RandoSave);
+ // ReSharper disable once MemberCanBePrivate.Global
+ public RandoSave Save => (RandoSave)ModuleSave;
+
+ public override void Load()
+ {
+ Console.WriteLine("Randomizer loading and ready to try things!");
+
+ //Initialize the randomizer state manager
+ skylandsGeneratorManager = new SkylandsGeneratorManager();
+ RandomizerStateManager.skylandsGeneratorManager = skylandsGeneratorManager;
+
+ randoStateManager = new RandomizerStateManager();
+
+ trackerManager = new TrackerManager();
+ ItemsAndLocationsHandler.TrackerManager = trackerManager;
+ RandoPortalManager.TrackerManager = trackerManager;
+ RandoLevelManager.TrackerManager = trackerManager;
+
+ //Plug in my code :3
+ On.InventoryManager.AddItem += InventoryManager_AddItem;
+ On.ProgressionManager.SetChallengeRoomAsCompleted += ProgressionManager_SetChallengeRoomAsCompleted;
+ On.HasItem.IsTrue += HasItem_IsTrue;
+ On.AwardNoteCutscene.ShouldPlay += AwardNoteCutscene_ShouldPlay;
+ On.CutsceneHasPlayed.IsTrue += CutsceneHasPlayed_IsTrue;
+ On.SaveGameSelectionScreen.OnLoadGame += SaveGameSelectionScreen_OnLoadGame;
+ On.SaveGameSelectionScreen.OnNewGame += SaveGameSelectionScreen_OnNewGame;
+ On.SaveGameSelectionScreen.ConfirmSaveDelete += SaveGameSelectionScreen_ConfirmSaveDelete;
+ On.SaveGameSelectionScreen.OnDeleteChoiceDone += SaveGameSelectionScreen_OnDelete;
+ On.SaveGameSelectionScreen.Update += SaveSelectionScreen_OnUpdate;
+ On.NameSavePopup.Update += OnNameSaveUpdate;
+ On.BackToTitleScreen.GoBackToTitleScreen += PauseScreen_OnQuitToTitle;
+ On.NecrophobicWorkerCutscene.Play += NecrophobicWorkerCutscene_Play;
+ IL.RuxxtinNoteAndAwardAmuletCutscene.Play += RuxxtinNoteAndAwardAmuletCutscene_Play;
+ On.DialogCutscene.Play += DialogCutscene_Play;
+ On.CatacombLevelInitializer.OnBeforeInitDone += CatacombLevelInitializer_OnBeforeInitDone;
+ On.DialogManager.LoadDialogs_ELanguage += DialogChanger.LoadDialogs_Elanguage;
+ On.OptionScreen.OnEnable += OnOptionScreenEnable;
+ On.LostWoods.SetAsSolved += LostWoodsManager.OnSetAsSolved;
+ // shop management
+ On.UpgradeButtonData.GetPrice += RandoShopManager.GetPrice;
+ On.LocalizationManager.GetText += RandoShopManager.GetText;
+ // On.UpgradeButton.Refresh += RandoShopManager.UpgradeButton_Refresh;
+ On.BuyMoneyWrenchCutscene.OnBuyWrenchChoice += RandoShopManager.BuyMoneyWrench;
+ On.BuyMoneyWrenchCutscene.EndCutsceneOnDialogDone += RandoShopManager.EndMoneyWrenchCutscene;
+ On.MoneySinkUnclogCutscene.OnDialogOutDone += RandoShopManager.UnclogSink;
+ On.GoToSousSolCutscene.EndCutScene += RandoShopManager.GoToSousSol;
+ On.IronHoodShopScreen.GetFigurineData += RandoShopManager.GetFigurineData;
+ On.SousSol.UnlockFigurine += RandoShopManager.UnlockFigurine;
+ On.Shop.Init += RandoShopManager.ShopInit;
+ On.JukeboxTrack.IsUnlocked += (orig, self) => true;
+ On.UpgradeButtonData.IsStoryUnlocked += RandoShopManager.IsStoryUnlocked;
+ On.AudioManager.PlayMusic += RandoMusicManager.OnPlayMusic;
+ // boss management
+ On.ProgressionManager.HasDefeatedBoss +=
+ (orig, self, bossName) => RandoBossManager.HasBossDefeated(bossName);
+ On.ProgressionManager.HasEverDefeatedBoss +=
+ (orig, self, bossName) => RandoBossManager.HasBossDefeated(bossName);
+ On.ProgressionManager.SetBossAsDefeated +=
+ (orig, self, bossName) => RandoBossManager.SetBossAsDefeated(bossName);
+ // level teleporting etc management
+ On.Level.ChangeRoom += RandoRoomManager.Level_ChangeRoom;
+ On.LevelManager.LoadLevel += RandoLevelManager.LoadLevel;
+ On.LevelManager.EndLevelLoading += RandoLevelManager.EndLevelLoading;
+ On.ElementalSkylandsLevelInitializer.OnBeforeInitDone += RandoLevelManager.ElementalSkylandsInit;
+ // On.PortalOpeningCutscene.OnOpenPortalEvent += RandoPortalManager.OpenPortalEvent;
+ On.TotHQ.LeaveToLevel += RandoPortalManager.LeaveHQ;
+ // generator deactivation management
+ skylandsGeneratorManager.ApplyHooks();
+ //These functions let us override and manage power seals ourselves with 'fake' items
+ On.ProgressionManager.TotalPowerSealCollected += ProgressionManager_TotalPowerSealCollected;
+ On.ShopChestOpenCutscene.OnChestOpened += (orig, self) =>
+ RandomizerStateManager.Instance.PowerSealManager?.OnShopChestOpen(orig, self);
+ On.ShopChestChangeShurikenCutscene.Play += (orig, self) =>
+ RandomizerStateManager.Instance.PowerSealManager?.OnShopChestOpen(orig, self);
+ //update loops for Archipelago
+ Courier.Events.PlayerController.OnUpdate += PlayerController_OnUpdate;
+ On.InGameHud.OnGUI += InGameHud_OnGUI;
+ On.SaveManager.DoActualSaving += SaveManager_DoActualSave;
+ On.PlayerController.Die += OnPlayerDie;
+ On.Quarble.OnDeathScreenDone += OnDeathScreenDone;
+ // On.MegaTimeShard.NextState += RandoTimeShardManager.NextState;
+ // On.MegaTimeShard.ReceiveHit += RandoTimeShardManager.ReceiveHit;
+ On.MegaTimeShard.OnBreakDone += MegaTimeShard_OnBreakDone;
+ On.DialogSequence.GetDialogList += DialogSequence_GetDialogList;
+ On.Cutscene.Play += Cutscene_Play;
+ On.PlayerController.Awake += OnPlayerController_Awake;
+ //temp add
#if DEBUG
- On.PhantomIntroCutscene.OnEnterRoom += PhantomIntro_OnEnterRoom; //this lets us skip the phantom fight
- On.UIManager.ShowView += UIManager_ShowView;
- On.MusicBox.SetNotesState += MusicBox_SetNotesState;
- On.PowerSeal.OnEnterRoom += PowerSeal_OnEnterRoom;
+ On.PhantomIntroCutscene.OnEnterRoom += PhantomIntro_OnEnterRoom; //this lets us skip the phantom fight
+ On.UIManager.ShowView += UIManager_ShowView;
+ On.MusicBox.SetNotesState += MusicBox_SetNotesState;
+ On.PowerSeal.OnEnterRoom += PowerSeal_OnEnterRoom;
#endif
- ItemsAndLocationsHandler.SkylandsGeneratorManager = skylandsGeneratorManager;
+ ItemsAndLocationsHandler.SkylandsGeneratorManager = skylandsGeneratorManager;
- Console.WriteLine("Randomizer finished loading!");
- }
+ Console.WriteLine("Randomizer finished loading!");
+ }
- private void SaveSelectionScreen_OnUpdate(On.SaveGameSelectionScreen.orig_Update orig, SaveGameSelectionScreen self)
+ private void SaveSelectionScreen_OnUpdate(On.SaveGameSelectionScreen.orig_Update orig, SaveGameSelectionScreen self)
+ {
+ orig(self);
+ if (closeLater)
{
- orig(self);
- if (closeLater)
+ closeLaterTimer += Time.deltaTime;
+ if (closeLaterTimer >= 3)
{
- closeLaterTimer += Time.deltaTime;
- if (closeLaterTimer >= 3)
- {
- closeLater.gameObject.SetActive(false);
- closeLater = null;
- }
+ closeLater.gameObject.SetActive(false);
+ closeLater = null;
}
}
+ }
- private void OnNameSaveUpdate(On.NameSavePopup.orig_Update orig, NameSavePopup self)
- {
- self.OnLetterErased();
- }
-
- private void OnPlayerController_Awake(On.PlayerController.orig_Awake orig, PlayerController self)
- {
- // try {
- // GameObject darkness = Courier.LoadFromAssetBundles("Assets/PrefabInstance/modded/DarkCave_LightStencil.prefab");
- // Object.Instantiate(darkness, self.transform);
- // } catch(Exception e) {
- // e.LogDetailed();
- // }
+ private void OnNameSaveUpdate(On.NameSavePopup.orig_Update orig, NameSavePopup self)
+ {
+ self.OnLetterErased();
+ }
- orig(self);
- }
+ private void OnPlayerController_Awake(On.PlayerController.orig_Awake orig, PlayerController self)
+ {
+ // try {
+ // GameObject darkness = Courier.LoadFromAssetBundles("Assets/PrefabInstance/modded/DarkCave_LightStencil.prefab");
+ // Object.Instantiate(darkness, self.transform);
+ // } catch(Exception e) {
+ // e.LogDetailed();
+ // }
+
+ orig(self);
+ }
- private void OnOptionScreenEnable(On.OptionScreen.orig_OnEnable orig, OptionScreen self)
- {
- if (RandomizerStateManager.Instance.APSave == null)
- RandoSave.TryLoad(Save.APSaveData);
- orig(self);
- }
+ private void OnOptionScreenEnable(On.OptionScreen.orig_OnEnable orig, OptionScreen self)
+ {
+ if (RandomizerStateManager.Instance.APSave == null)
+ RandoSave.TryLoad(Save.APSaveData);
+ orig(self);
+ }
- public override void Initialize()
- {
+ public override void Initialize()
+ {
#if DEBUG
- SceneManager.sceneLoaded += OnSceneLoadedRando;
+ SceneManager.sceneLoaded += OnSceneLoadedRando;
#endif
- //load config
- Debug.Log("Loading config from APConfig.toml");
- try
- {
- UserConfig.ReadConfig(ModPath);
- }
- catch (Exception e) { Console.Write(e); }
- ArchipelagoMenu.BuildArchipelagoMenu();
- RandoMenu.BuildRandoMenu();
- HintMenu.BuildHintMenu();
- }
-
- //temp function for seal research
- void PowerSeal_OnEnterRoom(On.PowerSeal.orig_OnEnterRoom orig, PowerSeal self, bool teleportedInRoom)
+ //load config
+ Debug.Log("Loading config from APConfig.toml");
+ try
{
- //just print out some info for me
- Console.WriteLine($"Entered power seal room: {Manager.Instance.GetRoomAtPosition(self.transform.position).roomKey}");
- orig(self, teleportedInRoom);
+ UserConfig.ReadConfig(ModPath);
}
+ catch (Exception e) { Console.Write(e); }
+ ArchipelagoMenu.BuildArchipelagoMenu();
+ RandoMenu.BuildRandoMenu();
+ HintMenu.BuildHintMenu();
+ }
- List DialogSequence_GetDialogList(On.DialogSequence.orig_GetDialogList orig, DialogSequence self)
+ //temp function for seal research
+ void PowerSeal_OnEnterRoom(On.PowerSeal.orig_OnEnterRoom orig, PowerSeal self, bool teleportedInRoom)
+ {
+ //just print out some info for me
+ Console.WriteLine($"Entered power seal room: {Manager.Instance.GetRoomAtPosition(self.transform.position).roomKey}");
+ orig(self, teleportedInRoom);
+ }
+
+ List DialogSequence_GetDialogList(On.DialogSequence.orig_GetDialogList orig, DialogSequence self)
+ {
+ //Using this function to add some of my own dialog stuff to the game.
+ if (ArchipelagoClient.HasConnected &&
+ new[] { "ARCHIPELAGO_ITEM", "DEATH_LINK" }.Contains(self.dialogID))
{
- //Using this function to add some of my own dialog stuff to the game.
- if (ArchipelagoClient.HasConnected &&
- new[] { "ARCHIPELAGO_ITEM", "DEATH_LINK" }.Contains(self.dialogID))
+ var dialogInfoList = new List();
+ var dialog = new DialogInfo();
+ switch (self.dialogID)
{
- var dialogInfoList = new List();
- var dialog = new DialogInfo();
- switch (self.dialogID)
- {
- case "ARCHIPELAGO_ITEM":
- dialog.text = self.name;
- break;
- case "DEATH_LINK":
- dialog.text = $"Deathlink: {self.name}";
- break;
- }
-
- dialogInfoList.Add(dialog);
-
- return dialogInfoList;
+ case "ARCHIPELAGO_ITEM":
+ dialog.text = self.name;
+ break;
+ case "DEATH_LINK":
+ dialog.text = $"Deathlink: {self.name}";
+ break;
}
- return orig(self);
+ dialogInfoList.Add(dialog);
+
+ return dialogInfoList;
}
- void InventoryManager_AddItem(On.InventoryManager.orig_AddItem orig, InventoryManager self, EItems itemId, int quantity)
+ return orig(self);
+ }
+
+ void InventoryManager_AddItem(On.InventoryManager.orig_AddItem orig, InventoryManager self, EItems itemId, int quantity)
+ {
+ if (!itemId.Equals(EItems.TIME_SHARD))
{
- if (!itemId.Equals(EItems.TIME_SHARD))
+ Debug.Log($"Called InventoryManager_AddItem method. Looking to give x{quantity} amount of item '{itemId}'.");
+ if (quantity == ItemsAndLocationsHandler.APQuantity)
{
- Debug.Log($"Called InventoryManager_AddItem method. Looking to give x{quantity} amount of item '{itemId}'.");
- if (quantity == ItemsAndLocationsHandler.APQuantity)
- {
- orig(self, itemId, 1);
- return;
- }
- if (randoStateManager.IsLocationRandomized(itemId, out var randoItemCheck))
+ orig(self, itemId, 1);
+ return;
+ }
+ if (randoStateManager.IsLocationRandomized(itemId, out var randoItemCheck))
+ {
+ if (itemId.Equals(EItems.CANDLE) &&
+ randoStateManager.IsLocationRandomized(EItems.TEA_SEED, out var seedCheck) &&
+ !RandomizerStateManager.HasCompletedCheck(seedCheck))
{
- if (itemId.Equals(EItems.CANDLE) &&
- randoStateManager.IsLocationRandomized(EItems.TEA_SEED, out var seedCheck) &&
- !RandomizerStateManager.HasCompletedCheck(seedCheck))
- {
- ItemsAndLocationsHandler.SendLocationCheck(seedCheck);
- }
- ItemsAndLocationsHandler.SendLocationCheck(randoItemCheck);
- return;
+ ItemsAndLocationsHandler.SendLocationCheck(seedCheck);
}
+ ItemsAndLocationsHandler.SendLocationCheck(randoItemCheck);
+ return;
}
- //Call original add with items
- orig(self, itemId, quantity);
-
}
+ //Call original add with items
+ orig(self, itemId, quantity);
+
+ }
- void ProgressionManager_SetChallengeRoomAsCompleted(On.ProgressionManager.orig_SetChallengeRoomAsCompleted orig, ProgressionManager self, string roomKey)
+ void ProgressionManager_SetChallengeRoomAsCompleted(On.ProgressionManager.orig_SetChallengeRoomAsCompleted orig, ProgressionManager self, string roomKey)
+ {
+ //if this is a rando file, go ahead and give the item we expect to get
+ if (ArchipelagoClient.HasConnected)
{
- //if this is a rando file, go ahead and give the item we expect to get
- if (ArchipelagoClient.HasConnected)
- {
- var powerSealLocation =
- ItemsAndLocationsHandler.ArchipelagoLocations.Find(loc => loc.Equals(roomKey));
- ItemsAndLocationsHandler.SendLocationCheck(powerSealLocation);
- }
- //For now calling the orig method once we are done so the game still things we are collecting seals. We can change this later.
- orig(self, roomKey);
+ var powerSealLocation =
+ ItemsAndLocationsHandler.ArchipelagoLocations.Find(loc => loc.Equals(roomKey));
+ ItemsAndLocationsHandler.SendLocationCheck(powerSealLocation);
}
+ //For now calling the orig method once we are done so the game still things we are collecting seals. We can change this later.
+ orig(self, roomKey);
+ }
- bool HasItem_IsTrue(On.HasItem.orig_IsTrue orig, HasItem self)
+ bool HasItem_IsTrue(On.HasItem.orig_IsTrue orig, HasItem self)
+ {
+ bool hasItem = false;
+ //Check to make sure this is an item that was randomized and make sure we are not ignoring this specific trigger check
+ if (ArchipelagoClient.HasConnected && randoStateManager.IsLocationRandomized(self.item, out var check) && !RandomizerConstants.GetSpecialTriggerNames().Contains(self.Owner.name))
{
- bool hasItem = false;
- //Check to make sure this is an item that was randomized and make sure we are not ignoring this specific trigger check
- if (ArchipelagoClient.HasConnected && randoStateManager.IsLocationRandomized(self.item, out var check) && !RandomizerConstants.GetSpecialTriggerNames().Contains(self.Owner.name))
+ if (self.transform.parent != null && "InteractionZone".Equals(self.Owner.name) && RandomizerConstants.GetSpecialTriggerNames().Contains(self.transform.parent.name) && EItems.KEY_OF_LOVE != self.item)
{
- if (self.transform.parent != null && "InteractionZone".Equals(self.Owner.name) && RandomizerConstants.GetSpecialTriggerNames().Contains(self.transform.parent.name) && EItems.KEY_OF_LOVE != self.item)
- {
- //Special triggers that need to use normal logic, call orig method. This also includes the trigger check for the key of love on the sunken door because yeah.
- Console.WriteLine($"While checking if player HasItem in an interaction zone, found parent object '{self.transform.parent.name}' in ignore logic. Calling orig HasItem logic.");
- return orig(self);
- }
-
- //OLD WAY
- //Don't actually check for the item i have, check to see if I have the item that was at it's location.
- //int itemQuantity = Manager.Instance.GetItemQuantity(randoStateManager.CurrentLocationToItemMapping[check].Item);
+ //Special triggers that need to use normal logic, call orig method. This also includes the trigger check for the key of love on the sunken door because yeah.
+ Console.WriteLine($"While checking if player HasItem in an interaction zone, found parent object '{self.transform.parent.name}' in ignore logic. Calling orig HasItem logic.");
+ return orig(self);
+ }
- //NEW WAY
- //Don't actually check for the item I have, check to see if I have done this check before. We'll do this by seeing if the item at its location has been collected yet or not
- int itemQuantity = RandomizerStateManager.HasCompletedCheck(check) ? 1 : 0;
- if (self.item.Equals(EItems.CANDLE) && itemQuantity == 1)
- {
- var seed = ItemsAndLocationsHandler.LocationFromEItem(EItems.TEA_SEED);
- var leaves = ItemsAndLocationsHandler.LocationFromEItem(EItems.TEA_LEAVES);
- itemQuantity = RandomizerStateManager.HasCompletedCheck(seed) &&
- RandomizerStateManager.HasCompletedCheck(leaves)
- ? 1
- : 0;
- }
+ //OLD WAY
+ //Don't actually check for the item i have, check to see if I have the item that was at it's location.
+ //int itemQuantity = Manager.Instance.GetItemQuantity(randoStateManager.CurrentLocationToItemMapping[check].Item);
- switch (self.conditionOperator)
- {
- case EConditionOperator.LESS_THAN:
- hasItem = itemQuantity < self.quantityToHave;
- break;
- case EConditionOperator.LESS_OR_EQUAL:
- hasItem = itemQuantity <= self.quantityToHave;
- break;
- case EConditionOperator.EQUAL:
- hasItem = itemQuantity == self.quantityToHave;
- break;
- case EConditionOperator.GREATER_OR_EQUAL:
- hasItem = itemQuantity >= self.quantityToHave;
- break;
- case EConditionOperator.GREATER_THAN:
- hasItem = itemQuantity > self.quantityToHave;
- break;
- }
- return hasItem;
+ //NEW WAY
+ //Don't actually check for the item I have, check to see if I have done this check before. We'll do this by seeing if the item at its location has been collected yet or not
+ int itemQuantity = RandomizerStateManager.HasCompletedCheck(check) ? 1 : 0;
+ if (self.item.Equals(EItems.CANDLE) && itemQuantity == 1)
+ {
+ var seed = ItemsAndLocationsHandler.LocationFromEItem(EItems.TEA_SEED);
+ var leaves = ItemsAndLocationsHandler.LocationFromEItem(EItems.TEA_LEAVES);
+ itemQuantity = RandomizerStateManager.HasCompletedCheck(seed) &&
+ RandomizerStateManager.HasCompletedCheck(leaves)
+ ? 1
+ : 0;
}
- Console.WriteLine("HasItem check was not randomized. Doing vanilla checks.");
- Debug.Log($"Is randomized file : '{ArchipelagoClient.HasConnected}' | Is location '{self.item}' randomized: '{randoStateManager.IsLocationRandomized(self.item, out check)}' | Not in the special triggers list: '{!RandomizerConstants.GetSpecialTriggerNames().Contains(self.Owner.name)}'|");
- return orig(self);
+ switch (self.conditionOperator)
+ {
+ case EConditionOperator.LESS_THAN:
+ hasItem = itemQuantity < self.quantityToHave;
+ break;
+ case EConditionOperator.LESS_OR_EQUAL:
+ hasItem = itemQuantity <= self.quantityToHave;
+ break;
+ case EConditionOperator.EQUAL:
+ hasItem = itemQuantity == self.quantityToHave;
+ break;
+ case EConditionOperator.GREATER_OR_EQUAL:
+ hasItem = itemQuantity >= self.quantityToHave;
+ break;
+ case EConditionOperator.GREATER_THAN:
+ hasItem = itemQuantity > self.quantityToHave;
+ break;
+ }
+ return hasItem;
}
+ Console.WriteLine("HasItem check was not randomized. Doing vanilla checks.");
+ Debug.Log($"Is randomized file : '{ArchipelagoClient.HasConnected}' | Is location '{self.item}' randomized: '{randoStateManager.IsLocationRandomized(self.item, out check)}' | Not in the special triggers list: '{!RandomizerConstants.GetSpecialTriggerNames().Contains(self.Owner.name)}'|");
+ return orig(self);
- bool AwardNoteCutscene_ShouldPlay(On.AwardNoteCutscene.orig_ShouldPlay orig, AwardNoteCutscene self)
- {
- //Need to handle note cutscene triggers so they will play as long as I dont have the actual item it grants
- if (!randoStateManager.IsLocationRandomized(self.noteToAward, out var noteCheck))
- return orig(self);
- var shouldPlay = !ArchipelagoClient.ServerData.CheckedLocations.Contains(noteCheck);
- if (shouldPlay)
- ItemsAndLocationsHandler.SendLocationCheck(noteCheck);
- return shouldPlay;
- }
+ }
- bool CutsceneHasPlayed_IsTrue(On.CutsceneHasPlayed.orig_IsTrue orig, CutsceneHasPlayed self)
- {
- if (RandomizerConstants.GetCutsceneMappings().ContainsKey(self.cutsceneId) &&
- randoStateManager.IsLocationRandomized(RandomizerConstants.GetCutsceneMappings()[self.cutsceneId],
- out var cutsceneCheck))
- {
- return RandomizerStateManager.HasCompletedCheck(cutsceneCheck);
- }
+ bool AwardNoteCutscene_ShouldPlay(On.AwardNoteCutscene.orig_ShouldPlay orig, AwardNoteCutscene self)
+ {
+ //Need to handle note cutscene triggers so they will play as long as I dont have the actual item it grants
+ if (!randoStateManager.IsLocationRandomized(self.noteToAward, out var noteCheck))
return orig(self);
- }
+ var shouldPlay = !ArchipelagoClient.ServerData.CheckedLocations.Contains(noteCheck);
+ if (shouldPlay)
+ ItemsAndLocationsHandler.SendLocationCheck(noteCheck);
+ return shouldPlay;
+ }
- void SaveGameSelectionScreen_OnLoadGame(On.SaveGameSelectionScreen.orig_OnLoadGame orig, SaveGameSelectionScreen self, int slotIndex)
+ bool CutsceneHasPlayed_IsTrue(On.CutsceneHasPlayed.orig_IsTrue orig, CutsceneHasPlayed self)
+ {
+ if (RandomizerConstants.GetCutsceneMappings().ContainsKey(self.cutsceneId) &&
+ randoStateManager.IsLocationRandomized(RandomizerConstants.GetCutsceneMappings()[self.cutsceneId],
+ out var cutsceneCheck))
{
- //slotIndex is 0-based, going to increment it locally to keep things simple.
- randoStateManager.CurrentFileSlot = slotIndex + 1;
+ return RandomizerStateManager.HasCompletedCheck(cutsceneCheck);
+ }
+ return orig(self);
+ }
- //This is probably a bad way to do this
- try
+ void SaveGameSelectionScreen_OnLoadGame(On.SaveGameSelectionScreen.orig_OnLoadGame orig, SaveGameSelectionScreen self, int slotIndex)
+ {
+ //slotIndex is 0-based, going to increment it locally to keep things simple.
+ randoStateManager.CurrentFileSlot = slotIndex + 1;
+
+ //This is probably a bad way to do this
+ try
+ {
+ RandoSave.TryLoad(Save.APSaveData);
+ if (ArchipelagoData.LoadData(randoStateManager.CurrentFileSlot))
{
- RandoSave.TryLoad(Save.APSaveData);
- if (ArchipelagoData.LoadData(randoStateManager.CurrentFileSlot))
- {
- if (!ArchipelagoClient.Offline)
- {
- // need to wait for the scout response from the server
- while (ArchipelagoClient.Authenticated && (randoStateManager.ScoutedLocations == null ||
- randoStateManager.ScoutedLocations.Count < 1))
- {
- Console.WriteLine("locations not scouted yet. waiting...");
- Thread.Sleep(100);
- }
- }
- Manager.Instance.LoadDialogs(Manager.Instance.CurrentLanguage);
- //The player is connected to an Archipelago server and trying to load a save file so check it's valid
- Console.WriteLine($"Successfully loaded Archipelago seed {randoStateManager.CurrentFileSlot}");
- Console.WriteLine("Current Inventory:");
- foreach (var item in randoStateManager.APSave[randoStateManager.CurrentFileSlot].ReceivedItems.Keys)
- {
- Console.WriteLine($"{item}: {randoStateManager.APSave[randoStateManager.CurrentFileSlot].ReceivedItems[item]}");
- }
- }
- else if (ArchipelagoClient.Authenticated &&
- string.IsNullOrEmpty(randoStateManager.APSave[randoStateManager.CurrentFileSlot].SlotName))
+ if (!ArchipelagoClient.Offline)
{
- ArchipelagoClient.ServerData.StartNewSeed();
- //We force a reload of all dialog when loading the game
- try
+ // need to wait for the scout response from the server
+ while (ArchipelagoClient.Authenticated && (randoStateManager.ScoutedLocations == null ||
+ randoStateManager.ScoutedLocations.Count < 1))
{
- Manager.Instance.LoadDialogs(Manager.Instance
- .CurrentLanguage);
- }
- catch (Exception e)
- {
- Console.WriteLine(e);
+ Console.WriteLine("locations not scouted yet. waiting...");
+ Thread.Sleep(100);
}
}
- else if (ArchipelagoClient.Offline)
+ Manager.Instance.LoadDialogs(Manager.Instance.CurrentLanguage);
+ //The player is connected to an Archipelago server and trying to load a save file so check it's valid
+ Console.WriteLine($"Successfully loaded Archipelago seed {randoStateManager.CurrentFileSlot}");
+ Console.WriteLine("Current Inventory:");
+ foreach (var item in randoStateManager.APSave[randoStateManager.CurrentFileSlot].ReceivedItems.Keys)
{
- if (ItemsAndLocationsHandler.ItemsLookup == null)
- ItemsAndLocationsHandler.Initialize();
- Manager.Instance.LoadDialogs(Manager.Instance.CurrentLanguage);
+ Console.WriteLine($"{item}: {randoStateManager.APSave[randoStateManager.CurrentFileSlot].ReceivedItems[item]}");
}
}
- catch (Exception e)
- {
- Console.WriteLine(e);
- }
- if (!ArchipelagoClient.HasConnected)
- {
- Console.WriteLine(
- $"This file slot ({randoStateManager.CurrentFileSlot}) has no seed generated or is not " +
- "a randomized file. Resetting the mappings and putting game items back to normal.");
- ArchipelagoClient.ServerData = new ArchipelagoData();
- }
- else
- {
- RandomizerStateManager.OnMainMenu = false;
- }
-
- orig(self, slotIndex);
- Manager.Instance.levelMusicShuffle = RandoMusicManager.ShuffleMusic;
- RandoMusicManager.BuildMusicLibrary();
- }
-
- void SaveGameSelectionScreen_OnNewGame(On.SaveGameSelectionScreen.orig_OnNewGame orig, SaveGameSelectionScreen self, SaveSlotUI slot)
- {
- Console.WriteLine("trying to load new game");
- if (ArchipelagoClient.Authenticated)
- RandomizerStateManager.InitializeNewSecondQuest(self, slot.slotIndex);
- else if (ArchipelagoClient.Offline)
+ else if (ArchipelagoClient.Authenticated &&
+ string.IsNullOrEmpty(randoStateManager.APSave[randoStateManager.CurrentFileSlot].SlotName))
{
+ ArchipelagoClient.ServerData.StartNewSeed();
+ //We force a reload of all dialog when loading the game
try
{
- RandomizerStateManager.InitializeNewSecondQuest(self, slot.slotIndex);
+ Manager.Instance.LoadDialogs(Manager.Instance
+ .CurrentLanguage);
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
- else if (Environment.GetCommandLineArgs().Length > 1)
- {
- Console.WriteLine("loading new game save... found command line args");
- foreach (var arg in Environment.GetCommandLineArgs())
- {
- Console.WriteLine(arg);
- if (!arg.Contains("archipelago")) continue;
- var uri = new Uri(arg);
- ArchipelagoClient.ServerData = new ArchipelagoData();
- var userInfo = uri.UserInfo.Split(':');
- ArchipelagoClient.ServerData.SlotName = userInfo[0];
- ArchipelagoClient.ServerData.Password = userInfo[1] == "None" ? "" : userInfo[1];
- ArchipelagoClient.ServerData.Uri = uri.Host;
- ArchipelagoClient.ServerData.Port = uri.Port;
- Console.WriteLine(ArchipelagoClient.ServerData.SlotName);
- Console.WriteLine(ArchipelagoClient.ServerData.Password);
- Console.WriteLine(ArchipelagoClient.ServerData.Uri);
- Console.WriteLine(ArchipelagoClient.ServerData.Port);
- var result = ArchipelagoClient.Connect();
- if (ArchipelagoClient.Authenticated)
- {
- RandomizerStateManager.InitializeNewSecondQuest(self, slot.slotIndex);
- return;
- }
- break;
- }
- orig(self, slot);
- self.nameSavePopup.OnLetterErased();
- closeLater =
- InitTextEntryPopup(self,
- "Not connected to an Archipelago server. Please connect before continuing.",
- _ => true, 0, null,
- CharsetFlags.Space);
- closeLater.Init("");
- closeLater.gameObject.SetActive(true);
- closeLaterTimer = 0f;
- }
- else
+ else if (ArchipelagoClient.Offline)
{
- orig(self, slot);
- self.nameSavePopup.OnLetterErased();
- closeLater =
- InitTextEntryPopup(self,
- "",
- _ => true, 0, null,
- CharsetFlags.Space);
- closeLater.Init("Not connected to an Archipelago server. Please connect before continuing.");
- closeLater.gameObject.SetActive(true);
- closeLaterTimer = 0f;
+ if (ItemsAndLocationsHandler.ItemsLookup == null)
+ ItemsAndLocationsHandler.Initialize();
+ Manager.Instance.LoadDialogs(Manager.Instance.CurrentLanguage);
}
}
-
- private void SaveGameSelectionScreen_ConfirmSaveDelete(On.SaveGameSelectionScreen.orig_ConfirmSaveDelete orig, SaveGameSelectionScreen self, SaveSlotUI slot)
+ catch (Exception e)
{
- orig(self, slot);
+ Console.WriteLine(e);
}
-
- private void SaveGameSelectionScreen_OnDelete(On.SaveGameSelectionScreen.orig_OnDeleteChoiceDone orig, SaveGameSelectionScreen self, bool delete)
+ if (!ArchipelagoClient.HasConnected)
{
- if (delete)
- {
- RandoSave.TryLoad(Save.APSaveData);
- var slotIndex = self.GetPrivateField("focusedSlot").slotIndex + 1;
- randoStateManager.APSave[slotIndex] = new ArchipelagoData();
- Save?.ForceUpdate();
- }
- orig(self, delete);
+ Console.WriteLine(
+ $"This file slot ({randoStateManager.CurrentFileSlot}) has no seed generated or is not " +
+ "a randomized file. Resetting the mappings and putting game items back to normal.");
+ ArchipelagoClient.ServerData = new ArchipelagoData();
}
-
- void PauseScreen_OnQuitToTitle(On.BackToTitleScreen.orig_GoBackToTitleScreen orig)
+ else
{
- if (ArchipelagoClient.HasConnected)
- {
- ArchipelagoClient.Disconnect();
- ArchipelagoClient.HasConnected = false;
- ArchipelagoClient.Offline = false;
- ArchipelagoClient.OfflineReceivedItems = 0;
- RandoBossManager.DefeatedBosses = [];
- RandoPortalManager.StartingPortals = null;
- RandoPortalManager.PortalMapping = null;
- RandoLevelManager.RandoLevelMapping = null;
- Manager.Instance.powerSealTotal = 0;
- HintMenu.ReBuildHintMenu();
- }
- randoStateManager = new RandomizerStateManager();
- ArchipelagoClient.ServerData = new ArchipelagoData();
- RandomizerStateManager.OnMainMenu = true;
- orig();
- Console.WriteLine("returned to title");
- Manager.Instance.GetView().UpdateShurikenVisibility();
+ RandomizerStateManager.OnMainMenu = false;
}
- //Fixing necro cutscene check
- void CatacombLevelInitializer_OnBeforeInitDone(On.CatacombLevelInitializer.orig_OnBeforeInitDone orig, CatacombLevelInitializer self)
+ orig(self, slotIndex);
+ Manager.Instance.levelMusicShuffle = RandoMusicManager.ShuffleMusic;
+ RandoMusicManager.BuildMusicLibrary();
+ }
+
+ void SaveGameSelectionScreen_OnNewGame(On.SaveGameSelectionScreen.orig_OnNewGame orig, SaveGameSelectionScreen self, SaveSlotUI slot)
+ {
+ Console.WriteLine("trying to load new game");
+ if (ArchipelagoClient.Authenticated)
+ RandomizerStateManager.InitializeNewSecondQuest(self, slot.slotIndex);
+ else if (ArchipelagoClient.Offline)
{
- //check to see if we already have the item at Necro check
- if (ArchipelagoClient.HasConnected)
+ try
{
- if (!RandomizerStateManager.HasCompletedCheck(
- ItemsAndLocationsHandler.LocationsLookup[new LocationRO("Necro")]))
- self.necrophobicWorkerCutscene.Play();
- else self.necrophobicWorkerCutscene.phobekin.gameObject.SetActive(false);
- //Call our overriden fixing function
- RandoCatacombLevelInitializer.FixPlayerStuckInChallengeRoom();
+ RandomizerStateManager.InitializeNewSecondQuest(self, slot.slotIndex);
}
- else
+ catch (Exception e)
{
- //we are not rando here, call orig method
- orig(self);
+ Console.WriteLine(e);
}
-
}
-
- // Breaking into Necro cutscene to fix things
- private static void NecrophobicWorkerCutscene_Play(On.NecrophobicWorkerCutscene.orig_Play orig, NecrophobicWorkerCutscene self)
+ else if (Environment.GetCommandLineArgs().Length > 1)
{
- //Cutscene moves Ninja around, lets see if i can stop it by making that "location" the current location the player is.
- if (ArchipelagoClient.HasConnected)
- self.playerStartPosition = Object.FindObjectOfType().transform;
- orig(self);
+ Console.WriteLine("loading new game save... found command line args");
+ foreach (var arg in Environment.GetCommandLineArgs())
+ {
+ Console.WriteLine(arg);
+ if (!arg.Contains("archipelago")) continue;
+ var uri = new Uri(arg);
+ ArchipelagoClient.ServerData = new ArchipelagoData();
+ var userInfo = uri.UserInfo.Split(':');
+ ArchipelagoClient.ServerData.SlotName = userInfo[0];
+ ArchipelagoClient.ServerData.Password = userInfo[1] == "None" ? "" : userInfo[1];
+ ArchipelagoClient.ServerData.Uri = uri.Host;
+ ArchipelagoClient.ServerData.Port = uri.Port;
+ Console.WriteLine(ArchipelagoClient.ServerData.SlotName);
+ Console.WriteLine(ArchipelagoClient.ServerData.Password);
+ Console.WriteLine(ArchipelagoClient.ServerData.Uri);
+ Console.WriteLine(ArchipelagoClient.ServerData.Port);
+ var result = ArchipelagoClient.Connect();
+ if (ArchipelagoClient.Authenticated)
+ {
+ RandomizerStateManager.InitializeNewSecondQuest(self, slot.slotIndex);
+ return;
+ }
+ break;
+ }
+ orig(self, slot);
+ self.nameSavePopup.OnLetterErased();
+ closeLater =
+ InitTextEntryPopup(self,
+ "Not connected to an Archipelago server. Please connect before continuing.",
+ _ => true, 0, null,
+ CharsetFlags.Space);
+ closeLater.Init("");
+ closeLater.gameObject.SetActive(true);
+ closeLaterTimer = 0f;
+ }
+ else
+ {
+ orig(self, slot);
+ self.nameSavePopup.OnLetterErased();
+ closeLater =
+ InitTextEntryPopup(self,
+ "",
+ _ => true, 0, null,
+ CharsetFlags.Space);
+ closeLater.Init("Not connected to an Archipelago server. Please connect before continuing.");
+ closeLater.gameObject.SetActive(true);
+ closeLaterTimer = 0f;
}
+ }
+
+ private void SaveGameSelectionScreen_ConfirmSaveDelete(On.SaveGameSelectionScreen.orig_ConfirmSaveDelete orig, SaveGameSelectionScreen self, SaveSlotUI slot)
+ {
+ orig(self, slot);
+ }
- void RuxxtinNoteAndAwardAmuletCutscene_Play(ILContext il)
+ private void SaveGameSelectionScreen_OnDelete(On.SaveGameSelectionScreen.orig_OnDeleteChoiceDone orig, SaveGameSelectionScreen self, bool delete)
+ {
+ if (delete)
{
- ILCursor cursor = new ILCursor(il);
+ RandoSave.TryLoad(Save.APSaveData);
+ var slotIndex = self.GetPrivateField("focusedSlot").slotIndex + 1;
+ randoStateManager.APSave[slotIndex] = new ArchipelagoData();
+ Save?.ForceUpdate();
+ }
+ orig(self, delete);
+ }
- while (cursor.TryGotoNext(MoveType.After, instr => instr.MatchLdcI4(55)))
- {
- cursor.EmitDelegate>(GetRandoItemByItem);
- }
+ void PauseScreen_OnQuitToTitle(On.BackToTitleScreen.orig_GoBackToTitleScreen orig)
+ {
+ if (ArchipelagoClient.HasConnected)
+ {
+ ArchipelagoClient.Disconnect();
+ ArchipelagoClient.HasConnected = false;
+ ArchipelagoClient.Offline = false;
+ ArchipelagoClient.OfflineReceivedItems = 0;
+ RandoBossManager.DefeatedBosses = [];
+ RandoPortalManager.StartingPortals = null;
+ RandoPortalManager.PortalMapping = null;
+ RandoLevelManager.RandoLevelMapping = null;
+ Manager.Instance.powerSealTotal = 0;
+ HintMenu.ReBuildHintMenu();
+ }
+ randoStateManager = new RandomizerStateManager();
+ ArchipelagoClient.ServerData = new ArchipelagoData();
+ RandomizerStateManager.OnMainMenu = true;
+ orig();
+ Console.WriteLine("returned to title");
+ Manager.Instance.GetView().UpdateShurikenVisibility();
+ }
+ //Fixing necro cutscene check
+ void CatacombLevelInitializer_OnBeforeInitDone(On.CatacombLevelInitializer.orig_OnBeforeInitDone orig, CatacombLevelInitializer self)
+ {
+ //check to see if we already have the item at Necro check
+ if (ArchipelagoClient.HasConnected)
+ {
+ if (!RandomizerStateManager.HasCompletedCheck(
+ ItemsAndLocationsHandler.LocationsLookup[new LocationRO("Necro")]))
+ self.necrophobicWorkerCutscene.Play();
+ else self.necrophobicWorkerCutscene.phobekin.gameObject.SetActive(false);
+ //Call our overriden fixing function
+ RandoCatacombLevelInitializer.FixPlayerStuckInChallengeRoom();
}
-
- void MegaTimeShard_OnBreakDone(On.MegaTimeShard.orig_OnBreakDone orig, MegaTimeShard self)
+ else
{
- var currentLevel = Manager.Instance.GetCurrentLevelEnum();
- var currentRoom = Manager.Instance.CurrentRoom.roomKey;
- RandoTimeShardManager.BreakShard(new RandoTimeShardManager.MegaShard(currentLevel, currentRoom));
+ //we are not rando here, call orig method
orig(self);
}
- int ProgressionManager_TotalPowerSealCollected(On.ProgressionManager.orig_TotalPowerSealCollected orig,
- ProgressionManager self)
+ }
+
+ // Breaking into Necro cutscene to fix things
+ private static void NecrophobicWorkerCutscene_Play(On.NecrophobicWorkerCutscene.orig_Play orig, NecrophobicWorkerCutscene self)
+ {
+ //Cutscene moves Ninja around, lets see if i can stop it by making that "location" the current location the player is.
+ if (ArchipelagoClient.HasConnected)
+ self.playerStartPosition = Object.FindObjectOfType().transform;
+ orig(self);
+ }
+
+ void RuxxtinNoteAndAwardAmuletCutscene_Play(ILContext il)
+ {
+ ILCursor cursor = new ILCursor(il);
+
+ while (cursor.TryGotoNext(MoveType.After, instr => instr.MatchLdcI4(55)))
{
- return randoStateManager.PowerSealManager?.AmountPowerSealsCollected() ?? orig(self);
+ cursor.EmitDelegate>(GetRandoItemByItem);
}
- void Cutscene_Play(On.Cutscene.orig_Play orig, Cutscene self)
- {
- var eventName = self.GetType().ToString();
+ }
+
+ void MegaTimeShard_OnBreakDone(On.MegaTimeShard.orig_OnBreakDone orig, MegaTimeShard self)
+ {
+ var currentLevel = Manager.Instance.GetCurrentLevelEnum();
+ var currentRoom = Manager.Instance.CurrentRoom.roomKey;
+ RandoTimeShardManager.BreakShard(new RandoTimeShardManager.MegaShard(currentLevel, currentRoom));
+ orig(self);
+ }
+
+ int ProgressionManager_TotalPowerSealCollected(On.ProgressionManager.orig_TotalPowerSealCollected orig,
+ ProgressionManager self)
+ {
+ return randoStateManager.PowerSealManager?.AmountPowerSealsCollected() ?? orig(self);
+ }
+
+ void Cutscene_Play(On.Cutscene.orig_Play orig, Cutscene self)
+ {
+ var eventName = self.GetType().ToString();
#if DEBUG
- Console.WriteLine($"Playing cutscene: {eventName}");
+ Console.WriteLine($"Playing cutscene: {eventName}");
#endif
- if (eventName == "PortalOpeningCutscene")
+ if (eventName == "PortalOpeningCutscene")
+ {
+ if (RandoPortalManager.StartingPortals != null)
{
- if (RandoPortalManager.StartingPortals != null)
+ var progManager = Manager.Instance;
+ foreach (var portal in RandoPortalManager.StartingPortals.Where(
+ portal => !portal.StartsWith("Autumn")
+ && !portal.StartsWith("Howling")
+ && !portal.StartsWith("Glacial")))
{
- var progManager = Manager.Instance;
- foreach (var portal in RandoPortalManager.StartingPortals.Where(
- portal => !portal.StartsWith("Autumn")
- && !portal.StartsWith("Howling")
- && !portal.StartsWith("Glacial")))
- {
- var cutsceneName = $"{portal.Replace(" ", "")}OpeningCutscene";
- progManager.cutscenesPlayed.Add(cutsceneName);
- }
+ var cutsceneName = $"{portal.Replace(" ", "")}OpeningCutscene";
+ progManager.cutscenesPlayed.Add(cutsceneName);
}
}
-
- if (ArchipelagoClient.EventsICareAbout.Contains(eventName) && ArchipelagoClient.Authenticated)
- {
- ArchipelagoClient.Session.DataStorage[Scope.Slot, "Events"] +=
- new List { eventName };
- }
-
- if (eventName.EndsWith("PortalOpeningCutscene"))
- {
- self.onDone += OnAnyPortalOpeningCutsceneDone;
- }
-
- orig(self);
}
- private void OnAnyPortalOpeningCutsceneDone(Cutscene cutscene)
+ if (ArchipelagoClient.EventsICareAbout.Contains(eventName) && ArchipelagoClient.Authenticated)
{
- cutscene.onDone -= OnAnyPortalOpeningCutsceneDone;
- trackerManager.ReconciliateUnlockedPortals();
+ ArchipelagoClient.Session.DataStorage[Scope.Slot, "Events"] +=
+ new List { eventName };
}
- void PhantomIntro_OnEnterRoom(On.PhantomIntroCutscene.orig_OnEnterRoom orig, PhantomIntroCutscene self,
- bool teleportedInRoom)
+ if (eventName.EndsWith("PortalOpeningCutscene"))
{
- if (randoStateManager.SkipPhantom)
- {
- Manager.Instance.StopMusic();
- Object.FindObjectOfType().Play();
- }
- else
- {
- orig(self, teleportedInRoom);
- }
+ self.onDone += OnAnyPortalOpeningCutsceneDone;
}
+ orig(self);
+ }
- View UIManager_ShowView(On.UIManager.orig_ShowView orig, UIManager self, Type viewType,
- EScreenLayers layer, IViewParams screenParams, bool transitionIn, AnimatorUpdateMode animUpdateMode)
+ private void OnAnyPortalOpeningCutsceneDone(Cutscene cutscene)
+ {
+ cutscene.onDone -= OnAnyPortalOpeningCutsceneDone;
+ trackerManager.ReconciliateUnlockedPortals();
+ }
+
+ void PhantomIntro_OnEnterRoom(On.PhantomIntroCutscene.orig_OnEnterRoom orig, PhantomIntroCutscene self,
+ bool teleportedInRoom)
+ {
+ if (randoStateManager.SkipPhantom)
+ {
+ Manager.Instance.StopMusic();
+ Object.FindObjectOfType().Play();
+ }
+ else
{
- Console.WriteLine($"viewType {viewType}");
- Console.WriteLine($"layer {layer}");
- Console.WriteLine($"params {screenParams}");
- Console.WriteLine($"transition {transitionIn}");
- Console.WriteLine($"updateMode {animUpdateMode}");
- return orig(self, viewType, layer, screenParams, transitionIn, animUpdateMode);
+ orig(self, teleportedInRoom);
}
+ }
- void DialogCutscene_Play(On.DialogCutscene.orig_Play orig, DialogCutscene self)
+
+ View UIManager_ShowView(On.UIManager.orig_ShowView orig, UIManager self, Type viewType,
+ EScreenLayers layer, IViewParams screenParams, bool transitionIn, AnimatorUpdateMode animUpdateMode)
+ {
+ Console.WriteLine($"viewType {viewType}");
+ Console.WriteLine($"layer {layer}");
+ Console.WriteLine($"params {screenParams}");
+ Console.WriteLine($"transition {transitionIn}");
+ Console.WriteLine($"updateMode {animUpdateMode}");
+ return orig(self, viewType, layer, screenParams, transitionIn, animUpdateMode);
+ }
+
+ void DialogCutscene_Play(On.DialogCutscene.orig_Play orig, DialogCutscene self)
+ {
+ // Console.WriteLine($"Playing dialog cutscene: {self}");
+ //ruxxtin cutscene is being a bitch so just gonna hard code around it here.
+ if (ArchipelagoClient.HasConnected && self.name.Equals("ReadNote"))
{
- // Console.WriteLine($"Playing dialog cutscene: {self}");
- //ruxxtin cutscene is being a bitch so just gonna hard code around it here.
- if (ArchipelagoClient.HasConnected && self.name.Equals("ReadNote"))
+ if (randoStateManager.IsLocationRandomized(EItems.RUXXTIN_AMULET, out var locID))
{
- if (randoStateManager.IsLocationRandomized(EItems.RUXXTIN_AMULET, out var locID))
+ if (!RandomizerStateManager.HasCompletedCheck(locID))
{
- if (!RandomizerStateManager.HasCompletedCheck(locID))
- {
- ItemsAndLocationsHandler.SendLocationCheck(locID);
- }
+ ItemsAndLocationsHandler.SendLocationCheck(locID);
}
}
- orig(self);
}
+ orig(self);
+ }
- void MusicBox_SetNotesState(On.MusicBox.orig_SetNotesState orig, MusicBox self)
- {
- // this determines which notes should be shown present in the music box
- orig(self);
- }
+ void MusicBox_SetNotesState(On.MusicBox.orig_SetNotesState orig, MusicBox self)
+ {
+ // this determines which notes should be shown present in the music box
+ orig(self);
+ }
- public static void OnToggleWindmillShuriken()
- {
- Manager.Instance.useWindmillShuriken = !Manager.Instance.useWindmillShuriken;
- InGameHud view = Manager.Instance.GetView();
- if (view != null)
- view.UpdateShurikenVisibility();
- }
+ public static void OnToggleWindmillShuriken()
+ {
+ Manager.Instance.useWindmillShuriken = !Manager.Instance.useWindmillShuriken;
+ InGameHud view = Manager.Instance.GetView();
+ if (view != null)
+ view.UpdateShurikenVisibility();
+ }
- public static void OnSelectTeleportToHq()
- {
- Console.WriteLine("Teleporting to HQ!");
+ public static void OnSelectTeleportToHq()
+ {
+ Console.WriteLine("Teleporting to HQ!");
#if DEBUG
- var position = Manager.Instance.Player.transform.position;
- Console.WriteLine($"{position.x} {position.y} {position.z}");
+ var position = Manager.Instance.Player.transform.position;
+ Console.WriteLine($"{position.x} {position.y} {position.z}");
#endif
- // ArchipelagoMenu.archipelagoScreen.Close(false);
+ // ArchipelagoMenu.archipelagoScreen.Close(false);
- RandoLevelManager.CleanupBeforeOptionsTeleport();
- //Load the HQ
- Manager.Instance.TeleportInToTHQ(true, ELevelEntranceID.ENTRANCE_A, null);
- ArchipelagoClient.Session.DataStorage[Scope.Slot, "CurrentRegion"] = ELevel.Level_13_TowerOfTimeHQ.ToString();
- RandoLevelManager.CleanupAfterTeleport();
- }
+ RandoLevelManager.CleanupBeforeOptionsTeleport();
+ //Load the HQ
+ Manager.Instance.TeleportInToTHQ(true, ELevelEntranceID.ENTRANCE_A, null);
+ ArchipelagoClient.Session.DataStorage[Scope.Slot, "CurrentRegion"] = ELevel.Level_13_TowerOfTimeHQ.ToString();
+ RandoLevelManager.CleanupAfterTeleport();
+ }
- public static void OnSelectTeleportToNinjaVillage()
- {
- Console.WriteLine("Teleporting to Ninja Village.");
- // ArchipelagoMenu.archipelagoScreen.Close(false);
- EBits dimension = Manager.Instance.currentDimension;
+ public static void OnSelectTeleportToNinjaVillage()
+ {
+ Console.WriteLine("Teleporting to Ninja Village.");
+ // ArchipelagoMenu.archipelagoScreen.Close(false);
+ EBits dimension = Manager.Instance.currentDimension;
+
+ RandoLevelManager.CleanupBeforeOptionsTeleport();
+ //Load to Ninja Village
+ RandoLevelManager.TeleportInArea(new LevelConstants.RandoLevel(ELevel.Level_01_NinjaVillage,
+ new Vector3(-153.3f, -56.5f)));
+ }
- RandoLevelManager.CleanupBeforeOptionsTeleport();
- //Load to Ninja Village
- RandoLevelManager.TeleportInArea(new LevelConstants.RandoLevel(ELevel.Level_01_NinjaVillage,
- new Vector3(-153.3f, -56.5f)));
- }
+ public static void OnSelectTeleportToSearing()
+ {
+ RandoLevelManager.CleanupBeforeOptionsTeleport();
+ RandoLevelManager.TeleportInArea(new LevelConstants.RandoLevel(ELevel.Level_08_SearingCrags,
+ new Vector3(380.5f, 311)));
+ }
- public static void OnSelectTeleportToSearing()
- {
- RandoLevelManager.CleanupBeforeOptionsTeleport();
- RandoLevelManager.TeleportInArea(new LevelConstants.RandoLevel(ELevel.Level_08_SearingCrags,
- new Vector3(380.5f, 311)));
- }
+ public static bool OnSelectArchipelagoHost(string answer)
+ {
+ if (answer == null) return true;
+ if (ArchipelagoClient.ServerData == null) ArchipelagoClient.ServerData = new ArchipelagoData();
+ var uri = answer;
+ ArchipelagoClient.ServerData.Uri = uri;
+ return true;
+ }
- public static bool OnSelectArchipelagoHost(string answer)
- {
- if (answer == null) return true;
- if (ArchipelagoClient.ServerData == null) ArchipelagoClient.ServerData = new ArchipelagoData();
- var uri = answer;
- ArchipelagoClient.ServerData.Uri = uri;
- return true;
- }
+ public static bool OnSelectArchipelagoPort(string answer)
+ {
+ if (answer == null) return true;
+ if (ArchipelagoClient.ServerData == null) ArchipelagoClient.ServerData = new ArchipelagoData();
+ int.TryParse(answer, out var port);
+ ArchipelagoClient.ServerData.Port = port;
+ return true;
+ }
- public static bool OnSelectArchipelagoPort(string answer)
+ public static bool ArchipelagoPortEnabled()
+ {
+ if (Manager.Instance.GetCurrentLevelEnum().Equals(ELevel.NONE))
{
- if (answer == null) return true;
- if (ArchipelagoClient.ServerData == null) ArchipelagoClient.ServerData = new ArchipelagoData();
- int.TryParse(answer, out var port);
- ArchipelagoClient.ServerData.Port = port;
- return true;
+ return !ArchipelagoClient.HasConnected;
}
- public static bool ArchipelagoPortEnabled()
- {
- if (Manager.Instance.GetCurrentLevelEnum().Equals(ELevel.NONE))
- {
- return !ArchipelagoClient.HasConnected;
- }
+ return ArchipelagoClient.HasConnected && !ArchipelagoClient.Authenticated && !ArchipelagoClient.Offline;
+ }
- return ArchipelagoClient.HasConnected && !ArchipelagoClient.Authenticated && !ArchipelagoClient.Offline;
- }
+ public static bool OnSelectArchipelagoName(string answer)
+ {
+ if (answer == null) return true;
+ if (ArchipelagoClient.ServerData == null) ArchipelagoClient.ServerData = new ArchipelagoData();
+ ArchipelagoClient.ServerData.SlotName = answer;
+ return true;
+ }
- public static bool OnSelectArchipelagoName(string answer)
+ public static bool OnSelectArchipelagoPass(string answer)
+ {
+ if (answer == null) return true;
+ if (ArchipelagoClient.ServerData == null) ArchipelagoClient.ServerData = new ArchipelagoData();
+ ArchipelagoClient.ServerData.Password = answer;
+ return true;
+ }
+
+ public static void OnSelectArchipelagoConnect()
+ {
+ ArchipelagoClient.ServerData ??= new ArchipelagoData();
+ if (!UserConfig.SlotName.IsNullOrEmpty())
{
- if (answer == null) return true;
- if (ArchipelagoClient.ServerData == null) ArchipelagoClient.ServerData = new ArchipelagoData();
- ArchipelagoClient.ServerData.SlotName = answer;
- return true;
+ ArchipelagoClient.ServerData.Uri = UserConfig.HostName;
+ ArchipelagoClient.ServerData.Port = UserConfig.Port;
+ ArchipelagoClient.ServerData.SlotName = UserConfig.SlotName;
+ ArchipelagoClient.ServerData.Password = UserConfig.Password;
}
-
- public static bool OnSelectArchipelagoPass(string answer)
+ else if (ArchipelagoClient.ServerData.SlotName.IsNullOrEmpty())
{
- if (answer == null) return true;
- if (ArchipelagoClient.ServerData == null) ArchipelagoClient.ServerData = new ArchipelagoData();
- ArchipelagoClient.ServerData.Password = answer;
- return true;
+ return;
}
- public static void OnSelectArchipelagoConnect()
- {
- ArchipelagoClient.ServerData ??= new ArchipelagoData();
- if (!UserConfig.SlotName.IsNullOrEmpty())
- {
- ArchipelagoClient.ServerData.Uri = UserConfig.HostName;
- ArchipelagoClient.ServerData.Port = UserConfig.Port;
- ArchipelagoClient.ServerData.SlotName = UserConfig.SlotName;
- ArchipelagoClient.ServerData.Password = UserConfig.Password;
- }
- else if (ArchipelagoClient.ServerData.SlotName.IsNullOrEmpty())
- {
- return;
- }
+ ArchipelagoClient.ConnectAsync(ArchipelagoMenu.ArchipelagoConnectButton);
+ }
- ArchipelagoClient.ConnectAsync(ArchipelagoMenu.ArchipelagoConnectButton);
- }
+ public static void OnSelectArchipelagoRelease()
+ {
+ ArchipelagoClient.SendSayPacket("!release");
+ }
- public static void OnSelectArchipelagoRelease()
- {
- ArchipelagoClient.SendSayPacket("!release");
- }
+ public static void OnSelectArchipelagoCollect()
+ {
+ ArchipelagoClient.SendSayPacket("!collect");
+ }
- public static void OnSelectArchipelagoCollect()
- {
- ArchipelagoClient.SendSayPacket("!collect");
- }
+ public static bool OnSelectArchipelagoHint(string answer)
+ {
+ ArchipelagoClient.SendSayPacket($"!hint {answer}");
+ return true;
+ }
- public static bool OnSelectArchipelagoHint(string answer)
- {
- ArchipelagoClient.SendSayPacket($"!hint {answer}");
- return true;
- }
+ public static void OnToggleAPStatus()
+ {
+ ArchipelagoClient.DisplayStatus = !ArchipelagoClient.DisplayStatus;
+ }
- public static void OnToggleAPStatus()
- {
- ArchipelagoClient.DisplayStatus = !ArchipelagoClient.DisplayStatus;
- }
+ public static void OnToggleAPMessages()
+ {
+ ArchipelagoClient.DisplayAPMessages = !ArchipelagoClient.DisplayAPMessages;
+ }
- public static void OnToggleAPMessages()
- {
- ArchipelagoClient.DisplayAPMessages = !ArchipelagoClient.DisplayAPMessages;
- }
+ public static void OnToggleDeathLink()
+ {
+ ArchipelagoData.DeathLink = !ArchipelagoData.DeathLink;
+ if (ArchipelagoData.DeathLink) ArchipelagoClient.DeathLinkHandler.DeathLinkService.EnableDeathLink();
+ else ArchipelagoClient.DeathLinkHandler.DeathLinkService.DisableDeathLink();
+ }
- public static void OnToggleDeathLink()
- {
- ArchipelagoData.DeathLink = !ArchipelagoData.DeathLink;
- if (ArchipelagoData.DeathLink) ArchipelagoClient.DeathLinkHandler.DeathLinkService.EnableDeathLink();
- else ArchipelagoClient.DeathLinkHandler.DeathLinkService.DisableDeathLink();
- }
+ public static bool OnSelectMessageTimer(string answer)
+ {
+ if (answer == null) return true;
+ if (ArchipelagoClient.ServerData == null) ArchipelagoClient.ServerData = new ArchipelagoData();
+ int.TryParse(answer, out var newTime);
+ UpdateTime = newTime;
+ return true;
+ }
- public static bool OnSelectMessageTimer(string answer)
- {
- if (answer == null) return true;
- if (ArchipelagoClient.ServerData == null) ArchipelagoClient.ServerData = new ArchipelagoData();
- int.TryParse(answer, out var newTime);
- UpdateTime = newTime;
- return true;
- }
+ ///
+ /// Delegate function for getting rando item. This can be used by IL hooks that need to make this call later.
+ ///
+ ///
+ ///
+ private EItems GetRandoItemByItem(EItems item)
+ {
+ return !randoStateManager.IsLocationRandomized(item, out var ruxxAmuletLocation) ? item : EItems.POTION;
+ }
- ///
- /// Delegate function for getting rando item. This can be used by IL hooks that need to make this call later.
- ///
- ///
- ///
- private EItems GetRandoItemByItem(EItems item)
- {
- return !randoStateManager.IsLocationRandomized(item, out var ruxxAmuletLocation) ? item : EItems.POTION;
- }
+ public static string GetCurrentSeedNum()
+ {
+ string seedNum = "Unknown";
- public static string GetCurrentSeedNum()
+ if (ArchipelagoClient.HasConnected)
{
- string seedNum = "Unknown";
+ seedNum = ArchipelagoClient.ServerData.SeedName;
+ }
- if (ArchipelagoClient.HasConnected)
- {
- seedNum = ArchipelagoClient.ServerData.SeedName;
- }
+ return seedNum;
+ }
- return seedNum;
- }
+ private void OnSceneLoadedRando(Scene scene, LoadSceneMode mode)
+ {
+ Console.WriteLine($"Scene loaded: '{scene.name}'");
+ }
- private void OnSceneLoadedRando(Scene scene, LoadSceneMode mode)
+ private void PlayerController_OnUpdate(PlayerController controller)
+ {
+ if (!ArchipelagoClient.HasConnected || randoStateManager.CurrentFileSlot == 0)
{
- Console.WriteLine($"Scene loaded: '{scene.name}'");
+ return;
}
-
- private void PlayerController_OnUpdate(PlayerController controller)
+ if (ArchipelagoClient.Authenticated)
{
- if (!ArchipelagoClient.HasConnected || randoStateManager.CurrentFileSlot == 0)
+ if (ArchipelagoClient.DeathLinkHandler.Player == null)
{
- return;
+ ArchipelagoClient.DeathLinkHandler.Player = controller;
}
- if (ArchipelagoClient.Authenticated)
- {
- if (ArchipelagoClient.DeathLinkHandler.Player == null)
- {
- ArchipelagoClient.DeathLinkHandler.Player = controller;
- }
- if (RandomizerStateManager.IsSafeTeleportState() && !Manager.Instance.IsPaused)
- {
- ArchipelagoClient.DeathLinkHandler.KillPlayer();
- }
+ if (RandomizerStateManager.IsSafeTeleportState() && !Manager.Instance.IsPaused)
+ {
+ ArchipelagoClient.DeathLinkHandler.KillPlayer();
}
- //This updates every {updateTime} seconds
- updateTimer += Time.deltaTime;
- TrapManager.TrapTimer += Time.deltaTime;
- if (!(updateTimer >= UpdateTime)) return;
- updateTimer = 0;
- ArchipelagoClient.UpdateArchipelagoState();
- apMessagesDisplay16.text = apMessagesDisplay8.text = ArchipelagoClient.UpdateMessagesText();
}
+ //This updates every {updateTime} seconds
+ updateTimer += Time.deltaTime;
+ TrapManager.TrapTimer += Time.deltaTime;
+ if (!(updateTimer >= UpdateTime)) return;
+ updateTimer = 0;
+ ArchipelagoClient.UpdateArchipelagoState();
+ apMessagesDisplay16.text = apMessagesDisplay8.text = ArchipelagoClient.UpdateMessagesText();
+ }
- private void InGameHud_OnGUI(On.InGameHud.orig_OnGUI orig, InGameHud self)
+ private void InGameHud_OnGUI(On.InGameHud.orig_OnGUI orig, InGameHud self)
+ {
+ orig(self);
+ if (apTextDisplay8 == null)
{
- orig(self);
- if (apTextDisplay8 == null)
- {
- apTextDisplay8 = Object.Instantiate(self.hud_8.coinCount, self.hud_8.gameObject.transform);
- apTextDisplay16 = Object.Instantiate(self.hud_16.coinCount, self.hud_16.gameObject.transform);
- apTextDisplay8.transform.Translate(0f, -110f, 0f);
- apTextDisplay16.transform.Translate(0f, -110f, 0f);
- apTextDisplay16.fontSize = apTextDisplay8.fontSize = UserConfig.StatusTextSize;
- apTextDisplay16.alignment = apTextDisplay8.alignment = TextAlignmentOptions.TopRight;
- apTextDisplay16.enableWordWrapping = apTextDisplay8.enableWordWrapping = true;
- apTextDisplay16.color = apTextDisplay8.color = Color.white;
-
- apMessagesDisplay8 = Object.Instantiate(self.hud_8.coinCount, self.hud_8.gameObject.transform);
- apMessagesDisplay16 = Object.Instantiate(self.hud_16.coinCount, self.hud_16.gameObject.transform);
- apMessagesDisplay8.transform.Translate(0f, -200f, 0f);
- apMessagesDisplay16.transform.Translate(0f, -200f, 0f);
- apMessagesDisplay16.fontSize = apMessagesDisplay8.fontSize = UserConfig.MessageTextSize;
- apMessagesDisplay16.alignment = apMessagesDisplay8.alignment = TextAlignmentOptions.BottomRight;
- apMessagesDisplay16.enableWordWrapping = apMessagesDisplay16.enableWordWrapping = true;
- apMessagesDisplay16.color = apMessagesDisplay8.color = Color.green;
- apMessagesDisplay16.text = apMessagesDisplay8.text = string.Empty;
- }
-
- if (ArchipelagoClient.Offline) return;
- //This updates every frame
+ apTextDisplay8 = Object.Instantiate(self.hud_8.coinCount, self.hud_8.gameObject.transform);
+ apTextDisplay16 = Object.Instantiate(self.hud_16.coinCount, self.hud_16.gameObject.transform);
+ apTextDisplay8.transform.Translate(0f, -110f, 0f);
+ apTextDisplay16.transform.Translate(0f, -110f, 0f);
apTextDisplay16.fontSize = apTextDisplay8.fontSize = UserConfig.StatusTextSize;
+ apTextDisplay16.alignment = apTextDisplay8.alignment = TextAlignmentOptions.TopRight;
+ apTextDisplay16.enableWordWrapping = apTextDisplay8.enableWordWrapping = true;
+ apTextDisplay16.color = apTextDisplay8.color = Color.white;
+
+ apMessagesDisplay8 = Object.Instantiate(self.hud_8.coinCount, self.hud_8.gameObject.transform);
+ apMessagesDisplay16 = Object.Instantiate(self.hud_16.coinCount, self.hud_16.gameObject.transform);
+ apMessagesDisplay8.transform.Translate(0f, -200f, 0f);
+ apMessagesDisplay16.transform.Translate(0f, -200f, 0f);
apMessagesDisplay16.fontSize = apMessagesDisplay8.fontSize = UserConfig.MessageTextSize;
- apTextDisplay16.text = apTextDisplay8.text = ArchipelagoClient.UpdateStatusText();
+ apMessagesDisplay16.alignment = apMessagesDisplay8.alignment = TextAlignmentOptions.BottomRight;
+ apMessagesDisplay16.enableWordWrapping = apMessagesDisplay16.enableWordWrapping = true;
+ apMessagesDisplay16.color = apMessagesDisplay8.color = Color.green;
+ apMessagesDisplay16.text = apMessagesDisplay8.text = string.Empty;
}
- private void SaveManager_DoActualSave(On.SaveManager.orig_DoActualSaving orig, SaveManager self, bool applySaveDelay = true)
- {
- // var checkpoint = Manager.Instance.checkpointSaveInfo;
- // var pos = checkpoint.loadedLevelPlayerPosition;
- // Console.WriteLine($"{checkpoint.loadedLevelCheckpointIndex} \n{checkpoint.playerFacingDirection}\n {pos.x} {pos.y} {pos.z}");
- orig(self, applySaveDelay);
- if (!ArchipelagoClient.HasConnected) return;
- Save?.Update();
- try
- {
- if (RandoPortalManager.LeftHQPortal && RandoPortalManager.ForceTeleport)
- {
- RandoPortalManager.Teleport();
- RandoPortalManager.ForceTeleport = false;
- return;
- }
- }
- catch (Exception e)
- {
- Console.WriteLine(e);
- }
+ if (ArchipelagoClient.Offline) return;
+ //This updates every frame
+ apTextDisplay16.fontSize = apTextDisplay8.fontSize = UserConfig.StatusTextSize;
+ apMessagesDisplay16.fontSize = apMessagesDisplay8.fontSize = UserConfig.MessageTextSize;
+ apTextDisplay16.text = apTextDisplay8.text = ArchipelagoClient.UpdateStatusText();
+ }
- if (LostWoodsManager.NeedsUnsolved)
- {
- LostWoodsManager.UnsolveLostWoods();
- }
- else if (LostWoodsManager.NeedsSolved)
- {
- // just keep trying to solve it until it eventually works lmao
- LostWoodsManager.SolveLostWoods();
+ private void SaveManager_DoActualSave(On.SaveManager.orig_DoActualSaving orig, SaveManager self, bool applySaveDelay = true)
+ {
+ // var checkpoint = Manager.Instance.checkpointSaveInfo;
+ // var pos = checkpoint.loadedLevelPlayerPosition;
+ // Console.WriteLine($"{checkpoint.loadedLevelCheckpointIndex} \n{checkpoint.playerFacingDirection}\n {pos.x} {pos.y} {pos.z}");
+ orig(self, applySaveDelay);
+ if (!ArchipelagoClient.HasConnected) return;
+ Save?.Update();
+ try
+ {
+ if (RandoPortalManager.LeftHQPortal && RandoPortalManager.ForceTeleport)
+ {
+ RandoPortalManager.Teleport();
+ RandoPortalManager.ForceTeleport = false;
+ return;
}
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine(e);
+ }
- // The game calls the save method after the ending cutscene before rolling credits
- if (ArchipelagoClient.Authenticated
- && Manager.Instance.GetCurrentLevelEnum().Equals(ELevel.Level_Ending))
- {
- ArchipelagoClient.UpdateClientStatus(ArchipelagoClientState.ClientGoal);
- }
+ if (LostWoodsManager.NeedsUnsolved)
+ {
+ LostWoodsManager.UnsolveLostWoods();
+ }
+ else if (LostWoodsManager.NeedsSolved)
+ {
+ // just keep trying to solve it until it eventually works lmao
+ LostWoodsManager.SolveLostWoods();
}
- private void OnPlayerDie(On.PlayerController.orig_Die orig, PlayerController self, EDeathType deathType,
- Transform killedBy)
+ // The game calls the save method after the ending cutscene before rolling credits
+ if (ArchipelagoClient.Authenticated
+ && Manager.Instance.GetCurrentLevelEnum().Equals(ELevel.Level_Ending))
{
- try
- {
- TrapManager.ResetPlayerState();
- Manager.Instance.CloseAllScreensOfType(false);
- ArchipelagoClient.DeathLinkHandler?.SendDeathLink(deathType, killedBy);
- }
- catch (Exception e)
- {
- Console.WriteLine(e);
- }
- orig(self, deathType, killedBy);
+ ArchipelagoClient.UpdateClientStatus(ArchipelagoClientState.ClientGoal);
}
+ }
- private void OnDeathScreenDone(On.Quarble.orig_OnDeathScreenDone orig, Quarble self)
+ private void OnPlayerDie(On.PlayerController.orig_Die orig, PlayerController self, EDeathType deathType,
+ Transform killedBy)
+ {
+ try
{
- orig(self);
- // this code doesn't expect music shuffle lmao
- Manager.Instance.StopMusic();
+ TrapManager.ResetPlayerState();
+ Manager.Instance.CloseAllScreensOfType(false);
+ ArchipelagoClient.DeathLinkHandler?.SendDeathLink(deathType, killedBy);
}
+ catch (Exception e)
+ {
+ Console.WriteLine(e);
+ }
+ orig(self, deathType, killedBy);
+ }
+
+ private void OnDeathScreenDone(On.Quarble.orig_OnDeathScreenDone orig, Quarble self)
+ {
+ orig(self);
+ // this code doesn't expect music shuffle lmao
+ Manager.Instance.StopMusic();
}
}
diff --git a/Archipelago/ArchipelagoClient.cs b/Archipelago/ArchipelagoClient.cs
index 534b507..c16213f 100644
--- a/Archipelago/ArchipelagoClient.cs
+++ b/Archipelago/ArchipelagoClient.cs
@@ -15,547 +15,546 @@
using UnityEngine;
using static Mod.Courier.UI.TextEntryButtonInfo;
-namespace MessengerRando.Archipelago
+namespace MessengerRando.Archipelago;
+
+public static class ArchipelagoClient
{
- public static class ArchipelagoClient
- {
- private const string ApVersion = "0.5.0";
- public static ArchipelagoData ServerData = new();
-
- private delegate void OnConnectAttempt(string result);
-
- public static bool Authenticated;
- public static bool HasConnected;
- private static bool attemptingConnection;
- public static bool Offline;
-
- public static bool DisplayAPMessages = true;
- public static bool FilterAPMessages = true;
- public static bool DisplayStatus = true;
- public static bool HintPopUps = true;
-
- public static ArchipelagoSession Session;
- public static DeathLinkInterface DeathLinkHandler;
-
- public static Queue ItemQueue = new();
- public static Queue DialogQueue = new();
- private static Queue messageQueue = new();
- public static int OfflineReceivedItems;
- private static string statusText = string.Empty;
- private static bool roomUpdate;
-
- public static List EventsICareAbout =
- [
- "DecurseQueenCutscene",
- "QueenDefrostLanternsCutscene",
- "ElderAwardSeedCutscene",
- "PlantTeaSeedCutscene",
- ];
-
- public static void ConnectAsync()
- {
- if (attemptingConnection || Authenticated) return;
- attemptingConnection = true;
- Debug.Log($"Connecting to {ServerData.Uri}:{ServerData.Port} as {ServerData.SlotName}");
- ThreadPool.QueueUserWorkItem(_ => Connect(OnConnected));
- }
+ private const string ApVersion = "0.5.0";
+ public static ArchipelagoData ServerData = new();
+
+ private delegate void OnConnectAttempt(string result);
+
+ public static bool Authenticated;
+ public static bool HasConnected;
+ private static bool attemptingConnection;
+ public static bool Offline;
+
+ public static bool DisplayAPMessages = true;
+ public static bool FilterAPMessages = true;
+ public static bool DisplayStatus = true;
+ public static bool HintPopUps = true;
+
+ public static ArchipelagoSession Session;
+ public static DeathLinkInterface DeathLinkHandler;
+
+ public static Queue ItemQueue = new();
+ public static Queue DialogQueue = new();
+ private static Queue messageQueue = new();
+ public static int OfflineReceivedItems;
+ private static string statusText = string.Empty;
+ private static bool roomUpdate;
+
+ public static List EventsICareAbout =
+ [
+ "DecurseQueenCutscene",
+ "QueenDefrostLanternsCutscene",
+ "ElderAwardSeedCutscene",
+ "PlantTeaSeedCutscene",
+ ];
+
+ public static void ConnectAsync()
+ {
+ if (attemptingConnection || Authenticated) return;
+ attemptingConnection = true;
+ Debug.Log($"Connecting to {ServerData.Uri}:{ServerData.Port} as {ServerData.SlotName}");
+ ThreadPool.QueueUserWorkItem(_ => Connect(OnConnected));
+ }
+
+ public static void ConnectAsync(SubMenuButtonInfo connectButton)
+ {
+ if (attemptingConnection || Authenticated) return;
+ attemptingConnection = true;
+ if (ServerData == null)
+ ServerData = new ArchipelagoData();
+ Debug.Log($"Connecting to {ServerData.Uri}:{ServerData.Port} as {ServerData.SlotName}");
+ Connect(result => OnConnected(result, connectButton));
+ }
- public static void ConnectAsync(SubMenuButtonInfo connectButton)
+ private static void OnConnected(string connectStats)
+ {
+ if (ServerData.CheckedLocations != null)
{
- if (attemptingConnection || Authenticated) return;
- attemptingConnection = true;
- if (ServerData == null)
- ServerData = new ArchipelagoData();
- Debug.Log($"Connecting to {ServerData.Uri}:{ServerData.Port} as {ServerData.SlotName}");
- Connect(result => OnConnected(result, connectButton));
+ Session.Locations.CompleteLocationChecksAsync(
+ _ => ServerData.CheckedLocations = Session.Locations.AllLocationsChecked.ToList(),
+ ServerData.CheckedLocations.ToArray());
}
- private static void OnConnected(string connectStats)
- {
- if (ServerData.CheckedLocations != null)
- {
- Session.Locations.CompleteLocationChecksAsync(
- _ => ServerData.CheckedLocations = Session.Locations.AllLocationsChecked.ToList(),
- ServerData.CheckedLocations.ToArray());
- }
+ attemptingConnection = false;
+ }
- attemptingConnection = false;
- }
+ private static void OnConnected(string outputText, SubMenuButtonInfo connectButton)
+ {
+ TextEntryPopup successPopup = InitTextEntryPopup(connectButton.addedTo, string.Empty,
+ _ => true, 0, null, CharsetFlags.Space);
+
+ successPopup.Init(outputText);
+ successPopup.gameObject.SetActive(true);
+ // Object.Destroy(successPopup.transform.Find("BigFrame").Find("SymbolsGrid").gameObject);
+ Console.WriteLine(outputText);
+ attemptingConnection = false;
+ }
- private static void OnConnected(string outputText, SubMenuButtonInfo connectButton)
- {
- TextEntryPopup successPopup = InitTextEntryPopup(connectButton.addedTo, string.Empty,
- _ => true, 0, null, CharsetFlags.Space);
+ private static ArchipelagoSession CreateSession()
+ {
+ var session = ArchipelagoSessionFactory.CreateSession(ServerData.Uri, ServerData.Port);
+ SetupSession(session);
+ return session;
+ }
- successPopup.Init(outputText);
- successPopup.gameObject.SetActive(true);
- // Object.Destroy(successPopup.transform.Find("BigFrame").Find("SymbolsGrid").gameObject);
- Console.WriteLine(outputText);
- attemptingConnection = false;
- }
+ private static ArchipelagoSession CreateSession(Uri uri)
+ {
+ var session = ArchipelagoSessionFactory.CreateSession(uri);
+ SetupSession(session);
+ return session;
+ }
- private static ArchipelagoSession CreateSession()
- {
- var session = ArchipelagoSessionFactory.CreateSession(ServerData.Uri, ServerData.Port);
- SetupSession(session);
- return session;
- }
+ private static void SetupSession(ArchipelagoSession session)
+ {
+ session.MessageLog.OnMessageReceived += OnMessageReceived;
+ session.Socket.ErrorReceived += SessionErrorReceived;
+ session.Socket.SocketClosed += SessionSocketClosed;
+ session.Socket.PacketReceived += OnPacketReceived;
+ }
- private static ArchipelagoSession CreateSession(Uri uri)
+ private static void OnPacketReceived(ArchipelagoPacketBase packet)
+ {
+ if (packet is RoomUpdatePacket)
{
- var session = ArchipelagoSessionFactory.CreateSession(uri);
- SetupSession(session);
- return session;
+ roomUpdate = true;
}
+ }
+
+ public static string Connect(Uri uri)
+ {
+ if (Authenticated) return "already connected";
- private static void SetupSession(ArchipelagoSession session)
+ try
{
- session.MessageLog.OnMessageReceived += OnMessageReceived;
- session.Socket.ErrorReceived += SessionErrorReceived;
- session.Socket.SocketClosed += SessionSocketClosed;
- session.Socket.PacketReceived += OnPacketReceived;
+ Session = CreateSession(uri);
}
-
- private static void OnPacketReceived(ArchipelagoPacketBase packet)
+ catch (Exception e)
{
- if (packet is RoomUpdatePacket)
- {
- roomUpdate = true;
- }
+ Console.WriteLine($"Error: {e}");
+ return e.ToString();
}
- public static string Connect(Uri uri)
- {
- if (Authenticated) return "already connected";
+ return TryConnect();
+ }
- try
- {
- Session = CreateSession(uri);
- }
- catch (Exception e)
- {
- Console.WriteLine($"Error: {e}");
- return e.ToString();
- }
+ public static string Connect()
+ {
+ if (Authenticated) return "already connected";
- return TryConnect();
+ try
+ {
+ Session = CreateSession();
}
-
- public static string Connect()
+ catch (Exception e)
{
- if (Authenticated) return "already connected";
+ Console.WriteLine($"Error: {e}");
+ return e.ToString();
+ }
- try
- {
- Session = CreateSession();
- }
- catch (Exception e)
- {
- Console.WriteLine($"Error: {e}");
- return e.ToString();
- }
+ return TryConnect();
+ }
+
+ private static string TryConnect()
+ {
+ if (ItemsAndLocationsHandler.ItemsLookup == null) ItemsAndLocationsHandler.Initialize();
+ var needSlotData = ServerData.SlotData == null;
+ LoginResult result;
- return TryConnect();
+ try
+ {
+ result = Session.TryConnectAndLogin(
+ "The Messenger",
+ ServerData.SlotName,
+ ItemsHandlingFlags.AllItems,
+ new Version(ApVersion),
+ password: ServerData.Password,
+ requestSlotData: needSlotData
+ );
+ }
+ catch (Exception e)
+ {
+ Console.Write($"Error: {e}");
+ result = new LoginFailure(e.GetBaseException().Message);
}
- private static string TryConnect()
+ return HandleConnectResult(result, needSlotData);
+ }
+
+ private static string HandleConnectResult(LoginResult result, bool needSlotData)
+ {
+ string outputText;
+ if (result.Successful)
{
- if (ItemsAndLocationsHandler.ItemsLookup == null) ItemsAndLocationsHandler.Initialize();
- var needSlotData = ServerData.SlotData == null;
- LoginResult result;
+ var success = (LoginSuccessful)result;
+ if (needSlotData)
+ ServerData.SlotData = success.SlotData;
+ ServerData.SeedName = Session.RoomState.Seed;
+ Authenticated = true;
try
{
- result = Session.TryConnectAndLogin(
- "The Messenger",
- ServerData.SlotName,
- ItemsHandlingFlags.AllItems,
- new Version(ApVersion),
- password: ServerData.Password,
- requestSlotData: needSlotData
- );
+ RandomizerStateManager.InitializeSeed();
}
catch (Exception e)
{
- Console.Write($"Error: {e}");
- result = new LoginFailure(e.GetBaseException().Message);
+ Console.WriteLine(e);
+ outputText =
+ "Something went wrong.\n" +
+ "Please submit a bug report with the log.txt, " +
+ "which can be found by the game executable.";
+ Authenticated = false;
+ Disconnect();
+ return outputText;
}
- return HandleConnectResult(result, needSlotData);
- }
+ DeathLinkHandler = new DeathLinkInterface();
- private static string HandleConnectResult(LoginResult result, bool needSlotData)
+ ThreadPool.QueueUserWorkItem(_ =>
+ Session.Locations.CompleteLocationChecksAsync(null,
+ ServerData.CheckedLocations.ToArray()));
+
+ HasConnected = true;
+ outputText = $"Successfully connected to {ServerData.Uri}:{ServerData.Port} as {ServerData.SlotName}!";
+ }
+ else
{
- string outputText;
- if (result.Successful)
- {
- var success = (LoginSuccessful)result;
- if (needSlotData)
- ServerData.SlotData = success.SlotData;
- ServerData.SeedName = Session.RoomState.Seed;
- Authenticated = true;
+ LoginFailure failure = (LoginFailure)result;
+ outputText = $"Failed to connect to {ServerData.Uri}:{ServerData.Port} as {ServerData.SlotName}\n";
+ outputText +=
+ failure.Errors.Aggregate(outputText, (current, error) => current + $"\n {error}");
- try
- {
- RandomizerStateManager.InitializeSeed();
- }
- catch (Exception e)
- {
- Console.WriteLine(e);
- outputText =
- "Something went wrong.\n" +
- "Please submit a bug report with the log.txt, " +
- "which can be found by the game executable.";
- Authenticated = false;
- Disconnect();
- return outputText;
- }
+ Console.WriteLine(outputText);
- DeathLinkHandler = new DeathLinkInterface();
+ Authenticated = false;
+ Disconnect();
+ }
- ThreadPool.QueueUserWorkItem(_ =>
- Session.Locations.CompleteLocationChecksAsync(null,
- ServerData.CheckedLocations.ToArray()));
+ return outputText;
+ }
- HasConnected = true;
- outputText = $"Successfully connected to {ServerData.Uri}:{ServerData.Port} as {ServerData.SlotName}!";
- }
- else
- {
- LoginFailure failure = (LoginFailure)result;
- outputText = $"Failed to connect to {ServerData.Uri}:{ServerData.Port} as {ServerData.SlotName}\n";
- outputText +=
- failure.Errors.Aggregate(outputText, (current, error) => current + $"\n {error}");
+ private static void Connect(OnConnectAttempt attempt)
+ {
+ attempt(Connect());
+ }
- Console.WriteLine(outputText);
+ public static string ColorizePlayerName(int player)
+ {
+ var color = player.Equals(Session.ConnectionInfo.Slot)
+ ? UserConfig.PlayerColor
+ : UserConfig.OtherPlayerColor;
+ return $"{Session.Players.GetPlayerAlias(player)}";
+ }
- Authenticated = false;
- Disconnect();
- }
+ public static string ColorizeLocation(long locID)
+ {
+ var color = UserConfig.LocationColor;
+ return $"{Session.Locations.GetLocationNameFromId(locID)}";
+ }
- return outputText;
- }
+ private static string ConvertHintMessage(HintItemSendLogMessage hintMessage)
+ {
+ var colorizedMessage = hintMessage.ToString();
+ colorizedMessage = colorizedMessage.Replace(hintMessage.Sender.Name,
+ ColorizePlayerName(hintMessage.Sender.Slot));
+ colorizedMessage = colorizedMessage.Replace(hintMessage.Receiver.Name,
+ ColorizePlayerName(hintMessage.Receiver.Slot));
+ colorizedMessage = colorizedMessage.Replace(hintMessage.Item.LocationDisplayName,
+ hintMessage.Item.ColorizeLocation());
+ colorizedMessage = colorizedMessage.Replace(hintMessage.Item.ItemDisplayName,
+ hintMessage.Item.Colorize());
+ Console.WriteLine(colorizedMessage);
+ return colorizedMessage;
+ }
- private static void Connect(OnConnectAttempt attempt)
+ private static void OnMessageReceived(LogMessage message)
+ {
+ Console.WriteLine(message.ToString());
+ if (FilterAPMessages)
{
- attempt(Connect());
- }
- public static string ColorizePlayerName(int player)
- {
- var color = player.Equals(Session.ConnectionInfo.Slot)
- ? UserConfig.PlayerColor
- : UserConfig.OtherPlayerColor;
- return $"{Session.Players.GetPlayerAlias(player)}";
- }
+ switch (message)
+ {
+ case HintItemSendLogMessage hintMessage:
+ if (hintMessage.IsFound || !hintMessage.IsRelatedToActivePlayer || !HintPopUps ||
+ RandomizerStateManager.SeenHints.Contains(hintMessage.Item.ItemId) ||
+ ItemsAndLocationsHandler.ShopLocation(hintMessage.Item.LocationId, out var shopLoc)) break;
+ RandomizerStateManager.SeenHints.Add(hintMessage.Item.ItemId);
+ messageQueue.Enqueue(hintMessage.ToString());
+ DialogQueue.Enqueue(ConvertHintMessage(hintMessage));
+ break;
+ case ItemSendLogMessage itemSendMessage:
+ if (itemSendMessage.IsRelatedToActivePlayer)
+ {
+ messageQueue.Enqueue(itemSendMessage.ToString());
+ }
- public static string ColorizeLocation(long locID)
- {
- var color = UserConfig.LocationColor;
- return $"{Session.Locations.GetLocationNameFromId(locID)}";
+ break;
+ }
}
-
- private static string ConvertHintMessage(HintItemSendLogMessage hintMessage)
+ else
{
- var colorizedMessage = hintMessage.ToString();
- colorizedMessage = colorizedMessage.Replace(hintMessage.Sender.Name,
- ColorizePlayerName(hintMessage.Sender.Slot));
- colorizedMessage = colorizedMessage.Replace(hintMessage.Receiver.Name,
- ColorizePlayerName(hintMessage.Receiver.Slot));
- colorizedMessage = colorizedMessage.Replace(hintMessage.Item.LocationDisplayName,
- hintMessage.Item.ColorizeLocation());
- colorizedMessage = colorizedMessage.Replace(hintMessage.Item.ItemDisplayName,
- hintMessage.Item.Colorize());
- Console.WriteLine(colorizedMessage);
- return colorizedMessage;
+ if (HintPopUps && message is HintItemSendLogMessage hintMessage &&
+ !ItemsAndLocationsHandler.ShopLocation(hintMessage.Item.LocationId, out var shopLoc))
+ DialogQueue.Enqueue(ConvertHintMessage(hintMessage));
+ messageQueue.Enqueue(message.ToString());
}
+ }
- private static void OnMessageReceived(LogMessage message)
+ public static void SyncLocations()
+ {
+ if (RandomizerStateManager.Instance.CurrentFileSlot == 0) return;
+ var checkedLocations = Session.Locations.AllLocationsChecked;
+ if (ServerData.CheckedLocations.Count == checkedLocations.Count) return;
+ foreach (var location in checkedLocations)
{
- Console.WriteLine(message.ToString());
- if (FilterAPMessages)
+ try
{
-
- switch (message)
+ if (ServerData.CheckedLocations.Contains(location)) continue;
+ var locName = Session.Locations.GetLocationNameFromId(location);
+ if (locName.Contains("Seal"))
{
- case HintItemSendLogMessage hintMessage:
- if (hintMessage.IsFound || !hintMessage.IsRelatedToActivePlayer || !HintPopUps ||
- RandomizerStateManager.SeenHints.Contains(hintMessage.Item.ItemId) ||
- ItemsAndLocationsHandler.ShopLocation(hintMessage.Item.LocationId, out var shopLoc)) break;
- RandomizerStateManager.SeenHints.Add(hintMessage.Item.ItemId);
- messageQueue.Enqueue(hintMessage.ToString());
- DialogQueue.Enqueue(ConvertHintMessage(hintMessage));
- break;
- case ItemSendLogMessage itemSendMessage:
- if (itemSendMessage.IsRelatedToActivePlayer)
- {
- messageQueue.Enqueue(itemSendMessage.ToString());
- }
-
- break;
+ var roomKey =
+ ItemsAndLocationsHandler.ArchipelagoLocations.Find(
+ loc => loc.PrettyLocationName.Equals(locName)).LocationName;
+ Manager.Instance.SetChallengeRoomAsCompleted(roomKey);
}
- }
- else
- {
- if (HintPopUps && message is HintItemSendLogMessage hintMessage &&
- !ItemsAndLocationsHandler.ShopLocation(hintMessage.Item.LocationId, out var shopLoc))
- DialogQueue.Enqueue(ConvertHintMessage(hintMessage));
- messageQueue.Enqueue(message.ToString());
- }
- }
-
- public static void SyncLocations()
- {
- if (RandomizerStateManager.Instance.CurrentFileSlot == 0) return;
- var checkedLocations = Session.Locations.AllLocationsChecked;
- if (ServerData.CheckedLocations.Count == checkedLocations.Count) return;
- foreach (var location in checkedLocations)
- {
- try
+ else if (ItemsAndLocationsHandler.ShopLocation(location, out var shopLoc))
{
- if (ServerData.CheckedLocations.Contains(location)) continue;
- var locName = Session.Locations.GetLocationNameFromId(location);
- if (locName.Contains("Seal"))
+ Debug.Log($"collecting {shopLoc.LocationName} ({shopLoc.PrettyLocationName})");
+ try
{
- var roomKey =
- ItemsAndLocationsHandler.ArchipelagoLocations.Find(
- loc => loc.PrettyLocationName.Equals(locName)).LocationName;
- Manager.Instance.SetChallengeRoomAsCompleted(roomKey);
+ var shopID = (EShopUpgradeID)Enum.Parse(typeof(EShopUpgradeID), shopLoc.LocationName);
+ Manager.Instance.SetShopUpgradeAsUnlocked(shopID);
}
- else if (ItemsAndLocationsHandler.ShopLocation(location, out var shopLoc))
+ catch (Exception e1)
{
- Debug.Log($"collecting {shopLoc.LocationName} ({shopLoc.PrettyLocationName})");
+ Debug.Log(e1);
try
{
- var shopID = (EShopUpgradeID)Enum.Parse(typeof(EShopUpgradeID), shopLoc.LocationName);
+ var shopID = (EShopUpgradeID)Enum.Parse(typeof(EShopUpgradeID),
+ shopLoc.PrettyLocationName);
Manager.Instance.SetShopUpgradeAsUnlocked(shopID);
}
- catch (Exception e1)
+ catch (Exception e2)
{
- Debug.Log(e1);
- try
- {
- var shopID = (EShopUpgradeID)Enum.Parse(typeof(EShopUpgradeID),
- shopLoc.PrettyLocationName);
- Manager.Instance.SetShopUpgradeAsUnlocked(shopID);
- }
- catch (Exception e2)
- {
- Debug.Log(e2);
- }
+ Debug.Log(e2);
}
}
- else
- {
- RandoBossManager.TryCollectLocation(location);
- }
-
- ServerData.CheckedLocations.Add(location);
}
- catch (Exception e)
+ else
{
- Console.WriteLine(e);
- Console.WriteLine($"{Session.Locations.GetLocationNameFromId(location)}: {location}");
+ RandoBossManager.TryCollectLocation(location);
}
- }
- }
-
- public static void SyncEvents()
- {
- Console.WriteLine("Checking datastorage events");
- foreach (var cutscene in Session.DataStorage[Scope.Slot, "Events"].To>())
- {
- Console.WriteLine(cutscene);
- Manager.Instance.cutscenesPlayed.Add(cutscene);
- }
- }
- private static void OnItemReceived(ReceivedItemsHelper helper)
- {
- var itemToUnlock = helper.DequeueItem();
- Console.WriteLine($"helper index: {helper.Index}");
- Console.WriteLine($"Saved index: {ServerData.Index}");
- if (helper.Index <= ServerData.Index) return;
-
- if (RandomizerStateManager.OnMainMenu)
- {
- OfflineReceivedItems++;
+ ServerData.CheckedLocations.Add(location);
}
- else
+ catch (Exception e)
{
- ServerData.Index++;
+ Console.WriteLine(e);
+ Console.WriteLine($"{Session.Locations.GetLocationNameFromId(location)}: {location}");
}
-
- ItemQueue.Enqueue(itemToUnlock.ItemId);
- if (itemToUnlock.Player != Session.ConnectionInfo.Slot)
- DialogQueue.Enqueue(itemToUnlock.ToReadableString());
}
+ }
- private static void SessionErrorReceived(Exception e, string message)
+ public static void SyncEvents()
+ {
+ Console.WriteLine("Checking datastorage events");
+ foreach (var cutscene in Session.DataStorage[Scope.Slot, "Events"].To>())
{
- Console.WriteLine(message);
- Console.WriteLine(e.GetBaseException().Message);
+ Console.WriteLine(cutscene);
+ Manager.Instance.cutscenesPlayed.Add(cutscene);
}
+ }
+
+ private static void OnItemReceived(ReceivedItemsHelper helper)
+ {
+ var itemToUnlock = helper.DequeueItem();
+ Console.WriteLine($"helper index: {helper.Index}");
+ Console.WriteLine($"Saved index: {ServerData.Index}");
+ if (helper.Index <= ServerData.Index) return;
- private static void SessionSocketClosed(string reason)
+ if (RandomizerStateManager.OnMainMenu)
{
- Console.WriteLine($"Connection to Archipelago lost: {reason}");
- Disconnect();
+ OfflineReceivedItems++;
}
-
- public static void Disconnect()
+ else
{
- Console.WriteLine("Disconnecting from server...");
- Session?.Socket.Disconnect();
- Session = null;
- Authenticated = false;
- attemptingConnection = false;
- DialogQueue = new Queue();
- ItemQueue = new Queue();
- messageQueue = new Queue();
+ ServerData.Index++;
}
- public static void UpdateArchipelagoState()
- {
- while (ItemQueue.Count > 0)
- {
- ItemsAndLocationsHandler.Unlock((long)ItemQueue.Dequeue());
- }
+ ItemQueue.Enqueue(itemToUnlock.ItemId);
+ if (itemToUnlock.Player != Session.ConnectionInfo.Slot)
+ DialogQueue.Enqueue(itemToUnlock.ToReadableString());
+ }
- if (DialogQueue.Count > 0)
- {
- var message = (string)DialogQueue.Dequeue();
- Console.WriteLine(message);
- DialogChanger.CreateDialogBox(message);
- }
+ private static void SessionErrorReceived(Exception e, string message)
+ {
+ Console.WriteLine(message);
+ Console.WriteLine(e.GetBaseException().Message);
+ }
- TrapManager.UpdateTrapStatus();
- if (Offline) return;
- if (!Authenticated)
- {
- Console.WriteLine("Attempting to reconnect to Archipelago Server...");
- ThreadPool.QueueUserWorkItem(_ => ConnectAsync());
- return;
- }
+ private static void SessionSocketClosed(string reason)
+ {
+ Console.WriteLine($"Connection to Archipelago lost: {reason}");
+ Disconnect();
+ }
- if (ServerData.Index < Session.Items.AllItemsReceived.Count)
- {
- ItemsAndLocationsHandler.UnlockItems();
- return;
- }
- if (!ItemsAndLocationsHandler.Synced)
- ItemsAndLocationsHandler.ReSync();
+ public static void Disconnect()
+ {
+ Console.WriteLine("Disconnecting from server...");
+ Session?.Socket.Disconnect();
+ Session = null;
+ Authenticated = false;
+ attemptingConnection = false;
+ DialogQueue = new Queue();
+ ItemQueue = new Queue();
+ messageQueue = new Queue();
+ }
+
+ public static void UpdateArchipelagoState()
+ {
+ while (ItemQueue.Count > 0)
+ {
+ ItemsAndLocationsHandler.Unlock((long)ItemQueue.Dequeue());
}
- public static void UpdateClientStatus(ArchipelagoClientState newState)
+ if (DialogQueue.Count > 0)
{
- Console.WriteLine($"Updating client status to {newState}");
- var statusUpdatePacket = new StatusUpdatePacket { Status = newState };
- Session.Socket.SendPacket(statusUpdatePacket);
+ var message = (string)DialogQueue.Dequeue();
+ Console.WriteLine(message);
+ DialogChanger.CreateDialogBox(message);
}
- private static bool ClientFinished()
+ TrapManager.UpdateTrapStatus();
+ if (Offline) return;
+ if (!Authenticated)
{
- return Session.DataStorage.GetClientStatus() == ArchipelagoClientState.ClientGoal;
+ Console.WriteLine("Attempting to reconnect to Archipelago Server...");
+ ThreadPool.QueueUserWorkItem(_ => ConnectAsync());
+ return;
}
- public static bool CanRelease()
+ if (ServerData.Index < Session.Items.AllItemsReceived.Count)
{
- if (!Authenticated) return false;
- try
+ ItemsAndLocationsHandler.UnlockItems();
+ return;
+ }
+ if (!ItemsAndLocationsHandler.Synced)
+ ItemsAndLocationsHandler.ReSync();
+ }
+
+ public static void UpdateClientStatus(ArchipelagoClientState newState)
+ {
+ Console.WriteLine($"Updating client status to {newState}");
+ var statusUpdatePacket = new StatusUpdatePacket { Status = newState };
+ Session.Socket.SendPacket(statusUpdatePacket);
+ }
+
+ private static bool ClientFinished()
+ {
+ return Session.DataStorage.GetClientStatus() == ArchipelagoClientState.ClientGoal;
+ }
+
+ public static bool CanRelease()
+ {
+ if (!Authenticated) return false;
+ try
+ {
+ return Session.RoomState.ReleasePermissions switch
{
- return Session.RoomState.ReleasePermissions switch
- {
- Permissions.Goal => ClientFinished(),
- Permissions.Enabled => true,
- _ => false
- };
- }
- catch (Exception e)
+ Permissions.Goal => ClientFinished(),
+ Permissions.Enabled => true,
+ _ => false
+ };
+ }
+ catch (Exception e)
+ {
+ if (e is ArchipelagoSocketClosedException)
{
- if (e is ArchipelagoSocketClosedException)
- {
- Disconnect();
- }
- Debug.Log(e);
- return false;
+ Disconnect();
}
+ Debug.Log(e);
+ return false;
}
+ }
- public static bool CanCollect()
+ public static bool CanCollect()
+ {
+ if (!Authenticated) return false;
+ try
{
- if (!Authenticated) return false;
- try
+ return Session.RoomState.CollectPermissions switch
{
- return Session.RoomState.CollectPermissions switch
- {
- Permissions.Goal => ClientFinished(),
- Permissions.Enabled => true,
- _ => false
- };
- }
- catch (Exception e)
+ Permissions.Goal => ClientFinished(),
+ Permissions.Enabled => true,
+ _ => false
+ };
+ }
+ catch (Exception e)
+ {
+ if (e is ArchipelagoSocketClosedException)
{
- if (e is ArchipelagoSocketClosedException)
- {
- Disconnect();
- }
- Debug.Log(e);
- return false;
+ Disconnect();
}
+ Debug.Log(e);
+ return false;
}
+ }
- private static int GetHintCost()
- {
- return Session.RoomState.HintCost;
- }
+ private static int GetHintCost()
+ {
+ return Session.RoomState.HintCost;
+ }
- public static bool CanHint()
- {
- return Authenticated && GetHintCost() <= Session.RoomState.HintPoints;
- }
+ public static bool CanHint()
+ {
+ return Authenticated && GetHintCost() <= Session.RoomState.HintPoints;
+ }
- public static string UpdateStatusText()
- {
- if (!roomUpdate) return statusText;
- roomUpdate = false;
- statusText = string.Empty;
- if (!DisplayStatus) return statusText;
- if (Authenticated)
- {
- statusText = $"Connected to Archipelago v{Session.RoomState.Version}";
- var hintCost = GetHintCost();
- if (hintCost > 0)
- {
- statusText += $"\nHint points available: {Session.RoomState.HintPoints}\nHint point cost: {hintCost}";
- }
- }
- else if (HasConnected)
+ public static string UpdateStatusText()
+ {
+ if (!roomUpdate) return statusText;
+ roomUpdate = false;
+ statusText = string.Empty;
+ if (!DisplayStatus) return statusText;
+ if (Authenticated)
+ {
+ statusText = $"Connected to Archipelago v{Session.RoomState.Version}";
+ var hintCost = GetHintCost();
+ if (hintCost > 0)
{
- statusText = "Disconnected from Archipelago server.";
+ statusText += $"\nHint points available: {Session.RoomState.HintPoints}\nHint point cost: {hintCost}";
}
- return statusText;
}
-
- public static string UpdateMessagesText()
+ else if (HasConnected)
{
- var text = string.Empty;
- if (messageQueue.Count <= 0) return text;
- if (DisplayAPMessages)
- text = (string)messageQueue.Dequeue();
- return text;
+ statusText = "Disconnected from Archipelago server.";
}
+ return statusText;
+ }
- public static void SendSayPacket(string text)
- {
- Session.Say(text);
- }
+ public static string UpdateMessagesText()
+ {
+ var text = string.Empty;
+ if (messageQueue.Count <= 0) return text;
+ if (DisplayAPMessages)
+ text = (string)messageQueue.Dequeue();
+ return text;
+ }
- public static void ClearMessages()
- {
- messageQueue = new Queue();
- DialogQueue = new Queue();
- }
+ public static void SendSayPacket(string text)
+ {
+ Session.Say(text);
+ }
+
+ public static void ClearMessages()
+ {
+ messageQueue = new Queue();
+ DialogQueue = new Queue();
}
}
diff --git a/Archipelago/ArchipelagoData.cs b/Archipelago/ArchipelagoData.cs
index dff21ae..eec5d31 100644
--- a/Archipelago/ArchipelagoData.cs
+++ b/Archipelago/ArchipelagoData.cs
@@ -5,134 +5,133 @@
using MessengerRando.Utils;
using Newtonsoft.Json;
-namespace MessengerRando.Archipelago
+namespace MessengerRando.Archipelago;
+
+public class ArchipelagoData
{
- public class ArchipelagoData
- {
- public string Uri = "archipelago.gg";
- public int Port = 38281;
- public string SlotName = "";
- public string Password = "";
- public int Index;
- public string SeedName = "Unknown";
- public Dictionary SlotData;
- public static bool DeathLink = false;
- public int PowerSealsCollected;
- public List DefeatedBosses;
- public List CheckedLocations;
- public Dictionary ReceivedItems;
- public Dictionary>> LocationData;
- public List AvailableTeleports;
+ public string Uri = "archipelago.gg";
+ public int Port = 38281;
+ public string SlotName = "";
+ public string Password = "";
+ public int Index;
+ public string SeedName = "Unknown";
+ public Dictionary SlotData;
+ public static bool DeathLink = false;
+ public int PowerSealsCollected;
+ public List DefeatedBosses;
+ public List CheckedLocations;
+ public Dictionary ReceivedItems;
+ public Dictionary>> LocationData;
+ public List AvailableTeleports;
- public void StartNewSeed()
- {
- Console.WriteLine("Creating new seed data");
- Index = ArchipelagoClient.OfflineReceivedItems;
- PowerSealsCollected = 0;
- DefeatedBosses = [];
- CheckedLocations = [];
- ReceivedItems = new Dictionary();
- AvailableTeleports = [false, false];
- }
+ public void StartNewSeed()
+ {
+ Console.WriteLine("Creating new seed data");
+ Index = ArchipelagoClient.OfflineReceivedItems;
+ PowerSealsCollected = 0;
+ DefeatedBosses = [];
+ CheckedLocations = [];
+ ReceivedItems = new Dictionary();
+ AvailableTeleports = [false, false];
+ }
- public override string ToString()
- {
- return JsonConvert.SerializeObject(this);
- }
+ public override string ToString()
+ {
+ return JsonConvert.SerializeObject(this);
+ }
- public static bool LoadData(int slot)
- {
- if (ArchipelagoClient.Offline) return false;
- Console.WriteLine($"Loading Archipelago data for slot {slot}");
- ArchipelagoClient.ServerData ??= new ArchipelagoData();
- return ArchipelagoClient.ServerData.loadData(slot);
- }
+ public static bool LoadData(int slot)
+ {
+ if (ArchipelagoClient.Offline) return false;
+ Console.WriteLine($"Loading Archipelago data for slot {slot}");
+ ArchipelagoClient.ServerData ??= new ArchipelagoData();
+ return ArchipelagoClient.ServerData.loadData(slot);
+ }
- // ReSharper disable once InconsistentNaming
- private bool loadData(int slot)
+ // ReSharper disable once InconsistentNaming
+ private bool loadData(int slot)
+ {
+ if (!RandomizerStateManager.Instance.APSave.TryGetValue(slot, out var tempServerData) ||
+ tempServerData.SeedName == null || tempServerData.SeedName.Equals("Unknown"))
+ return false;
+ try
{
- if (!RandomizerStateManager.Instance.APSave.TryGetValue(slot, out var tempServerData) ||
- tempServerData.SeedName == null || tempServerData.SeedName.Equals("Unknown"))
- return false;
- try
+ var i = 0;
+ if (ArchipelagoClient.Authenticated)
{
- var i = 0;
- if (ArchipelagoClient.Authenticated)
+ //we're already connected to an archipelago server, but have a save file, so disconnect to clean up
+ ArchipelagoClient.Disconnect();
+ if (tempServerData.SeedName.Equals(SeedName) && tempServerData.SlotName.Equals(SlotName))
{
- //we're already connected to an archipelago server, but have a save file, so disconnect to clean up
- ArchipelagoClient.Disconnect();
- if (tempServerData.SeedName.Equals(SeedName) && tempServerData.SlotName.Equals(SlotName))
- {
- //We're continuing an existing multiworld so likely a port change. Save the new data
- Index = tempServerData.Index;
- PowerSealsCollected = tempServerData.PowerSealsCollected;
- CheckedLocations = tempServerData.CheckedLocations ?? [];
- RandoBossManager.DefeatedBosses = DefeatedBosses =
- tempServerData.DefeatedBosses ?? [];
- ReceivedItems = tempServerData.ReceivedItems ?? [];
- AvailableTeleports = tempServerData.AvailableTeleports ?? [false, false];
+ //We're continuing an existing multiworld so likely a port change. Save the new data
+ Index = tempServerData.Index;
+ PowerSealsCollected = tempServerData.PowerSealsCollected;
+ CheckedLocations = tempServerData.CheckedLocations ?? [];
+ RandoBossManager.DefeatedBosses = DefeatedBosses =
+ tempServerData.DefeatedBosses ?? [];
+ ReceivedItems = tempServerData.ReceivedItems ?? [];
+ AvailableTeleports = tempServerData.AvailableTeleports ?? [false, false];
- ThreadPool.QueueUserWorkItem(_ =>
- ArchipelagoClient.Session.Locations.CompleteLocationChecksAsync(null,
- CheckedLocations.ToArray()));
- Console.WriteLine("connected from main menu, but continuing a seed.");
- Console.WriteLine($"items in remote queue: {ArchipelagoClient.ItemQueue.Count}");
- Console.WriteLine($"saved index: {Index}");
- while (ArchipelagoClient.ItemQueue.Count > 0 && i < Index)
- {
- ArchipelagoClient.ItemQueue.Dequeue();
- i += 1;
- }
-
- Console.WriteLine($"Setting index to {ArchipelagoClient.OfflineReceivedItems}");
- Index = ArchipelagoClient.OfflineReceivedItems;
- RandomizerStateManager.OnMainMenu = false;
- // reconnect
- ArchipelagoClient.Connect();
- return true;
+ ThreadPool.QueueUserWorkItem(_ =>
+ ArchipelagoClient.Session.Locations.CompleteLocationChecksAsync(null,
+ CheckedLocations.ToArray()));
+ Console.WriteLine("connected from main menu, but continuing a seed.");
+ Console.WriteLine($"items in remote queue: {ArchipelagoClient.ItemQueue.Count}");
+ Console.WriteLine($"saved index: {Index}");
+ while (ArchipelagoClient.ItemQueue.Count > 0 && i < Index)
+ {
+ ArchipelagoClient.ItemQueue.Dequeue();
+ i += 1;
}
- //There was archipelago save data and it doesn't match our current connection so abort.
- return ArchipelagoClient.HasConnected = false;
- }
- //We aren't connected to an Archipelago server so attempt to use the found data
- Uri = tempServerData.Uri;
- Port = tempServerData.Port;
- SlotName = tempServerData.SlotName;
- Password = tempServerData.Password;
- SeedName = tempServerData.SeedName;
- Index = tempServerData.Index;
- Console.WriteLine($"saved index: {Index}");
- PowerSealsCollected = tempServerData.PowerSealsCollected;
- CheckedLocations = tempServerData.CheckedLocations ?? [];
- RandoBossManager.DefeatedBosses = DefeatedBosses = tempServerData.DefeatedBosses ?? [];
- ReceivedItems = tempServerData.ReceivedItems ?? new Dictionary();
- SlotData = tempServerData.SlotData;
- LocationData = tempServerData.LocationData;
- AvailableTeleports = tempServerData.AvailableTeleports ?? [false, false];
- //Attempt to connect to the server and save the new data
- Console.WriteLine("Rando save found!");
- if (Uri == "offline")
- {
- Console.WriteLine("continuing offline seed");
- RandomizerStateManager.InitializeSeed();
- return ArchipelagoClient.HasConnected = ArchipelagoClient.Offline = true;
+ Console.WriteLine($"Setting index to {ArchipelagoClient.OfflineReceivedItems}");
+ Index = ArchipelagoClient.OfflineReceivedItems;
+ RandomizerStateManager.OnMainMenu = false;
+ // reconnect
+ ArchipelagoClient.Connect();
+ return true;
}
+ //There was archipelago save data and it doesn't match our current connection so abort.
+ return ArchipelagoClient.HasConnected = false;
+ }
+ //We aren't connected to an Archipelago server so attempt to use the found data
+ Uri = tempServerData.Uri;
+ Port = tempServerData.Port;
+ SlotName = tempServerData.SlotName;
+ Password = tempServerData.Password;
+ SeedName = tempServerData.SeedName;
+ Index = tempServerData.Index;
+ Console.WriteLine($"saved index: {Index}");
+ PowerSealsCollected = tempServerData.PowerSealsCollected;
+ CheckedLocations = tempServerData.CheckedLocations ?? [];
+ RandoBossManager.DefeatedBosses = DefeatedBosses = tempServerData.DefeatedBosses ?? [];
+ ReceivedItems = tempServerData.ReceivedItems ?? new Dictionary();
+ SlotData = tempServerData.SlotData;
+ LocationData = tempServerData.LocationData;
+ AvailableTeleports = tempServerData.AvailableTeleports ?? [false, false];
- RandomizerStateManager.OnMainMenu = false;
- ArchipelagoClient.Connect();
- while (ArchipelagoClient.ItemQueue.Count > 0 && i < Index)
- {
- ArchipelagoClient.ItemQueue.Dequeue();
- i += 1;
- }
- return ArchipelagoClient.HasConnected = true;
+ //Attempt to connect to the server and save the new data
+ Console.WriteLine("Rando save found!");
+ if (Uri == "offline")
+ {
+ Console.WriteLine("continuing offline seed");
+ RandomizerStateManager.InitializeSeed();
+ return ArchipelagoClient.HasConnected = ArchipelagoClient.Offline = true;
}
- catch (Exception ex)
+
+ RandomizerStateManager.OnMainMenu = false;
+ ArchipelagoClient.Connect();
+ while (ArchipelagoClient.ItemQueue.Count > 0 && i < Index)
{
- Console.WriteLine(ex.ToString());
- return false;
+ ArchipelagoClient.ItemQueue.Dequeue();
+ i += 1;
}
+ return ArchipelagoClient.HasConnected = true;
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine(ex.ToString());
+ return false;
}
}
}
\ No newline at end of file
diff --git a/Archipelago/DeathLinkInterface.cs b/Archipelago/DeathLinkInterface.cs
index df08ef8..f238092 100644
--- a/Archipelago/DeathLinkInterface.cs
+++ b/Archipelago/DeathLinkInterface.cs
@@ -1,191 +1,190 @@
-using Archipelago.MultiClient.Net.BounceFeatures.DeathLink;
-using System;
+using System;
using System.Collections.Generic;
+using Archipelago.MultiClient.Net.BounceFeatures.DeathLink;
using MessengerRando.Utils;
using Mod.Courier;
using UnityEngine;
using WebSocketSharp;
-namespace MessengerRando.Archipelago
+namespace MessengerRando.Archipelago;
+
+public class DeathLinkInterface
{
- public class DeathLinkInterface
+ public DeathLinkService DeathLinkService;
+ public PlayerController Player;
+ private readonly List deathLinks = new List();
+ private bool receivedDeath;
+ private int deathsSent;
+ private List genericDeathCauses;
+ private List projectileDeathCauses;
+ private List spikeDeathCauses;
+ private List pitfallDeathCauses;
+ private List squishDeathCauses;
+ private List frequentDeathCauses;
+
+ public DeathLinkInterface()
{
- public DeathLinkService DeathLinkService;
- public PlayerController Player;
- private readonly List deathLinks = new List();
- private bool receivedDeath;
- private int deathsSent;
- private List genericDeathCauses;
- private List projectileDeathCauses;
- private List spikeDeathCauses;
- private List pitfallDeathCauses;
- private List squishDeathCauses;
- private List frequentDeathCauses;
+ try
+ {
+ Console.WriteLine($"Initializing death link service... Should be set to {ArchipelagoData.DeathLink}");
+ DeathLinkService = ArchipelagoClient.Session.CreateDeathLinkService();
+ DeathLinkService.OnDeathLinkReceived += DeathLinkReceived;
+ GenerateFunnyCauses();
- public DeathLinkInterface()
+ if (ArchipelagoData.DeathLink)
+ DeathLinkService.EnableDeathLink();
+ else
+ DeathLinkService.DisableDeathLink();
+ }
+ catch (Exception e)
{
- try
- {
- Console.WriteLine($"Initializing death link service... Should be set to {ArchipelagoData.DeathLink}");
- DeathLinkService = ArchipelagoClient.Session.CreateDeathLinkService();
- DeathLinkService.OnDeathLinkReceived += DeathLinkReceived;
- GenerateFunnyCauses();
-
- if (ArchipelagoData.DeathLink)
- DeathLinkService.EnableDeathLink();
- else
- DeathLinkService.DisableDeathLink();
- }
- catch (Exception e)
- {
- Console.WriteLine(e);
- }
+ Console.WriteLine(e);
}
+ }
+
+ public void DeathLinkReceived(DeathLink deathLink)
+ {
+ receivedDeath = true;
+ deathLinks.Add(deathLink);
+ Console.WriteLine($"Received Death Link from: {deathLink.Source} due to {deathLink.Cause}");
+ }
- public void DeathLinkReceived(DeathLink deathLink)
+ public void KillPlayer()
+ {
+ try
{
- receivedDeath = true;
- deathLinks.Add(deathLink);
- Console.WriteLine($"Received Death Link from: {deathLink.Source} due to {deathLink.Cause}");
+ if (deathLinks.Count > 0) receivedDeath = true;
+ if (!receivedDeath) return;
+ var cause = deathLinks[0].Cause;
+ if (cause.IsNullOrEmpty()) cause = $"{deathLinks[0].Source} sent you pain from afar.";
+ DialogSequence receivedDeathDialog = ScriptableObject.CreateInstance();
+ receivedDeathDialog.dialogID = "DEATH_LINK";
+ receivedDeathDialog.name = cause;
+ receivedDeathDialog.choices = new List();
+ AwardItemPopupParams receivedDeathParams = new AwardItemPopupParams(receivedDeathDialog, false);
+ Manager.Instance.ShowView(EScreenLayers.PROMPT, receivedDeathParams);
+ Player.Kill(EDeathType.GENERIC, null);
+ deathLinks.RemoveAt(0);
+ receivedDeath = false;
}
-
- public void KillPlayer()
+ catch (Exception e)
{
- try
- {
- if (deathLinks.Count > 0) receivedDeath = true;
- if (!receivedDeath) return;
- var cause = deathLinks[0].Cause;
- if (cause.IsNullOrEmpty()) cause = $"{deathLinks[0].Source} sent you pain from afar.";
- DialogSequence receivedDeathDialog = ScriptableObject.CreateInstance();
- receivedDeathDialog.dialogID = "DEATH_LINK";
- receivedDeathDialog.name = cause;
- receivedDeathDialog.choices = new List();
- AwardItemPopupParams receivedDeathParams = new AwardItemPopupParams(receivedDeathDialog, false);
- Manager.Instance.ShowView(EScreenLayers.PROMPT, receivedDeathParams);
- Player.Kill(EDeathType.GENERIC, null);
- deathLinks.RemoveAt(0);
- receivedDeath = false;
- }
- catch (Exception e)
- {
- Console.WriteLine(e.ToString());
- }
+ Console.WriteLine(e.ToString());
}
+ }
- public void SendDeathLink(EDeathType deathType, Transform killer)
+ public void SendDeathLink(EDeathType deathType, Transform killer)
+ {
+ try
{
- try
- {
- if (!ArchipelagoData.DeathLink || receivedDeath) return;
- deathsSent++;
- Console.WriteLine("Sharing death with your friends...");
- var alias = ArchipelagoClient.Session.Players.GetPlayerAliasAndName(ArchipelagoClient.Session.ConnectionInfo.Slot);
- // Debug.Log(killer.GetType());
- var cause = GetDeathLinkCause(deathType);
- DeathLinkService.SendDeathLink(new DeathLink(ArchipelagoClient.ServerData.SlotName, alias + cause));
- }
- catch (Exception e)
- {
- Console.WriteLine($"Error: {e}");
- }
+ if (!ArchipelagoData.DeathLink || receivedDeath) return;
+ deathsSent++;
+ Console.WriteLine("Sharing death with your friends...");
+ var alias = ArchipelagoClient.Session.Players.GetPlayerAliasAndName(ArchipelagoClient.Session.ConnectionInfo.Slot);
+ // Debug.Log(killer.GetType());
+ var cause = GetDeathLinkCause(deathType);
+ DeathLinkService.SendDeathLink(new DeathLink(ArchipelagoClient.ServerData.SlotName, alias + cause));
}
+ catch (Exception e)
+ {
+ Console.WriteLine($"Error: {e}");
+ }
+ }
- private void GenerateFunnyCauses()
+ private void GenerateFunnyCauses()
+ {
+ genericDeathCauses = new List
{
- genericDeathCauses = new List
- {
- " dropped their message.",
- " forgot to jump.",
- " just wanted to see Quarble.",
- " thought it was a simulation.",
- " blames that on input delay.",
- $" has had their life saved {deathsSent} times.",
- " zigged when they should have zagged.",
- " let Quarble win another bet.",
- " wasn't able to get a selfie with Quarble.",
- " meant to do that.",
- " is playing with their feet.",
- };
-
- projectileDeathCauses = new List
- {
- " thought that was a health potion.",
- " didn't dodge.",
- " walked into that one.",
- " forgot the 5 d's of dealing with projectiles.",
- " visited the Shopkeeper, but they don't carry awareness upgrades.",
- " forgot to tell the enemies not to shoot The Messenger.",
- };
+ " dropped their message.",
+ " forgot to jump.",
+ " just wanted to see Quarble.",
+ " thought it was a simulation.",
+ " blames that on input delay.",
+ $" has had their life saved {deathsSent} times.",
+ " zigged when they should have zagged.",
+ " let Quarble win another bet.",
+ " wasn't able to get a selfie with Quarble.",
+ " meant to do that.",
+ " is playing with their feet.",
+ };
- spikeDeathCauses = new List
- {
- " didn't avoid the spikes.",
- " didn't watch their step.",
- " lacks aichmophobia.",
- " needs an item to reduce spike damage.",
- " saved Quarble from a very boring dinner.",
- };
+ projectileDeathCauses = new List
+ {
+ " thought that was a health potion.",
+ " didn't dodge.",
+ " walked into that one.",
+ " forgot the 5 d's of dealing with projectiles.",
+ " visited the Shopkeeper, but they don't carry awareness upgrades.",
+ " forgot to tell the enemies not to shoot The Messenger.",
+ };
- pitfallDeathCauses = new List
- {
- " just fell in a pit.",
- " definitely fell due to input lag.",
- " thought that was a secret passage.",
- " wanted to see how long until the death quotes loop.",
- };
+ spikeDeathCauses = new List
+ {
+ " didn't avoid the spikes.",
+ " didn't watch their step.",
+ " lacks aichmophobia.",
+ " needs an item to reduce spike damage.",
+ " saved Quarble from a very boring dinner.",
+ };
- squishDeathCauses = new List
- {
- " died in a painful way.",
- " had to confirm that one.",
- " wasn't forgiven by the moving blocks.",
- " got crushed.",
- " was pressed.",
- };
+ pitfallDeathCauses = new List
+ {
+ " just fell in a pit.",
+ " definitely fell due to input lag.",
+ " thought that was a secret passage.",
+ " wanted to see how long until the death quotes loop.",
+ };
- frequentDeathCauses = new List
- {
- " deserves a discount at this point.",
- " won't give Quarble a break.",
- " is considering the package offer.",
- " is keeping Quarble busy.",
- " is overheating Quarble's ring.",
- " is letting Quarble do all the work.",
- " is keeping Quarble from his family.",
- };
- }
+ squishDeathCauses = new List
+ {
+ " died in a painful way.",
+ " had to confirm that one.",
+ " wasn't forgiven by the moving blocks.",
+ " got crushed.",
+ " was pressed.",
+ };
- private string GetDeathLinkCause(EDeathType deathType)
+ frequentDeathCauses = new List
{
- var random = RandomizerStateManager.SeedRandom;
- try
- {
- switch (deathType)
- {
- case EDeathType.INTRO:
- return " is a new customer!";
- case EDeathType.GENERIC:
- return genericDeathCauses[random.Next(genericDeathCauses.Count)];
- case EDeathType.PROJECTILE:
- return projectileDeathCauses[random.Next(projectileDeathCauses.Count)];
- case EDeathType.SPIKES:
- return spikeDeathCauses[random.Next(spikeDeathCauses.Count)];
- case EDeathType.PITFALL:
- return pitfallDeathCauses[random.Next(pitfallDeathCauses.Count)];
- case EDeathType.SQUISH:
- return squishDeathCauses[random.Next(squishDeathCauses.Count)];
- case EDeathType.FREQUENT:
- return frequentDeathCauses[random.Next(frequentDeathCauses.Count)];
- default:
- throw new ArgumentOutOfRangeException(nameof(deathType));
- }
- }
- catch (Exception e)
+ " deserves a discount at this point.",
+ " won't give Quarble a break.",
+ " is considering the package offer.",
+ " is keeping Quarble busy.",
+ " is overheating Quarble's ring.",
+ " is letting Quarble do all the work.",
+ " is keeping Quarble from his family.",
+ };
+ }
+
+ private string GetDeathLinkCause(EDeathType deathType)
+ {
+ var random = RandomizerStateManager.SeedRandom;
+ try
+ {
+ switch (deathType)
{
- e.LogDetailed();
- return " is a menace";
+ case EDeathType.INTRO:
+ return " is a new customer!";
+ case EDeathType.GENERIC:
+ return genericDeathCauses[random.Next(genericDeathCauses.Count)];
+ case EDeathType.PROJECTILE:
+ return projectileDeathCauses[random.Next(projectileDeathCauses.Count)];
+ case EDeathType.SPIKES:
+ return spikeDeathCauses[random.Next(spikeDeathCauses.Count)];
+ case EDeathType.PITFALL:
+ return pitfallDeathCauses[random.Next(pitfallDeathCauses.Count)];
+ case EDeathType.SQUISH:
+ return squishDeathCauses[random.Next(squishDeathCauses.Count)];
+ case EDeathType.FREQUENT:
+ return frequentDeathCauses[random.Next(frequentDeathCauses.Count)];
+ default:
+ throw new ArgumentOutOfRangeException(nameof(deathType));
}
}
+ catch (Exception e)
+ {
+ e.LogDetailed();
+ return " is a menace";
+ }
}
}
diff --git a/Archipelago/ItemsAndLocationsHandler.cs b/Archipelago/ItemsAndLocationsHandler.cs
index da36ef4..e1877b9 100644
--- a/Archipelago/ItemsAndLocationsHandler.cs
+++ b/Archipelago/ItemsAndLocationsHandler.cs
@@ -6,566 +6,565 @@
using MessengerRando.RO;
using MessengerRando.Utils;
-namespace MessengerRando.Archipelago
-{
- public static class ItemsAndLocationsHandler
- {
- public static Dictionary ItemsLookup;
- public static Dictionary LocationsLookup;
- private static Dictionary EItemsLocationsLookup;
- public static Dictionary IDtoLocationsLookup;
+namespace MessengerRando.Archipelago;
- public static RandomizerStateManager RandoStateManager;
- public static SkylandsGeneratorManager SkylandsGeneratorManager;
+public static class ItemsAndLocationsHandler
+{
+ public static Dictionary ItemsLookup;
+ public static Dictionary LocationsLookup;
+ private static Dictionary EItemsLocationsLookup;
+ public static Dictionary IDtoLocationsLookup;
- public const int APQuantity = 69;
- public const long BaseOffset = 0xADD_000;
+ public static RandomizerStateManager RandoStateManager;
+ public static SkylandsGeneratorManager SkylandsGeneratorManager;
- public static bool Synced;
- public static TrackerManager TrackerManager;
+ public const int APQuantity = 69;
+ public const long BaseOffset = 0xADD_000;
- ///
- /// Builds the item and lookup dictionaries for converting to and from AP checks. Will always make every location
- /// a check, whether they are or not, for simplicity's sake.
- ///
- public static void Initialize()
- {
-
- long offset = BaseOffset;
- Console.WriteLine("Building ItemsLookup...");
- ItemsLookup = new Dictionary();
- foreach (var figurine in Enum.GetValues(typeof(EFigurine)))
- ArchipelagoItems.Add(new RandoItemRO(figurine.ToString(), EItems.NONE));
- ArchipelagoItems.AddRange(new List
- {
- new RandoItemRO("Money Wrench", EItems.MONEY_WRENCH),
- new RandoItemRO("Teleport Trap", EItems.NONE),
- new RandoItemRO("Prophecy Trap", EItems.NONE),
- new RandoItemRO("Progressive Generator Shutdown", EItems.NONE),
- new RandoItemRO("Darkness Trap", EItems.NONE),
- new RandoItemRO("Health", EItems.POTION),
- new RandoItemRO("Mana", EItems.MANA),
- new RandoItemRO("Feather", EItems.FEATHER),
- new RandoItemRO("Mask Fragment", EItems.MASK_PIECE),
- });
-
- foreach (var item in ArchipelagoItems)
- {
- ItemsLookup.Add(offset, item);
- // Console.WriteLine($"{item.Name}: {offset}");
- ++offset;
- }
+ public static bool Synced;
+ public static TrackerManager TrackerManager;
- offset = BaseOffset;
- Console.WriteLine("Building LocationsLookup...");
- LocationsLookup = new Dictionary();
- EItemsLocationsLookup = new Dictionary();
- IDtoLocationsLookup = new Dictionary();
-
- var megaShards = RandoTimeShardManager.MegaShardLookup.Select(item => item.Loc).ToList();
- ArchipelagoLocations.AddRange(megaShards);
- ArchipelagoLocations.AddRange(BossLocations);
- ArchipelagoLocations.AddRange(ShopLocations);
- foreach (var figurine in Enum.GetValues(typeof(EFigurine)))
- ArchipelagoLocations.Add(new LocationRO(figurine.ToString()));
- ArchipelagoLocations.Add(new LocationRO("Money Wrench", EItems.MONEY_WRENCH));
-
- ArchipelagoLocations.Add(new LocationRO("Elemental Skylands - Shutdown Air Generator"));
- ArchipelagoLocations.Add(new LocationRO("Elemental Skylands - Shutdown Earth Generator"));
- ArchipelagoLocations.Add(new LocationRO("Elemental Skylands - Shutdown Water Generator"));
- ArchipelagoLocations.Add(new LocationRO("Elemental Skylands - Shutdown Fire Generator"));
-
- foreach (var progLocation in ArchipelagoLocations)
- {
- LocationsLookup.Add(progLocation, offset);
- IDtoLocationsLookup.Add(offset, progLocation);
- Console.WriteLine($"{progLocation.PrettyLocationName}: {offset}");
- if (progLocation.VanillaItem != EItems.NONE &&
- !EItemsLocationsLookup.ContainsKey(progLocation.VanillaItem))
- EItemsLocationsLookup.Add(progLocation.VanillaItem, offset);
- ++offset;
- }
- }
+ ///
+ /// Builds the item and lookup dictionaries for converting to and from AP checks. Will always make every location
+ /// a check, whether they are or not, for simplicity's sake.
+ ///
+ public static void Initialize()
+ {
- private static readonly List ArchipelagoItems =
- [
- new RandoItemRO("Key_Of_Hope", EItems.KEY_OF_HOPE),
- new RandoItemRO("Key_Of_Chaos", EItems.KEY_OF_CHAOS),
- new RandoItemRO("Key_Of_Courage", EItems.KEY_OF_COURAGE),
- new RandoItemRO("Key_Of_Love", EItems.KEY_OF_LOVE),
- new RandoItemRO("Key_Of_Strength", EItems.KEY_OF_STRENGTH),
- new RandoItemRO("Key_Of_Symbiosis", EItems.KEY_OF_SYMBIOSIS),
- //upgrades
- new RandoItemRO("Windmill_Shuriken", EItems.WINDMILL_SHURIKEN),
- new RandoItemRO("Wingsuit", EItems.WINGSUIT),
- new RandoItemRO("Rope_Dart", EItems.GRAPLOU),
- new RandoItemRO("Ninja_Tabis", EItems.MAGIC_BOOTS),
- //quest items
- //new RandoItemRO("Astral_Seed", EItems.TEA_SEED),
- //new RandoItemRO("Astral_Tea_Leaves", EItems.TEA_LEAVES),
- new RandoItemRO("Candle", EItems.CANDLE),
- new RandoItemRO("Seashell", EItems.SEASHELL),
- new RandoItemRO("Power_Thistle", EItems.POWER_THISTLE),
- new RandoItemRO("Demon_King_Crown", EItems.DEMON_KING_CROWN),
- new RandoItemRO("Ruxxtin_Amulet", EItems.RUXXTIN_AMULET),
- new RandoItemRO("Fairy_Bottle", EItems.FAIRY_BOTTLE),
- new RandoItemRO("Sun_Crest", EItems.SUN_CREST),
- new RandoItemRO("Moon_Crest", EItems.MOON_CREST),
- //Phobekins
- new RandoItemRO("Necro", EItems.NECROPHOBIC_WORKER),
- new RandoItemRO("Pyro", EItems.PYROPHOBIC_WORKER),
- new RandoItemRO("Claustro", EItems.CLAUSTROPHOBIC_WORKER),
- new RandoItemRO("Acro", EItems.ACROPHOBIC_WORKER),
- //Power seals
- new RandoItemRO("PowerSeal", EItems.POWER_SEAL),
- //time shards
- new RandoItemRO("Timeshard", EItems.TIME_SHARD),
- new RandoItemRO("Timeshard (10)", EItems.TIME_SHARD),
- new RandoItemRO("Timeshard (50)", EItems.TIME_SHARD),
- new RandoItemRO("Timeshard (100)", EItems.TIME_SHARD),
- new RandoItemRO("Timeshard (300)", EItems.TIME_SHARD),
- new RandoItemRO("Timeshard (500)", EItems.TIME_SHARD),
- //shop items
- new RandoItemRO("Karuta Plates", EItems.HEART_CONTAINER),
- new RandoItemRO("Serendipitous Bodies", EItems.ENEMY_DROP_HP),
- new RandoItemRO("Path of Resilience", EItems.DAMAGE_REDUCTION),
- new RandoItemRO("Kusari Jacket", EItems.HEART_CONTAINER),
- new RandoItemRO("Energy Shuriken", EItems.SHURIKEN),
- new RandoItemRO("Serendipitous Minds", EItems.ENEMY_DROP_MANA),
- new RandoItemRO("Prepared Mind", EItems.SHURIKEN_UPGRADE),
- new RandoItemRO("Meditation", EItems.CHECKPOINT_UPGRADE),
- new RandoItemRO("Rejuvenative Spirit", EItems.POTION_FULL_HEAL_AND_HP_UPGRADE),
- new RandoItemRO("Centered Mind", EItems.SHURIKEN_UPGRADE),
- new RandoItemRO("Strike of the Ninja", EItems.ATTACK_PROJECTILES),
- new RandoItemRO("Second Wind", EItems.AIR_RECOVER),
- new RandoItemRO("Currents Master", EItems.SWIM_DASH),
- new RandoItemRO("Aerobatics Warrior", EItems.GLIDE_ATTACK),
- new RandoItemRO("Demon's Bane", EItems.CHARGED_ATTACK),
- new RandoItemRO("Devil's Due", EItems.QUARBLE_DISCOUNT_50),
- new RandoItemRO("Time Sense", EItems.MAP_TIME_WARP),
- new RandoItemRO("Power Sense", EItems.MAP_POWER_SEAL_TOTAL),
- new RandoItemRO("Focused Power Sense", EItems.MAP_POWER_SEAL_PINS)
- ];
-
- public static readonly List ArchipelagoLocations =
- [
- new LocationRO("Key_Of_Love", EItems.KEY_OF_LOVE),
- new LocationRO("Key_Of_Courage", EItems.KEY_OF_COURAGE),
- new LocationRO("Key_Of_Chaos", EItems.KEY_OF_CHAOS),
- new LocationRO("Key_Of_Symbiosis", EItems.KEY_OF_SYMBIOSIS),
- new LocationRO("Key_Of_Strength", EItems.KEY_OF_STRENGTH),
- new LocationRO("Key_Of_Hope", EItems.KEY_OF_HOPE),
- //upgrades
- new LocationRO("Wingsuit", EItems.WINGSUIT),
- new LocationRO("Rope_Dart", EItems.GRAPLOU),
- new LocationRO("Ninja_Tabis", EItems.MAGIC_BOOTS),
- new LocationRO("Climbing_Claws", EItems.CLIMBING_CLAWS),
- //quest items
- new LocationRO("Astral_Seed", EItems.TEA_SEED),
- new LocationRO("Astral_Tea_Leaves", EItems.TEA_LEAVES),
- new LocationRO("Candle", EItems.CANDLE),
- new LocationRO("Seashell", EItems.SEASHELL),
- new LocationRO("Power_Thistle", EItems.POWER_THISTLE),
- new LocationRO("Demon_King_Crown", EItems.DEMON_KING_CROWN),
- new LocationRO("Ruxxtin_Amulet", EItems.RUXXTIN_AMULET),
- new LocationRO("Fairy_Bottle", EItems.FAIRY_BOTTLE),
- new LocationRO("Sun_Crest", EItems.SUN_CREST),
- new LocationRO("Moon_Crest", EItems.MOON_CREST),
- //Phobekins
- new LocationRO("Necro", EItems.NECROPHOBIC_WORKER),
- new LocationRO("Pyro", EItems.PYROPHOBIC_WORKER),
- new LocationRO("Claustro", EItems.CLAUSTROPHOBIC_WORKER),
- new LocationRO("Acro", EItems.ACROPHOBIC_WORKER),
- //power seals
- //Ninja Village
- new LocationRO("-436-404-44-28", "Ninja Village Seal - Tree House"),
- //Autumn Hills
- new LocationRO("-52-20-60-44", "Autumn Hills Seal - Trip Saws"),
- new LocationRO("556588-44-28", "Autumn Hills Seal - Double Swing Saws"),
- new LocationRO("748780-76-60", "Autumn Hills Seal - Spike Ball Swing"),
- new LocationRO("748780-108-76", "Autumn Hills Seal - Spike Ball Darts"),
- //Catacombs
- new LocationRO("236268-44-28", "Catacombs Seal - Triple Spike Crushers"),
- new LocationRO("492524-44-28", "Catacombs Seal - Crusher Gauntlet"),
- new LocationRO("556588-60-44", "Catacombs Seal - Dirty Pond"),
- //Bamboo Creek
- new LocationRO("-84-52-28-12", "Bamboo Creek Seal - Spike Crushers and Doors"),
- new LocationRO("172236-44-28", "Bamboo Creek Seal - Spike Ball Pits"),
- new LocationRO("300332-1236", "Bamboo Creek Seal - Spike Crushers and Doors v2"),
- //Howling Grotto
- new LocationRO("108140-28-12", "Howling Grotto Seal - Windy Saws and Balls"),
- new LocationRO("300332-92-76", "Howling Grotto Seal - Crushing Pits"),
- new LocationRO("460492-172-156", "Howling Grotto Seal - Breezy Crushers"),
- //Quillshroom Marsh
- new LocationRO("204236-28-12", "Quillshroom Marsh Seal - Spikey Window"),
- new LocationRO("652684-60-28", "Quillshroom Marsh Seal - Sand Trap"),
- new LocationRO("940972-28-12", "Quillshroom Marsh Seal - Do the Spike Wave"),
- //Searing Crags
- new LocationRO("761085268", "Searing Crags Seal - Triple Ball Spinner"),
- new LocationRO("300332196212", "Searing Crags Seal - Raining Rocks"),
- new LocationRO("364396292308", "Searing Crags Seal - Rhythm Rocks"),
- //Glacial Peak
- new LocationRO("140172-492-476", "Glacial Peak Seal - Ice Climbers"),
- new LocationRO("236268-396-380", "Glacial Peak Seal - Projectile Spike Pit"),
- new LocationRO("236268-156-140", "Glacial Peak Seal - Glacial Air Swag"),
- //Tower Of Time
- new LocationRO("-84-522036", "Tower Of Time Seal - Time Waster Seal"),
- new LocationRO("7610852116", "Tower Of Time Seal - Lantern Climb"),
- new LocationRO("-52-20116132", "Tower Of Time Seal - Arcane Orbs"),
- //Cloud Ruins
- new LocationRO("-148-116420", "Cloud Ruins Seal - Ghost Pit"),
- new LocationRO("108140-44-28", "Cloud Ruins Seal - Toothbrush Alley"),
- new LocationRO("748780-44-28", "Cloud Ruins Seal - Saw Pit"),
- new LocationRO("11321164-124", "Cloud Ruins Seal - Money Farm Room"),
- //Underworld
- new LocationRO("-276-244-444", "Underworld Seal - Sharp and Windy Climb"),
- new LocationRO("-180-148-44-28", "Underworld Seal - Spike Wall"),
- new LocationRO("-180-148-60-44", "Underworld Seal - Fireball Wave"),
- new LocationRO("-2012-124", "Underworld Seal - Rising Fanta"),
- //Forlorn Temple
- new LocationRO("172268-284", "Forlorn Temple Seal - Rocket Maze"),
- new LocationRO("140172100164", "Forlorn Temple Seal - Rocket Sunset"),
- //Sunken Shrine
- new LocationRO("204236-124", "Sunken Shrine Seal - Ultra Lifeguard"),
- new LocationRO("172268-188-172", "Sunken Shrine Seal - Waterfall Paradise"),
- new LocationRO("-148-116-124-60", "Sunken Shrine Seal - Tabi Gauntlet"),
- //Riviere Turquoise
- new LocationRO("844876-284", "Riviere Turquoise Seal - Bounces and Balls"),
- new LocationRO("460492-124-108", "Riviere Turquoise Seal - Launch of Faith"),
- new LocationRO("-180-1483668", "Riviere Turquoise Seal - Flower Power"),
- //Elemental Skylands
- new LocationRO("-52-20420436", "Elemental Skylands Seal - Air Seal"),
- new LocationRO("18361868372388", "Elemental Skylands Seal - Water Seal"),
- new LocationRO("28602892356388", "Elemental Skylands Seal - Fire Seal"),
- ];
-
- private static readonly List BossLocations =
- [
- new LocationRO("LeafGolem"),
- new LocationRO("Necromancer"),
- new LocationRO("EmeraldGolem"),
- new LocationRO("QueenOfQuills")
- ];
-
- private static readonly List ShopLocations =
- [
- new LocationRO("HP_UPGRADE_1", EItems.HEART_CONTAINER),
- new LocationRO("ENEMY_DROP_HP", EItems.ENEMY_DROP_HP),
- new LocationRO("DAMAGE_REDUCTION", EItems.DAMAGE_REDUCTION),
- new LocationRO("HP_UPGRADE_2", EItems.HEART_CONTAINER),
- new LocationRO("SHURIKEN", EItems.SHURIKEN),
- new LocationRO("ENEMY_DROP_MANA", EItems.ENEMY_DROP_MANA),
- new LocationRO("SHURIKEN_UPGRADE_1", EItems.SHURIKEN_UPGRADE),
- new LocationRO("CHECKPOINT_FULL", EItems.CHECKPOINT_UPGRADE),
- new LocationRO("POTION_FULL_HEAL_AND_HP", EItems.POTION_FULL_HEAL_AND_HP_UPGRADE),
- new LocationRO("SHURIKEN_UPGRADE_2", EItems.SHURIKEN_UPGRADE),
- new LocationRO("ATTACK_PROJECTILE", EItems.ATTACK_PROJECTILES),
- new LocationRO("AIR_RECOVER", EItems.AIR_RECOVER),
- new LocationRO("SWIM_DASH", EItems.SWIM_DASH),
- new LocationRO("GLIDE_ATTACK", EItems.GLIDE_ATTACK),
- new LocationRO("CHARGED_ATTACK", EItems.CHARGED_ATTACK),
- new LocationRO("QUARBLE_DISCOUNT_50", EItems.QUARBLE_DISCOUNT_50),
- new LocationRO("TIME_WARP", EItems.MAP_TIME_WARP),
- new LocationRO("POWER_SEAL_WORLD_MAP", EItems.MAP_POWER_SEAL_TOTAL),
- new LocationRO("POWER_SEAL", EItems.MAP_POWER_SEAL_PINS)
- ];
-
- private static readonly Dictionary SpecialNames = new()
+ long offset = BaseOffset;
+ Console.WriteLine("Building ItemsLookup...");
+ ItemsLookup = new Dictionary();
+ foreach (var figurine in Enum.GetValues(typeof(EFigurine)))
+ ArchipelagoItems.Add(new RandoItemRO(figurine.ToString(), EItems.NONE));
+ ArchipelagoItems.AddRange(new List
{
- { "HP_UPGRADE_1", "HP_UPGRADE_2" },
- { "SHURIKEN_UPGRADE_1", "SHURIKEN_UPGRADE_2" },
- };
-
- private static bool ShopItem(EItems item)
+ new RandoItemRO("Money Wrench", EItems.MONEY_WRENCH),
+ new RandoItemRO("Teleport Trap", EItems.NONE),
+ new RandoItemRO("Prophecy Trap", EItems.NONE),
+ new RandoItemRO("Progressive Generator Shutdown", EItems.NONE),
+ new RandoItemRO("Darkness Trap", EItems.NONE),
+ new RandoItemRO("Health", EItems.POTION),
+ new RandoItemRO("Mana", EItems.MANA),
+ new RandoItemRO("Feather", EItems.FEATHER),
+ new RandoItemRO("Mask Fragment", EItems.MASK_PIECE),
+ });
+
+ foreach (var item in ArchipelagoItems)
{
- var shopItems = new List
- {
- EItems.HEART_CONTAINER,
- EItems.SHURIKEN,
- EItems.SHURIKEN_UPGRADE,
- EItems.CHECKPOINT_UPGRADE,
- EItems.POTION_FULL_HEAL_AND_HP_UPGRADE,
- EItems.MAP_TIME_WARP,
- EItems.MAP_POWER_SEAL_TOTAL,
- EItems.MAP_POWER_SEAL_PINS,
- };
- return shopItems.Contains(item);
+ ItemsLookup.Add(offset, item);
+ // Console.WriteLine($"{item.Name}: {offset}");
+ ++offset;
}
- public static long ItemFromEItem(EItems item)
+ offset = BaseOffset;
+ Console.WriteLine("Building LocationsLookup...");
+ LocationsLookup = new Dictionary();
+ EItemsLocationsLookup = new Dictionary();
+ IDtoLocationsLookup = new Dictionary();
+
+ var megaShards = RandoTimeShardManager.MegaShardLookup.Select(item => item.Loc).ToList();
+ ArchipelagoLocations.AddRange(megaShards);
+ ArchipelagoLocations.AddRange(BossLocations);
+ ArchipelagoLocations.AddRange(ShopLocations);
+ foreach (var figurine in Enum.GetValues(typeof(EFigurine)))
+ ArchipelagoLocations.Add(new LocationRO(figurine.ToString()));
+ ArchipelagoLocations.Add(new LocationRO("Money Wrench", EItems.MONEY_WRENCH));
+
+ ArchipelagoLocations.Add(new LocationRO("Elemental Skylands - Shutdown Air Generator"));
+ ArchipelagoLocations.Add(new LocationRO("Elemental Skylands - Shutdown Earth Generator"));
+ ArchipelagoLocations.Add(new LocationRO("Elemental Skylands - Shutdown Water Generator"));
+ ArchipelagoLocations.Add(new LocationRO("Elemental Skylands - Shutdown Fire Generator"));
+
+ foreach (var progLocation in ArchipelagoLocations)
{
- return ItemsLookup.First(x => x.Value.Equals(item)).Key;
+ LocationsLookup.Add(progLocation, offset);
+ IDtoLocationsLookup.Add(offset, progLocation);
+ Console.WriteLine($"{progLocation.PrettyLocationName}: {offset}");
+ if (progLocation.VanillaItem != EItems.NONE &&
+ !EItemsLocationsLookup.ContainsKey(progLocation.VanillaItem))
+ EItemsLocationsLookup.Add(progLocation.VanillaItem, offset);
+ ++offset;
}
+ }
+
+ private static readonly List ArchipelagoItems =
+ [
+ new RandoItemRO("Key_Of_Hope", EItems.KEY_OF_HOPE),
+ new RandoItemRO("Key_Of_Chaos", EItems.KEY_OF_CHAOS),
+ new RandoItemRO("Key_Of_Courage", EItems.KEY_OF_COURAGE),
+ new RandoItemRO("Key_Of_Love", EItems.KEY_OF_LOVE),
+ new RandoItemRO("Key_Of_Strength", EItems.KEY_OF_STRENGTH),
+ new RandoItemRO("Key_Of_Symbiosis", EItems.KEY_OF_SYMBIOSIS),
+ //upgrades
+ new RandoItemRO("Windmill_Shuriken", EItems.WINDMILL_SHURIKEN),
+ new RandoItemRO("Wingsuit", EItems.WINGSUIT),
+ new RandoItemRO("Rope_Dart", EItems.GRAPLOU),
+ new RandoItemRO("Ninja_Tabis", EItems.MAGIC_BOOTS),
+ //quest items
+ //new RandoItemRO("Astral_Seed", EItems.TEA_SEED),
+ //new RandoItemRO("Astral_Tea_Leaves", EItems.TEA_LEAVES),
+ new RandoItemRO("Candle", EItems.CANDLE),
+ new RandoItemRO("Seashell", EItems.SEASHELL),
+ new RandoItemRO("Power_Thistle", EItems.POWER_THISTLE),
+ new RandoItemRO("Demon_King_Crown", EItems.DEMON_KING_CROWN),
+ new RandoItemRO("Ruxxtin_Amulet", EItems.RUXXTIN_AMULET),
+ new RandoItemRO("Fairy_Bottle", EItems.FAIRY_BOTTLE),
+ new RandoItemRO("Sun_Crest", EItems.SUN_CREST),
+ new RandoItemRO("Moon_Crest", EItems.MOON_CREST),
+ //Phobekins
+ new RandoItemRO("Necro", EItems.NECROPHOBIC_WORKER),
+ new RandoItemRO("Pyro", EItems.PYROPHOBIC_WORKER),
+ new RandoItemRO("Claustro", EItems.CLAUSTROPHOBIC_WORKER),
+ new RandoItemRO("Acro", EItems.ACROPHOBIC_WORKER),
+ //Power seals
+ new RandoItemRO("PowerSeal", EItems.POWER_SEAL),
+ //time shards
+ new RandoItemRO("Timeshard", EItems.TIME_SHARD),
+ new RandoItemRO("Timeshard (10)", EItems.TIME_SHARD),
+ new RandoItemRO("Timeshard (50)", EItems.TIME_SHARD),
+ new RandoItemRO("Timeshard (100)", EItems.TIME_SHARD),
+ new RandoItemRO("Timeshard (300)", EItems.TIME_SHARD),
+ new RandoItemRO("Timeshard (500)", EItems.TIME_SHARD),
+ //shop items
+ new RandoItemRO("Karuta Plates", EItems.HEART_CONTAINER),
+ new RandoItemRO("Serendipitous Bodies", EItems.ENEMY_DROP_HP),
+ new RandoItemRO("Path of Resilience", EItems.DAMAGE_REDUCTION),
+ new RandoItemRO("Kusari Jacket", EItems.HEART_CONTAINER),
+ new RandoItemRO("Energy Shuriken", EItems.SHURIKEN),
+ new RandoItemRO("Serendipitous Minds", EItems.ENEMY_DROP_MANA),
+ new RandoItemRO("Prepared Mind", EItems.SHURIKEN_UPGRADE),
+ new RandoItemRO("Meditation", EItems.CHECKPOINT_UPGRADE),
+ new RandoItemRO("Rejuvenative Spirit", EItems.POTION_FULL_HEAL_AND_HP_UPGRADE),
+ new RandoItemRO("Centered Mind", EItems.SHURIKEN_UPGRADE),
+ new RandoItemRO("Strike of the Ninja", EItems.ATTACK_PROJECTILES),
+ new RandoItemRO("Second Wind", EItems.AIR_RECOVER),
+ new RandoItemRO("Currents Master", EItems.SWIM_DASH),
+ new RandoItemRO("Aerobatics Warrior", EItems.GLIDE_ATTACK),
+ new RandoItemRO("Demon's Bane", EItems.CHARGED_ATTACK),
+ new RandoItemRO("Devil's Due", EItems.QUARBLE_DISCOUNT_50),
+ new RandoItemRO("Time Sense", EItems.MAP_TIME_WARP),
+ new RandoItemRO("Power Sense", EItems.MAP_POWER_SEAL_TOTAL),
+ new RandoItemRO("Focused Power Sense", EItems.MAP_POWER_SEAL_PINS)
+ ];
+
+ public static readonly List ArchipelagoLocations =
+ [
+ new LocationRO("Key_Of_Love", EItems.KEY_OF_LOVE),
+ new LocationRO("Key_Of_Courage", EItems.KEY_OF_COURAGE),
+ new LocationRO("Key_Of_Chaos", EItems.KEY_OF_CHAOS),
+ new LocationRO("Key_Of_Symbiosis", EItems.KEY_OF_SYMBIOSIS),
+ new LocationRO("Key_Of_Strength", EItems.KEY_OF_STRENGTH),
+ new LocationRO("Key_Of_Hope", EItems.KEY_OF_HOPE),
+ //upgrades
+ new LocationRO("Wingsuit", EItems.WINGSUIT),
+ new LocationRO("Rope_Dart", EItems.GRAPLOU),
+ new LocationRO("Ninja_Tabis", EItems.MAGIC_BOOTS),
+ new LocationRO("Climbing_Claws", EItems.CLIMBING_CLAWS),
+ //quest items
+ new LocationRO("Astral_Seed", EItems.TEA_SEED),
+ new LocationRO("Astral_Tea_Leaves", EItems.TEA_LEAVES),
+ new LocationRO("Candle", EItems.CANDLE),
+ new LocationRO("Seashell", EItems.SEASHELL),
+ new LocationRO("Power_Thistle", EItems.POWER_THISTLE),
+ new LocationRO("Demon_King_Crown", EItems.DEMON_KING_CROWN),
+ new LocationRO("Ruxxtin_Amulet", EItems.RUXXTIN_AMULET),
+ new LocationRO("Fairy_Bottle", EItems.FAIRY_BOTTLE),
+ new LocationRO("Sun_Crest", EItems.SUN_CREST),
+ new LocationRO("Moon_Crest", EItems.MOON_CREST),
+ //Phobekins
+ new LocationRO("Necro", EItems.NECROPHOBIC_WORKER),
+ new LocationRO("Pyro", EItems.PYROPHOBIC_WORKER),
+ new LocationRO("Claustro", EItems.CLAUSTROPHOBIC_WORKER),
+ new LocationRO("Acro", EItems.ACROPHOBIC_WORKER),
+ //power seals
+ //Ninja Village
+ new LocationRO("-436-404-44-28", "Ninja Village Seal - Tree House"),
+ //Autumn Hills
+ new LocationRO("-52-20-60-44", "Autumn Hills Seal - Trip Saws"),
+ new LocationRO("556588-44-28", "Autumn Hills Seal - Double Swing Saws"),
+ new LocationRO("748780-76-60", "Autumn Hills Seal - Spike Ball Swing"),
+ new LocationRO("748780-108-76", "Autumn Hills Seal - Spike Ball Darts"),
+ //Catacombs
+ new LocationRO("236268-44-28", "Catacombs Seal - Triple Spike Crushers"),
+ new LocationRO("492524-44-28", "Catacombs Seal - Crusher Gauntlet"),
+ new LocationRO("556588-60-44", "Catacombs Seal - Dirty Pond"),
+ //Bamboo Creek
+ new LocationRO("-84-52-28-12", "Bamboo Creek Seal - Spike Crushers and Doors"),
+ new LocationRO("172236-44-28", "Bamboo Creek Seal - Spike Ball Pits"),
+ new LocationRO("300332-1236", "Bamboo Creek Seal - Spike Crushers and Doors v2"),
+ //Howling Grotto
+ new LocationRO("108140-28-12", "Howling Grotto Seal - Windy Saws and Balls"),
+ new LocationRO("300332-92-76", "Howling Grotto Seal - Crushing Pits"),
+ new LocationRO("460492-172-156", "Howling Grotto Seal - Breezy Crushers"),
+ //Quillshroom Marsh
+ new LocationRO("204236-28-12", "Quillshroom Marsh Seal - Spikey Window"),
+ new LocationRO("652684-60-28", "Quillshroom Marsh Seal - Sand Trap"),
+ new LocationRO("940972-28-12", "Quillshroom Marsh Seal - Do the Spike Wave"),
+ //Searing Crags
+ new LocationRO("761085268", "Searing Crags Seal - Triple Ball Spinner"),
+ new LocationRO("300332196212", "Searing Crags Seal - Raining Rocks"),
+ new LocationRO("364396292308", "Searing Crags Seal - Rhythm Rocks"),
+ //Glacial Peak
+ new LocationRO("140172-492-476", "Glacial Peak Seal - Ice Climbers"),
+ new LocationRO("236268-396-380", "Glacial Peak Seal - Projectile Spike Pit"),
+ new LocationRO("236268-156-140", "Glacial Peak Seal - Glacial Air Swag"),
+ //Tower Of Time
+ new LocationRO("-84-522036", "Tower Of Time Seal - Time Waster Seal"),
+ new LocationRO("7610852116", "Tower Of Time Seal - Lantern Climb"),
+ new LocationRO("-52-20116132", "Tower Of Time Seal - Arcane Orbs"),
+ //Cloud Ruins
+ new LocationRO("-148-116420", "Cloud Ruins Seal - Ghost Pit"),
+ new LocationRO("108140-44-28", "Cloud Ruins Seal - Toothbrush Alley"),
+ new LocationRO("748780-44-28", "Cloud Ruins Seal - Saw Pit"),
+ new LocationRO("11321164-124", "Cloud Ruins Seal - Money Farm Room"),
+ //Underworld
+ new LocationRO("-276-244-444", "Underworld Seal - Sharp and Windy Climb"),
+ new LocationRO("-180-148-44-28", "Underworld Seal - Spike Wall"),
+ new LocationRO("-180-148-60-44", "Underworld Seal - Fireball Wave"),
+ new LocationRO("-2012-124", "Underworld Seal - Rising Fanta"),
+ //Forlorn Temple
+ new LocationRO("172268-284", "Forlorn Temple Seal - Rocket Maze"),
+ new LocationRO("140172100164", "Forlorn Temple Seal - Rocket Sunset"),
+ //Sunken Shrine
+ new LocationRO("204236-124", "Sunken Shrine Seal - Ultra Lifeguard"),
+ new LocationRO("172268-188-172", "Sunken Shrine Seal - Waterfall Paradise"),
+ new LocationRO("-148-116-124-60", "Sunken Shrine Seal - Tabi Gauntlet"),
+ //Riviere Turquoise
+ new LocationRO("844876-284", "Riviere Turquoise Seal - Bounces and Balls"),
+ new LocationRO("460492-124-108", "Riviere Turquoise Seal - Launch of Faith"),
+ new LocationRO("-180-1483668", "Riviere Turquoise Seal - Flower Power"),
+ //Elemental Skylands
+ new LocationRO("-52-20420436", "Elemental Skylands Seal - Air Seal"),
+ new LocationRO("18361868372388", "Elemental Skylands Seal - Water Seal"),
+ new LocationRO("28602892356388", "Elemental Skylands Seal - Fire Seal"),
+ ];
+
+ private static readonly List BossLocations =
+ [
+ new LocationRO("LeafGolem"),
+ new LocationRO("Necromancer"),
+ new LocationRO("EmeraldGolem"),
+ new LocationRO("QueenOfQuills")
+ ];
+
+ private static readonly List ShopLocations =
+ [
+ new LocationRO("HP_UPGRADE_1", EItems.HEART_CONTAINER),
+ new LocationRO("ENEMY_DROP_HP", EItems.ENEMY_DROP_HP),
+ new LocationRO("DAMAGE_REDUCTION", EItems.DAMAGE_REDUCTION),
+ new LocationRO("HP_UPGRADE_2", EItems.HEART_CONTAINER),
+ new LocationRO("SHURIKEN", EItems.SHURIKEN),
+ new LocationRO("ENEMY_DROP_MANA", EItems.ENEMY_DROP_MANA),
+ new LocationRO("SHURIKEN_UPGRADE_1", EItems.SHURIKEN_UPGRADE),
+ new LocationRO("CHECKPOINT_FULL", EItems.CHECKPOINT_UPGRADE),
+ new LocationRO("POTION_FULL_HEAL_AND_HP", EItems.POTION_FULL_HEAL_AND_HP_UPGRADE),
+ new LocationRO("SHURIKEN_UPGRADE_2", EItems.SHURIKEN_UPGRADE),
+ new LocationRO("ATTACK_PROJECTILE", EItems.ATTACK_PROJECTILES),
+ new LocationRO("AIR_RECOVER", EItems.AIR_RECOVER),
+ new LocationRO("SWIM_DASH", EItems.SWIM_DASH),
+ new LocationRO("GLIDE_ATTACK", EItems.GLIDE_ATTACK),
+ new LocationRO("CHARGED_ATTACK", EItems.CHARGED_ATTACK),
+ new LocationRO("QUARBLE_DISCOUNT_50", EItems.QUARBLE_DISCOUNT_50),
+ new LocationRO("TIME_WARP", EItems.MAP_TIME_WARP),
+ new LocationRO("POWER_SEAL_WORLD_MAP", EItems.MAP_POWER_SEAL_TOTAL),
+ new LocationRO("POWER_SEAL", EItems.MAP_POWER_SEAL_PINS)
+ ];
+
+ private static readonly Dictionary SpecialNames = new()
+ {
+ { "HP_UPGRADE_1", "HP_UPGRADE_2" },
+ { "SHURIKEN_UPGRADE_1", "SHURIKEN_UPGRADE_2" },
+ };
- public static long LocationFromEItem(EItems location)
+ private static bool ShopItem(EItems item)
+ {
+ var shopItems = new List
{
- if (EItemsLocationsLookup == null)
- Initialize();
- return !EItemsLocationsLookup.TryGetValue(location, out var value) ? 0 : value;
- }
+ EItems.HEART_CONTAINER,
+ EItems.SHURIKEN,
+ EItems.SHURIKEN_UPGRADE,
+ EItems.CHECKPOINT_UPGRADE,
+ EItems.POTION_FULL_HEAL_AND_HP_UPGRADE,
+ EItems.MAP_TIME_WARP,
+ EItems.MAP_POWER_SEAL_TOTAL,
+ EItems.MAP_POWER_SEAL_PINS,
+ };
+ return shopItems.Contains(item);
+ }
+
+ public static long ItemFromEItem(EItems item)
+ {
+ return ItemsLookup.First(x => x.Value.Equals(item)).Key;
+ }
+
+ public static long LocationFromEItem(EItems location)
+ {
+ if (EItemsLocationsLookup == null)
+ Initialize();
+ return !EItemsLocationsLookup.TryGetValue(location, out var value) ? 0 : value;
+ }
- public static bool ShopLocation(long locationID, out LocationRO shopLocation)
+ public static bool ShopLocation(long locationID, out LocationRO shopLocation)
+ {
+ shopLocation = LocationFromID(locationID);
+ return ShopLocations.Contains(shopLocation);
+ }
+
+ private static LocationRO LocationFromID(long locationID)
+ {
+ return IDtoLocationsLookup[locationID];
+ }
+
+ public static bool HasDialog(long locationID)
+ {
+ Console.WriteLine($"Checking if {locationID} has associated dialog");
+ if (!IDtoLocationsLookup.ContainsKey(locationID)) return false;
+ var location = LocationFromID(locationID).PrettyLocationName;
+ try
{
- shopLocation = LocationFromID(locationID);
- return ShopLocations.Contains(shopLocation);
+ var locationEnum = (EItems)Enum.Parse(typeof(EItems), location);
+ Console.WriteLine($"{locationEnum}");
+ return DialogChanger.ItemDialogID.ContainsKey(locationEnum);
}
-
- private static LocationRO LocationFromID(long locationID)
+ catch
{
- return IDtoLocationsLookup[locationID];
+ return false;
}
+ }
- public static bool HasDialog(long locationID)
+ ///
+ /// We received an item from the server so add it to our inventory. Set the quantity to an absurd number here so we can differentiate.
+ ///
+ ///
+ ///
+ public static void Unlock(long itemToUnlock, int quantity = APQuantity)
+ {
+ if (!ItemsLookup.TryGetValue(itemToUnlock, out var randoItem) || RandoStateManager.CurrentFileSlot == 0)
{
- Console.WriteLine($"Checking if {locationID} has associated dialog");
- if (!IDtoLocationsLookup.ContainsKey(locationID)) return false;
- var location = LocationFromID(locationID).PrettyLocationName;
- try
- {
- var locationEnum = (EItems)Enum.Parse(typeof(EItems), location);
- Console.WriteLine($"{locationEnum}");
- return DialogChanger.ItemDialogID.ContainsKey(locationEnum);
- }
- catch
- {
- return false;
- }
+ Console.WriteLine($"Couldn't find {itemToUnlock} or not currently in game");
+ return;
}
+ Console.WriteLine($"Unlocking {itemToUnlock}, {randoItem.Item}");
- ///
- /// We received an item from the server so add it to our inventory. Set the quantity to an absurd number here so we can differentiate.
- ///
- ///
- ///
- public static void Unlock(long itemToUnlock, int quantity = APQuantity)
+ switch (randoItem.Item)
{
- if (!ItemsLookup.TryGetValue(itemToUnlock, out var randoItem) || RandoStateManager.CurrentFileSlot == 0)
- {
- Console.WriteLine($"Couldn't find {itemToUnlock} or not currently in game");
- return;
- }
- Console.WriteLine($"Unlocking {itemToUnlock}, {randoItem.Item}");
-
- switch (randoItem.Item)
- {
- case EItems.WINDMILL_SHURIKEN:
- var shurikenID = ItemFromEItem(EItems.SHURIKEN);
- if (!ArchipelagoClient.ServerData.ReceivedItems.ContainsKey(shurikenID))
+ case EItems.WINDMILL_SHURIKEN:
+ var shurikenID = ItemFromEItem(EItems.SHURIKEN);
+ if (!ArchipelagoClient.ServerData.ReceivedItems.ContainsKey(shurikenID))
+ {
+ Manager.Instance.AddItem(EItems.SHURIKEN, APQuantity);
+ }
+ APRandomizerMain.OnToggleWindmillShuriken();
+ break;
+ case EItems.TIME_SHARD:
+ switch (randoItem.Name)
+ {
+ case "Timeshard":
+ quantity = ArchipelagoClient.ServerData.SlotData.ContainsKey("shop") ? 1 : 100;
+ break;
+ case "Timeshard (10)":
+ quantity = 10;
+ break;
+ case "Timeshard (50)":
+ quantity = 50;
+ break;
+ case "Timeshard (100)":
+ quantity = 100;
+ break;
+ case "Timeshard (300)":
+ quantity = 300;
+ break;
+ case "Timeshard (500)":
+ quantity = 500;
+ break;
+ }
+ Console.WriteLine($"Unlocking time shards... {quantity}");
+ Manager.Instance.CollectTimeShard(quantity);
+ break;
+ case EItems.POWER_SEAL:
+ RandoStateManager.PowerSealManager.AddPowerSeal();
+ break;
+ case EItems.NONE:
+ try
+ {
+ var figurine = (EFigurine)Enum.Parse(typeof(EFigurine), randoItem.Name);
+ RandoShopManager.UnlockFigurine(figurine);
+ }
+ catch
+ {
+ if (randoItem.Name.EndsWith("Generator Shutdown"))
{
- Manager.Instance.AddItem(EItems.SHURIKEN, APQuantity);
+ SkylandsGeneratorManager.ReceiveGeneratorShutdown(randoItem.Name);
+ break;
}
- APRandomizerMain.OnToggleWindmillShuriken();
- break;
- case EItems.TIME_SHARD:
switch (randoItem.Name)
{
- case "Timeshard":
- quantity = ArchipelagoClient.ServerData.SlotData.ContainsKey("shop") ? 1 : 100;
- break;
- case "Timeshard (10)":
- quantity = 10;
- break;
- case "Timeshard (50)":
- quantity = 50;
- break;
- case "Timeshard (100)":
- quantity = 100;
+ case "Darkness Trap":
+ TrapManager.StartDarkness();
break;
- case "Timeshard (300)":
- quantity = 300;
+ case "Teleport Trap":
+ TrapManager.TryTeleportPlayer();
break;
- case "Timeshard (500)":
- quantity = 500;
+ case "Prophecy Trap":
+ TrapManager.StartProphecyCutscene();
break;
}
- Console.WriteLine($"Unlocking time shards... {quantity}");
- Manager.Instance.CollectTimeShard(quantity);
- break;
- case EItems.POWER_SEAL:
- RandoStateManager.PowerSealManager.AddPowerSeal();
- break;
- case EItems.NONE:
- try
- {
- var figurine = (EFigurine)Enum.Parse(typeof(EFigurine), randoItem.Name);
- RandoShopManager.UnlockFigurine(figurine);
- }
- catch
- {
- if (randoItem.Name.EndsWith("Generator Shutdown"))
- {
- SkylandsGeneratorManager.ReceiveGeneratorShutdown(randoItem.Name);
- break;
- }
- switch (randoItem.Name)
- {
- case "Darkness Trap":
- TrapManager.StartDarkness();
- break;
- case "Teleport Trap":
- TrapManager.TryTeleportPlayer();
- break;
- case "Prophecy Trap":
- TrapManager.StartProphecyCutscene();
- break;
- }
- }
+ }
- break;
- default:
- Console.WriteLine($"Checking if {randoItem.Item} is a shop item: {ShopItem(randoItem.Item)}");
- if (ShopItem(randoItem.Item))
+ break;
+ default:
+ Console.WriteLine($"Checking if {randoItem.Item} is a shop item: {ShopItem(randoItem.Item)}");
+ if (ShopItem(randoItem.Item))
+ {
+ // don't award shuriken twice if we already got it from windmill shuriken
+ if (randoItem.Item.Equals(EItems.SHURIKEN) &
+ ArchipelagoClient.ServerData.ReceivedItems.ContainsKey(itemToUnlock)) return;
+ if (!new List { EItems.HEART_CONTAINER, EItems.SHURIKEN_UPGRADE }.Contains(
+ randoItem.Item))
{
- // don't award shuriken twice if we already got it from windmill shuriken
- if (randoItem.Item.Equals(EItems.SHURIKEN) &
- ArchipelagoClient.ServerData.ReceivedItems.ContainsKey(itemToUnlock)) return;
- if (!new List { EItems.HEART_CONTAINER, EItems.SHURIKEN_UPGRADE }.Contains(
- randoItem.Item))
+ Console.WriteLine($"checking if {itemToUnlock} has been received already");
+ if (ArchipelagoClient.ServerData.ReceivedItems.ContainsKey(itemToUnlock))
{
- Console.WriteLine($"checking if {itemToUnlock} has been received already");
- if (ArchipelagoClient.ServerData.ReceivedItems.ContainsKey(itemToUnlock))
- {
- Console.WriteLine("bailing");
- return;
- }
+ Console.WriteLine("bailing");
+ return;
}
- else if (ArchipelagoClient.ServerData.ReceivedItems.TryGetValue(itemToUnlock, out var count) &&
- count > 1) return;
- Manager.Instance.AddItem(randoItem.Item, quantity);
- var view = Manager.Instance.GetView();
- view.UpdateMaxHeart();
- view.UpdateMaxMana();
- view.UpdateShurikenVisibility();
}
- else if (!ArchipelagoClient.ServerData.ReceivedItems.ContainsKey(itemToUnlock))
- Manager.Instance.AddItem(randoItem.Item, quantity);
- break;
- }
-
- if (ArchipelagoClient.ServerData.ReceivedItems.ContainsKey(itemToUnlock))
- ArchipelagoClient.ServerData.ReceivedItems[itemToUnlock] += 1;
- else
- ArchipelagoClient.ServerData.ReceivedItems.Add(itemToUnlock, 1);
+ else if (ArchipelagoClient.ServerData.ReceivedItems.TryGetValue(itemToUnlock, out var count) &&
+ count > 1) return;
+ Manager.Instance.AddItem(randoItem.Item, quantity);
+ var view = Manager.Instance.GetView();
+ view.UpdateMaxHeart();
+ view.UpdateMaxMana();
+ view.UpdateShurikenVisibility();
+ }
+ else if (!ArchipelagoClient.ServerData.ReceivedItems.ContainsKey(itemToUnlock))
+ Manager.Instance.AddItem(randoItem.Item, quantity);
+ break;
}
- public static bool IsLocationChecked(LocationRO location)
+ if (ArchipelagoClient.ServerData.ReceivedItems.ContainsKey(itemToUnlock))
+ ArchipelagoClient.ServerData.ReceivedItems[itemToUnlock] += 1;
+ else
+ ArchipelagoClient.ServerData.ReceivedItems.Add(itemToUnlock, 1);
+ }
+
+ public static bool IsLocationChecked(LocationRO location)
+ {
+ LocationsLookup.TryGetValue(location, out var locationID);
+ return RandomizerStateManager.HasCompletedCheck(locationID);
+ }
+
+ public static void SendLocationCheck(LocationRO checkedLocation)
+ {
+ LocationsLookup.TryGetValue(checkedLocation, out var locationID);
+ if (ArchipelagoClient.ServerData.CheckedLocations.Contains(locationID)) return;
+ try
{
- LocationsLookup.TryGetValue(location, out var locationID);
- return RandomizerStateManager.HasCompletedCheck(locationID);
+ SendLocationCheck(locationID);
}
+ catch (Exception e)
+ {
+ Console.WriteLine(e);
+ ArchipelagoClient.Disconnect();
+ }
+ }
- public static void SendLocationCheck(LocationRO checkedLocation)
+ public static void SendLocationCheck(long locationID)
+ {
+ if (!LocationsLookup.Values.Contains(locationID)) return;
+ Console.WriteLine($"Checking if we need to modify the location {locationID} before sending");
+ if (ArchipelagoClient.ServerData.CheckedLocations.Contains(locationID))
{
- LocationsLookup.TryGetValue(checkedLocation, out var locationID);
- if (ArchipelagoClient.ServerData.CheckedLocations.Contains(locationID)) return;
- try
+ var loc = LocationFromID(locationID);
+ if (SpecialNames.TryGetValue(loc.LocationName, out var name))
{
- SendLocationCheck(locationID);
- }
- catch (Exception e)
- {
- Console.WriteLine(e);
- ArchipelagoClient.Disconnect();
+ LocationsLookup.TryGetValue(new LocationRO(name,
+ (EItems)Enum.Parse(typeof(EItems), loc.PrettyLocationName)), out locationID);
}
+ else return;
}
+ ArchipelagoClient.ServerData.CheckedLocations.Add(locationID);
- public static void SendLocationCheck(long locationID)
+ Console.WriteLine("Sending location checks");
+ if (ArchipelagoClient.Authenticated)
{
- if (!LocationsLookup.Values.Contains(locationID)) return;
- Console.WriteLine($"Checking if we need to modify the location {locationID} before sending");
- if (ArchipelagoClient.ServerData.CheckedLocations.Contains(locationID))
+ ThreadPool.QueueUserWorkItem(_ =>
+ ArchipelagoClient.Session.Locations.CompleteLocationChecksAsync(null,
+ ArchipelagoClient.ServerData.CheckedLocations.ToArray()));
+ if (!RandoStateManager.ScoutedLocations.TryGetValue(locationID, out var item)) return;
+ if (!HasDialog(locationID))
{
- var loc = LocationFromID(locationID);
- if (SpecialNames.TryGetValue(loc.LocationName, out var name))
+ string dialog;
+ if (item.OwnItem())
{
- LocationsLookup.TryGetValue(new LocationRO(name,
- (EItems)Enum.Parse(typeof(EItems), loc.PrettyLocationName)), out locationID);
+ dialog = item.ToReadableString();
}
- else return;
- }
- ArchipelagoClient.ServerData.CheckedLocations.Add(locationID);
-
- Console.WriteLine("Sending location checks");
- if (ArchipelagoClient.Authenticated)
- {
- ThreadPool.QueueUserWorkItem(_ =>
- ArchipelagoClient.Session.Locations.CompleteLocationChecksAsync(null,
- ArchipelagoClient.ServerData.CheckedLocations.ToArray()));
- if (!RandoStateManager.ScoutedLocations.TryGetValue(locationID, out var item)) return;
- if (!HasDialog(locationID))
+ else
{
- string dialog;
- if (item.OwnItem())
- {
- dialog = item.ToReadableString();
- }
- else
- {
- var otherPlayer = ArchipelagoClient.Session.Players.GetPlayerAlias(item.Player);
- dialog = item.ToReadableString(otherPlayer);
- }
- if (RandomizerStateManager.IsSafeTeleportState())
- DialogChanger.CreateDialogBox(dialog);
- else
- ArchipelagoClient.DialogQueue.Enqueue(dialog);
+ var otherPlayer = ArchipelagoClient.Session.Players.GetPlayerAlias(item.Player);
+ dialog = item.ToReadableString(otherPlayer);
}
- }
- else if (ArchipelagoClient.Offline)
- {
- var itemToUnlock = ArchipelagoClient.ServerData.LocationData[locationID].First().Value[0];
if (RandomizerStateManager.IsSafeTeleportState())
- Unlock(itemToUnlock);
+ DialogChanger.CreateDialogBox(dialog);
else
- ArchipelagoClient.ItemQueue.Enqueue(itemToUnlock);
-
- if (!HasDialog(locationID))
- {
- var dialog = SeedGenerator.GetOfflineDialog(locationID);
- if (RandomizerStateManager.IsSafeTeleportState())
- DialogChanger.CreateDialogBox(dialog);
- else
- ArchipelagoClient.DialogQueue.Enqueue(dialog);
- }
+ ArchipelagoClient.DialogQueue.Enqueue(dialog);
}
- Manager.Instance.SaveGame();
}
-
- public static void UnlockItems()
+ else if (ArchipelagoClient.Offline)
{
- while (ArchipelagoClient.ServerData.Index < ArchipelagoClient.Session.Items.AllItemsReceived.Count)
+ var itemToUnlock = ArchipelagoClient.ServerData.LocationData[locationID].First().Value[0];
+ if (RandomizerStateManager.IsSafeTeleportState())
+ Unlock(itemToUnlock);
+ else
+ ArchipelagoClient.ItemQueue.Enqueue(itemToUnlock);
+
+ if (!HasDialog(locationID))
{
- var item = ArchipelagoClient.Session.Items.AllItemsReceived[ArchipelagoClient.ServerData.Index++];
- Unlock(item.ItemId);
- if (item.Player.Slot != ArchipelagoClient.Session.ConnectionInfo.Slot)
- ArchipelagoClient.DialogQueue.Enqueue(item.ToReadableString());
+ var dialog = SeedGenerator.GetOfflineDialog(locationID);
+ if (RandomizerStateManager.IsSafeTeleportState())
+ DialogChanger.CreateDialogBox(dialog);
+ else
+ ArchipelagoClient.DialogQueue.Enqueue(dialog);
}
-
- Synced = false;
}
+ Manager.Instance.SaveGame();
+ }
- public static void ReSync()
+ public static void UnlockItems()
+ {
+ while (ArchipelagoClient.ServerData.Index < ArchipelagoClient.Session.Items.AllItemsReceived.Count)
{
- Synced = true;
- ArchipelagoClient.SyncEvents();
- TrackerManager.ReconciliateUnlockedPortals();
+ var item = ArchipelagoClient.Session.Items.AllItemsReceived[ArchipelagoClient.ServerData.Index++];
+ Unlock(item.ItemId);
+ if (item.Player.Slot != ArchipelagoClient.Session.ConnectionInfo.Slot)
+ ArchipelagoClient.DialogQueue.Enqueue(item.ToReadableString());
+ }
- var receivedItems = new Dictionary();
+ Synced = false;
+ }
- for (int i = 0; i < ArchipelagoClient.ServerData.Index; i++)
- {
- var itemToUnlock = ArchipelagoClient.Session.Items.AllItemsReceived[i];
- var currentItem = itemToUnlock.ItemId;
- if (!receivedItems.ContainsKey(currentItem)) receivedItems.Add(currentItem, 1);
- else receivedItems[currentItem] += 1;
- if (ArchipelagoClient.ServerData.ReceivedItems.ContainsKey(currentItem) &&
- ArchipelagoClient.ServerData.ReceivedItems[currentItem] >= receivedItems[currentItem]) continue;
- Console.WriteLine($"Determined {currentItem} missing while resyncing.");
- Unlock(currentItem);
- if (itemToUnlock.OwnItem() &&
- HasDialog(itemToUnlock.LocationId))
- continue;
- ArchipelagoClient.DialogQueue.Enqueue(itemToUnlock.ToReadableString());
- }
+ public static void ReSync()
+ {
+ Synced = true;
+ ArchipelagoClient.SyncEvents();
+ TrackerManager.ReconciliateUnlockedPortals();
+
+ var receivedItems = new Dictionary();
+
+ for (int i = 0; i < ArchipelagoClient.ServerData.Index; i++)
+ {
+ var itemToUnlock = ArchipelagoClient.Session.Items.AllItemsReceived[i];
+ var currentItem = itemToUnlock.ItemId;
+ if (!receivedItems.ContainsKey(currentItem)) receivedItems.Add(currentItem, 1);
+ else receivedItems[currentItem] += 1;
+ if (ArchipelagoClient.ServerData.ReceivedItems.ContainsKey(currentItem) &&
+ ArchipelagoClient.ServerData.ReceivedItems[currentItem] >= receivedItems[currentItem]) continue;
+ Console.WriteLine($"Determined {currentItem} missing while resyncing.");
+ Unlock(currentItem);
+ if (itemToUnlock.OwnItem() &&
+ HasDialog(itemToUnlock.LocationId))
+ continue;
+ ArchipelagoClient.DialogQueue.Enqueue(itemToUnlock.ToReadableString());
}
}
}
diff --git a/Archipelago/TrackerManager.cs b/Archipelago/TrackerManager.cs
index 4dce507..edeedd6 100644
--- a/Archipelago/TrackerManager.cs
+++ b/Archipelago/TrackerManager.cs
@@ -4,41 +4,40 @@
using Archipelago.MultiClient.Net.Enums;
using MessengerRando.GameOverrideManagers;
-namespace MessengerRando.Archipelago
+namespace MessengerRando.Archipelago;
+
+public class TrackerManager
{
- public class TrackerManager
- {
- private List VisitedEntrances = [];
+ private List VisitedEntrances = [];
- public void AddVisitedEntrance(string entrance)
- {
- if (VisitedEntrances.Contains(entrance)) return;
+ public void AddVisitedEntrance(string entrance)
+ {
+ if (VisitedEntrances.Contains(entrance)) return;
- if (!ArchipelagoClient.Authenticated) return;
- VisitedEntrances = ArchipelagoClient.Session.DataStorage[Scope.Slot, "VisitedEntrances"].To>() ?? [];
- if (VisitedEntrances.Contains(entrance)) return;
+ if (!ArchipelagoClient.Authenticated) return;
+ VisitedEntrances = ArchipelagoClient.Session.DataStorage[Scope.Slot, "VisitedEntrances"].To>() ?? [];
+ if (VisitedEntrances.Contains(entrance)) return;
- Console.WriteLine("Adding visited entrance: " + entrance);
- VisitedEntrances.Add(entrance);
- VisitedEntrances.Sort();
- ArchipelagoClient.Session.DataStorage[Scope.Slot, "VisitedEntrances"] = VisitedEntrances;
+ Console.WriteLine("Adding visited entrance: " + entrance);
+ VisitedEntrances.Add(entrance);
+ VisitedEntrances.Sort();
+ ArchipelagoClient.Session.DataStorage[Scope.Slot, "VisitedEntrances"] = VisitedEntrances;
- return;
- }
+ return;
+ }
- public void ReconciliateUnlockedPortals()
- {
- if (!ArchipelagoClient.Authenticated) return;
+ public void ReconciliateUnlockedPortals()
+ {
+ if (!ArchipelagoClient.Authenticated) return;
- var unlockedPortals = RandoPortalManager.UnlockedPortals;
- unlockedPortals.UnionWith(ArchipelagoClient.Session.DataStorage[Scope.Slot, "UnlockedPortals"].To>() ?? []);
+ var unlockedPortals = RandoPortalManager.UnlockedPortals;
+ unlockedPortals.UnionWith(ArchipelagoClient.Session.DataStorage[Scope.Slot, "UnlockedPortals"].To>() ?? []);
- var unlockedPortalsList = unlockedPortals.ToList();
- unlockedPortalsList.Sort();
- Console.WriteLine($"Updating unlocked portals with Data Storage. Unlocked portals are\n\t{string.Join("\n\t", [.. unlockedPortalsList])}");
- ArchipelagoClient.Session.DataStorage[Scope.Slot, "UnlockedPortals"] = unlockedPortalsList;
- }
+ var unlockedPortalsList = unlockedPortals.ToList();
+ unlockedPortalsList.Sort();
+ Console.WriteLine($"Updating unlocked portals with Data Storage. Unlocked portals are\n\t{string.Join("\n\t", [.. unlockedPortalsList])}");
+ ArchipelagoClient.Session.DataStorage[Scope.Slot, "UnlockedPortals"] = unlockedPortalsList;
}
}
diff --git a/Exceptions/RandomizerException.cs b/Exceptions/RandomizerException.cs
index f33fcc5..44f86c1 100644
--- a/Exceptions/RandomizerException.cs
+++ b/Exceptions/RandomizerException.cs
@@ -1,27 +1,26 @@
using System;
using System.Runtime.Serialization;
-namespace MessengerRando.Exceptions
+namespace MessengerRando.Exceptions;
+
+///
+/// Empty rando exception class used to keep track of errors
+///
+public class RandomizerException : Exception
{
- ///
- /// Empty rando exception class used to keep track of errors
- ///
- public class RandomizerException : Exception
+ public RandomizerException()
{
- public RandomizerException()
- {
- }
+ }
- public RandomizerException(string message) : base(message)
- {
- }
+ public RandomizerException(string message) : base(message)
+ {
+ }
- public RandomizerException(string message, Exception innerException) : base(message, innerException)
- {
- }
+ public RandomizerException(string message, Exception innerException) : base(message, innerException)
+ {
+ }
- protected RandomizerException(SerializationInfo info, StreamingContext context) : base(info, context)
- {
- }
+ protected RandomizerException(SerializationInfo info, StreamingContext context) : base(info, context)
+ {
}
}
diff --git a/GameOverrideManagers/FlavorDialogManager.cs b/GameOverrideManagers/FlavorDialogManager.cs
index b863a83..fbd4145 100644
--- a/GameOverrideManagers/FlavorDialogManager.cs
+++ b/GameOverrideManagers/FlavorDialogManager.cs
@@ -1,153 +1,152 @@
using System.Collections.Generic;
using MessengerRando.Utils;
-namespace MessengerRando.GameOverrideManagers
+namespace MessengerRando.GameOverrideManagers;
+
+public static class FlavorDialogManager
{
- public static class FlavorDialogManager
+ private struct DialogBox
{
- private struct DialogBox
- {
- public string Text;
- public CharacterDefinition Speaker;
- public int Delay;
+ public string Text;
+ public CharacterDefinition Speaker;
+ public int Delay;
- public DialogBox(string text, ECharacter speaker, int delay)
- {
- Text = text;
- Speaker = Manager.Instance.GetCharacterDefinition(speaker);
- Delay = delay;
- }
+ public DialogBox(string text, ECharacter speaker, int delay)
+ {
+ Text = text;
+ Speaker = Manager.Instance.GetCharacterDefinition(speaker);
+ Delay = delay;
}
+ }
- public static CharacterDefinition ProphetDefinition;
- public static CharacterDefinition MessengerDefinition;
+ public static CharacterDefinition ProphetDefinition;
+ public static CharacterDefinition MessengerDefinition;
- static List ModifyDialogInfo(string locID, List infoToReplace)
+ static List ModifyDialogInfo(string locID, List infoToReplace)
+ {
+ switch (locID)
{
- switch (locID)
- {
- case "PROPHET_HEY":
- var prophetHey = infoToReplace[0];
- prophetHey.text =
- ProphetHeyReplacements[RandomizerStateManager.SeedRandom.Next(ProphetHeyReplacements.Count)];
- prophetHey.skippable = false;
- break;
- case "PROPHET_INTRO_3":
- ProphetDefinition = infoToReplace[0].characterDefinition;
- MessengerDefinition = infoToReplace[1].characterDefinition;
- var newText =
- ProphetIntroReplacements[
- RandomizerStateManager.SeedRandom.Next(ProphetIntroReplacements.Count)];
- // var toRemove = 0;
- var newInfoList = new List();
- foreach (var kvp in newText)
+ case "PROPHET_HEY":
+ var prophetHey = infoToReplace[0];
+ prophetHey.text =
+ ProphetHeyReplacements[RandomizerStateManager.SeedRandom.Next(ProphetHeyReplacements.Count)];
+ prophetHey.skippable = false;
+ break;
+ case "PROPHET_INTRO_3":
+ ProphetDefinition = infoToReplace[0].characterDefinition;
+ MessengerDefinition = infoToReplace[1].characterDefinition;
+ var newText =
+ ProphetIntroReplacements[
+ RandomizerStateManager.SeedRandom.Next(ProphetIntroReplacements.Count)];
+ // var toRemove = 0;
+ var newInfoList = new List();
+ foreach (var kvp in newText)
+ {
+ CharacterDefinition replaceChar;
+ switch (kvp.Value)
{
- CharacterDefinition replaceChar;
- switch (kvp.Value)
- {
- case "Prophet":
- replaceChar = ProphetDefinition;
- break;
- case "Messenger":
- replaceChar = MessengerDefinition;
- break;
- default:
- replaceChar = ProphetDefinition;
- break;
- }
-
- var newInfo = new DialogInfo
- {
- text = kvp.Key,
- textID = "PROPHET_INTRO_3",
- characterDefinition = replaceChar,
- skippable = false,
- autoClose = true,
- };
- newInfoList.Add(newInfo);
+ case "Prophet":
+ replaceChar = ProphetDefinition;
+ break;
+ case "Messenger":
+ replaceChar = MessengerDefinition;
+ break;
+ default:
+ replaceChar = ProphetDefinition;
+ break;
}
- newInfoList[newInfoList.Count - 1].autoCloseDelay = 2.0f;
- infoToReplace = newInfoList;
- break;
- }
+ var newInfo = new DialogInfo
+ {
+ text = kvp.Key,
+ textID = "PROPHET_INTRO_3",
+ characterDefinition = replaceChar,
+ skippable = false,
+ autoClose = true,
+ };
+ newInfoList.Add(newInfo);
+ }
+ newInfoList[newInfoList.Count - 1].autoCloseDelay = 2.0f;
- return infoToReplace;
+ infoToReplace = newInfoList;
+ break;
}
- public static void UpdateLoc(Dictionary> loc)
+ return infoToReplace;
+ }
+
+ public static void UpdateLoc(Dictionary> loc)
+ {
+ foreach (var textID in DialogToReplace)
{
- foreach (var textID in DialogToReplace)
- {
- loc[textID] = ModifyDialogInfo(textID, loc[textID]);
- }
+ loc[textID] = ModifyDialogInfo(textID, loc[textID]);
}
+ }
- static readonly List DialogToReplace = new List
- {
- "PROPHET_HEY",
- "PROPHET_INTRO_3",
- };
+ static readonly List DialogToReplace = new List
+ {
+ "PROPHET_HEY",
+ "PROPHET_INTRO_3",
+ };
- static readonly List ProphetHeyReplacements = new List
- {
- "You have been randomized.",
- "Echo!",
- "Shoutouts to Simpleflips.",
- };
+ static readonly List ProphetHeyReplacements = new List
+ {
+ "You have been randomized.",
+ "Echo!",
+ "Shoutouts to Simpleflips.",
+ };
- static readonly List> ProphetIntroReplacements = new List>
+ static readonly List> ProphetIntroReplacements = new List>
+ {
+ new Dictionary
{
- new Dictionary
- {
- { "Do you have any extra die?", "Prophet" },
- { "What? I have Quarble I guess.", "Messenger" },
- { "No, like for rolling. I haven't been able to find mine.", "Prophet" },
- { "For what?", "Messenger" },
- { "Well I figure I'll have to make a perception check at some point with all these texts.", "Prophet" },
- { "...", "Messenger" },
- { "Can you at least have a look around to see if you can find them?", "Prophet" },
- { "Sure.", "Messenger" },
- {
- "*ahem* BEHOLD, and may you see success on your journey oh yee valiant Messenger.",
- "Prophet"
- },
- { "Uh. Right. Thanks.", "Messenger" },
- },
- new Dictionary
- {
- { "I don't think we're in Kansas anymore.", "Prophet" },
- { "And I forgot my red shoes.", "Messenger" },
- },
- new Dictionary
+ { "Do you have any extra die?", "Prophet" },
+ { "What? I have Quarble I guess.", "Messenger" },
+ { "No, like for rolling. I haven't been able to find mine.", "Prophet" },
+ { "For what?", "Messenger" },
+ { "Well I figure I'll have to make a perception check at some point with all these texts.", "Prophet" },
+ { "...", "Messenger" },
+ { "Can you at least have a look around to see if you can find them?", "Prophet" },
+ { "Sure.", "Messenger" },
{
- { "Do you ever think about what we're doing here?", "Prophet" },
- { "Something about this Music Box thing, right?", "Messenger" },
- { "Nevermind. *ahem* AND THUS THE WHEEL OF TIME CONTINUED TO TURN.", "Prophet" },
- {
- "AND ALL THOSE WITHIN CONTINUED UNABATED, UNRELENTING ALONG THE CHARIOT OF THEIR ULTIMATE DESTINY.",
- "Prophet"
- },
- { "...", "Messenger" },
- { "Look just go find the things, ok?", "Prophet" },
- { "...Right.", "Messenger" },
+ "*ahem* BEHOLD, and may you see success on your journey oh yee valiant Messenger.",
+ "Prophet"
},
- new Dictionary
+ { "Uh. Right. Thanks.", "Messenger" },
+ },
+ new Dictionary
+ {
+ { "I don't think we're in Kansas anymore.", "Prophet" },
+ { "And I forgot my red shoes.", "Messenger" },
+ },
+ new Dictionary
+ {
+ { "Do you ever think about what we're doing here?", "Prophet" },
+ { "Something about this Music Box thing, right?", "Messenger" },
+ { "Nevermind. *ahem* AND THUS THE WHEEL OF TIME CONTINUED TO TURN.", "Prophet" },
{
- { "I could really go for a pizza right now.", "Prophet" },
- { "Get me anchovies.", "Messenger" },
+ "AND ALL THOSE WITHIN CONTINUED UNABATED, UNRELENTING ALONG THE CHARIOT OF THEIR ULTIMATE DESTINY.",
+ "Prophet"
},
- new Dictionary
- {
- { "Welcome, young Messenger", "Prophet" },
- { "Who are you?" , "Messenger" },
- { "I am your sister's cousin's father's brother's dog's veterinarian's nephew's parole officer's " +
- "evil twin's best friend's long lost roommate's third favorite singer's tax consultant's " +
- "chef's architect's dungeon master", "Prophet" },
- { "And what does that make us?", "Messenger" },
- { "-CHARACTER LIMIT EXCEEDED-", "Prophet" },
- { "OVERFLOW ERROR", "Prophet" },
- }
- };
- }
+ { "...", "Messenger" },
+ { "Look just go find the things, ok?", "Prophet" },
+ { "...Right.", "Messenger" },
+ },
+ new Dictionary
+ {
+ { "I could really go for a pizza right now.", "Prophet" },
+ { "Get me anchovies.", "Messenger" },
+ },
+ new Dictionary
+ {
+ { "Welcome, young Messenger", "Prophet" },
+ { "Who are you?" , "Messenger" },
+ { "I am your sister's cousin's father's brother's dog's veterinarian's nephew's parole officer's " +
+ "evil twin's best friend's long lost roommate's third favorite singer's tax consultant's " +
+ "chef's architect's dungeon master", "Prophet" },
+ { "And what does that make us?", "Messenger" },
+ { "-CHARACTER LIMIT EXCEEDED-", "Prophet" },
+ { "OVERFLOW ERROR", "Prophet" },
+ }
+ };
}
\ No newline at end of file
diff --git a/GameOverrideManagers/LostWoodsManager.cs b/GameOverrideManagers/LostWoodsManager.cs
index 0feef12..017a325 100644
--- a/GameOverrideManagers/LostWoodsManager.cs
+++ b/GameOverrideManagers/LostWoodsManager.cs
@@ -2,46 +2,45 @@
using System.Reflection;
using Object = UnityEngine.Object;
-namespace MessengerRando.GameOverrideManagers
+namespace MessengerRando.GameOverrideManagers;
+
+public static class LostWoodsManager
{
- public static class LostWoodsManager
- {
- public static bool ShouldBeSolved;
- public static bool NeedsSolved;
- private static bool tempSolve;
- public static bool NeedsUnsolved;
+ public static bool ShouldBeSolved;
+ public static bool NeedsSolved;
+ private static bool tempSolve;
+ public static bool NeedsUnsolved;
- public static void OnSetAsSolved(On.LostWoods.orig_SetAsSolved orig, LostWoods self)
+ public static void OnSetAsSolved(On.LostWoods.orig_SetAsSolved orig, LostWoods self)
+ {
+ // if (ShouldBeSolved || tempSolve)
+ orig(self);
+ }
+ public static void SolveLostWoods()
+ {
+ tempSolve = true;
+ NeedsUnsolved = !ShouldBeSolved;
+ try
{
- // if (ShouldBeSolved || tempSolve)
- orig(self);
+ LostWoods.Instance.SetAsSolved();
+ tempSolve = NeedsSolved = false;
}
- public static void SolveLostWoods()
+ catch (Exception e)
{
- tempSolve = true;
- NeedsUnsolved = !ShouldBeSolved;
- try
- {
- LostWoods.Instance.SetAsSolved();
- tempSolve = NeedsSolved = false;
- }
- catch (Exception e)
- {
- Console.WriteLine(e);
- NeedsSolved = ShouldBeSolved;
- tempSolve = false;
- }
+ Console.WriteLine(e);
+ NeedsSolved = ShouldBeSolved;
+ tempSolve = false;
}
+ }
- public static void UnsolveLostWoods()
+ public static void UnsolveLostWoods()
+ {
+ var lostWoodsSolved =
+ typeof(LostWoods).GetField("solved", BindingFlags.NonPublic | BindingFlags.Instance);
+ if (lostWoodsSolved != null)
{
- var lostWoodsSolved =
- typeof(LostWoods).GetField("solved", BindingFlags.NonPublic | BindingFlags.Instance);
- if (lostWoodsSolved != null)
- {
- lostWoodsSolved.SetValue(Object.FindObjectsOfType(), true);
- NeedsUnsolved = false;
- }
+ lostWoodsSolved.SetValue(Object.FindObjectsOfType(), true);
+ NeedsUnsolved = false;
}
}
}
\ No newline at end of file
diff --git a/GameOverrideManagers/RandoBossManager.cs b/GameOverrideManagers/RandoBossManager.cs
index a353f02..26a5727 100644
--- a/GameOverrideManagers/RandoBossManager.cs
+++ b/GameOverrideManagers/RandoBossManager.cs
@@ -8,256 +8,255 @@
using Object = UnityEngine.Object;
// ReSharper disable StringLiteralTypo
-namespace MessengerRando.GameOverrideManagers
+namespace MessengerRando.GameOverrideManagers;
+
+public abstract class RandoBossManager
{
- public abstract class RandoBossManager
- {
- public static List DefeatedBosses = [];
+ public static List DefeatedBosses = [];
- private readonly Dictionary origToNewBoss;
- private static bool bossOverride;
+ private readonly Dictionary origToNewBoss;
+ private static bool bossOverride;
- private struct BossLocation
- {
- public readonly ELevel BossRegion;
- public readonly Vector2 PlayerPosition;
- public readonly EBits PlayerDimension;
+ private struct BossLocation
+ {
+ public readonly ELevel BossRegion;
+ public readonly Vector2 PlayerPosition;
+ public readonly EBits PlayerDimension;
- public BossLocation(ELevel area, Vector2 pos, EBits dim)
- {
- BossRegion = area;
- PlayerPosition = pos;
- PlayerDimension = dim;
- }
+ public BossLocation(ELevel area, Vector2 pos, EBits dim)
+ {
+ BossRegion = area;
+ PlayerPosition = pos;
+ PlayerDimension = dim;
}
+ }
- private static readonly List VanillaBossNames = new List
- {
- "LeafGolem",
- "Necromancer",
- "EmeraldGolem",
- "QueenOfQuills",
- // "Colos_Susses",
- "Manfred",
- // "TowerGolem",
- "DemonGeneral",
- "DemonArtificier",
- "ButterflyMatriarch",
- "ClockworkConcierge",
- "Phantom"
- };
-
- private static readonly Dictionary IDToBossMap = new Dictionary
- {
- { 11391075, "LeafGolem" },
- { 11391076, "Necromancer" },
- { 11391077, "EmeraldGolem" },
- { 11391078, "QueenOfQuills" },
- };
+ private static readonly List VanillaBossNames = new List
+ {
+ "LeafGolem",
+ "Necromancer",
+ "EmeraldGolem",
+ "QueenOfQuills",
+ // "Colos_Susses",
+ "Manfred",
+ // "TowerGolem",
+ "DemonGeneral",
+ "DemonArtificier",
+ "ButterflyMatriarch",
+ "ClockworkConcierge",
+ "Phantom"
+ };
- public static readonly Dictionary BossCutscenes = new Dictionary
- {
- { "LeafGolem", "LeafGolemIntroCutscene" },
- { "Necromancer", "NecromancerIntroCutscene" },
- { "EmeraldGolem", "EmeraldGolemIntroCutscene" },
- { "QueenOfQuills", "QueenOfQuillsIntroCutscene" },
- // {"Colos_Susses", },
- { "Manfred", "ManfredIntroCutscene" },
- // {"TowerGolem", },
- { "DemonGeneral", "DemonGeneralIntroCutscene" },
- { "DemonArtificier", "DemonArtificierIntroCutscene" },
- { "ButterflyMatriarch", "ButterflyMatriarchIntroCutscene" },
- { "Phantom", "PhantomIntroCutscene" }
- };
+ private static readonly Dictionary IDToBossMap = new Dictionary
+ {
+ { 11391075, "LeafGolem" },
+ { 11391076, "Necromancer" },
+ { 11391077, "EmeraldGolem" },
+ { 11391078, "QueenOfQuills" },
+ };
- private static readonly Dictionary RoomToVanillaBoss = new Dictionary
- {
- { "908940-28-12", "LeafGolem" },
- { "748780-76-60", "Necromancer" },
- { "556588-140-60", "EmeraldGolem" },
- { "11001132-44-28", "QueenOfQuills" },
- { "332364308324", "Colos_Susses" },
- { "11641228-28-12", "Manfred" },
- // { "108140228244", "TowerGolem" },
- { "140172-44-28", "DemonGeneral" },
- { "396428-12436", "DemonArtificier" },
- { "-308-276420", "ButterflyMatriarch" }
- };
+ public static readonly Dictionary BossCutscenes = new Dictionary