Decompiled source of Sail a dex v1.5.7
Sail-a-dex\Sail-a-dex.dll
Decompiled 2 weeks ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using ModSaveBackups; using UnityEngine; using UnityEngine.Networking; using UnityEngine.Rendering; using cakeslice; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("Sail-a-dex")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("raddude")] [assembly: AssemblyProduct("Sail-a-dex")] [assembly: AssemblyCopyright("Copyright © 2025")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("165a01b3-48da-400d-a25f-d6d01b2b3120")] [assembly: AssemblyFileVersion("1.5.7.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.5.7.0")] [module: UnverifiableCode] namespace sailadex; internal class PassageDude { public class FerryTravelPatches { [HarmonyPostfix] public static void TeleportPlayerPatch() { if (Configs.statsUIEnabled.Value) { StatsUI.Instance.PlayerTeleported(); } } } public static void PatchMod() { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Expected O, but got Unknown Type type = AccessTools.TypeByName("FerryTravel"); MethodInfo methodInfo = AccessTools.Method(type, "TeleportPlayer", (Type[])null, (Type[])null); MethodInfo methodInfo2 = AccessTools.Method(typeof(FerryTravelPatches), "TeleportPlayerPatch", (Type[])null, (Type[])null); SAD_Plugin.HarmonyInstance.Patch((MethodBase)methodInfo, new HarmonyMethod(methodInfo2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } } internal class RandomEncounters { public class EncounterGeneratorPatches { [HarmonyPostfix] public static void FlotsamCountPatch() { if (IsFlotsamEnabled) { StatsUI.Instance.IncrementIntStat("FlotsamEncounters"); } } [HarmonyPostfix] public static void DenseFogCountPatch() { if (IsDenseFogEnabled) { StatsUI.Instance.IncrementIntStat("DenseFogEncounters"); } } [HarmonyPostfix] public static void SeaLifeCountPatch() { if (IsSeaLifeModEnabled) { StatsUI.Instance.IncrementIntStat("SeaLifeEncounters"); } } [HarmonyPostfix] public static void FishingBonanzaCountPatch() { if (IsFishingBonanzaEnabled) { StatsUI.Instance.IncrementIntStat("FishingBonanzaEnc"); } } [HarmonyPostfix] public static void IntenseStormCountPatch() { if (IsIntenseStormEnabled) { StatsUI.Instance.IncrementIntStat("IntenseStormEnc"); } } } internal static bool IsSeaLifeModEnabled { get { BaseUnityPlugin privateField = SAD_Plugin.RE_PluginInstance.GetPrivateField<BaseUnityPlugin>("seaLifeModInstance"); ConfigEntry<bool> privateField2 = SAD_Plugin.RE_PluginInstance.GetPrivateField<ConfigEntry<bool>>("controlSeaLifeMod"); if (privateField2 != null) { return (Object)(object)privateField != (Object)null && privateField2.Value; } return SAD_Plugin.RE_PluginInstance.GetPrivateProperty<bool>("IsSeaLifeModEnabled"); } } internal static bool IsFlotsamEnabled { get { if (SAD_Plugin.RE_PluginInstance.GetPrivateField<ConfigEntry<bool>>("enableFlotsam") != null) { return SAD_Plugin.RE_PluginInstance.GetPrivateField<ConfigEntry<bool>>("enableFlotsam").Value; } return SAD_Plugin.RE_PluginInstance.GetPrivateProperty<bool>("IsFlotsamEnabled"); } } internal static bool IsDenseFogEnabled { get { if (SAD_Plugin.RE_PluginInstance.GetPrivateField<ConfigEntry<bool>>("enableDenseFog") != null) { return SAD_Plugin.RE_PluginInstance.GetPrivateField<ConfigEntry<bool>>("enableDenseFog").Value; } return SAD_Plugin.RE_PluginInstance.GetPrivateProperty<bool>("IsDenseFogEnabled"); } } internal static bool IsFishingBonanzaEnabled { get { if (SAD_Plugin.RE_PluginInstance.GetPrivateField<ConfigEntry<bool>>("enableFishingBonanza") != null) { return SAD_Plugin.RE_PluginInstance.GetPrivateField<ConfigEntry<bool>>("enableFishingBonanza").Value; } return SAD_Plugin.RE_PluginInstance.GetPrivateProperty<bool>("IsFishingBonanzaEnabled"); } } internal static bool IsIntenseStormEnabled { get { if (SAD_Plugin.RE_PluginInstance.GetPrivateField<ConfigEntry<bool>>("enableIntenseStorm") != null) { return SAD_Plugin.RE_PluginInstance.GetPrivateField<ConfigEntry<bool>>("enableIntenseStorm").Value; } return SAD_Plugin.RE_PluginInstance.GetPrivateProperty<bool>("IsIntenseStormEnabled"); } } public static void PatchMod() { //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Expected O, but got Unknown Type type = AccessTools.TypeByName("EncounterGenerator"); (string, string)[] array = new(string, string)[5] { ("GenerateFlotsam", "FlotsamCountPatch"), ("GenerateDenseFog", "DenseFogCountPatch"), ("GenerateWhales", "SeaLifeCountPatch"), ("GenerateFishingBonanza", "FishingBonanzaCountPatch"), ("GenerateIntenseStorm", "IntenseStormCountPatch") }; (string, string)[] array2 = array; for (int i = 0; i < array2.Length; i++) { (string, string) tuple = array2[i]; string item = tuple.Item1; string item2 = tuple.Item2; MethodInfo methodInfo = AccessTools.Method(type, item, (Type[])null, (Type[])null); if (methodInfo == null && item.Equals("GenerateWhales")) { methodInfo = AccessTools.Method(type, "GenerateWhale", (Type[])null, (Type[])null); } MethodInfo methodInfo2 = AccessTools.Method(typeof(EncounterGeneratorPatches), item2, (Type[])null, (Type[])null); SAD_Plugin.HarmonyInstance.Patch((MethodBase)methodInfo, new HarmonyMethod(methodInfo2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } } } internal class EventPatches { [HarmonyPatch(typeof(FishingRodFish))] private class FishingRodFishPatches { [HarmonyPrefix] [HarmonyPatch("CollectFish")] public static void CollectFishPatch(GameObject ___currentFish) { if (Configs.fishCaughtUIEnabled.Value) { FishCaughtUI.Instance.RegisterCatch(___currentFish); } } } [HarmonyPatch(typeof(IslandMarketWarehouseArea))] private class IslandMarketWarehouseAreaPatches { [HarmonyPostfix] [HarmonyPatch("OnTriggerEnter")] public static void OnTriggerEnterPatch(IslandMarket ___market, Collider other) { if (Configs.portsVisitedUIEnabled.Value && ((Component)other).CompareTag("Player")) { PortsVisitedUI.Instance.RegisterVisit(___market.GetPortName()); } if (Configs.statsUIEnabled.Value && ((Component)other).CompareTag("Player")) { StatsUI.Instance.IncrementPortVisited(___market.GetPortName()); } } } [HarmonyPatch(typeof(ShipItem))] private class ShipItemPatches { [HarmonyPostfix] [HarmonyPatch("EnterBoat")] public static void EnterBoatPatch() { if (Configs.statsUIEnabled.Value && GameState.playing) { StatsUI.Instance.RegisterCurrentMass(); } } [HarmonyPostfix] [HarmonyPatch("ExitBoat")] public static void ExitBoatPatch() { if (Configs.statsUIEnabled.Value && GameState.playing) { StatsUI.Instance.RegisterCurrentMass(); } } } [HarmonyPatch(typeof(PickupableBoatMooringRope))] private class PickupableBoatMooringRopePatches { [HarmonyPrefix] [HarmonyPatch("OnPickup")] public static void OnPickupPrePatch(Rigidbody ___boatRigidbody, out string __state) { __state = (from r in ((Component)___boatRigidbody).gameObject.GetComponent<BoatMooringRopes>().ropes where (Object)(object)r.GetPrivateField<SpringJoint>("mooredToSpring") != (Object)null select ((Object)((Component)r.GetPrivateField<SpringJoint>("mooredToSpring")).transform.parent).name).FirstOrDefault(); } [HarmonyPostfix] [HarmonyPatch("OnPickup")] public static void OnPickupPatch(Rigidbody ___boatRigidbody, string __state) { if (Configs.statsUIEnabled.Value && !GameState.currentlyLoading && GameState.playing && !((Component)___boatRigidbody).gameObject.GetComponent<BoatMooringRopes>().AnyRopeMoored()) { SAD_Plugin.LogDebug($"Unmoor from {__state} Day: {GameState.day} Time: {Sun.sun.globalTime}"); StatsUI.Instance.RegisterUnderway(__state); } } [HarmonyPostfix] [HarmonyPatch("MoorTo")] public static void MoorToPatch(Rigidbody ___boatRigidbody) { if (!Configs.statsUIEnabled.Value || GameState.currentlyLoading || !GameState.playing) { return; } if (!((Object)(object)((Component)___boatRigidbody).transform == (Object)(object)GameState.lastBoat)) { Transform transform = ((Component)___boatRigidbody).transform; Transform currentBoat = GameState.currentBoat; if (!((Object)(object)transform == (Object)(object)((currentBoat != null) ? currentBoat.parent : null))) { return; } } if (((Component)___boatRigidbody).gameObject.GetComponent<BoatMooringRopes>().AnyRopeMoored()) { string text = (from r in ((Component)___boatRigidbody).gameObject.GetComponent<BoatMooringRopes>().ropes where (Object)(object)r.GetPrivateField<SpringJoint>("mooredToSpring") != (Object)null select ((Object)((Component)r.GetPrivateField<SpringJoint>("mooredToSpring")).transform.parent).name).FirstOrDefault(); SAD_Plugin.LogDebug($"Moored at: {text} Day: {GameState.day} Time: {Sun.sun.globalTime} "); StatsUI.Instance.RegisterMoored(text); StatsUI.Instance.UpdateMilesText(); } } } [HarmonyPatch(typeof(ShipItemBottle))] private class ShipItemBottlePatches { [HarmonyPostfix] [HarmonyPatch("Drink")] public static void DrinkPatch(float ___health) { if (Configs.statsUIEnabled.Value && ___health > 0f) { StatsUI.Instance.IncrementIntStat("DrinksTaken"); } } } [HarmonyPatch(typeof(ShipItemFood))] private class ShipItemFoodPatches { [HarmonyPrefix] [HarmonyPatch("EatFood")] public static void EatFoodPatch() { if (Configs.statsUIEnabled.Value && !(PlayerNeeds.instance.eatCooldown > 0f)) { StatsUI.Instance.IncrementIntStat("FoodsEaten"); } } } [HarmonyPatch(typeof(ShipItemPipe))] private class ShipItemPipePatches { [HarmonyPrefix] [HarmonyPatch("StopSmoking")] public static void StopSmokingPatch(float ___currentInhaleDuration) { if (Configs.statsUIEnabled.Value && ___currentInhaleDuration > 0f) { StatsUI.Instance.IncrementIntStat("TimesSmoked"); } } } [HarmonyPatch(typeof(Sleep))] private class SleepPatches { [HarmonyPostfix] [HarmonyPatch("EnterBed")] public static void EnterBedPatch() { if (Configs.statsUIEnabled.Value) { StatsUI.Instance.IncrementIntStat("TimesSlept"); if (Configs.updateMilesSailed.Value == "sleep") { StatsUI.Instance.UpdateMilesText(); } } } } [HarmonyPatch(typeof(PlayerMissions))] private class PlayerMissionsPatches { [HarmonyPostfix] [HarmonyPatch("CompleteMission")] public static void CompleteMissionPatch() { if (Configs.statsUIEnabled.Value) { StatsUI.Instance.IncrementIntStat("MissionsCompleted"); } } } [HarmonyPatch(typeof(Port))] private class PortPatches { [HarmonyPostfix] [HarmonyPatch("Update")] public static void UpdatePatch(bool ___teleportPlayer) { if (Configs.statsUIEnabled.Value && ___teleportPlayer) { StatsUI.Instance.PlayerTeleported(); } } } [HarmonyPatch(typeof(BoatMass))] private class BoatMassPatches { [HarmonyPostfix] [HarmonyPatch("FixedUpdate")] public static void FixedUpdatePatch() { if (Configs.statsUIEnabled.Value && (Object)(object)GameState.currentBoat != (Object)null) { StatsUI.Instance.TrackDistance(); } } [HarmonyPostfix] [HarmonyPatch("UpdateMass")] public static void UpdateMassPatch(Rigidbody ___body) { if (Configs.statsUIEnabled.Value && (Object)(object)GameState.currentBoat != (Object)null) { StatsUI.Instance.RegisterTotalMass(___body.mass); } } } [HarmonyPatch(typeof(WeatherStorms))] private class WeatherStormPatches { [HarmonyPostfix] [HarmonyPatch("GetNormalizedDistance")] public static void GetNormalizedDistancePatch(float __result) { if (Configs.statsUIEnabled.Value && (Object)(object)GameState.currentBoat != (Object)null && !((Component)GameState.currentBoat.parent).gameObject.GetComponent<BoatMooringRopes>().AnyRopeMoored() && __result <= WeatherStorms.instance.GetPrivateField<float>("rainBorder")) { StatsUI.Instance.IncrementStormsWeathered(); } if (__result > WeatherStorms.instance.GetPrivateField<float>("cloudyBorder")) { StatsUI.Instance.ClearLastStorm(); } } } } public class FishCaughtUI : MonoBehaviour { public TextMesh[] _fishNameTMs; public TextMesh[] _caughtCountTMs; public Dictionary<string, GameObject> _fishBadgeGOs; public Dictionary<string, int> _caughtFish; public Dictionary<string, bool> _fishBadges; private static readonly int[] FISH_BADGE_AMOUNTS = new int[3] { 25, 50, 100 }; private static readonly int[] TOTAL_FISH_BADGE_AMOUNTS = new int[3] { 50, 250, 500 }; public static readonly string[] FishNames = new string[12] { "templefish", "sunspot fish", "tuna", "blue shimmertail", "salmon", "eel", "blackfin hunter", "trout", "north fish", "swamp snapper", "blue bubbler", "fire fish" }; public static readonly string[] TotalFishBadgeNames = new string[4] { "caught50", "caught250", "caught500", "caughtAll" }; public static FishCaughtUI Instance { get; private set; } public IReadOnlyDictionary<string, int> CaughtFish => _caughtFish; public IReadOnlyDictionary<string, bool> FishBadges => _fishBadges; private void Awake() { if ((Object)(object)Instance != (Object)null && (Object)(object)Instance != (Object)(object)this) { Object.Destroy((Object)(object)((Component)this).gameObject); return; } Instance = this; _caughtFish = new Dictionary<string, int>(); _fishBadges = new Dictionary<string, bool>(); _fishBadgeGOs = new Dictionary<string, GameObject>(); string[] fishNames = FishNames; foreach (string text in fishNames) { _caughtFish.Add(text, 0); int[] fISH_BADGE_AMOUNTS = FISH_BADGE_AMOUNTS; foreach (int num in fISH_BADGE_AMOUNTS) { _fishBadges.Add($"{text}{num}", value: false); } } string[] totalFishBadgeNames = TotalFishBadgeNames; foreach (string key in totalFishBadgeNames) { _fishBadges.Add(key, value: false); } } public void RegisterCatch(GameObject fish) { string name = ((ShipItem)fish.GetComponent<ShipItemFood>()).name; if (!_caughtFish.ContainsKey(name)) { SAD_Plugin.LogWarning("Fish caught " + name + " is not in fish caught log"); return; } _caughtFish[name]++; CheckBadges(name); SAD_Plugin.LogDebug("Caught: " + name); } public void UpdatePage() { UpdateTexts(); UpdateBadges(); } private void UpdateTexts() { int num = 0; int num2 = 0; foreach (KeyValuePair<string, int> item in _caughtFish) { if (Configs.fishNamesHidden.Value) { _fishNameTMs[num].text = ((item.Value > 0) ? item.Key : "???"); } else { _fishNameTMs[num].text = item.Key; } _caughtCountTMs[num].text = item.Value.ToString(); num2 += item.Value; num++; } _fishNameTMs[_fishNameTMs.Length - 1].text = "Total"; _caughtCountTMs[_caughtCountTMs.Length - 1].text = $"{num2}"; } public void CheckBadges(string fishName) { CheckIndividualFishBadges(fishName); CheckAllFishBadges(); } public void CheckIndividualFishBadges(string fishName) { int[] fISH_BADGE_AMOUNTS = FISH_BADGE_AMOUNTS; foreach (int num in fISH_BADGE_AMOUNTS) { if (!_fishBadges[$"{fishName}{num}"] && _caughtFish[fishName] >= num) { if (Configs.notificationsEnabled.Value) { NotificationUiQueue.Instance.QueueNotification($"Caught {num} {fishName}"); } _fishBadges[$"{fishName}{num}"] = true; } } } public void CheckAllFishBadges() { int num = _caughtFish.Values.Sum(); for (int i = 0; i < TOTAL_FISH_BADGE_AMOUNTS.Length; i++) { if (!_fishBadges[TotalFishBadgeNames[i]] && num >= TOTAL_FISH_BADGE_AMOUNTS[i]) { if (Configs.notificationsEnabled.Value) { NotificationUiQueue.Instance.QueueNotification($"Caught {TOTAL_FISH_BADGE_AMOUNTS[i]} fish"); } _fishBadges[TotalFishBadgeNames[i]] = true; } } if (!_fishBadges[TotalFishBadgeNames[3]] && !_caughtFish.Values.Any((int v) => v.Equals(0))) { if (Configs.notificationsEnabled.Value) { NotificationUiQueue.Instance.QueueNotification("Caught all fish"); } _fishBadges[TotalFishBadgeNames[3]] = true; } } private void UpdateBadges() { foreach (KeyValuePair<string, bool> fishBadge in _fishBadges) { _fishBadgeGOs[fishBadge.Key].SetActive(fishBadge.Value); } } public void SetUIElems(TextMesh[] fishNameTMs, TextMesh[] caughtCountTMs, Dictionary<string, GameObject> fishBadgeGOs) { _fishNameTMs = fishNameTMs; _caughtCountTMs = caughtCountTMs; _fishBadgeGOs = fishBadgeGOs; } public void LoadCaughtFish(Dictionary<string, int> caughtFish) { ShimmertailNameFix(caughtFish); SaveLoadPatches.LoadDictionary(caughtFish, _caughtFish); } public void LoadFishBadges(Dictionary<string, bool> fishBadges) { ShimmertailNameFix(fishBadges); SaveLoadPatches.LoadDictionary(fishBadges, _fishBadges); } private void ShimmertailNameFix(Dictionary<string, int> caughtFish) { if (caughtFish.ContainsKey("shimmertail")) { caughtFish.Add("blue shimmertail", caughtFish["shimmertail"]); caughtFish.Remove("shimmertail"); SAD_Plugin.LogInfo("Shimmertail converted to blue shimmertail in caught counts"); } } private void ShimmertailNameFix(Dictionary<string, bool> fishBadges) { int[] fISH_BADGE_AMOUNTS = FISH_BADGE_AMOUNTS; foreach (int num in fISH_BADGE_AMOUNTS) { if (fishBadges.ContainsKey($"shimmertail{num}")) { fishBadges.Add($"blue shimmertail{num}", fishBadges[$"shimmertail{num}"]); fishBadges.Remove($"shimmertail{num}"); SAD_Plugin.LogInfo($"Shimmertail{num} converted to blue shimmertail{num} in fish badges"); } } } } internal class LogUIPatches { [HarmonyPatch(typeof(MissionListUI))] private class MissionListUIPatches { [HarmonyPrefix] [HarmonyPatch("ToggleMenu")] public static void TogglePatch() { //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) bookmarks[0].SetActive(false); bookmarks[1].SetActive(false); bookmarks[2].SetActive(false); Stack<float> stack = new Stack<float>(); stack.Push(-0.515f); stack.Push(-0.387f); stack.Push(-0.26f); if (Configs.fishCaughtUIEnabled.Value) { bookmarks[0].transform.localPosition = new Vector3(stack.Pop(), 0.0027f, -0.4566f); bookmarks[0].SetActive(true); } if (Configs.portsVisitedUIEnabled.Value) { bookmarks[1].transform.localPosition = new Vector3(stack.Pop(), 0.0028f, -0.4566f); bookmarks[1].SetActive(true); } if (Configs.statsUIEnabled.Value) { bookmarks[2].transform.localPosition = new Vector3(stack.Pop(), -0.0032f, -0.4566f); bookmarks[2].SetActive(true); } } [HarmonyPostfix] [HarmonyPatch("HideUI")] public static void HideUIPatches() { fishCaughtUI.SetActive(false); portsVisitedUI.SetActive(false); statsUI.SetActive(false); } [HarmonyPostfix] [HarmonyPatch("SwitchMode")] public static void SwitchModePatches(MissionListMode mode) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Expected I4, but got Unknown fishCaughtUI.SetActive(false); portsVisitedUI.SetActive(false); statsUI.SetActive(false); switch (mode - 5) { case 0: fishCaughtUI.SetActive(true); FishCaughtUI.Instance.UpdatePage(); break; case 1: portsVisitedUI.SetActive(true); PortsVisitedUI.Instance.UpdatePage(); break; case 2: statsUI.SetActive(true); StatsUI.Instance.UpdatePage(); break; } } [HarmonyPrefix] [HarmonyPatch("Start")] public static void StartPatch(GameObject ___modeButtons, GameObject ___reputationUI) { bookmarks = UIBuilder.MakeBookmarks(___modeButtons); statsUI = UIBuilder.MakeStatsUI(___reputationUI); portsVisitedUI = UIBuilder.MakePortsVisitedUI(___reputationUI); fishCaughtUI = UIBuilder.MakeFishCaughtUI(___reputationUI); } } [HarmonyPatch(typeof(NotificationUi))] private class NotificationUiPatches { [HarmonyPostfix] [HarmonyPatch("Start")] public static void StartPatch(NotificationUi ___instance) { if (Configs.notificationsEnabled.Value) { ((Component)___instance).gameObject.AddComponent<NotificationUiQueue>(); } } } private static GameObject fishCaughtUI; private static GameObject portsVisitedUI; private static GameObject statsUI; private static List<GameObject> bookmarks; } internal sealed class Region { private readonly int _index; private readonly string _name; private readonly string _badgeName; private readonly string _code; private readonly List<string> _ports; private readonly List<string> _islands; public static readonly Region AlAnkh = new Region(0, "Al'Ankh", "alankhBadge", "Aa", new List<string> { "Gold Rock City", "Al'Nilem", "Neverdin", "Albacore Town", "Alchemist's Island", "Al'Ankh Academy", "Oasis" }, new List<string> { "island 1 A (gold rock)", "island 2 A (AlNilem)", "island 3 A (Neverdin)", "island 4 A (fish island)", "island 5 A (clear mind)", "island 6 A (lion fang)", "island 7 A (alchemist's island)", "island 8 A (academy)", "island 20 A (Oasis)" }); public static readonly Region EmeraldArchipelago = new Region(1, "Emerald Archipelago", "emeraldBadge", "Ea", new List<string> { "Dragon Cliffs", "Sanctuary", "Crab Beach", "New Port", "Sage Hills", "Serpent Isle", "Dead Cove", "Turtle Island" }, new List<string> { "island 9 E (dragon cliffs)", "island 10 E (sanctuary)", "island 11 E (crab beach)", "island 12 E (New Port)", "island 13 E (Sage Hills)", "island 22 E (serpent isle)", "island 37 E (swamp)", "island 38 E (jungle)", "island 39 E (onsen)" }); public static readonly Region Aestrin = new Region(2, "Aestrin", "mediBadge", "Ae", new List<string> { "Fort Aestrin", "Sunspire", "Mount Malefic", "Siren Song", "Eastwind", "Firefly Grotto", "Aestra Abbey", "Fey Valley", "Happy Bay", "Chronos" }, new List<string> { "island 15 M (Fort)", "island 16 M (Sunspire)", "island 17 M (Mount Malefic)", "island 18 M (HappyBay)", "island 19 M (Eastwind)", "island 21 M (Siren Song)", "island 33 M cave church", "island 34 M monastery", "island 35 M valley", "island 23 M oracle", "island 25 (chronos)" }); public static readonly Region FireFishLagoon = new Region(3, "Fire Fish Lagoon", "lagoonBadge", "Ffl", new List<string> { "Kicia Bay", "Fire Fish Town", "On'na", "Sen'na" }, new List<string> { "island 26 Lagoon Temple", "island 27 Lagoon Shipyard", "island 28 Lagoon Senna", "island 29 Lagoon Onna", "island 31 Lagoon Fisherman" }); public static readonly IReadOnlyList<Region> AllRegions = new List<Region> { AlAnkh, EmeraldArchipelago, Aestrin, FireFishLagoon }.AsReadOnly(); public static readonly IReadOnlyList<string> AllBadgeNames = new List<string> { AlAnkh.BadgeName, EmeraldArchipelago.BadgeName, Aestrin.BadgeName, FireFishLagoon.BadgeName, "allPortsBadge" }.AsReadOnly(); public int Index => _index; public string Name => _name; public string BadgeName => _badgeName; public string Code => _code; public IReadOnlyList<string> Ports => _ports.AsReadOnly(); public IReadOnlyList<string> Islands => _islands.AsReadOnly(); public static IReadOnlyList<string> AllPorts { get { List<string> list = new List<string>(); foreach (Region allRegion in AllRegions) { list.AddRange(allRegion.Ports); } return list.AsReadOnly(); } } public static IReadOnlyList<string> TransitCodes { get { List<string> list = new List<string>(); foreach (Region allRegion in AllRegions) { foreach (Region allRegion2 in AllRegions) { if (allRegion.Index != allRegion2.Index) { list.Add(allRegion.Code + allRegion2.Code); } } } return list.AsReadOnly(); } } private Region(int index, string name, string badgeName, string code, List<string> ports, List<string> islands) { _index = index; _name = name; _badgeName = badgeName; _code = code; _ports = ports; _islands = islands; } public override string ToString() { return Name ?? ""; } } internal class UIBuilder { [CompilerGenerated] private sealed class <CreateBadgeObject>d__12 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public Dictionary<string, GameObject> badgeGOs; public string name; public Transform parent; public Vector3 scale; public Vector3 position; private GameObject <badge>5__1; private MeshRenderer <meshRenderer>5__2; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <CreateBadgeObject>d__12(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <badge>5__1 = null; <meshRenderer>5__2 = null; <>1__state = -2; } private bool MoveNext() { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Expected O, but got Unknown //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitUntil((Func<bool>)(() => AssetsLoader.BadgesLoaded)); <>1__state = 1; return true; case 1: <>1__state = -1; <badge>5__1 = GameObject.CreatePrimitive((PrimitiveType)5); <badge>5__1.layer = 5; <badge>5__1.transform.SetParent(parent, false); <badge>5__1.transform.localScale = scale; <badge>5__1.transform.localPosition = position; ((Object)<badge>5__1).name = name; if (name.Equals("allPortsBadge")) { <badge>5__1.transform.localEulerAngles = new Vector3(0f, 180f, 0f); } <meshRenderer>5__2 = <badge>5__1.GetComponent<MeshRenderer>(); ((Renderer)<meshRenderer>5__2).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)<meshRenderer>5__2).material = AssetsLoader.Materials[name]; Object.Destroy((Object)(object)<badge>5__1.GetComponent<MeshCollider>()); badgeGOs.Add(name, <badge>5__1); return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } internal const MissionListMode FISH_CAUGHT = 5; internal const MissionListMode PORTS_VISITED = 6; internal const MissionListMode STATS = 7; private const int FISH_CAUGHT_FONT_SIZE = 50; private const int STAT_HEADER_FONT_SIZE = 45; private const int STAT_FONT_SIZE = 40; internal static List<GameObject> MakeBookmarks(GameObject modeButtons) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Unknown result type (might be due to invalid IL or missing references) List<GameObject> list = new List<GameObject>(); GameObject gameObject = ((Component)modeButtons.transform.GetChild(9)).gameObject; GameObject val = Object.Instantiate<GameObject>(gameObject); val.transform.parent = modeButtons.transform; val.transform.localRotation = gameObject.transform.localRotation; val.transform.localScale = gameObject.transform.localScale; ((Object)val).name = "bookmark fish caught"; ((Component)val.transform.GetChild(0)).gameObject.GetComponent<TextMesh>().text = "fish caught"; GPButtonLogMode component = val.GetComponent<GPButtonLogMode>(); Traverse.Create((object)component).Field("mode").SetValue((object)(MissionListMode)5); Object.Destroy((Object)(object)val.GetComponent<Outline>()); list.Add(val); GameObject val2 = Object.Instantiate<GameObject>(gameObject); val2.transform.parent = modeButtons.transform; val2.transform.localRotation = gameObject.transform.localRotation; val2.transform.localScale = gameObject.transform.localScale; ((Object)val2).name = "bookmark ports visited"; ((Component)val2.transform.GetChild(0)).gameObject.GetComponent<TextMesh>().text = "ports visited"; GPButtonLogMode component2 = val2.GetComponent<GPButtonLogMode>(); Traverse.Create((object)component2).Field("mode").SetValue((object)(MissionListMode)6); Object.Destroy((Object)(object)val2.GetComponent<Outline>()); list.Add(val2); GameObject val3 = Object.Instantiate<GameObject>(gameObject); val3.transform.parent = modeButtons.transform; val3.transform.localRotation = gameObject.transform.localRotation; val3.transform.localScale = gameObject.transform.localScale; ((Object)val3).name = "bookmark stats"; ((Component)val3.transform.GetChild(0)).gameObject.GetComponent<TextMesh>().text = "stats & transit"; GPButtonLogMode component3 = val3.GetComponent<GPButtonLogMode>(); Traverse.Create((object)component3).Field("mode").SetValue((object)(MissionListMode)7); Object.Destroy((Object)(object)val3.GetComponent<Outline>()); list.Add(val3); return list; } internal static GameObject MakeFishCaughtUI(GameObject repUI) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0266: Unknown result type (might be due to invalid IL or missing references) //IL_026b: Unknown result type (might be due to invalid IL or missing references) //IL_0275: Unknown result type (might be due to invalid IL or missing references) //IL_028d: Unknown result type (might be due to invalid IL or missing references) //IL_02a5: Unknown result type (might be due to invalid IL or missing references) //IL_042b: Unknown result type (might be due to invalid IL or missing references) //IL_0430: Unknown result type (might be due to invalid IL or missing references) //IL_043a: Unknown result type (might be due to invalid IL or missing references) //IL_0452: Unknown result type (might be due to invalid IL or missing references) //IL_046a: Unknown result type (might be due to invalid IL or missing references) //IL_0329: Unknown result type (might be due to invalid IL or missing references) //IL_0347: Unknown result type (might be due to invalid IL or missing references) //IL_04f4: Unknown result type (might be due to invalid IL or missing references) //IL_0512: Unknown result type (might be due to invalid IL or missing references) GameObject val = Object.Instantiate<GameObject>(repUI); Object.Destroy((Object)(object)val.GetComponent<ReputationUI>()); val.transform.parent = repUI.transform.parent; val.transform.localPosition = repUI.transform.localPosition; val.transform.localRotation = repUI.transform.localRotation; val.transform.localScale = repUI.transform.localScale; ((Object)val).name = "fish caught ui"; Object.Destroy((Object)(object)((Component)val.transform.GetChild(2)).gameObject); Object.Destroy((Object)(object)((Component)val.transform.GetChild(1)).gameObject); val.AddComponent<FishCaughtUI>(); GameObject gameObject = ((Component)val.transform.GetChild(0)).gameObject; gameObject.GetComponent<TextMesh>().font = ((Component)gameObject.transform.GetChild(1)).GetComponent<TextMesh>().font; ((Renderer)gameObject.GetComponent<MeshRenderer>()).material = ((Renderer)((Component)gameObject.transform.GetChild(1)).GetComponent<MeshRenderer>()).material; ((Object)((Component)gameObject.transform.GetChild(1)).gameObject).name = "caught count"; Transform child = gameObject.transform.GetChild(1); Vector3 localPosition = gameObject.transform.GetChild(1).localPosition; child.localPosition = new Vector3(55f, 0f, ((Vector3)(ref localPosition))[2]); ((Component)gameObject.transform.GetChild(1)).GetComponent<TextMesh>().fontSize = 50; TextMesh[] array = (TextMesh[])(object)new TextMesh[FishCaughtUI.FishNames.Length + 1]; TextMesh[] array2 = (TextMesh[])(object)new TextMesh[FishCaughtUI.FishNames.Length + 1]; Dictionary<string, GameObject> dictionary = new Dictionary<string, GameObject>(); for (int i = 0; i < FishCaughtUI.FishNames.Length; i++) { GameObject val2 = Object.Instantiate<GameObject>(gameObject); Object.Destroy((Object)(object)((Component)val2.transform.GetChild(4)).gameObject); Object.Destroy((Object)(object)((Component)val2.transform.GetChild(3)).gameObject); Object.Destroy((Object)(object)((Component)val2.transform.GetChild(2)).gameObject); Object.Destroy((Object)(object)((Component)val2.transform.GetChild(0)).gameObject); val2.GetComponent<TextMesh>().fontSize = 50; ((Object)val2).name = FishCaughtUI.FishNames[i]; val2.transform.parent = gameObject.transform.parent; Transform transform = val2.transform; float num = 0.24f - 0.0375f * (float)i; localPosition = gameObject.transform.localPosition; transform.localPosition = new Vector3(0.8f, num, ((Vector3)(ref localPosition))[2]); val2.transform.localRotation = gameObject.transform.localRotation; val2.transform.localScale = gameObject.transform.localScale; array2[i] = val2.GetComponent<TextMesh>(); array[i] = ((Component)val2.transform.GetChild(1)).GetComponent<TextMesh>(); string[] array3 = new string[3] { "25", "50", "100" }; for (int j = 0; j < array3.Length; j++) { string name = ((Object)val2).name + array3[j]; ((MonoBehaviour)SAD_Plugin.Instance).StartCoroutine(CreateBadgeObject(dictionary, name, val2.transform, new Vector3(12f, 12f, 1f), new Vector3(75f + (float)j * 13f, 0f, 0f))); } } GameObject val3 = Object.Instantiate<GameObject>(gameObject); Object.Destroy((Object)(object)((Component)val3.transform.GetChild(4)).gameObject); Object.Destroy((Object)(object)((Component)val3.transform.GetChild(3)).gameObject); Object.Destroy((Object)(object)((Component)val3.transform.GetChild(2)).gameObject); Object.Destroy((Object)(object)((Component)val3.transform.GetChild(0)).gameObject); ((Object)val3).name = "totalCaught"; val3.transform.parent = gameObject.transform.parent; Transform transform2 = val3.transform; localPosition = gameObject.transform.localPosition; transform2.localPosition = new Vector3(0.8f, -0.21f, ((Vector3)(ref localPosition))[2]); val3.transform.localRotation = gameObject.transform.localRotation; val3.transform.localScale = gameObject.transform.localScale; array2[FishCaughtUI.FishNames.Length] = val3.GetComponent<TextMesh>(); array[FishCaughtUI.FishNames.Length] = ((Component)val3.transform.GetChild(1)).GetComponent<TextMesh>(); string[] array4 = new string[4] { "caught50", "caught250", "caught500", "caughtAll" }; for (int k = 0; k < array4.Length; k++) { string name2 = array4[k]; ((MonoBehaviour)SAD_Plugin.Instance).StartCoroutine(CreateBadgeObject(dictionary, name2, val3.transform, new Vector3(15f, 15f, 1f), new Vector3(15f + (float)k * 20f, -13f, 0f))); } Object.Destroy((Object)(object)gameObject); FishCaughtUI.Instance.SetUIElems(array2, array, dictionary); SAD_Plugin.LogDebug("Loaded fish caught UI"); return val; } internal static GameObject MakePortsVisitedUI(GameObject repUI) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_02f9: Unknown result type (might be due to invalid IL or missing references) //IL_0327: Unknown result type (might be due to invalid IL or missing references) //IL_05b4: Unknown result type (might be due to invalid IL or missing references) //IL_05c8: Unknown result type (might be due to invalid IL or missing references) //IL_0387: Unknown result type (might be due to invalid IL or missing references) //IL_038c: Unknown result type (might be due to invalid IL or missing references) //IL_039d: Unknown result type (might be due to invalid IL or missing references) //IL_03a2: Unknown result type (might be due to invalid IL or missing references) //IL_03bd: Unknown result type (might be due to invalid IL or missing references) //IL_03c2: Unknown result type (might be due to invalid IL or missing references) //IL_03cc: Unknown result type (might be due to invalid IL or missing references) //IL_03e5: Unknown result type (might be due to invalid IL or missing references) //IL_03fe: Unknown result type (might be due to invalid IL or missing references) //IL_0458: Unknown result type (might be due to invalid IL or missing references) //IL_045d: Unknown result type (might be due to invalid IL or missing references) //IL_046e: Unknown result type (might be due to invalid IL or missing references) //IL_0473: Unknown result type (might be due to invalid IL or missing references) //IL_048e: Unknown result type (might be due to invalid IL or missing references) //IL_0493: Unknown result type (might be due to invalid IL or missing references) //IL_049d: Unknown result type (might be due to invalid IL or missing references) //IL_04b6: Unknown result type (might be due to invalid IL or missing references) //IL_04cf: Unknown result type (might be due to invalid IL or missing references) //IL_0557: Unknown result type (might be due to invalid IL or missing references) //IL_056b: Unknown result type (might be due to invalid IL or missing references) GameObject val = Object.Instantiate<GameObject>(repUI); Object.Destroy((Object)(object)val.GetComponent<ReputationUI>()); val.transform.parent = repUI.transform.parent; val.transform.localPosition = repUI.transform.localPosition; val.transform.localRotation = repUI.transform.localRotation; val.transform.localScale = repUI.transform.localScale; ((Object)val).name = "ports visited ui"; val.AddComponent<PortsVisitedUI>(); Transform child = val.transform.GetChild(0); Vector3 localPosition = val.transform.GetChild(0).localPosition; child.localPosition = new Vector3(0.75f, 0.22f, ((Vector3)(ref localPosition))[2]); Transform child2 = val.transform.GetChild(1); localPosition = val.transform.GetChild(1).localPosition; child2.localPosition = new Vector3(0.75f, 0.01f, ((Vector3)(ref localPosition))[2]); Transform child3 = val.transform.GetChild(2); localPosition = val.transform.GetChild(2).localPosition; child3.localPosition = new Vector3(0.02f, 0.22f, ((Vector3)(ref localPosition))[2]); GameObject val2 = Object.Instantiate<GameObject>(((Component)val.transform.GetChild(1)).gameObject); val2.transform.parent = val.transform; Transform transform = val2.transform; localPosition = val.transform.GetChild(1).localPosition; transform.localPosition = new Vector3(0.02f, -0.065f, ((Vector3)(ref localPosition))[2]); val2.transform.localRotation = val.transform.GetChild(1).localRotation; val2.transform.localScale = val.transform.GetChild(1).localScale; ((Object)val2).name = "lagoon"; val2.GetComponent<TextMesh>().text = "Fire Fish Lagoon"; TextMesh[] array = (TextMesh[])(object)new TextMesh[Region.AllPorts.Count]; TextMesh[] array2 = (TextMesh[])(object)new TextMesh[Region.AllPorts.Count]; Dictionary<string, GameObject> dictionary = new Dictionary<string, GameObject>(); int num = 0; int[] array3 = new int[4] { Region.AlAnkh.Ports.Count, Region.EmeraldArchipelago.Ports.Count, Region.Aestrin.Ports.Count, Region.FireFishLagoon.Ports.Count }; for (int i = 0; i < array3.Length; i++) { Transform child4 = val.transform.GetChild(i); Object.Destroy((Object)(object)((Component)child4.GetChild(1)).gameObject); Object.Destroy((Object)(object)((Component)child4.GetChild(2)).gameObject); Object.Destroy((Object)(object)((Component)child4.GetChild(4)).gameObject); GameObject gameObject = ((Component)child4.GetChild(0)).gameObject; GameObject gameObject2 = ((Component)child4.GetChild(3)).gameObject; ((Object)gameObject).name = "port1"; gameObject.transform.localPosition = new Vector3(5f, -8f, -0.1f); ((Object)gameObject2).name = "visited port1"; gameObject2.transform.localPosition = new Vector3(70f, -9f, 0f); array[num] = gameObject.GetComponent<TextMesh>(); array2[num] = gameObject2.GetComponent<TextMesh>(); num++; for (int j = 1; j < array3[i]; j++) { GameObject val3 = Object.Instantiate<GameObject>(gameObject); val3.transform.parent = gameObject.transform.parent; Transform transform2 = val3.transform; localPosition = gameObject.transform.localPosition; float num2 = ((Vector3)(ref localPosition))[0]; localPosition = gameObject.transform.localPosition; float num3 = ((Vector3)(ref localPosition))[1] - 7.5f * (float)j; localPosition = gameObject.transform.localPosition; transform2.localPosition = new Vector3(num2, num3, ((Vector3)(ref localPosition))[2]); val3.transform.localRotation = gameObject.transform.localRotation; val3.transform.localScale = gameObject.transform.localScale; ((Object)val3).name = "port" + (j + 1); GameObject val4 = Object.Instantiate<GameObject>(gameObject2); val4.transform.parent = gameObject2.transform.parent; Transform transform3 = val4.transform; localPosition = gameObject2.transform.localPosition; float num4 = ((Vector3)(ref localPosition))[0]; localPosition = gameObject2.transform.localPosition; float num5 = ((Vector3)(ref localPosition))[1] - 7.5f * (float)j; localPosition = gameObject2.transform.localPosition; transform3.localPosition = new Vector3(num4, num5, ((Vector3)(ref localPosition))[2]); val4.transform.localRotation = gameObject2.transform.localRotation; val4.transform.localScale = gameObject2.transform.localScale; ((Object)val4).name = $"visited port{j + 1}"; array[num] = val3.GetComponent<TextMesh>(); array2[num] = val4.GetComponent<TextMesh>(); num++; } string name = ((Object)child4).name + "Badge"; ((MonoBehaviour)SAD_Plugin.Instance).StartCoroutine(CreateBadgeObject(dictionary, name, child4, new Vector3(15f, 15f, 1f), new Vector3(-8f, -2f, 0f))); } ((MonoBehaviour)SAD_Plugin.Instance).StartCoroutine(CreateBadgeObject(dictionary, "allPortsBadge", val.transform, new Vector3(0.1f, 0.0675f, 1f), new Vector3(0.55f, -0.245f, -0.007f))); PortsVisitedUI.Instance.SetUIElems(array, array2, dictionary); SAD_Plugin.LogDebug("Loaded ports visited UI"); return val; } internal static GameObject MakeStatsUI(GameObject repUI) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_0219: Unknown result type (might be due to invalid IL or missing references) //IL_03e8: Unknown result type (might be due to invalid IL or missing references) //IL_04c9: Unknown result type (might be due to invalid IL or missing references) //IL_0594: Unknown result type (might be due to invalid IL or missing references) GameObject val = Object.Instantiate<GameObject>(repUI); Object.Destroy((Object)(object)val.GetComponent<ReputationUI>()); val.transform.parent = repUI.transform.parent; val.transform.localPosition = repUI.transform.localPosition; val.transform.localRotation = repUI.transform.localRotation; val.transform.localScale = repUI.transform.localScale; ((Object)val).name = "stats ui"; Object.Destroy((Object)(object)((Component)val.transform.GetChild(2)).gameObject); Object.Destroy((Object)(object)((Component)val.transform.GetChild(1)).gameObject); val.AddComponent<StatsUI>(); GameObject gameObject = ((Component)val.transform.GetChild(0)).gameObject; gameObject.GetComponent<TextMesh>().font = ((Component)gameObject.transform.GetChild(1)).GetComponent<TextMesh>().font; gameObject.GetComponent<TextMesh>().fontSize = 40; ((Renderer)gameObject.GetComponent<MeshRenderer>()).material = ((Renderer)((Component)gameObject.transform.GetChild(1)).GetComponent<MeshRenderer>()).material; ((Object)((Component)gameObject.transform.GetChild(0)).gameObject).name = "current value"; gameObject.transform.GetChild(0).localPosition = new Vector3(38f, 0f, 0f); ((Component)gameObject.transform.GetChild(0)).GetComponent<TextMesh>().font = ((Component)gameObject.transform.GetChild(1)).GetComponent<TextMesh>().font; ((Component)gameObject.transform.GetChild(0)).GetComponent<TextMesh>().fontSize = 40; ((Component)gameObject.transform.GetChild(0)).GetComponent<TextMesh>().anchor = (TextAnchor)3; ((Renderer)((Component)gameObject.transform.GetChild(0)).GetComponent<MeshRenderer>()).material = ((Renderer)((Component)gameObject.transform.GetChild(1)).GetComponent<MeshRenderer>()).material; ((Object)((Component)gameObject.transform.GetChild(1)).gameObject).name = "record value"; gameObject.transform.GetChild(1).localPosition = new Vector3(80f, 0f, 0f); ((Component)gameObject.transform.GetChild(1)).GetComponent<TextMesh>().fontSize = 40; ((Component)gameObject.transform.GetChild(1)).GetComponent<TextMesh>().anchor = (TextAnchor)3; ((Component)gameObject.transform.GetChild(1)).GetComponent<TextMesh>().fontStyle = (FontStyle)0; Dictionary<string, TextMesh> dictionary = new Dictionary<string, TextMesh>(); AddTrackedStat(gameObject, "CargoMass", 0.215f, dictionary); AddTrackedStat(gameObject, "TotalMass", 0.19f, dictionary); AddTrackedStat(gameObject, "UnderwayTime", 0.165f, dictionary); AddTrackedStat(gameObject, "MilesSailed", 0.09f, dictionary, ltime: true); List<float> list = new List<float>(); int num = 0; string[] intStatNames = StatsUI.IntStatNames; foreach (string text in intStatNames) { if (!(text == "UnderwayDay")) { if (StatsUI.RandomEncounterStats.ContainsKey(text)) { list.Add(0.065f - 0.025f * (float)num); } AddTrackedStat(gameObject, text, 0.065f - 0.025f * (float)num, dictionary, ltime: true); num++; } } StatsUI.RandomEncounterStatYPos = list; int num2 = 0; foreach (string transitCode in Region.TransitCodes) { AddTrackedStat(gameObject, transitCode, 0.215f - 0.025f * (float)num2, dictionary, ltime: false, transit: true); num2++; } StatsUI.Instance.SetUIElems(dictionary); ((Object)gameObject).name = "stats header"; gameObject.GetComponent<TextMesh>().text = "Stat Current Record"; gameObject.transform.localPosition = new Vector3(0.82f, 0.24f, -0.007f); gameObject.GetComponent<TextMesh>().fontSize = 45; gameObject.GetComponent<TextMesh>().fontStyle = (FontStyle)1; Object.Destroy((Object)(object)((Component)gameObject.transform.GetChild(4)).gameObject); Object.Destroy((Object)(object)((Component)gameObject.transform.GetChild(3)).gameObject); Object.Destroy((Object)(object)((Component)gameObject.transform.GetChild(2)).gameObject); Object.Destroy((Object)(object)((Component)gameObject.transform.GetChild(1)).gameObject); Object.Destroy((Object)(object)((Component)gameObject.transform.GetChild(0)).gameObject); GameObject val2 = Object.Instantiate<GameObject>(gameObject, gameObject.transform.parent); ((Object)val2).name = "lifetime stats header"; val2.GetComponent<TextMesh>().text = "Lifetime Stats"; val2.transform.localPosition = new Vector3(0.82f, 0.115f, -0.007f); Object.Destroy((Object)(object)((Component)val2.transform.GetChild(4)).gameObject); Object.Destroy((Object)(object)((Component)val2.transform.GetChild(3)).gameObject); Object.Destroy((Object)(object)((Component)val2.transform.GetChild(2)).gameObject); Object.Destroy((Object)(object)((Component)val2.transform.GetChild(1)).gameObject); Object.Destroy((Object)(object)((Component)val2.transform.GetChild(0)).gameObject); GameObject val3 = Object.Instantiate<GameObject>(gameObject, gameObject.transform.parent); ((Object)val3).name = "transit times header"; val3.GetComponent<TextMesh>().text = "Transit Times Last Record"; val3.transform.localPosition = new Vector3(0.14f, 0.24f, -0.007f); Object.Destroy((Object)(object)((Component)val3.transform.GetChild(4)).gameObject); Object.Destroy((Object)(object)((Component)val3.transform.GetChild(3)).gameObject); Object.Destroy((Object)(object)((Component)val3.transform.GetChild(2)).gameObject); Object.Destroy((Object)(object)((Component)val3.transform.GetChild(1)).gameObject); Object.Destroy((Object)(object)((Component)val3.transform.GetChild(0)).gameObject); SAD_Plugin.LogDebug("Loaded stats & transit UI"); return val; } private static void AddTrackedStat(GameObject templateGO, string name, float yPos, Dictionary<string, TextMesh> statTMs, bool ltime = false, bool transit = false) { //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) float num = (transit ? 0.14f : 0.82f); string text = (transit ? "last" : "current"); GameObject val = Object.Instantiate<GameObject>(templateGO); Object.Destroy((Object)(object)((Component)val.transform.GetChild(4)).gameObject); Object.Destroy((Object)(object)((Component)val.transform.GetChild(3)).gameObject); Object.Destroy((Object)(object)((Component)val.transform.GetChild(2)).gameObject); if (ltime) { Object.Destroy((Object)(object)((Component)val.transform.GetChild(1)).gameObject); val.transform.GetChild(0).localPosition = new Vector3(41f, 0f, 0f); } ((Object)val).name = name; val.transform.parent = templateGO.transform.parent; Transform transform = val.transform; Vector3 localPosition = templateGO.transform.localPosition; transform.localPosition = new Vector3(num, yPos, ((Vector3)(ref localPosition))[2]); val.transform.localRotation = templateGO.transform.localRotation; val.transform.localScale = templateGO.transform.localScale; statTMs[name] = val.GetComponent<TextMesh>(); statTMs[text + name] = ((Component)val.transform.GetChild(0)).GetComponent<TextMesh>(); if (!ltime) { statTMs["record" + name] = ((Component)val.transform.GetChild(1)).GetComponent<TextMesh>(); } AddLine(((Component)val.transform.GetChild(1)).gameObject); } private static void AddLine(GameObject templateGO) { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) GameObject val = Object.Instantiate<GameObject>(templateGO); ((Object)val).name = "line"; val.transform.parent = templateGO.transform.parent; val.transform.localPosition = new Vector3(-1.2f, -1.75f, 0f); val.transform.localRotation = templateGO.transform.localRotation; val.transform.localScale = templateGO.transform.localScale; TextMesh component = val.GetComponent<TextMesh>(); component.color = Color32.op_Implicit(new Color32((byte)2, (byte)2, (byte)10, (byte)133)); component.text = "--------------------------------------------------------"; } [IteratorStateMachine(typeof(<CreateBadgeObject>d__12))] private static IEnumerator CreateBadgeObject(Dictionary<string, GameObject> badgeGOs, string name, Transform parent, Vector3 scale, Vector3 position) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <CreateBadgeObject>d__12(0) { badgeGOs = badgeGOs, name = name, parent = parent, scale = scale, position = position }; } } internal class AssetsLoader { [CompilerGenerated] private sealed class <>c__DisplayClass22_0 { public byte[] fileData; internal void <LoadBadgeRing>b__0(byte[] result) { fileData = result; } } [CompilerGenerated] private sealed class <>c__DisplayClass24_0 { public byte[] fileData; internal void <LoadFishTexture>b__0(byte[] result) { fileData = result; } } [CompilerGenerated] private sealed class <>c__DisplayClass29_0 { public byte[] fileData; internal void <LoadTexture>b__0(byte[] result) { fileData = result; } } [CompilerGenerated] private sealed class <GenerateFishBadges>d__25 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; private int[] <amountNums>5__1; private string[] <>s__2; private int <>s__3; private string <fishName>5__4; private Texture2D <fishTexture>5__5; private int <i>5__6; private int <amount>5__7; private Texture2D <ringTexture>5__8; private string <badgeName>5__9; private Texture2D <combinedTexture>5__10; private string[] <>s__11; private int <>s__12; private string <caughtBadge>5__13; private string <path>5__14; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <GenerateFishBadges>d__25(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <amountNums>5__1 = null; <>s__2 = null; <fishName>5__4 = null; <fishTexture>5__5 = null; <ringTexture>5__8 = null; <badgeName>5__9 = null; <combinedTexture>5__10 = null; <>s__11 = null; <caughtBadge>5__13 = null; <path>5__14 = null; <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <amountNums>5__1 = new int[3] { 25, 50, 100 }; <>s__2 = FishCaughtUI.FishNames; <>s__3 = 0; goto IL_0216; case 1: <>1__state = -1; <fishTexture>5__5 = null; <fishName>5__4 = null; goto IL_0208; case 2: { <>1__state = -1; <path>5__14 = null; <caughtBadge>5__13 = null; <>s__12++; break; } IL_0216: if (<>s__3 < <>s__2.Length) { <fishName>5__4 = <>s__2[<>s__3]; if (!_fishTextures.ContainsKey(<fishName>5__4)) { SAD_Plugin.LogError("Fish texture not found for: " + <fishName>5__4); goto IL_0208; } <fishTexture>5__5 = _fishTextures[<fishName>5__4]; <i>5__6 = 0; while (<i>5__6 < <amountNums>5__1.Length) { <amount>5__7 = <amountNums>5__1[<i>5__6]; if (!_badgeRings.ContainsKey(<amount>5__7)) { SAD_Plugin.LogError($"Badge ring not found for amount: {<amount>5__7}"); } else { <ringTexture>5__8 = _badgeRings[<amount>5__7]; <badgeName>5__9 = <fishName>5__4 + <amount>5__7; <combinedTexture>5__10 = CombineTextures(<fishTexture>5__5, <ringTexture>5__8); ((Object)<combinedTexture>5__10).name = <badgeName>5__9; _textures[<badgeName>5__9] = <combinedTexture>5__10; Materials[<badgeName>5__9] = CreateMaterial(<combinedTexture>5__10); <ringTexture>5__8 = null; <badgeName>5__9 = null; <combinedTexture>5__10 = null; } <i>5__6++; } <>2__current = null; <>1__state = 1; return true; } <>s__2 = null; <>s__11 = FishCaughtUI.TotalFishBadgeNames; <>s__12 = 0; break; IL_0208: <>s__3++; goto IL_0216; } if (<>s__12 < <>s__11.Length) { <caughtBadge>5__13 = <>s__11[<>s__12]; <path>5__14 = FindAssetPath(<caughtBadge>5__13 + ".png"); <>2__current = ((MonoBehaviour)SAD_Plugin.Instance).StartCoroutine(LoadTexture(<path>5__14, <caughtBadge>5__13)); <>1__state = 2; return true; } <>s__11 = null; return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <LoadAssetsAsync>d__18 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; private Coroutine <audioCoroutine>5__1; private Coroutine <fishBadgeCoroutine>5__2; private Coroutine <portBadgeCoroutine>5__3; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <LoadAssetsAsync>d__18(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <audioCoroutine>5__1 = null; <fishBadgeCoroutine>5__2 = null; <portBadgeCoroutine>5__3 = null; <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <audioCoroutine>5__1 = ((MonoBehaviour)SAD_Plugin.Instance).StartCoroutine(LoadAudio()); <fishBadgeCoroutine>5__2 = ((MonoBehaviour)SAD_Plugin.Instance).StartCoroutine(LoadFishBadges()); <portBadgeCoroutine>5__3 = ((MonoBehaviour)SAD_Plugin.Instance).StartCoroutine(LoadPortBadges()); <>2__current = <audioCoroutine>5__1; <>1__state = 1; return true; case 1: <>1__state = -1; <>2__current = <fishBadgeCoroutine>5__2; <>1__state = 2; return true; case 2: <>1__state = -1; <>2__current = <portBadgeCoroutine>5__3; <>1__state = 3; return true; case 3: <>1__state = -1; SAD_Plugin.LogInfo("Assets loaded"); return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <LoadAudio>d__19 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; private string <clipPath>5__1; private UnityWebRequest <webRequest>5__2; private AudioClip <clip>5__3; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <LoadAudio>d__19(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { int num = <>1__state; if (num == -3 || num == 1) { try { } finally { <>m__Finally1(); } } <clipPath>5__1 = null; <webRequest>5__2 = null; <clip>5__3 = null; <>1__state = -2; } private bool MoveNext() { bool result; try { switch (<>1__state) { default: result = false; break; case 0: <>1__state = -1; <clipPath>5__1 = FindAssetPath("twoBells.wav"); <webRequest>5__2 = UnityWebRequestMultimedia.GetAudioClip("file://" + <clipPath>5__1, (AudioType)20); <>1__state = -3; <>2__current = <webRequest>5__2.SendWebRequest(); <>1__state = 1; result = true; break; case 1: <>1__state = -3; if (<webRequest>5__2.isNetworkError || <webRequest>5__2.isHttpError) { SAD_Plugin.LogError(<webRequest>5__2.error); result = false; <>m__Finally1(); break; } <clip>5__3 = DownloadHandlerAudioClip.GetContent(<webRequest>5__2); ((Object)<clip>5__3).name = "twoBells"; NotificationSound = <clip>5__3; SAD_Plugin.LogDebug("Audio loaded."); <clip>5__3 = null; <>m__Finally1(); <webRequest>5__2 = null; result = false; break; } } catch { //try-fault ((IDisposable)this).Dispose(); throw; } return result; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } private void <>m__Finally1() { <>1__state = -1; if (<webRequest>5__2 != null) { ((IDisposable)<webRequest>5__2).Dispose(); } } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <LoadBadgeRing>d__22 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public string path; public int amount; private <>c__DisplayClass22_0 <>8__1; private Texture2D <texture2D>5__2; private bool <success>5__3; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <LoadBadgeRing>d__22(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>8__1 = null; <texture2D>5__2 = null; <>1__state = -2; } private bool MoveNext() { //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>8__1 = new <>c__DisplayClass22_0(); if (!File.Exists(path)) { SAD_Plugin.LogError("Badge ring file not found: " + path); return false; } <texture2D>5__2 = new Texture2D(1, 1); <>8__1.fileData = null; <>2__current = ((MonoBehaviour)SAD_Plugin.Instance).StartCoroutine(LoadFile(path, delegate(byte[] result) { <>8__1.fileData = result; })); <>1__state = 1; return true; case 1: <>1__state = -1; if (<>8__1.fileData != null && <>8__1.fileData.Length != 0) { <success>5__3 = ImageConversion.LoadImage(<texture2D>5__2, <>8__1.fileData); if (!<success>5__3) { SAD_Plugin.LogError("Failed to load badge ring from bytes: " + path); return false; } _badgeRings[amount] = <texture2D>5__2; } return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <LoadBadgeRings>d__21 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; private int[] <amountNums>5__1; private List<Coroutine> <ringCoroutines>5__2; private int[] <>s__3; private int <>s__4; private int <amount>5__5; private string <ringName>5__6; private string <path>5__7; private List<Coroutine>.Enumerator <>s__8; private Coroutine <coroutine>5__9; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <LoadBadgeRings>d__21(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { int num = <>1__state; if (num == -3 || num == 1) { try { } finally { <>m__Finally1(); } } <amountNums>5__1 = null; <ringCoroutines>5__2 = null; <>s__3 = null; <ringName>5__6 = null; <path>5__7 = null; <>s__8 = default(List<Coroutine>.Enumerator); <coroutine>5__9 = null; <>1__state = -2; } private bool MoveNext() { try { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <amountNums>5__1 = new int[3] { 25, 50, 100 }; <ringCoroutines>5__2 = new List<Coroutine>(); <>s__3 = <amountNums>5__1; for (<>s__4 = 0; <>s__4 < <>s__3.Length; <>s__4++) { <amount>5__5 = <>s__3[<>s__4]; <ringName>5__6 = <amount>5__5 + "Fish"; <path>5__7 = FindAssetPath(<ringName>5__6 + ".png"); <ringCoroutines>5__2.Add(((MonoBehaviour)SAD_Plugin.Instance).StartCoroutine(LoadBadgeRing(<path>5__7, <amount>5__5))); <ringName>5__6 = null; <path>5__7 = null; } <>s__3 = null; <>s__8 = <ringCoroutines>5__2.GetEnumerator(); <>1__state = -3; break; case 1: <>1__state = -3; <coroutine>5__9 = null; break; } if (<>s__8.MoveNext()) { <coroutine>5__9 = <>s__8.Current; <>2__current = <coroutine>5__9; <>1__state = 1; return true; } <>m__Finally1(); <>s__8 = default(List<Coroutine>.Enumerator); return false; } catch { //try-fault ((IDisposable)this).Dispose(); throw; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } private void <>m__Finally1() { <>1__state = -1; ((IDisposable)<>s__8).Dispose(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <LoadFile>d__30 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public string path; public Action<byte[]> onComplete; private byte[] <result>5__1; private UnityWebRequest <www>5__2; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <LoadFile>d__30(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { int num = <>1__state; if (num == -3 || num == 2) { try { } finally { <>m__Finally1(); } } <result>5__1 = null; <www>5__2 = null; <>1__state = -2; } private bool MoveNext() { bool result; try { switch (<>1__state) { default: result = false; break; case 0: <>1__state = -1; <result>5__1 = null; <>2__current = null; <>1__state = 1; result = true; break; case 1: <>1__state = -1; <www>5__2 = UnityWebRequest.Get("file://" + path); <>1__state = -3; <>2__current = <www>5__2.SendWebRequest(); <>1__state = 2; result = true; break; case 2: <>1__state = -3; if (<www>5__2.isNetworkError || <www>5__2.isHttpError) { SAD_Plugin.LogError(<www>5__2.error); result = false; <>m__Finally1(); } else { <result>5__1 = <www>5__2.downloadHandler.data; <>m__Finally1(); <www>5__2 = null; onComplete(<result>5__1); result = false; } break; } } catch { //try-fault ((IDisposable)this).Dispose(); throw; } return result; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } private void <>m__Finally1() { <>1__state = -1; if (<www>5__2 != null) { ((IDisposable)<www>5__2).Dispose(); } } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <LoadFishBadges>d__20 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <LoadFishBadges>d__20(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = ((MonoBehaviour)SAD_Plugin.Instance).StartCoroutine(LoadBadgeRings()); <>1__state = 1; return true; case 1: <>1__state = -1; <>2__current = ((MonoBehaviour)SAD_Plugin.Instance).StartCoroutine(LoadFishTextures()); <>1__state = 2; return true; case 2: <>1__state = -1; <>2__current = ((MonoBehaviour)SAD_Plugin.Instance).StartCoroutine(GenerateFishBadges()); <>1__state = 3; return true; case 3: <>1__state = -1; _fishBadgesLoaded = true; SAD_Plugin.LogDebug("Fish badges loaded."); return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <LoadFishTexture>d__24 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public string path; public string fishName; private <>c__DisplayClass24_0 <>8__1; private Texture2D <texture2D>5__2; private bool <success>5__3; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <LoadFishTexture>d__24(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>8__1 = null; <texture2D>5__2 = null; <>1__state = -2; } private bool MoveNext() { //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>8__1 = new <>c__DisplayClass24_0(); if (!File.Exists(path)) { SAD_Plugin.LogError("Fish texture file not found: " + path); return false; } <texture2D>5__2 = new Texture2D(1, 1); <>8__1.fileData = null; <>2__current = ((MonoBehaviour)SAD_Plugin.Instance).StartCoroutine(LoadFile(path, delegate(byte[] result) { <>8__1.fileData = result; })); <>1__state = 1; return true; case 1: <>1__state = -1; if (<>8__1.fileData != null && <>8__1.fileData.Length != 0) { <success>5__3 = ImageConversion.LoadImage(<texture2D>5__2, <>8__1.fileData); if (!<success>5__3) { SAD_Plugin.LogError("Failed to load fish texture from bytes: " + path); return false; } _fishTextures[fishName] = <texture2D>5__2; } return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <LoadFishTextures>d__23 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; private List<Coroutine> <fishCoroutines>5__1; private string[] <>s__2; private int <>s__3; private string <fishName>5__4; private string <path>5__5; private List<Coroutine>.Enumerator <>s__6; private Coroutine <coroutine>5__7; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <LoadFishTextures>d__23(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { int num = <>1__state; if (num == -3 || num == 1) { try { } finally { <>m__Finally1(); } } <fishCoroutines>5__1 = null; <>s__2 = null; <fishName>5__4 = null; <path>5__5 = null; <>s__6 = default(List<Coroutine>.Enumerator); <coroutine>5__7 = null; <>1__state = -2; } private bool MoveNext() { try { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <fishCoroutines>5__1 = new List<Coroutine>(); <>s__2 = FishCaughtUI.FishNames; for (<>s__3 = 0; <>s__3 < <>s__2.Length; <>s__3++) { <fishName>5__4 = <>s__2[<>s__3]; <path>5__5 = FindAssetPath(<fishName>5__4 + ".png"); <fishCoroutines>5__1.Add(((MonoBehaviour)SAD_Plugin.Instance).StartCoroutine(LoadFishTexture(<path>5__5, <fishName>5__4))); <path>5__5 = null; <fishName>5__4 = null; } <>s__2 = null; <>s__6 = <fishCoroutines>5__1.GetEnumerator(); <>1__state = -3; break; case 1: <>1__state = -3; <coroutine>5__7 = null; break; } if (<>s__6.MoveNext()) { <coroutine>5__7 = <>s__6.Current; <>2__current = <coroutine>5__7; <>1__state = 1; return true; } <>m__Finally1(); <>s__6 = default(List<Coroutine>.Enumerator); return false; } catch { //try-fault ((IDisposable)this).Dispose(); throw; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } private void <>m__Finally1() { <>1__state = -1; ((IDisposable)<>s__6).Dispose(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <LoadPortBadges>d__28 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; private List<Coroutine> <textureCoroutines>5__1; private IEnumerator<string> <>s__2; private string <pbName>5__3; private string <path>5__4; private List<Coroutine>.Enumerator <>s__5; private Coroutine <coroutine>5__6; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <LoadPortBadges>d__28(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { int num = <>1__state; if (num == -3 || num == 1) { try { } finally { <>m__Finally1(); } } <textureCoroutines>5__1 = null; <>s__2 = null; <pbName>5__3 = null; <path>5__4 = null; <>s__5 = default(List<Coroutine>.Enumerator); <coroutine>5__6 = null; <>1__state = -2; } private bool MoveNext() { try { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <textureCoroutines>5__1 = new List<Coroutine>(); <>s__2 = Region.AllBadgeNames.GetEnumerator(); try { while (<>s__2.MoveNext()) { <pbName>5__3 = <>s__2.Current; <path>5__4 = FindAssetPath(<pbName>5__3 + ".png"); <textureCoroutines>5__1.Add(((MonoBehaviour)SAD_Plugin.Instance).StartCoroutine(LoadTexture(<path>5__4, <pbName>5__3))); <path>5__4 = null; <pbName>5__3 = null; } } finally { if (<>s__2 != null) { <>s__2.Dispose(); } } <>s__2 = null; <>s__5 = <textureCoroutines>5__1.GetEnumerator(); <>1__state = -3; break; case 1: <>1__state = -3; <coroutine>5__6 = null; break; } if (<>s__5.MoveNext()) { <coroutine>5__6 = <>s__5.Current; <>2__current = <coroutine>5__6; <>1__state = 1; return true; } <>m__Finally1(); <>s__5 = default(List<Coroutine>.Enumerator); _portBadgesLoaded = true; SAD_Plugin.LogDebug("Port badges loaded."); return false; } catch { //try-fault ((IDisposable)this).Dispose(); throw; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } private void <>m__Finally1() { <>1__state = -1; ((IDisposable)<>s__5).Dispose(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <LoadTexture>d__29 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public string path; public string textureName; private <>c__DisplayClass29_0 <>8__1; private Texture2D <texture2D>5__2; private bool <success>5__3; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <LoadTexture>d__29(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>8__1 = null; <texture2D>5__2 = null; <>1__state = -2; } private bool MoveNext() { //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>8__1 = new <>c__DisplayClass29_0(); if (!File.Exists(path)) { SAD_Plugin.LogError("File not found: " + path); return false; } <texture2D>5__2 = new Texture2D(1, 1); <>8__1.fileData = null; <>2__current = ((MonoBehaviour)SAD_Plugin.Instance).StartCoroutine(LoadFile(path, delegate(byte[] result) { <>8__1.fileData = result; })); <>1__state = 1; return true; case 1: <>1__state = -1; if (<>8__1.fileData != null && <>8__1.fileData.Length != 0) { <success>5__3 = ImageConversion.LoadImage(<texture2D>5__2, <>8__1.fileData); if (!<success>5__3) { SAD_Plugin.LogError("Failed to load texture from bytes: " + path); return false; } _textures[textureName] = <texture2D>5__2; Materials[textureName] = CreateMaterial(<texture2D>5__2); } return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private static Dictionary<string, Texture2D> _textures; private static Dictionary<string, Texture2D> _fishTextures; private static Dictionary<int, Texture2D> _badgeRings; private static bool _fishBadgesLoaded; private static bool _portBadgesLoaded; private static readonly List<string> assetPaths = new List<string> { Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)SAD_Plugin.Instance).Info.Location), "Assets"), Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)SAD_Plugin.Instance).Info.Location)) }; public static bool BadgesLoaded => _fishBadgesLoaded && _portBadgesLoaded; public static AudioClip NotificationSound { get; private set; } public static Dictionary<string, Material> Materials { get; private set; } public static string FindAssetPath(string fileName) { foreach (string assetPath in assetPaths) { string text = Path.Combine(assetPath, fileName); if (File.Exists(text)) { return text; } } return null; } public static void Start() { Materials = new Dictionary<string, Material>(); _textures = new Dictionary<string, Texture2D>(); _fishTextures = new Dictionary<string, Texture2D>(); _badgeRings = new Dictionary<int, Texture2D>(); ((MonoBehaviour)SAD_Plugin.Instance).StartCoroutine(LoadAssetsAsync()); } [IteratorStateMachine(typeof(<LoadAssetsAsync>d__18))] private static IEnumerator LoadAssetsAsync() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <LoadAssetsAsync>d__18(0); } [IteratorStateMachine(typeof(<LoadAudio>d__19))] private static IEnumerator LoadAudio() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <LoadAudio>d__19(0); } [IteratorStateMachine(typeof(<LoadFishBadges>d__20))] private static IEnumerator LoadFishBadges() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <LoadFishBadges>d__20(0); } [IteratorStateMachine(typeof(<LoadBadgeRings>d__21))] private static IEnumerator LoadBadgeRings() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <LoadBadgeRings>d__21(0); } [IteratorStateMachine(typeof(<LoadBadgeRing>d__22))] private static IEnumerator LoadBadgeRing(string path, int amount) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <LoadBadgeRing>d__22(0) { path = path, amount = amount }; } [IteratorStateMachine(typeof(<LoadFishTextures>d__23))] private static IEnumerator LoadFishTextures() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <LoadFishTextures>d__23(0); } [IteratorStateMachine(typeof(<LoadFishTexture>d__24))] private static IEnumerator LoadFishTexture(string path, string fishName) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <LoadFishTexture>d__24(0) { path = path, fishName = fishName }; } [IteratorStateMachine(typeof(<GenerateFishBadges>d__25))] private static IEnumerator GenerateFishBadges() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <GenerateFishBadges>d__25(0); } private static Texture2D CombineTextures(Texture2D fishTexture, Texture2D ringTexture) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Expected O, but got Unknown //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) int width = ((Texture)ringTexture).width; int height = ((Texture)ringTexture).height; Texture2D val = new Texture2D(width, height, (TextureFormat)4, false); Color[] pixels = ringTexture.GetPixels(); val.SetPixels(pixels); Texture2D val2 = ScaleTexture(fishTexture, width, height); Color[] pixels2 = val2.GetPixels(); for (int i = 0; i < pixels.Length; i++) { Color val3 = pixels2[i]; Color val4 = pixels[i]; if (val3.a > 0f) { pixels[i] = Color.Lerp(val4, val3, val3.a); } } val.SetPixels(pixels); val.Apply(); Object.DestroyImmediate((Object)(object)val2); return val; } private static Texture2D ScaleTexture(Texture2D source, int targetWidth, int targetHeight) { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Expected O, but got Unknown //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) float num = (float)((Texture)source).width / (float)((Texture)source).height; float num2 = (float)targetWidth / (float)targetHeight; int num3; int num4; if (num > num2) { num3 = targetWidth; num4 = Mathf.RoundToInt((float)targetWidth / num); } else { num4 = targetHeight; num3 = Mathf.RoundToInt((float)targetHeight * num); } Texture2D val = new Texture2D(targetWidth, targetHeight, source.format, false); Color[] array = (Color[])(object)new Color[targetWidth * targetHeight]; for (int i = 0; i < array.Length; i++) { array[i] = Color.clear; } int num5 = (targetWidth - num3) / 2; int num6 = (targetHeight - num4) / 2; Color[] pixels = source.GetPixels(); for (int j = 0; j < num4; j++) { for (int k = 0; k < num3; k++) { float num7 = (float)k / (float)num3 * (float)((Texture)source).width; float num8 = (float)j / (float)num4 * (float)((Texture)source).height; int num9 = Mathf.FloorToInt(num7); int num10 = Mathf.FloorToInt(num8); num9 = Mathf.Clamp(num9, 0, ((Texture)source).width - 1); num10 = Mathf.Clamp(num10, 0, ((Texture)source).height - 1); int num11 = num10 * ((Texture)source).width + num9; int num12 = (j + num6) * targetWidth + (k + num5); if (num12 >= 0 && num12 < array.Length) { array[num12] = pixels[num11]; } } } val.SetPixels(array); val.Apply(); return val; } [IteratorStateMachine(typeof(<LoadPortBadges>d__28))] private static IEnumerator LoadPortBadges() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <LoadPortBadges>d__28(0); } [IteratorStateMachine(typeof(<LoadTexture>d__29))] private static IEnumerator LoadTexture(string path, string textureName) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <LoadTexture>d__29(0) { path = path, textureName = textureName }; } [IteratorStateMachine(typeof(<LoadFile>d__30))] private static IEnumerator LoadFile(string path, Action<byte[]> onComplete) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <LoadFile>d__30(0) { path = path, onComplete = onComplete }; } private static Material CreateMaterial(Texture2D tex) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Expected O, but got Unknown Material val = new Material(Shader.Find("Standard")) { renderQueue = 2001, mainTexture = (Texture)(object)tex }; val.EnableKeyword("_ALPHATEST_ON"); val.SetShaderPassEnabled("ShadowCaster", false); return val; } } internal class Configs { internal static ConfigEntry<bool> fishNamesHidden; internal static ConfigEntry<bool> portNamesHidden; internal static ConfigEntry<bool> fishCaughtUIEnabled; internal static ConfigEntry<bool> portsVisitedUIEnabled; internal static ConfigEntry<bool> statsUIEnabled; internal static ConfigEntry<bool> notificationsEnabled; internal static ConfigEntry<float> notificationSoundVolume; internal static ConfigEntry<string> updateMilesSailed; internal static void InitializeConfigs() { //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Expected O, but got Unknown ConfigFile config = ((BaseUnityPlugin)SAD_Plugin.Instance).Config; fishNamesHidden = config.Bind<bool>("Settings", "Hide Fish Names Before Caught", true, "true = fish names will be hidden before being caught for the first time."); portNamesHidden = config.Bind<bool>("Settings", "Hide Port Names Before Visited", false, "true = port names will be hidden before visited for the first time."); fishCaughtUIEnabled = config.Bind<bool>("Settings", "Enable Fish Caught UI", true, "true = UI for how many fish you caught will be enabled."); portsVisitedUIEnabled = config.Bind<bool>("Settings", "Enable Ports Visited UI", true, "true = UI for which ports you have visited will be enabled."); statsUIEnabled = config.Bind<bool>("Settings", "Enable Stats UI", true, "true = UI for various stats will be enabled."); notificationsEnabled = config.Bind<bool>("Settings", "Enable Notifications", true, "true = notifications on badge earned will be enabled."); notificationSoundVolume = config.Bind<float>("Settings", "Notification Volume", 0.2f, "Above 1f is loud and not recommended. Set to 0f to disable."); updateMilesSailed = config.Bind<string>("Settings", "Miles Sailed Updates", "moored", new ConfigDescription("Miles sailed text will be updated once moored, going to sleeping or moored, or in real time.", (AcceptableValueBase)(object)new AcceptableValueList<string>(new string[3] { "moored", "sleep", "realtime" }), Array.Empty<object>())); } } internal static class Extensions { public static T GetPrivateField<T>(this object obj, string field) { return (T)Traverse.Create(obj).Field(field).GetValue(); } public static T GetPrivateProperty<T>(this object obj, string property) { return (T)Traverse.Create(obj).Property(property, (object[])null).GetValue(); } } public class NotificationUiQueue : MonoBehaviour { private float _timer; private Queue<string> _queue; private AudioSource _audioSource; private const float TIMER_DURATION = 3f; public static NotificationUiQueue Instance { get; private set; } public void Start() { if ((Object)(object)Instance != (Object)null && (Object)(object)Instance != (Object)(object)this) { Object.Destroy((Object)(object)((Component)this).gameObject); return; } Instance = this; _queue = new Queue<string>(); _timer = 0f; _audioSource = ((Component)this).gameObject.AddComponent<AudioSource>(); _audioSource.volume = Configs.notificationSoundVolume.Value; _audioSource.spatialBlend = 1f; _audioSource.minDistance = 10f; _audioSource.maxDistance = 20f; } private void Update() { if (_timer > 0f) { _timer -= Time.deltaTime; return; } _timer = 0f; if (_queue.Count > 0) { NotificationUi.instance.ShowNotification(_queue.Dequeue()); if (Configs.notificationSoundVolume.Value > 0f) { _audioSource.PlayOneShot(AssetsLoader.NotificationSound); } _timer = 3f; } } public void QueueNotification(string message) { _queue.Enqueue(message); } } [BepInPlugin("com.raddude82.sailadex", "Sail-a-dex", "1.5.7")] [BepInDependency("com.raddude82.modsavebackups", "1.1.1")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public class SAD_Plugin : BaseUnityPlugin { public const string PLUGIN_GUID = "com.raddude82.sailadex"; public const string PLUGIN_NAME = "Sail-a-dex"; public const string PLUGIN_VERSION = "1.5.7"; public const string MODSAVEBACKUPS_GUID = "com.raddude82.modsavebackups"; public const string MODSAVEBACKUPS_VERSION = "1.1.1"; public const string PASSAGEDUDE_GUID = "pr0skynesis.passagedude"; public const string RANDOMENCOUNTERS_GUID = "com.raddude82.randomencounters"; internal static ManualLogSource _logger; internal static BaseUnityPlugin RE_PluginInstance { get; private set; } internal static SAD_Plugin Instance { get; private set; } internal static Harmony HarmonyInstance { get; private set; } internal static void LogDebug(string message) { _logger.LogDebug((object)message); } internal static void LogInfo(string message) { _logger.LogInfo((object)message); } internal static void LogWarning(string message) { _logger.LogWarning((object)message); } internal static void LogError(string message) { _logger.LogError((object)message); } private void Awake() { if ((Object)(object)Instance != (Object)null && (Object)(object)Instance != (Object)(object)this) { Object.Destroy((Object)(object)((Component)this).gameObject); return; } Instance = this; _logger = ((BaseUnityPlugin)this).Logger; Configs.InitializeConfigs(); AssetsLoader.Start(); HarmonyInstance = Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "com.raddude82.sailadex"); foreach (KeyValuePair<string, PluginInfo> pluginInfo in Chainloader.PluginInfos) { BepInPlugin metadata = pluginInfo.Value.Metadata; if (metadata.GUID.Equals("pr0skynesis.passagedude")) { LogInfo("pr0skynesis.passagedude found"); PassageDude.PatchMod(); } if (metadata.GUID.Equals("com.raddude82.randomencounters")) { LogInfo("com.raddude82.randomencounters found"); RE_PluginInstance = pluginInfo.Value.Instance; RandomEncounters.PatchMod(); } } } } public class PortsVisitedUI : MonoBehaviour { private TextMesh[] _portNameTMs; private TextMesh[] _portVisitedTMs; private Dictionary<string, GameObject> _portBadgeGOs; private Dictionary<string, bool> _visitedPorts; private Dictionary<string, bool> _portBadges; public static PortsVisitedUI Instance { get; private set; } public IReadOnlyDictionary<string, bool> VisitedPorts => _visitedPorts; public IReadOnlyDictionary<string, bool> PortBadges => _portBadges; private void Awake() { if ((Object)(object)Instance != (Object)null && (Object)(object)Instance != (Object)(object)this) { Object.Destroy((Object)(object)((Component)this).gameObject); return; } Instance = this; _visitedPorts = new Dictionary<string, bool>(); foreach (string allPort in Region.AllPorts) { _visitedPorts[allPort] = false; } _portBadges = new Dictionary<string, bool>(); foreach (string allBadgeName in Region.AllBadgeNames) { _portBadges[allBadgeName] = false; } } public void RegisterVisit(string portName) { if (!_visitedPorts.ContainsKey(portName)) { SAD_Plugin.LogWarning("Attempted to register visit to unknown port: " + portName); return; } if (!_visitedPorts[portName]) { _visitedPorts[portName] = true; CheckBadges(); } SAD_Plugin.LogDebug("Visited: " + portName); } public void UpdatePage() { UpdateTexts(); UpdateBadges(); } private void UpdateTexts() { int num = 0; foreach (KeyValuePair<string, bool> visitedPort in _visitedPorts) { if (num >= _portNameTMs.Length || num >= _portVisitedTMs.Length) { SAD_Plugin.LogWarning("Not enough TextMesh objects to display all ports"); break; } _portNameTMs[num].text = GetPortDisplayName(visitedPort.Key, visitedPort.Value); _portVisitedTMs[num].text = (visitedPort.Value ? "✓" : "✗"); num++; } } private string GetPortDisplayName(string portName, bool visited) { return (Configs.portNamesHidden.Value && !visited) ? "???" : portName; } public void CheckBadges() { foreach (Region allRegion in Region.AllRegions) { if (!_portBadges[allRegion.BadgeName] && allRegion.Ports.All((string p) => _visitedPorts[p])) { _portBadges[allRegion.BadgeName] = true; ShowBadgeNotification(allRegion.Name); } } if (!_portBadges["allPortsBadge"] && Region.AllPorts.All((string p) => _visitedPorts[p])) { _portBadges["allPortsBadge"] = true; ShowBadgeNotification("all"); } } private void ShowBadgeNotification(string region) { if (Configs.notificationsEnabled.Value) { string message = ((region != "all") ? ("Visited all\n" + region + " ports") : "Visited all ports"); NotificationUiQueue.Instance.QueueNotification(message); } } public void UpdateBadges() { foreach (KeyValuePair<string, bool> portBadge in _portBadges) { if (!_portBadgeGOs.ContainsKey(portBadge.Key)) { SAD_Plugin.LogWarning("Missing GameObject for badge: " + portBadge.Key); } else { _portBadgeGOs[portBadge.Key].SetActive(portBadge.Value); } } } public void SetUIElems(TextMesh[] portNameTMs, TextMesh[] portVisitedTMs, Dictionary<string, GameObject> portBadgeGOs) { _portNameTMs = portNameTMs; _portVisitedTMs = portVisitedTMs; _portBadgeGOs = portBadgeGOs; } public void LoadVisitedPorts(Dictionary<string, bool> visitedPorts) { SaveLoadPatches.LoadDictionary(visitedPorts, _visitedPorts); } public void LoadPortBadges(Dictionary<string, bool> portBadges) { SaveLoadPatches.LoadDictionary(portBadges, _portBadges); } } internal class SaveLoadPatches { [HarmonyPatch(typeof(SaveLoadManager))] private class SaveLoadManagerPatches { [HarmonyPostfix] [HarmonyPatch("SaveModData")] public static void DoSaveGamePatch() { SailadexSaveContainer sailadexSaveContainer = new SailadexSaveContainer { caughtFish = FishCaughtUI.Instance.CaughtFish.ToDictionary((KeyValuePair<string, int> entry) => entry.Key, (KeyValuePair<string, int> entry) => entry.Value), fishBadges = FishCaughtUI.Instance.FishBadges.ToDictionary((KeyValuePair<string, bool> entry) => entry.Key, (KeyValuePair<string, bool> entry) => entry.Value), visitedPorts = PortsVisitedUI.Instance.VisitedPorts.ToDictionary((KeyValuePair<string, bool> entry) => entry.Key, (KeyValuePair<string, bool> entry) => entry.Value), portBadges = PortsVisitedUI.Instance.PortBadges.ToDictionary((KeyValuePair<string, bool> entry) => entry.Key, (KeyValuePair<string, bool> entry) => entry.Value), floatStats = StatsUI.Instance.FloatStats.ToDictionary((KeyValuePair<string, float> entry) => entry.Key, (KeyValuePair<string, float> entry) => entry.Value), intStats = StatsUI.Instance.IntStats.ToDictionary((KeyValuePair<string, int> entry) => entry.Key, (KeyValuePair<string, int> entry) => entry.Value), boolArrayStats = StatsUI.Instance.BoolArrayStats.ToDictionary((KeyValuePair<string, bool[]> entry) => entry.Key, (Key