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.6.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.6.0.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("FishingBonanzaEncounters"); } } [HarmonyPostfix] public static void IntenseStormCountPatch() { if (IsIntenseStormEnabled) { StatsUI.Instance.IncrementIntStat("IntenseStormEncounters"); } } } internal static bool IsSeaLifeModEnabled { get { BaseUnityPlugin privateField = SAD_Plugin.RE_PluginInstance.GetPrivateField("seaLifeModInstance"); ConfigEntry privateField2 = SAD_Plugin.RE_PluginInstance.GetPrivateField>("controlSeaLifeMod"); if (privateField2 != null) { return (Object)(object)privateField != (Object)null && privateField2.Value; } return SAD_Plugin.RE_PluginInstance.GetPrivateProperty("IsSeaLifeModEnabled"); } } internal static bool IsFlotsamEnabled { get { if (SAD_Plugin.RE_PluginInstance.GetPrivateField>("enableFlotsam") != null) { return SAD_Plugin.RE_PluginInstance.GetPrivateField>("enableFlotsam").Value; } return SAD_Plugin.RE_PluginInstance.GetPrivateProperty("IsFlotsamEnabled"); } } internal static bool IsDenseFogEnabled { get { if (SAD_Plugin.RE_PluginInstance.GetPrivateField>("enableDenseFog") != null) { return SAD_Plugin.RE_PluginInstance.GetPrivateField>("enableDenseFog").Value; } return SAD_Plugin.RE_PluginInstance.GetPrivateProperty("IsDenseFogEnabled"); } } internal static bool IsFishingBonanzaEnabled { get { if (SAD_Plugin.RE_PluginInstance.GetPrivateField>("enableFishingBonanza") != null) { return SAD_Plugin.RE_PluginInstance.GetPrivateField>("enableFishingBonanza").Value; } return SAD_Plugin.RE_PluginInstance.GetPrivateProperty("IsFishingBonanzaEnabled"); } } internal static bool IsIntenseStormEnabled { get { if (SAD_Plugin.RE_PluginInstance.GetPrivateField>("enableIntenseStorm") != null) { return SAD_Plugin.RE_PluginInstance.GetPrivateField>("enableIntenseStorm").Value; } return SAD_Plugin.RE_PluginInstance.GetPrivateProperty("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().ropes where (Object)(object)r.GetPrivateField("mooredToSpring") != (Object)null select ((Object)((Component)r.GetPrivateField("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().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().AnyRopeMoored()) { string text = (from r in ((Component)___boatRigidbody).gameObject.GetComponent().ropes where (Object)(object)r.GetPrivateField("mooredToSpring") != (Object)null select ((Object)((Component)r.GetPrivateField("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 (GameState.playing) { if (Configs.statsUIEnabled.Value && (Object)(object)GameState.currentBoat != (Object)null && StatsUI.Instance.IsUnderway && __result <= 0.33f) { StatsUI.Instance.IncrementStormsWeathered(); } if (__result > 0.66f) { StatsUI.Instance.ClearLastStorm(); } } } } } public class FishCaughtUI : MonoBehaviour { public TextMesh[] _fishNameTMs; public TextMesh[] _caughtCountTMs; public Dictionary _fishBadgeGOs; public Dictionary _caughtFish; public Dictionary _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 CaughtFish => _caughtFish; public IReadOnlyDictionary 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(); _fishBadges = new Dictionary(); _fishBadgeGOs = new Dictionary(); 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()).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 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 fishBadge in _fishBadges) { _fishBadgeGOs[fishBadge.Key].SetActive(fishBadge.Value); } } public void SetUIElems(TextMesh[] fishNameTMs, TextMesh[] caughtCountTMs, Dictionary fishBadgeGOs) { _fishNameTMs = fishNameTMs; _caughtCountTMs = caughtCountTMs; _fishBadgeGOs = fishBadgeGOs; } public void LoadCaughtFish(Dictionary caughtFish) { ShimmertailNameFix(caughtFish); SaveLoadPatches.LoadDictionary(caughtFish, _caughtFish); } public void LoadFishBadges(Dictionary fishBadges) { ShimmertailNameFix(fishBadges); SaveLoadPatches.LoadDictionary(fishBadges, _fishBadges); } private void ShimmertailNameFix(Dictionary 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 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 stack = new Stack(); 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(); } } } private static GameObject fishCaughtUI; private static GameObject portsVisitedUI; private static GameObject statsUI; private static List bookmarks; } internal sealed class Region { private readonly int _index; private readonly string _name; private readonly string _badgeName; private readonly string _code; private readonly List _ports; private readonly List _islands; public static readonly Region AlAnkh; public static readonly Region EmeraldArchipelago; public static readonly Region Aestrin; public static readonly Region FireFishLagoon; public static readonly IReadOnlyList AllRegions; public static readonly IReadOnlyList AllBadgeNames; public int Index => _index; public string Name => _name; public string BadgeName => _badgeName; public string Code => _code; public IReadOnlyList Ports => _ports.AsReadOnly(); public IReadOnlyList Islands => _islands.AsReadOnly(); public static IReadOnlyList AllPorts { get; private set; } public static IReadOnlyList TransitCodes { get; private set; } private Region(int index, string name, string badgeName, string code, List ports, List islands) { _index = index; _name = name; _badgeName = badgeName; _code = code; _ports = ports; _islands = islands; } public override string ToString() { return Name ?? ""; } static Region() { AlAnkh = new Region(0, "Al'Ankh", "alankhBadge", "Aa", new List { "Gold Rock City", "Al'Nilem", "Neverdin", "Albacore Town", "Alchemist's Island", "Al'Ankh Academy", "Oasis", "Old Ankh Town", "Mirage Mountain", "Saffron Island" }, new List { "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)", "island 40 (coffee)", "island 41 (mirage mountain)", "island 42 ()" }); EmeraldArchipelago = new Region(1, "Emerald Archipelago", "emeraldBadge", "Ea", new List { "Dragon Cliffs", "Sanctuary", "Crab Beach", "New Port", "Sage Hills", "Serpent Isle", "Dead Cove", "Turtle Island" }, new List { "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)" }); Aestrin = new Region(2, "Aestrin", "mediBadge", "Ae", new List { "Fort Aestrin", "Sunspire", "Mount Malefic", "Siren Song", "Eastwind", "Firefly Grotto", "Aestra Abbey", "Fey Valley", "Happy Bay", "Chronos" }, new List { "island 15 M (Fort)", "island 16 M (Sunspire)", "island 17 M (Mount Malefic)", "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 18 M (Oasis)", "island 25 (chronos)" }); FireFishLagoon = new Region(3, "Fire Fish Lagoon", "lagoonBadge", "Ffl", new List { "Kicia Bay", "Fire Fish Town", "On'na", "Sen'na" }, new List { "island 26 Lagoon Temple", "island 27 Lagoon Shipyard", "island 28 Lagoon Senna", "island 29 Lagoon Onna", "island 31 Lagoon Fisherman" }); AllRegions = new List { AlAnkh, EmeraldArchipelago, Aestrin, FireFishLagoon }.AsReadOnly(); AllBadgeNames = new List { AlAnkh.BadgeName, EmeraldArchipelago.BadgeName, Aestrin.BadgeName, FireFishLagoon.BadgeName, "allPortsBadge" }.AsReadOnly(); List list = new List(); foreach (Region allRegion in AllRegions) { list.AddRange(allRegion.Ports); } AllPorts = list.AsReadOnly(); List list2 = new List(); foreach (Region allRegion2 in AllRegions) { foreach (Region allRegion3 in AllRegions) { if (allRegion2.Index != allRegion3.Index) { list2.Add(allRegion2.Code + allRegion3.Code); } } } TransitCodes = list2.AsReadOnly(); } } internal class UIBuilder { [CompilerGenerated] private sealed class d__12 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public Dictionary badgeGOs; public string name; public Transform parent; public Vector3 scale; public Vector3 position; private GameObject 5__1; private MeshRenderer 5__2; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__12(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { 5__1 = null; 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)(() => AssetsLoader.BadgesLoaded)); <>1__state = 1; return true; case 1: <>1__state = -1; 5__1 = GameObject.CreatePrimitive((PrimitiveType)5); 5__1.layer = 5; 5__1.transform.SetParent(parent, false); 5__1.transform.localScale = scale; 5__1.transform.localPosition = position; ((Object)5__1).name = name; if (name.Equals("allPortsBadge")) { 5__1.transform.localEulerAngles = new Vector3(0f, 180f, 0f); } 5__2 = 5__1.GetComponent(); ((Renderer)5__2).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)5__2).material = AssetsLoader.Materials[name]; Object.Destroy((Object)(object)5__1.GetComponent()); badgeGOs.Add(name, 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 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 list = new List(); GameObject gameObject = ((Component)modeButtons.transform.GetChild(9)).gameObject; GameObject val = Object.Instantiate(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().text = "fish caught"; GPButtonLogMode component = val.GetComponent(); Traverse.Create((object)component).Field("mode").SetValue((object)(MissionListMode)5); Object.Destroy((Object)(object)val.GetComponent()); list.Add(val); GameObject val2 = Object.Instantiate(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().text = "ports visited"; GPButtonLogMode component2 = val2.GetComponent(); Traverse.Create((object)component2).Field("mode").SetValue((object)(MissionListMode)6); Object.Destroy((Object)(object)val2.GetComponent()); list.Add(val2); GameObject val3 = Object.Instantiate(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().text = "stats & transit"; GPButtonLogMode component3 = val3.GetComponent(); Traverse.Create((object)component3).Field("mode").SetValue((object)(MissionListMode)7); Object.Destroy((Object)(object)val3.GetComponent()); 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_01c0: 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_01cf: Unknown result type (might be due to invalid IL or missing references) //IL_02e1: Unknown result type (might be due to invalid IL or missing references) //IL_02e6: Unknown result type (might be due to invalid IL or missing references) //IL_02f0: Unknown result type (might be due to invalid IL or missing references) //IL_0308: Unknown result type (might be due to invalid IL or missing references) //IL_0320: Unknown result type (might be due to invalid IL or missing references) //IL_04a6: Unknown result type (might be due to invalid IL or missing references) //IL_04ab: Unknown result type (might be due to invalid IL or missing references) //IL_04b5: Unknown result type (might be due to invalid IL or missing references) //IL_04cd: Unknown result type (might be due to invalid IL or missing references) //IL_04e5: Unknown result type (might be due to invalid IL or missing references) //IL_03a4: 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_056f: Unknown result type (might be due to invalid IL or missing references) //IL_058d: Unknown result type (might be due to invalid IL or missing references) GameObject val = Object.Instantiate(repUI); Object.Destroy((Object)(object)val.GetComponent()); 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(7)).gameObject); Object.Destroy((Object)(object)((Component)val.transform.GetChild(6)).gameObject); Object.Destroy((Object)(object)((Component)val.transform.GetChild(5)).gameObject); 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); Object.Destroy((Object)(object)((Component)val.transform.GetChild(0)).gameObject); val.AddComponent(); GameObject gameObject = ((Component)val.transform.GetChild(1)).gameObject; gameObject.SetActive(true); gameObject.GetComponent().font = ((Component)gameObject.transform.GetChild(1)).GetComponent().font; ((Renderer)gameObject.GetComponent()).material = ((Renderer)((Component)gameObject.transform.GetChild(1)).GetComponent()).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().fontSize = 50; TextMesh[] array = (TextMesh[])(object)new TextMesh[FishCaughtUI.FishNames.Length + 1]; TextMesh[] array2 = (TextMesh[])(object)new TextMesh[FishCaughtUI.FishNames.Length + 1]; Dictionary dictionary = new Dictionary(); for (int i = 0; i < FishCaughtUI.FishNames.Length; i++) { GameObject val2 = Object.Instantiate(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().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(); array[i] = ((Component)val2.transform.GetChild(1)).GetComponent(); 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); 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(); array[FishCaughtUI.FishNames.Length] = ((Component)val3.transform.GetChild(1)).GetComponent(); 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_0118: 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_0127: 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_0159: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_021f: Unknown result type (might be due to invalid IL or missing references) //IL_0224: Unknown result type (might be due to invalid IL or missing references) //IL_022e: Unknown result type (might be due to invalid IL or missing references) //IL_024b: Unknown result type (might be due to invalid IL or missing references) //IL_0268: Unknown result type (might be due to invalid IL or missing references) //IL_0744: Unknown result type (might be due to invalid IL or missing references) //IL_0758: Unknown result type (might be due to invalid IL or missing references) //IL_0433: Unknown result type (might be due to invalid IL or missing references) //IL_048c: Unknown result type (might be due to invalid IL or missing references) //IL_03dd: Unknown result type (might be due to invalid IL or missing references) //IL_0517: Unknown result type (might be due to invalid IL or missing references) //IL_051c: Unknown result type (might be due to invalid IL or missing references) //IL_052d: Unknown result type (might be due to invalid IL or missing references) //IL_0532: Unknown result type (might be due to invalid IL or missing references) //IL_054d: Unknown result type (might be due to invalid IL or missing references) //IL_0552: Unknown result type (might be due to invalid IL or missing references) //IL_055c: Unknown result type (might be due to invalid IL or missing references) //IL_0575: Unknown result type (might be due to invalid IL or missing references) //IL_058e: Unknown result type (might be due to invalid IL or missing references) //IL_05e8: Unknown result type (might be due to invalid IL or missing references) //IL_05ed: Unknown result type (might be due to invalid IL or missing references) //IL_05fe: Unknown result type (might be due to invalid IL or missing references) //IL_0603: Unknown result type (might be due to invalid IL or missing references) //IL_061e: Unknown result type (might be due to invalid IL or missing references) //IL_0623: Unknown result type (might be due to invalid IL or missing references) //IL_062d: Unknown result type (might be due to invalid IL or missing references) //IL_0646: Unknown result type (might be due to invalid IL or missing references) //IL_065f: Unknown result type (might be due to invalid IL or missing references) //IL_06e7: Unknown result type (might be due to invalid IL or missing references) //IL_06fb: Unknown result type (might be due to invalid IL or missing references) GameObject val = Object.Instantiate(repUI); Object.Destroy((Object)(object)val.GetComponent()); 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"; Object.Destroy((Object)(object)((Component)val.transform.GetChild(7)).gameObject); Object.Destroy((Object)(object)((Component)val.transform.GetChild(6)).gameObject); Object.Destroy((Object)(object)((Component)val.transform.GetChild(5)).gameObject); Object.Destroy((Object)(object)((Component)val.transform.GetChild(4)).gameObject); Object.Destroy((Object)(object)((Component)val.transform.GetChild(3)).gameObject); val.AddComponent(); Transform child = val.transform.GetChild(0); Vector3 localPosition = val.transform.GetChild(0).localPosition; child.localPosition = new Vector3(0.75f, 0.245f, ((Vector3)(ref localPosition))[2]); Transform child2 = val.transform.GetChild(1); localPosition = val.transform.GetChild(1).localPosition; child2.localPosition = new Vector3(0.75f, -0.05f, ((Vector3)(ref localPosition))[2]); Transform child3 = val.transform.GetChild(2); localPosition = val.transform.GetChild(2).localPosition; child3.localPosition = new Vector3(0.02f, 0.245f, ((Vector3)(ref localPosition))[2]); ((Component)val.transform.GetChild(1)).gameObject.SetActive(true); ((Component)val.transform.GetChild(2)).gameObject.SetActive(true); GameObject val2 = Object.Instantiate(((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.05f, ((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().text = "Fire Fish Lagoon"; TextMesh[] array = (TextMesh[])(object)new TextMesh[Region.AllPorts.Count]; TextMesh[] array2 = (TextMesh[])(object)new TextMesh[Region.AllPorts.Count]; Dictionary dictionary = new Dictionary(); 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); if (i == 3) { child4 = val.transform.GetChild(8); } 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); if (i == 0) { Object.Destroy((Object)(object)((Component)child4.GetChild(5)).gameObject); ((Component)child4.GetChild(6)).GetComponent().alignment = (TextAlignment)0; ((Component)child4.GetChild(6)).GetComponent().anchor = (TextAnchor)3; ((Component)child4.GetChild(6)).GetComponent().fontSize = 60; ((Component)child4.GetChild(6)).transform.localPosition = Vector3.zero; } GameObject gameObject = ((Component)child4.GetChild(0)).gameObject; GameObject gameObject2 = ((Component)child4.GetChild(3)).gameObject; gameObject2.SetActive(true); ((Object)gameObject).name = "port1"; gameObject.transform.localPosition = new Vector3(5f, -8f, -0.1f); gameObject.GetComponent().alignment = (TextAlignment)0; gameObject.GetComponent().anchor = (TextAnchor)3; gameObject.GetComponent().fontSize = 50; ((Object)gameObject2).name = "visited port1"; gameObject2.transform.localPosition = new Vector3(70f, -9f, 0f); gameObject2.GetComponent().alignment = (TextAlignment)2; gameObject2.GetComponent().anchor = (TextAnchor)5; gameObject2.GetComponent().fontSize = 50; array[num] = gameObject.GetComponent(); array2[num] = gameObject2.GetComponent(); num++; for (int j = 1; j < array3[i]; j++) { GameObject val3 = Object.Instantiate(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(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(); array2[num] = val4.GetComponent(); 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.15f, -0.23f, -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_01d8: Unknown result type (might be due to invalid IL or missing references) //IL_02f5: Unknown result type (might be due to invalid IL or missing references) //IL_04c4: Unknown result type (might be due to invalid IL or missing references) //IL_05a5: Unknown result type (might be due to invalid IL or missing references) //IL_0670: Unknown result type (might be due to invalid IL or missing references) GameObject val = Object.Instantiate(repUI); Object.Destroy((Object)(object)val.GetComponent()); 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(7)).gameObject); Object.Destroy((Object)(object)((Component)val.transform.GetChild(6)).gameObject); Object.Destroy((Object)(object)((Component)val.transform.GetChild(5)).gameObject); 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); Object.Destroy((Object)(object)((Component)val.transform.GetChild(0)).gameObject); val.AddComponent(); GameObject gameObject = ((Component)val.transform.GetChild(1)).gameObject; gameObject.SetActive(true); gameObject.GetComponent().font = ((Component)gameObject.transform.GetChild(1)).GetComponent().font; gameObject.GetComponent().fontSize = 40; gameObject.GetComponent().characterSize = 1f; ((Renderer)gameObject.GetComponent()).material = ((Renderer)((Component)gameObject.transform.GetChild(1)).GetComponent()).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().font = ((Component)gameObject.transform.GetChild(1)).GetComponent().font; ((Component)gameObject.transform.GetChild(0)).GetComponent().fontSize = 40; ((Component)gameObject.transform.GetChild(0)).GetComponent().anchor = (TextAnchor)3; ((Component)gameObject.transform.GetChild(0)).GetComponent().fontStyle = (FontStyle)0; ((Component)gameObject.transform.GetChild(0)).GetComponent().characterSize = 1f; ((Component)gameObject.transform.GetChild(0)).GetComponent().lineSpacing = 1f; ((Renderer)((Component)gameObject.transform.GetChild(0)).GetComponent()).material = ((Renderer)((Component)gameObject.transform.GetChild(1)).GetComponent()).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().fontSize = 40; ((Component)gameObject.transform.GetChild(1)).GetComponent().anchor = (TextAnchor)3; ((Component)gameObject.transform.GetChild(1)).GetComponent().fontStyle = (FontStyle)0; Dictionary dictionary = new Dictionary(); 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 list = new List(); 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().text = "Stat Current Record"; gameObject.transform.localPosition = new Vector3(0.82f, 0.24f, -0.007f); gameObject.GetComponent().fontSize = 45; gameObject.GetComponent().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.transform.parent); ((Object)val2).name = "lifetime stats header"; val2.GetComponent().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.transform.parent); ((Object)val3).name = "transit times header"; val3.GetComponent().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 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(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(); statTMs[text + name] = ((Component)val.transform.GetChild(0)).GetComponent(); if (!ltime) { statTMs["record" + name] = ((Component)val.transform.GetChild(1)).GetComponent(); } 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(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(); component.color = Color32.op_Implicit(new Color32((byte)2, (byte)2, (byte)10, (byte)133)); component.text = "--------------------------------------------------------"; } [IteratorStateMachine(typeof(d__12))] private static IEnumerator CreateBadgeObject(Dictionary 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 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 b__0(byte[] result) { fileData = result; } } [CompilerGenerated] private sealed class <>c__DisplayClass24_0 { public byte[] fileData; internal void b__0(byte[] result) { fileData = result; } } [CompilerGenerated] private sealed class <>c__DisplayClass29_0 { public byte[] fileData; internal void b__0(byte[] result) { fileData = result; } } [CompilerGenerated] private sealed class d__25 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; private int[] 5__1; private string[] <>s__2; private int <>s__3; private string 5__4; private Texture2D 5__5; private Dictionary 5__6; private int 5__7; private int 5__8; private Texture2D 5__9; private string 5__10; private string 5__11; private Texture2D 5__12; private Texture2D 5__13; private Dictionary.ValueCollection.Enumerator <>s__14; private Texture2D 5__15; private string[] <>s__16; private int <>s__17; private string 5__18; private string 5__19; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__25(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { 5__1 = null; <>s__2 = null; 5__4 = null; 5__5 = null; 5__6 = null; 5__9 = null; 5__10 = null; 5__11 = null; 5__12 = null; 5__13 = null; <>s__14 = default(Dictionary.ValueCollection.Enumerator); 5__15 = null; <>s__16 = null; 5__18 = null; 5__19 = null; <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; 5__1 = new int[3] { 25, 50, 100 }; <>s__2 = FishCaughtUI.FishNames; <>s__3 = 0; goto IL_0334; case 1: <>1__state = -1; 5__5 = null; 5__6 = null; 5__4 = null; goto IL_0326; case 2: { <>1__state = -1; 5__19 = null; 5__18 = null; <>s__17++; break; } IL_0334: if (<>s__3 < <>s__2.Length) { 5__4 = <>s__2[<>s__3]; if (!_fishTextures.ContainsKey(5__4)) { SAD_Plugin.LogError("Fish texture not found for: " + 5__4); goto IL_0326; } 5__5 = _fishTextures[5__4]; 5__6 = new Dictionary(); 5__7 = 0; while (5__7 < 5__1.Length) { 5__8 = 5__1[5__7]; if (!_badgeRings.ContainsKey(5__8)) { SAD_Plugin.LogError($"Badge ring not found for amount: {5__8}"); } else { 5__9 = _badgeRings[5__8]; 5__10 = 5__4 + 5__8; 5__11 = $"{((Texture)5__9).width}x{((Texture)5__9).height}"; if (!5__6.TryGetValue(5__11, out 5__12)) { 5__12 = ScaleTexture(5__5, ((Texture)5__9).width, ((Texture)5__9).height); 5__6.Add(5__11, 5__12); } 5__13 = CombineTextures(5__12, 5__9); ((Object)5__13).name = 5__10; _textures[5__10] = 5__13; Materials[5__10] = CreateMaterial(5__13); 5__9 = null; 5__10 = null; 5__11 = null; 5__12 = null; 5__13 = null; } 5__7++; } <>s__14 = 5__6.Values.GetEnumerator(); try { while (<>s__14.MoveNext()) { 5__15 = <>s__14.Current; Object.DestroyImmediate((Object)(object)5__15); 5__15 = null; } } finally { ((IDisposable)<>s__14).Dispose(); } <>s__14 = default(Dictionary.ValueCollection.Enumerator); <>2__current = null; <>1__state = 1; return true; } <>s__2 = null; <>s__16 = FishCaughtUI.TotalFishBadgeNames; <>s__17 = 0; break; IL_0326: <>s__3++; goto IL_0334; } if (<>s__17 < <>s__16.Length) { 5__18 = <>s__16[<>s__17]; 5__19 = FindAssetPath(5__18 + ".png"); <>2__current = ((MonoBehaviour)SAD_Plugin.Instance).StartCoroutine(LoadTexture(5__19, 5__18)); <>1__state = 2; return true; } <>s__16 = 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 d__18 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; private Coroutine 5__1; private Coroutine 5__2; private Coroutine 5__3; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__18(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { 5__1 = null; 5__2 = null; 5__3 = null; <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; 5__1 = ((MonoBehaviour)SAD_Plugin.Instance).StartCoroutine(LoadAudio()); 5__2 = ((MonoBehaviour)SAD_Plugin.Instance).StartCoroutine(LoadFishBadges()); 5__3 = ((MonoBehaviour)SAD_Plugin.Instance).StartCoroutine(LoadPortBadges()); <>2__current = 5__1; <>1__state = 1; return true; case 1: <>1__state = -1; <>2__current = 5__2; <>1__state = 2; return true; case 2: <>1__state = -1; <>2__current = 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 d__19 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; private string 5__1; private UnityWebRequest 5__2; private AudioClip 5__3; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public 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(); } } 5__1 = null; 5__2 = null; 5__3 = null; <>1__state = -2; } private bool MoveNext() { bool result; try { switch (<>1__state) { default: result = false; break; case 0: <>1__state = -1; 5__1 = FindAssetPath("twoBells.wav"); 5__2 = UnityWebRequestMultimedia.GetAudioClip("file://" + 5__1, (AudioType)20); <>1__state = -3; <>2__current = 5__2.SendWebRequest(); <>1__state = 1; result = true; break; case 1: <>1__state = -3; if (5__2.isNetworkError || 5__2.isHttpError) { SAD_Plugin.LogError(5__2.error); result = false; <>m__Finally1(); break; } 5__3 = DownloadHandlerAudioClip.GetContent(5__2); ((Object)5__3).name = "twoBells"; NotificationSound = 5__3; SAD_Plugin.LogDebug("Audio loaded."); 5__3 = null; <>m__Finally1(); 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 (5__2 != null) { ((IDisposable)5__2).Dispose(); } } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class d__22 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public string path; public int amount; private <>c__DisplayClass22_0 <>8__1; private Texture2D 5__2; private bool 5__3; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__22(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>8__1 = null; 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; } 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) { 5__3 = ImageConversion.LoadImage(5__2, <>8__1.fileData); if (!5__3) { SAD_Plugin.LogError("Failed to load badge ring from bytes: " + path); return false; } _badgeRings[amount] = 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 d__21 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; private int[] 5__1; private List 5__2; private int[] <>s__3; private int <>s__4; private int 5__5; private string 5__6; private string 5__7; private List.Enumerator <>s__8; private Coroutine 5__9; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public 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(); } } 5__1 = null; 5__2 = null; <>s__3 = null; 5__6 = null; 5__7 = null; <>s__8 = default(List.Enumerator); 5__9 = null; <>1__state = -2; } private bool MoveNext() { try { switch (<>1__state) { default: return false; case 0: <>1__state = -1; 5__1 = new int[3] { 25, 50, 100 }; 5__2 = new List(); <>s__3 = 5__1; for (<>s__4 = 0; <>s__4 < <>s__3.Length; <>s__4++) { 5__5 = <>s__3[<>s__4]; 5__6 = 5__5 + "Fish"; 5__7 = FindAssetPath(5__6 + ".png"); 5__2.Add(((MonoBehaviour)SAD_Plugin.Instance).StartCoroutine(LoadBadgeRing(5__7, 5__5))); 5__6 = null; 5__7 = null; } <>s__3 = null; <>s__8 = 5__2.GetEnumerator(); <>1__state = -3; break; case 1: <>1__state = -3; 5__9 = null; break; } if (<>s__8.MoveNext()) { 5__9 = <>s__8.Current; <>2__current = 5__9; <>1__state = 1; return true; } <>m__Finally1(); <>s__8 = default(List.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 d__30 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public string path; public Action onComplete; private byte[] 5__1; private UnityWebRequest 5__2; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public 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(); } } 5__1 = null; 5__2 = null; <>1__state = -2; } private bool MoveNext() { bool result; try { switch (<>1__state) { default: result = false; break; case 0: <>1__state = -1; 5__1 = null; <>2__current = null; <>1__state = 1; result = true; break; case 1: <>1__state = -1; 5__2 = UnityWebRequest.Get("file://" + path); <>1__state = -3; <>2__current = 5__2.SendWebRequest(); <>1__state = 2; result = true; break; case 2: <>1__state = -3; if (5__2.isNetworkError || 5__2.isHttpError) { SAD_Plugin.LogError(5__2.error); result = false; <>m__Finally1(); } else { 5__1 = 5__2.downloadHandler.data; <>m__Finally1(); 5__2 = null; onComplete(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 (5__2 != null) { ((IDisposable)5__2).Dispose(); } } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class d__20 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public 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 d__24 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public string path; public string fishName; private <>c__DisplayClass24_0 <>8__1; private Texture2D 5__2; private bool 5__3; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__24(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>8__1 = null; 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; } 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) { 5__3 = ImageConversion.LoadImage(5__2, <>8__1.fileData); if (!5__3) { SAD_Plugin.LogError("Failed to load fish texture from bytes: " + path); return false; } _fishTextures[fishName] = 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 d__23 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; private List 5__1; private string[] <>s__2; private int <>s__3; private string 5__4; private string 5__5; private List.Enumerator <>s__6; private Coroutine 5__7; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public 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(); } } 5__1 = null; <>s__2 = null; 5__4 = null; 5__5 = null; <>s__6 = default(List.Enumerator); 5__7 = null; <>1__state = -2; } private bool MoveNext() { try { switch (<>1__state) { default: return false; case 0: <>1__state = -1; 5__1 = new List(); <>s__2 = FishCaughtUI.FishNames; for (<>s__3 = 0; <>s__3 < <>s__2.Length; <>s__3++) { 5__4 = <>s__2[<>s__3]; 5__5 = FindAssetPath(5__4 + ".png"); 5__1.Add(((MonoBehaviour)SAD_Plugin.Instance).StartCoroutine(LoadFishTexture(5__5, 5__4))); 5__5 = null; 5__4 = null; } <>s__2 = null; <>s__6 = 5__1.GetEnumerator(); <>1__state = -3; break; case 1: <>1__state = -3; 5__7 = null; break; } if (<>s__6.MoveNext()) { 5__7 = <>s__6.Current; <>2__current = 5__7; <>1__state = 1; return true; } <>m__Finally1(); <>s__6 = default(List.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 d__28 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; private List 5__1; private IEnumerator <>s__2; private string 5__3; private string 5__4; private List.Enumerator <>s__5; private Coroutine 5__6; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public 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(); } } 5__1 = null; <>s__2 = null; 5__3 = null; 5__4 = null; <>s__5 = default(List.Enumerator); 5__6 = null; <>1__state = -2; } private bool MoveNext() { try { switch (<>1__state) { default: return false; case 0: <>1__state = -1; 5__1 = new List(); <>s__2 = Region.AllBadgeNames.GetEnumerator(); try { while (<>s__2.MoveNext()) { 5__3 = <>s__2.Current; 5__4 = FindAssetPath(5__3 + ".png"); 5__1.Add(((MonoBehaviour)SAD_Plugin.Instance).StartCoroutine(LoadTexture(5__4, 5__3))); 5__4 = null; 5__3 = null; } } finally { if (<>s__2 != null) { <>s__2.Dispose(); } } <>s__2 = null; <>s__5 = 5__1.GetEnumerator(); <>1__state = -3; break; case 1: <>1__state = -3; 5__6 = null; break; } if (<>s__5.MoveNext()) { 5__6 = <>s__5.Current; <>2__current = 5__6; <>1__state = 1; return true; } <>m__Finally1(); <>s__5 = default(List.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 d__29 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public string path; public string textureName; private <>c__DisplayClass29_0 <>8__1; private Texture2D 5__2; private bool 5__3; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__29(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>8__1 = null; 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; } 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) { 5__3 = ImageConversion.LoadImage(5__2, <>8__1.fileData); if (!5__3) { SAD_Plugin.LogError("Failed to load texture from bytes: " + path); return false; } _textures[textureName] = 5__2; Materials[textureName] = CreateMaterial(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 _textures; private static Dictionary _fishTextures; private static Dictionary _badgeRings; private static bool _fishBadgesLoaded; private static bool _portBadgesLoaded; private static readonly List assetPaths = new List { 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 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(); _textures = new Dictionary(); _fishTextures = new Dictionary(); _badgeRings = new Dictionary(); ((MonoBehaviour)SAD_Plugin.Instance).StartCoroutine(LoadAssetsAsync()); } [IteratorStateMachine(typeof(d__18))] private static IEnumerator LoadAssetsAsync() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__18(0); } [IteratorStateMachine(typeof(d__19))] private static IEnumerator LoadAudio() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__19(0); } [IteratorStateMachine(typeof(d__20))] private static IEnumerator LoadFishBadges() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__20(0); } [IteratorStateMachine(typeof(d__21))] private static IEnumerator LoadBadgeRings() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__21(0); } [IteratorStateMachine(typeof(d__22))] private static IEnumerator LoadBadgeRing(string path, int amount) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__22(0) { path = path, amount = amount }; } [IteratorStateMachine(typeof(d__23))] private static IEnumerator LoadFishTextures() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__23(0); } [IteratorStateMachine(typeof(d__24))] private static IEnumerator LoadFishTexture(string path, string fishName) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__24(0) { path = path, fishName = fishName }; } [IteratorStateMachine(typeof(d__25))] private static IEnumerator GenerateFishBadges() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__25(0); } private static Texture2D CombineTextures(Texture2D scaledFishTexture, Texture2D ringTexture) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Expected O, but got Unknown //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0063: 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_0067: 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_0073: 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); Color[] pixels2 = scaledFishTexture.GetPixels(); for (int i = 0; i < pixels.Length; i++) { Color val2 = pixels2[i]; Color val3 = pixels[i]; if (val2.a > 0f) { pixels[i] = Color.Lerp(val3, val2, val2.a); } } val.SetPixels(pixels); val.Apply(); 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(d__28))] private static IEnumerator LoadPortBadges() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__28(0); } [IteratorStateMachine(typeof(d__29))] private static IEnumerator LoadTexture(string path, string textureName) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__29(0) { path = path, textureName = textureName }; } [IteratorStateMachine(typeof(d__30))] private static IEnumerator LoadFile(string path, Action onComplete) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new 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 fishNamesHidden; internal static ConfigEntry portNamesHidden; internal static ConfigEntry fishCaughtUIEnabled; internal static ConfigEntry portsVisitedUIEnabled; internal static ConfigEntry statsUIEnabled; internal static ConfigEntry notificationsEnabled; internal static ConfigEntry notificationSoundVolume; internal static ConfigEntry 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("Settings", "Hide Fish Names Before Caught", true, "true = fish names will be hidden before being caught for the first time."); portNamesHidden = config.Bind("Settings", "Hide Port Names Before Visited", false, "true = port names will be hidden before visited for the first time."); fishCaughtUIEnabled = config.Bind("Settings", "Enable Fish Caught UI", true, "true = UI for how many fish you caught will be enabled."); portsVisitedUIEnabled = config.Bind("Settings", "Enable Ports Visited UI", true, "true = UI for which ports you have visited will be enabled."); statsUIEnabled = config.Bind("Settings", "Enable Stats UI", true, "true = UI for various stats will be enabled."); notificationsEnabled = config.Bind("Settings", "Enable Notifications", true, "true = notifications on badge earned will be enabled."); notificationSoundVolume = config.Bind("Settings", "Notification Volume", 0.2f, "Above 1f is loud and not recommended. Set to 0f to disable."); updateMilesSailed = config.Bind("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(new string[3] { "moored", "sleep", "realtime" }), Array.Empty())); } } internal static class Extensions { public static T GetPrivateField(this object obj, string field) { return (T)Traverse.Create(obj).Field(field).GetValue(); } public static T GetPrivateProperty(this object obj, string property) { return (T)Traverse.Create(obj).Property(property, (object[])null).GetValue(); } } public class NotificationUiQueue : MonoBehaviour { [CompilerGenerated] private sealed class d__9 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public NotificationUiQueue <>4__this; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__9(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; break; case 1: <>1__state = -1; break; } if (<>4__this._queue.Count > 0) { NotificationUi.instance.ShowNotification(<>4__this._queue.Dequeue()); if (Configs.notificationSoundVolume.Value > 0f) { <>4__this._audioSource.PlayOneShot(AssetsLoader.NotificationSound); } <>2__current = (object)new WaitForSeconds(3f); <>1__state = 1; return true; } <>4__this._queueCoroutine = 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(); } } private Coroutine _queueCoroutine; private Queue _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(); _queueCoroutine = null; _audioSource = ((Component)this).gameObject.AddComponent(); _audioSource.volume = Configs.notificationSoundVolume.Value; _audioSource.spatialBlend = 1f; _audioSource.minDistance = 10f; _audioSource.maxDistance = 20f; } [IteratorStateMachine(typeof(d__9))] private IEnumerator ProcessQueue() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__9(0) { <>4__this = this }; } public void QueueNotification(string message) { _queue.Enqueue(message); if (_queueCoroutine == null) { _queueCoroutine = ((MonoBehaviour)this).StartCoroutine(ProcessQueue()); } } } [BepInPlugin("com.raddude82.sailadex", "Sail-a-dex", "1.6.0")] [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.6.0"; 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 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 _portBadgeGOs; private Dictionary _visitedPorts; private Dictionary _portBadges; public static PortsVisitedUI Instance { get; private set; } public IReadOnlyDictionary VisitedPorts => _visitedPorts; public IReadOnlyDictionary 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(); foreach (string allPort in Region.AllPorts) { _visitedPorts[allPort] = false; } _portBadges = new Dictionary(); 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 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 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 portBadgeGOs) { _portNameTMs = portNameTMs; _portVisitedTMs = portVisitedTMs; _portBadgeGOs = portBadgeGOs; } public void LoadVisitedPorts(Dictionary visitedPorts) { SaveLoadPatches.LoadDictionary(visitedPorts, _visitedPorts); } public void LoadPortBadges(Dictionary 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 entry) => entry.Key, (KeyValuePair entry) => entry.Value), fishBadges = FishCaughtUI.Instance.FishBadges.ToDictionary((KeyValuePair entry) => entry.Key, (KeyValuePair entry) => entry.Value), visitedPorts = PortsVisitedUI.Instance.VisitedPorts.ToDictionary((KeyValuePair entry) => entry.Key, (KeyValuePair entry) => entry.Value), portBadges = PortsVisitedUI.Instance.PortBadges.ToDictionary((KeyValuePair entry) => entry.Key, (KeyValuePair entry) => entry.Value), floatStats = StatsUI.Instance.FloatStats.ToDictionary((KeyValuePair entry) => entry.Key, (KeyValuePair entry) => entry.Value), intStats = StatsUI.Instance.IntStats.ToDictionary((KeyValuePair entry) => entry.Key, (KeyValuePair entry) => entry.Value), boolArrayStats = StatsUI.Instance.BoolArrayStats.ToDictionary((KeyValuePair entry) => entry.Key, (KeyValuePair entry) => entry.Value), isUnderway = StatsUI.Instance.IsUnderway, lastStorm = StatsUI.Instance.lastStorm, lastPortVisited = StatsUI.Instance.lastPortVisited }; ModSave.Save(((BaseUnityPlugin)SAD_Plugin.Instance).Info, (object)sailadexSaveContainer); } [HarmonyPostfix] [HarmonyPatch("LoadModData")] public static void LoadModDataPatch() { SailadexSaveContainer sailadexSaveContainer = default(SailadexSaveContainer); if (!ModSave.Load(((BaseUnityPlugin)SAD_Plugin.Instance).Info, ref sailadexSaveContainer)) { SAD_Plugin.LogWarning("Save file loading failed. If this is the first time loading this save with this mod, this is normal."); return; } if (sailadexSaveContainer.caughtFish != null) { FishCaughtUI.Instance.LoadCaughtFish(sailadexSaveContainer.caughtFish); } if (sailadexSaveContainer.fishBadges != null) { FishCaughtUI.Instance.LoadFishBadges(sailadexSaveContainer.fishBadges); } if (sailadexSaveContainer.visitedPorts != null) { PortsVisitedUI.Instance.LoadVisitedPorts(sailadexSaveContainer.visitedPorts); } if (sailadexSaveContainer.portBadges != null) { PortsVisitedUI.Instance.LoadPortBadges(sailadexSaveContainer.portBadges); } if (sailadexSaveContainer.floatStats != null) { StatsUI.Instance.LoadFloatStats(sailadexSaveContainer.floatStats); } if (sailadexSaveContainer.intStats != null) { StatsUI.Instance.LoadIntStats(sailadexSaveContainer.intStats); } if (sailadexSaveContainer.boolArrayStats != null) { StatsUI.Instance.LoadBoolArrayStats(sailadexSaveContainer.boolArrayStats); } if (sailadexSaveContainer.lastStorm != null) { StatsUI.Instance.lastStorm = sailadexSaveContainer.lastStorm; } if (sailadexSaveContainer.lastPortVisited != null) { StatsUI.Instance.lastPortVisited = sailadexSaveContainer.lastPortVisited; } StatsUI.Instance.IsUnderway = sailadexSaveContainer.isUnderway; } } public static void LoadDictionary(Dictionary saveDict, Dictionary gameDict) { foreach (KeyValuePair item in saveDict) { if (!gameDict.ContainsKey(item.Key)) { SAD_Plugin.LogWarning("LoadData: " + item.Key + " not found in game"); } else { gameDict[item.Key] = item.Value; } } } } [Serializable] public class SailadexSaveContainer { public Dictionary caughtFish; public Dictionary visitedPorts; public Dictionary fishBadges; public Dictionary portBadges; public Dictionary floatStats; public Dictionary intStats; public Dictionary boolArrayStats; public bool isUnderway; public string lastStorm; public string lastPortVisited; } public class StatsUI : MonoBehaviour { private Dictionary _statTMs; private Dictionary _floatStats; private Dictionary _intStats; private Dictionary _boolArrayStats; private Vector3 lastPosition; internal string lastPortVisited; private int trackerTimer; internal string lastStorm; private const int TRACKER_TIMER_VALUE = 1000; private const float MILES_CONVERSION_FACTOR = 61f; public static readonly string[] FloatStatNames = new string[4] { "CargoMass", "TotalMass", "UnderwayTime", "MilesSailed" }; public static readonly string[] IntStatNames = new string[13] { "UnderwayDay", "PortsVisited", "MissionsCompleted", "DrinksTaken", "FoodsEaten", "TimesSmoked", "TimesSlept", "StormsWeathered", "FlotsamEncounters", "DenseFogEncounters", "SeaLifeEncounters", "FishingBonanzaEncounters", "IntenseStormEncounters" }; private static readonly Dictionary> _randomEncounterStats = new Dictionary> { { "FlotsamEncounters", () => RandomEncounters.IsFlotsamEnabled }, { "DenseFogEncounters", () => RandomEncounters.IsDenseFogEnabled }, { "SeaLifeEncounters", () => RandomEncounters.IsSeaLifeModEnabled }, { "FishingBonanzaEncounters", () => RandomEncounters.IsFishingBonanzaEnabled }, { "IntenseStormEncounters", () => RandomEncounters.IsIntenseStormEnabled } }; public static StatsUI Instance { get; private set; } public bool IsUnderway { get; internal set; } public static IReadOnlyDictionary> RandomEncounterStats => _randomEncounterStats; public static List RandomEncounterStatYPos { get; set; } public IReadOnlyDictionary FloatStats => _floatStats; public IReadOnlyDictionary IntStats => _intStats; public IReadOnlyDictionary BoolArrayStats => _boolArrayStats; private void Awake() { //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)Instance != (Object)null && (Object)(object)Instance != (Object)(object)this) { Object.Destroy((Object)(object)((Component)this).gameObject); return; } Instance = this; _floatStats = new Dictionary(); _intStats = new Dictionary(); _boolArrayStats = new Dictionary(); _statTMs = new Dictionary(); lastPosition = Vector3.zero; lastPortVisited = string.Empty; trackerTimer = 1000; lastStorm = string.Empty; IsUnderway = false; string[] floatStatNames = FloatStatNames; foreach (string text in floatStatNames) { _floatStats.Add(text, 0f); _floatStats.Add("current" + text, 0f); _floatStats.Add("record" + text, 0f); } string[] intStatNames = IntStatNames; foreach (string text2 in intStatNames) { _intStats.Add(text2, 0); _intStats.Add("current" + text2, 0); _intStats.Add("record" + text2, 0); } foreach (string transitCode in Region.TransitCodes) { _floatStats.Add("last" + transitCode + "TransitTime", 0f); _intStats.Add("last" + transitCode + "TransitDay", 0); _floatStats.Add("record" + transitCode + "TransitTime", 0f); _intStats.Add("record" + transitCode + "TransitDay", 0); } foreach (Region allRegion in Region.AllRegions) { _floatStats.Add(allRegion.Code + "UnderwayTime", 0f); _intStats.Add(allRegion.Code + "UnderwayDay", 0); _boolArrayStats.Add(allRegion.Code + "Transit", new bool[4]); } } public void RegisterCurrentMass() { Transform currentBoat = GameState.currentBoat; if (!((Object)(object)((currentBoat != null) ? currentBoat.parent : null) == (Object)null) || !((Object)(object)GameState.lastBoat == (Object)null)) { GameObject val = (((Object)(object)GameState.currentBoat != (Object)null) ? ((Component)GameState.currentBoat.parent).gameObject : ((Component)GameState.lastBoat).gameObject); _floatStats["currentCargoMass"] = (from item in val.GetComponent().GetPrivateField>("itemsOnBoat") where IsCargoItem(item) select item).Sum((ItemRigidbody item) => item.GetBody().mass); } } private bool IsCargoItem(ItemRigidbody item) { Good component = ((Component)item.GetShipItem()).GetComponent(); if ((Object)(object)component == (Object)null) { return false; } string sizeDescription = component.sizeDescription; return sizeDescription.Contains("crate") || sizeDescription.Contains("package") || sizeDescription.Contains("barrel") || sizeDescription.Contains("bundle"); } public void RegisterTotalMass(float totalMass) { _floatStats["currentTotalMass"] = totalMass; } private void UpdateMassRecords() { if (_floatStats["recordCargoMass"] < _floatStats["currentCargoMass"]) { _floatStats["recordCargoMass"] = _floatStats["currentCargoMass"]; } if (_floatStats["recordTotalMass"] < _floatStats["currentTotalMass"]) { _floatStats["recordTotalMass"] = _floatStats["currentTotalMass"]; } } public void RegisterUnderway(string islandName) { if (string.IsNullOrEmpty(islandName)) { return; } IsUnderway = true; UpdateMassRecords(); ResetUnderwayTimers(); if (islandName == "island 18 M (HappyBay)") { return; } foreach (Region allRegion in Region.AllRegions) { if (allRegion.Islands.Contains(islandName)) { TrackRegionUnderway(allRegion.Code); break; } } } private void ResetUnderwayTimers() { _floatStats["UnderwayTime"] = Sun.sun.globalTime; _intStats["UnderwayDay"] = GameState.day; } private void TrackRegionUnderway(string regionCode) { _floatStats[regionCode + "UnderwayTime"] = Sun.sun.globalTime; _intStats[regionCode + "UnderwayDay"] = GameState.day; for (int i = 0; i < Region.AllRegions.Count; i++) { _boolArrayStats[regionCode + "Transit"][i] = false; } } private void UpdateUnderwayRecords() { if (_intStats["currentUnderwayDay"] > _intStats["recordUnderwayDay"] || (_intStats["currentUnderwayDay"] == _intStats["recordUnderwayDay"] && _floatStats["currentUnderwayTime"] > _floatStats["recordUnderwayTime"])) { _intStats["recordUnderwayDay"] = _intStats["currentUnderwayDay"]; _floatStats["recordUnderwayTime"] = _floatStats["currentUnderwayTime"]; } _floatStats["UnderwayTime"] = 0f; _intStats["UnderwayDay"] = 0; } public void RegisterMoored(string islandName) { if (!Utility.IsNullOrWhiteSpace(islandName)) { IsUnderway = false; UpdateStats(); UpdateUnderwayRecords(); if (!islandName.Equals("island 18 M (HappyBay)")) { ProcessRegionalArrival(islandName); } } } private void ProcessRegionalArrival(string islandName) { foreach (Region allRegion in Region.AllRegions) { if (!allRegion.Islands.Contains(islandName)) { continue; } { foreach (Region allRegion2 in Region.AllRegions) { if (!(allRegion2.Code == allRegion.Code)) { CheckPossibleTransit(allRegion2.Code, allRegion.Code, allRegion.Index); } } break; } } } private void CheckPossibleTransit(string departureRegion, string arrivalRegion, int arrivalIndex) { string transitCode = departureRegion + arrivalRegion; bool flag = _floatStats[departureRegion + "UnderwayTime"] > 0f || _intStats[departureRegion + "UnderwayDay"] > 0; bool flag2 = _boolArrayStats[departureRegion + "Transit"][arrivalIndex]; if (!flag2 && flag) { CheckTransitTime(departureRegion, transitCode, arrivalIndex); } } public void CheckTransitTime(string underwayKey, string transitCode, int destInt) { int num = GameState.day - _intStats[underwayKey + "UnderwayDay"]; float num2 = Sun.sun.globalTime - _floatStats[underwayKey + "UnderwayTime"]; if (num2 < 0f) { num2 += 24f; num--; } _intStats["last" + transitCode + "TransitDay"] = num; _floatStats["last" + transitCode + "TransitTime"] = num2; if ((_intStats["record" + transitCode + "TransitDay"] == 0 && _floatStats["record" + transitCode + "TransitTime"] == 0f) || _intStats["record" + transitCode + "TransitDay"] > num || (_intStats["record" + transitCode + "TransitDay"] == num && _floatStats["record" + transitCode + "TransitTime"] > num2)) { _intStats["record" + transitCode + "TransitDay"] = num; _floatStats["record" + transitCode + "TransitTime"] = num2; if (Configs.notificationsEnabled.Value) { NotificationUiQueue.Instance.QueueNotification("Fastest " + FormatTransitName(transitCode) + " time"); } } _boolArrayStats[underwayKey + "Transit"][destInt] = true; } public void PlayerTeleported() { SAD_Plugin.LogInfo("Player teleported, resetting current transits"); foreach (Region allRegion in Region.AllRegions) { int num = 0; for (int i = 0; i < Region.AllRegions.Count; i++) { if (i != num) { _boolArrayStats[allRegion.Code + "Transit"][i] = true; } num++; } } } public void TrackDistance() { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0062: 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_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)GameState.currentBoat == (Object)null) && IsUnderway) { Vector3 globeCoords = FloatingOriginManager.instance.GetGlobeCoords(GameState.currentBoat); Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(globeCoords.x, 0f, globeCoords.z); if (lastPosition == Vector3.zero) { lastPosition = val; return; } if (trackerTimer > 1) { trackerTimer--; return; } _floatStats["currentMilesSailed"] += Vector3.Distance(lastPosition, val) * 61f; lastPosition = val; trackerTimer = 1000; } } public void UpdateMilesText() { _floatStats["MilesSailed"] = _floatStats["currentMilesSailed"]; } public void IncrementIntStat(string statName) { if (!_intStats.ContainsKey("current" + statName)) { _intStats.Add("current" + statName, 0); } _intStats["current" + statName]++; } public void IncrementPortVisited(string port) { if (!(lastPortVisited == port)) { IncrementIntStat("PortsVisited"); lastPortVisited = port; } } public void IncrementStormsWeathered() { string name = ((Object)WeatherStorms.instance.GetCurrentStorm()).name; if (!(lastStorm == name)) { SAD_Plugin.LogDebug("Weathering " + name); IncrementIntStat("StormsWeathered"); lastStorm = name; } } public void ClearLastStorm() { if (!Utility.IsNullOrWhiteSpace(lastStorm)) { SAD_Plugin.LogDebug("Storm cleared"); lastStorm = string.Empty; } } public void UpdatePage() { UpdateStats(); UpdateTexts(); } private void UpdateStats() { if (_intStats["UnderwayDay"] > 0 || _floatStats["UnderwayTime"] > 0f) { _intStats["currentUnderwayDay"] = GameState.day - _intStats["UnderwayDay"]; _floatStats["currentUnderwayTime"] = Sun.sun.globalTime - _floatStats["UnderwayTime"]; } if (_floatStats["currentUnderwayTime"] < 0f) { _floatStats["currentUnderwayTime"] += 24f; _intStats["currentUnderwayDay"]--; } } private void UpdateTexts() { UpdateFloatTexts(); UpdateIntTexts(); UpdateTransitTexts(); } private void UpdateFloatTexts() { string[] floatStatNames = FloatStatNames; foreach (string text in floatStatNames) { switch (text) { case "UnderwayTime": _statTMs[text].text = FormatStatName(text); _statTMs["currentUnderwayTime"].text = FormatUnderwayTime(_intStats["currentUnderwayDay"], _floatStats["currentUnderwayTime"]); _statTMs["recordUnderwayTime"].text = FormatUnderwayTime(_intStats["recordUnderwayDay"], _floatStats["recordUnderwayTime"]); break; case "CargoMass": _statTMs[text].text = FormatStatName(text); _statTMs["currentCargoMass"].text = ((_floatStats["currentCargoMass"] == 0f) ? "-" : string.Format("{0:#,##0.#} lbs", _floatStats["currentCargoMass"])); _statTMs["recordCargoMass"].text = ((_floatStats["recordCargoMass"] == 0f) ? "-" : string.Format("{0:#,##0.#} lbs", _floatStats["recordCargoMass"])); break; case "TotalMass": _statTMs[text].text = FormatStatName(text); _statTMs["currentTotalMass"].text = ((_floatStats["currentTotalMass"] == 0f) ? "-" : string.Format("{0:#,##0.#} lbs", _floatStats["currentTotalMass"])); _statTMs["recordTotalMass"].text = ((_floatStats["recordTotalMass"] == 0f) ? "-" : string.Format("{0:#,##0.#} lbs", _floatStats["recordTotalMass"])); break; case "MilesSailed": _statTMs[text].text = FormatStatName(text); if (Configs.updateMilesSailed.Value == "realtime") { _statTMs["currentMilesSailed"].text = string.Format("{0:#,##0.#}", _floatStats["currentMilesSailed"]); } else { _statTMs["currentMilesSailed"].text = string.Format("{0:#,##0.#}", _floatStats["MilesSailed"]); } break; default: _statTMs[text].text = FormatStatName(text); _statTMs["current" + text].text = _floatStats["current" + text].ToString(); _statTMs["record" + text].text = _floatStats["record" + text].ToString(); break; } } } private void UpdateIntTexts() { Queue posQueue = new Queue(RandomEncounterStatYPos); string[] intStatNames = IntStatNames; foreach (string text in intStatNames) { if (!(text == "UnderwayDay")) { if (_randomEncounterStats.ContainsKey(text)) { PositionRandomEnounterStat(text, posQueue); } _statTMs[text].text = FormatStatName(text); _statTMs["current" + text].text = string.Format("{0:#,##0}", _intStats["current" + text]); } } } private void UpdateTransitTexts() { foreach (string transitCode in Region.TransitCodes) { _statTMs[transitCode].text = FormatTransitName(transitCode); _statTMs["last" + transitCode].text = FormatUnderwayTime(_intStats["last" + transitCode + "TransitDay"], _floatStats["last" + transitCode + "TransitTime"]); _statTMs["record" + transitCode].text = FormatUnderwayTime(_intStats["record" + transitCode + "TransitDay"], _floatStats["record" + transitCode + "TransitTime"]); } } private string FormatUnderwayTime(int underwayDay, float underwayTime) { if (underwayDay == 0 && underwayTime == 0f) { return "-"; } if (underwayDay > 0) { string arg = ((underwayDay == 1) ? "Day" : "Days"); return $"{underwayDay} {arg} {underwayTime:0.0} Hours"; } return $"{underwayTime:0.0} Hours"; } private string FormatStatName(string name) { if (name.Contains("Encounters")) { name = name.Replace("Encounters", "Encs"); } return Regex.Replace(name, "([a-z])([A-Z])", "$1 $2"); } private string FormatTransitName(string name) { string text = FormatStatName(name); return text.ToUpper().Insert(text.IndexOf(' '), " to"); } private void PositionRandomEnounterStat(string stat, Queue posQueue) { //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)SAD_Plugin.RE_PluginInstance == (Object)null || !_randomEncounterStats[stat]()) { ((Component)_statTMs[stat]).gameObject.SetActive(false); } else if ((Object)(object)SAD_Plugin.RE_PluginInstance != (Object)null && _randomEncounterStats[stat]()) { ((Component)_statTMs[stat]).gameObject.SetActive(true); Vector3 localPosition = ((Component)_statTMs[stat]).transform.localPosition; ((Component)_statTMs[stat]).transform.localPosition = new Vector3(localPosition.x, posQueue.Dequeue(), localPosition.z); } } public void SetUIElems(Dictionary statTMs) { _statTMs = statTMs; } public void LoadFloatStats(Dictionary floatStats) { SaveLoadPatches.LoadDictionary(floatStats, _floatStats); } public void LoadIntStats(Dictionary intStats) { SaveLoadPatches.LoadDictionary(intStats, _intStats); } public void LoadBoolArrayStats(Dictionary boolArrayStats) { foreach (KeyValuePair boolArrayStat in boolArrayStats) { if (!_boolArrayStats.ContainsKey(boolArrayStat.Key)) { SAD_Plugin.LogWarning("Attempted to set unknown boolArrayStat: " + boolArrayStat.Key); } else { _boolArrayStats[boolArrayStat.Key] = (bool[])boolArrayStat.Value.Clone(); } } } }