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