using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
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;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
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("https://github.com/bryon82/SailwindSail-a-dex")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("raddude")]
[assembly: AssemblyProduct("Sail-a-dex")]
[assembly: AssemblyCopyright("Copyright © 2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("165a01b3-48da-400d-a25f-d6d01b2b3120")]
[assembly: AssemblyFileVersion("2.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.0.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 REConfigs
{
internal static bool IsSeaLifeModEnabled => Get("IsSeaLifeModEnabled");
internal static bool IsFlotsamEnabled => Get("IsFlotsamEnabled");
internal static bool IsDenseFogEnabled => Get("IsDenseFogEnabled");
internal static bool IsFishingBonanzaEnabled => Get("IsFishingBonanzaEnabled");
internal static bool IsIntenseStormEnabled => Get("IsIntenseStormEnabled");
private static bool Get([CallerMemberName] string property = "")
{
return SAD_Plugin.RE_PluginInstance.GetStaticProperty<bool>(property);
}
}
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("Update")]
public static void UpdatePatch()
{
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();
}
}
}
}
}
internal class ModDataPatches
{
[HarmonyPatch(typeof(SaveLoadManager))]
private class SaveLoadManagerPatches
{
[HarmonyPrefix]
[HarmonyPatch("SaveModData")]
public static void SaveModData()
{
FishCaughtUI.Instance.SaveFishCaughtUI();
PortsVisitedUI.Instance.SavePortsVisitedUI();
StatsUI.Instance.SaveStatsUI();
}
[HarmonyPrefix]
[HarmonyPatch("LoadModData")]
public static void LoadModData()
{
FishCaughtUI.Instance.LoadFishCaughtUI();
PortsVisitedUI.Instance.LoadPortsVisitedUI();
StatsUI.Instance.LoadStatsUI();
}
}
}
public class FishCaughtUI : MonoBehaviour
{
public TextMesh[] _fishNameTMs;
public TextMesh[] _caughtCountTMs;
public Dictionary<string, GameObject> _fishBadgeGOs;
public Dictionary<string, int> _caughtFish;
public Dictionary<string, bool> _fishBadges;
private static readonly int[] FISH_BADGE_AMOUNTS = new int[3] { 25, 50, 100 };
private static readonly int[] TOTAL_FISH_BADGE_AMOUNTS = new int[3] { 50, 250, 500 };
public static readonly string[] FishNames = new string[12]
{
"templefish", "sunspot fish", "tuna", "blue shimmertail", "salmon", "eel", "blackfin hunter", "trout", "north fish", "swamp snapper",
"blue bubbler", "fire fish"
};
public static readonly string[] TotalFishBadgeNames = new string[4] { "caught50", "caught250", "caught500", "caughtAll" };
public static FishCaughtUI Instance { get; private set; }
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 LoadFishCaughtUI()
{
ModData.GetDictEntry("Sail-a-dex.CaughtFish", _caughtFish);
ModData.GetDictEntry("Sail-a-dex.FishBadges", _fishBadges);
}
public void SaveFishCaughtUI()
{
ModData.AddDictEntry("Sail-a-dex.CaughtFish", _caughtFish);
ModData.AddDictEntry("Sail-a-dex.FishBadges", _fishBadges);
}
}
internal class LogUIPatches
{
[HarmonyPatch(typeof(MissionListUI))]
private class MissionListUIPatches
{
[HarmonyPrefix]
[HarmonyPatch("ToggleMenu")]
public static void TogglePatch()
{
//IL_004d: 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_0083: Unknown result type (might be due to invalid IL or missing references)
//IL_00a4: 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)
//IL_00da: Unknown result type (might be due to invalid IL or missing references)
//IL_0101: 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_015d: Unknown result type (might be due to invalid IL or missing references)
//IL_017a: 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)
//IL_01d8: 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<Vector3> stack = new Stack<Vector3>();
stack.Push(new Vector3(-0.515f, -0.0035f, -0.4566f));
stack.Push(new Vector3(-0.387f, 0.0028f, -0.4566f));
stack.Push(new Vector3(-0.26f, 0.0032f, -0.4566f));
Stack<Vector3> stack2 = new Stack<Vector3>();
stack2.Push(new Vector3(-0.515f, 0.0082f, -0.4516f));
stack2.Push(new Vector3(-0.387f, 0.0138f, -0.4516f));
stack2.Push(new Vector3(-0.26f, 0.0137f, -0.4516f));
if (Configs.fishCaughtUIEnabled.Value)
{
logModeButtons[5].SetPrivateField("inactiveLocalPos", stack.Pop());
logModeButtons[5].SetPrivateField("activeLocalPos", stack2.Pop());
bookmarks[0].SetActive(true);
}
if (Configs.portsVisitedUIEnabled.Value)
{
logModeButtons[6].SetPrivateField("inactiveLocalPos", stack.Pop());
logModeButtons[6].SetPrivateField("activeLocalPos", stack2.Pop());
bookmarks[1].SetActive(true);
}
if (Configs.statsUIEnabled.Value)
{
logModeButtons[7].SetPrivateField("inactiveLocalPos", stack.Pop());
logModeButtons[7].SetPrivateField("activeLocalPos", stack2.Pop());
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, ref GPButtonLogMode[] ___logModeButtons, GameObject ___reputationUI)
{
List<GPButtonLogMode> existingLogModeButtons = new List<GPButtonLogMode>(___logModeButtons);
(List<GameObject>, GPButtonLogMode[]) tuple = UIBuilder.MakeBookmarks(___modeButtons, existingLogModeButtons);
bookmarks = tuple.Item1;
logModeButtons = tuple.Item2;
statsUI = UIBuilder.MakeStatsUI(___reputationUI);
portsVisitedUI = UIBuilder.MakePortsVisitedUI(___reputationUI);
fishCaughtUI = UIBuilder.MakeFishCaughtUI(___reputationUI);
___logModeButtons = logModeButtons;
}
}
[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;
private static GPButtonLogMode[] logModeButtons;
}
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;
public static readonly Region EmeraldArchipelago;
public static readonly Region Aestrin;
public static readonly Region FireFishLagoon;
public static readonly IReadOnlyList<Region> AllRegions;
public static readonly IReadOnlyList<string> AllBadgeNames;
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; private set; }
public static IReadOnlyList<string> TransitCodes { get; private set; }
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 ?? "";
}
static 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", "Old Ankh Town", "Mirage Mountain", "Saffron Island" }, 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)", "island 40 (coffee)",
"island 41 (mirage mountain)", "island 42 ()"
});
EmeraldArchipelago = new Region(1, "Emerald Archipelago", "emeraldBadge", "Ea", new List<string> { "Dragon Cliffs", "Sanctuary", "Crab Beach", "New Port", "Sage Hills", "Serpent Isle", "Dead Cove", "Turtle Island" }, new List<string> { "island 9 E (dragon cliffs)", "island 10 E (sanctuary)", "island 11 E (crab beach)", "island 12 E (New Port)", "island 13 E (Sage Hills)", "island 22 E (serpent isle)", "island 37 E (swamp)", "island 38 E (jungle)", "island 39 E (onsen)" });
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 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<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" });
AllRegions = new List<Region> { AlAnkh, EmeraldArchipelago, Aestrin, FireFishLagoon }.AsReadOnly();
AllBadgeNames = new List<string> { AlAnkh.BadgeName, EmeraldArchipelago.BadgeName, Aestrin.BadgeName, FireFishLagoon.BadgeName, "allPortsBadge" }.AsReadOnly();
List<string> list = new List<string>();
foreach (Region allRegion in AllRegions)
{
list.AddRange(allRegion.Ports);
}
AllPorts = list.AsReadOnly();
List<string> list2 = new List<string>();
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 ModData
{
public static void AddEntry<T>(string dataName, T data)
{
string value = ((data == null) ? string.Empty : data.ToString());
if (GameState.modData.ContainsKey(dataName))
{
GameState.modData[dataName] = value;
}
else
{
GameState.modData.Add(dataName, value);
}
}
public static T GetEntry<T>(string dataName)
{
if (!GameState.modData.ContainsKey(dataName))
{
SAD_Plugin.LogWarning("GetEntry: " + dataName + " not found in modData");
return default(T);
}
string value = GameState.modData[dataName];
return (T)Convert.ChangeType(value, typeof(T));
}
public static void AddDictEntry<K, T>(string dataName, Dictionary<K, T> data)
{
StringBuilder stringBuilder = new StringBuilder();
if (typeof(T) == typeof(bool[]))
{
foreach (KeyValuePair<K, T> datum in data)
{
stringBuilder.AppendLine(string.Format("{0}|{1}", datum.Key, string.Join(",", (bool[])(object)datum.Value)));
}
}
else if (typeof(T) == typeof(float))
{
foreach (KeyValuePair<K, T> datum2 in data)
{
stringBuilder.AppendLine($"{datum2.Key}|{((float)(object)datum2.Value).ToString(CultureInfo.InvariantCulture)}");
}
}
else
{
foreach (KeyValuePair<K, T> datum3 in data)
{
stringBuilder.AppendLine($"{datum3.Key}|{datum3.Value}");
}
}
string value = stringBuilder.ToString();
if (GameState.modData.ContainsKey(dataName))
{
GameState.modData[dataName] = value;
}
else
{
GameState.modData.Add(dataName, value);
}
}
public static void GetDictEntry<K, T>(string dataName, Dictionary<K, T> gameDict)
{
if (!GameState.modData.ContainsKey(dataName))
{
SAD_Plugin.LogWarning("LoadDictFromModData: " + dataName + " not found in modData");
return;
}
string text = GameState.modData[dataName];
string[] array = text.Split(new char[1] { '\n' }, StringSplitOptions.RemoveEmptyEntries);
string[] array2 = array;
foreach (string text2 in array2)
{
string[] array3 = text2.Trim().Split(new char[1] { '|' });
if (array3.Length >= 2)
{
K val = (K)Convert.ChangeType(array3[0], typeof(K));
if (!gameDict.ContainsKey(val))
{
SAD_Plugin.LogWarning($"LoadDictFromModData: {val} not found in game");
}
else
{
gameDict[val] = ParseValue<T>(array3[1]);
}
}
}
}
private static T ParseValue<T>(string raw)
{
if (typeof(T) == typeof(bool[]))
{
bool[] array = Array.ConvertAll(raw.Split(new char[1] { ',' }), bool.Parse);
return (T)(object)array;
}
if (typeof(T) == typeof(float))
{
return (T)(object)float.Parse(raw, CultureInfo.InvariantCulture);
}
return (T)Convert.ChangeType(raw, typeof(T));
}
}
internal class UIBuilder
{
internal const MissionListMode FISH_CAUGHT = (MissionListMode)5;
internal const MissionListMode PORTS_VISITED = (MissionListMode)6;
internal const MissionListMode STATS = (MissionListMode)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>, GPButtonLogMode[]) MakeBookmarks(GameObject modeButtons, List<GPButtonLogMode> existingLogModeButtons)
{
//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_00f5: Unknown result type (might be due to invalid IL or missing references)
//IL_010d: Unknown result type (might be due to invalid IL or missing references)
//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
//IL_01cc: 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);
existingLogModeButtons.Add(component);
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);
existingLogModeButtons.Add(component2);
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);
existingLogModeButtons.Add(component3);
return (list, existingLogModeButtons.ToArray());
}
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<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(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<FishCaughtUI>();
GameObject gameObject = ((Component)val.transform.GetChild(1)).gameObject;
gameObject.SetActive(true);
gameObject.GetComponent<TextMesh>().font = ((Component)gameObject.transform.GetChild(1)).GetComponent<TextMesh>().font;
((Renderer)gameObject.GetComponent<MeshRenderer>()).material = ((Renderer)((Component)gameObject.transform.GetChild(1)).GetComponent<MeshRenderer>()).material;
((Object)((Component)gameObject.transform.GetChild(1)).gameObject).name = "caught count";
Transform child = gameObject.transform.GetChild(1);
Vector3 localPosition = gameObject.transform.GetChild(1).localPosition;
child.localPosition = new Vector3(55f, 0f, ((Vector3)(ref localPosition))[2]);
((Component)gameObject.transform.GetChild(1)).GetComponent<TextMesh>().fontSize = 50;
TextMesh[] array = (TextMesh[])(object)new TextMesh[FishCaughtUI.FishNames.Length + 1];
TextMesh[] array2 = (TextMesh[])(object)new TextMesh[FishCaughtUI.FishNames.Length + 1];
Dictionary<string, GameObject> dictionary = new Dictionary<string, GameObject>();
for (int i = 0; i < FishCaughtUI.FishNames.Length; i++)
{
GameObject val2 = Object.Instantiate<GameObject>(gameObject);
Object.Destroy((Object)(object)((Component)val2.transform.GetChild(4)).gameObject);
Object.Destroy((Object)(object)((Component)val2.transform.GetChild(3)).gameObject);
Object.Destroy((Object)(object)((Component)val2.transform.GetChild(2)).gameObject);
Object.Destroy((Object)(object)((Component)val2.transform.GetChild(0)).gameObject);
val2.GetComponent<TextMesh>().fontSize = 50;
((Object)val2).name = FishCaughtUI.FishNames[i];
val2.transform.parent = gameObject.transform.parent;
Transform transform = val2.transform;
float num = 0.24f - 0.0375f * (float)i;
localPosition = gameObject.transform.localPosition;
transform.localPosition = new Vector3(0.8f, num, ((Vector3)(ref localPosition))[2]);
val2.transform.localRotation = gameObject.transform.localRotation;
val2.transform.localScale = gameObject.transform.localScale;
array2[i] = val2.GetComponent<TextMesh>();
array[i] = ((Component)val2.transform.GetChild(1)).GetComponent<TextMesh>();
string[] array3 = new string[3] { "25", "50", "100" };
for (int j = 0; j < array3.Length; j++)
{
string name = ((Object)val2).name + array3[j];
((MonoBehaviour)SAD_Plugin.Instance).StartCoroutine(CreateBadgeObject(dictionary, name, val2.transform, new Vector3(12f, 12f, 1f), new Vector3(75f + (float)j * 13f, 0f, 0f)));
}
}
GameObject val3 = Object.Instantiate<GameObject>(gameObject);
Object.Destroy((Object)(object)((Component)val3.transform.GetChild(4)).gameObject);
Object.Destroy((Object)(object)((Component)val3.transform.GetChild(3)).gameObject);
Object.Destroy((Object)(object)((Component)val3.transform.GetChild(2)).gameObject);
Object.Destroy((Object)(object)((Component)val3.transform.GetChild(0)).gameObject);
((Object)val3).name = "totalCaught";
val3.transform.parent = gameObject.transform.parent;
Transform transform2 = val3.transform;
localPosition = gameObject.transform.localPosition;
transform2.localPosition = new Vector3(0.8f, -0.21f, ((Vector3)(ref localPosition))[2]);
val3.transform.localRotation = gameObject.transform.localRotation;
val3.transform.localScale = gameObject.transform.localScale;
array2[FishCaughtUI.FishNames.Length] = val3.GetComponent<TextMesh>();
array[FishCaughtUI.FishNames.Length] = ((Component)val3.transform.GetChild(1)).GetComponent<TextMesh>();
string[] array4 = new string[4] { "caught50", "caught250", "caught500", "caughtAll" };
for (int k = 0; k < array4.Length; k++)
{
string name2 = array4[k];
((MonoBehaviour)SAD_Plugin.Instance).StartCoroutine(CreateBadgeObject(dictionary, name2, val3.transform, new Vector3(15f, 15f, 1f), new Vector3(15f + (float)k * 20f, -13f, 0f)));
}
Object.Destroy((Object)(object)gameObject);
FishCaughtUI.Instance.SetUIElems(array2, array, dictionary);
SAD_Plugin.LogDebug("Loaded fish caught UI");
return val;
}
internal static GameObject MakePortsVisitedUI(GameObject repUI)
{
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
//IL_004e: Unknown result type (might be due to invalid IL or missing references)
//IL_0065: Unknown result type (might be due to invalid IL or missing references)
//IL_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<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";
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<PortsVisitedUI>();
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<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.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<TextMesh>().text = "Fire Fish Lagoon";
TextMesh[] array = (TextMesh[])(object)new TextMesh[Region.AllPorts.Count];
TextMesh[] array2 = (TextMesh[])(object)new TextMesh[Region.AllPorts.Count];
Dictionary<string, GameObject> dictionary = new Dictionary<string, GameObject>();
int num = 0;
int[] array3 = new int[4]
{
Region.AlAnkh.Ports.Count,
Region.EmeraldArchipelago.Ports.Count,
Region.Aestrin.Ports.Count,
Region.FireFishLagoon.Ports.Count
};
for (int i = 0; i < array3.Length; i++)
{
Transform child4 = val.transform.GetChild(i);
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<TextMesh>().alignment = (TextAlignment)0;
((Component)child4.GetChild(6)).GetComponent<TextMesh>().anchor = (TextAnchor)3;
((Component)child4.GetChild(6)).GetComponent<TextMesh>().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<TextMesh>().alignment = (TextAlignment)0;
gameObject.GetComponent<TextMesh>().anchor = (TextAnchor)3;
gameObject.GetComponent<TextMesh>().fontSize = 50;
((Object)gameObject2).name = "visited port1";
gameObject2.transform.localPosition = new Vector3(70f, -9f, 0f);
gameObject2.GetComponent<TextMesh>().alignment = (TextAlignment)2;
gameObject2.GetComponent<TextMesh>().anchor = (TextAnchor)5;
gameObject2.GetComponent<TextMesh>().fontSize = 50;
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.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<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(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<StatsUI>();
GameObject gameObject = ((Component)val.transform.GetChild(1)).gameObject;
gameObject.SetActive(true);
gameObject.GetComponent<TextMesh>().font = ((Component)gameObject.transform.GetChild(1)).GetComponent<TextMesh>().font;
gameObject.GetComponent<TextMesh>().fontSize = 40;
gameObject.GetComponent<TextMesh>().characterSize = 1f;
((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;
((Component)gameObject.transform.GetChild(0)).GetComponent<TextMesh>().fontStyle = (FontStyle)0;
((Component)gameObject.transform.GetChild(0)).GetComponent<TextMesh>().characterSize = 1f;
((Component)gameObject.transform.GetChild(0)).GetComponent<TextMesh>().lineSpacing = 1f;
((Renderer)((Component)gameObject.transform.GetChild(0)).GetComponent<MeshRenderer>()).material = ((Renderer)((Component)gameObject.transform.GetChild(1)).GetComponent<MeshRenderer>()).material;
((Object)((Component)gameObject.transform.GetChild(1)).gameObject).name = "record value";
gameObject.transform.GetChild(1).localPosition = new Vector3(80f, 0f, 0f);
((Component)gameObject.transform.GetChild(1)).GetComponent<TextMesh>().fontSize = 40;
((Component)gameObject.transform.GetChild(1)).GetComponent<TextMesh>().anchor = (TextAnchor)3;
((Component)gameObject.transform.GetChild(1)).GetComponent<TextMesh>().fontStyle = (FontStyle)0;
Dictionary<string, TextMesh> dictionary = new Dictionary<string, TextMesh>();
AddTrackedStat(gameObject, "CargoMass", 0.215f, dictionary);
AddTrackedStat(gameObject, "TotalMass", 0.19f, dictionary);
AddTrackedStat(gameObject, "UnderwayTime", 0.165f, dictionary);
AddTrackedStat(gameObject, "MilesSailed", 0.09f, dictionary, ltime: true);
List<float> list = new List<float>();
int num = 0;
string[] intStatNames = StatsUI.IntStatNames;
foreach (string text in intStatNames)
{
if (!(text == "UnderwayDay"))
{
if (StatsUI.RandomEncounterStats.ContainsKey(text))
{
list.Add(0.065f - 0.025f * (float)num);
}
AddTrackedStat(gameObject, text, 0.065f - 0.025f * (float)num, dictionary, ltime: true);
num++;
}
}
StatsUI.RandomEncounterStatYPos = list;
int num2 = 0;
foreach (string transitCode in Region.TransitCodes)
{
AddTrackedStat(gameObject, transitCode, 0.215f - 0.025f * (float)num2, dictionary, ltime: false, transit: true);
num2++;
}
StatsUI.Instance.SetUIElems(dictionary);
((Object)gameObject).name = "stats header";
gameObject.GetComponent<TextMesh>().text = "Stat Current Record";
gameObject.transform.localPosition = new Vector3(0.82f, 0.24f, -0.007f);
gameObject.GetComponent<TextMesh>().fontSize = 45;
gameObject.GetComponent<TextMesh>().fontStyle = (FontStyle)1;
Object.Destroy((Object)(object)((Component)gameObject.transform.GetChild(4)).gameObject);
Object.Destroy((Object)(object)((Component)gameObject.transform.GetChild(3)).gameObject);
Object.Destroy((Object)(object)((Component)gameObject.transform.GetChild(2)).gameObject);
Object.Destroy((Object)(object)((Component)gameObject.transform.GetChild(1)).gameObject);
Object.Destroy((Object)(object)((Component)gameObject.transform.GetChild(0)).gameObject);
GameObject val2 = Object.Instantiate<GameObject>(gameObject, gameObject.transform.parent);
((Object)val2).name = "lifetime stats header";
val2.GetComponent<TextMesh>().text = "Lifetime Stats";
val2.transform.localPosition = new Vector3(0.82f, 0.115f, -0.007f);
Object.Destroy((Object)(object)((Component)val2.transform.GetChild(4)).gameObject);
Object.Destroy((Object)(object)((Component)val2.transform.GetChild(3)).gameObject);
Object.Destroy((Object)(object)((Component)val2.transform.GetChild(2)).gameObject);
Object.Destroy((Object)(object)((Component)val2.transform.GetChild(1)).gameObject);
Object.Destroy((Object)(object)((Component)val2.transform.GetChild(0)).gameObject);
GameObject val3 = Object.Instantiate<GameObject>(gameObject, gameObject.transform.parent);
((Object)val3).name = "transit times header";
val3.GetComponent<TextMesh>().text = "Transit Times Last Record";
val3.transform.localPosition = new Vector3(0.14f, 0.24f, -0.007f);
Object.Destroy((Object)(object)((Component)val3.transform.GetChild(4)).gameObject);
Object.Destroy((Object)(object)((Component)val3.transform.GetChild(3)).gameObject);
Object.Destroy((Object)(object)((Component)val3.transform.GetChild(2)).gameObject);
Object.Destroy((Object)(object)((Component)val3.transform.GetChild(1)).gameObject);
Object.Destroy((Object)(object)((Component)val3.transform.GetChild(0)).gameObject);
SAD_Plugin.LogDebug("Loaded stats & transit UI");
return val;
}
private static void AddTrackedStat(GameObject templateGO, string name, float yPos, Dictionary<string, TextMesh> statTMs, bool ltime = false, bool transit = false)
{
//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
//IL_0107: Unknown result type (might be due to invalid IL or missing references)
//IL_011e: Unknown result type (might be due to invalid IL or missing references)
//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
float num = (transit ? 0.14f : 0.82f);
string text = (transit ? "last" : "current");
GameObject val = Object.Instantiate<GameObject>(templateGO);
Object.Destroy((Object)(object)((Component)val.transform.GetChild(4)).gameObject);
Object.Destroy((Object)(object)((Component)val.transform.GetChild(3)).gameObject);
Object.Destroy((Object)(object)((Component)val.transform.GetChild(2)).gameObject);
if (ltime)
{
Object.Destroy((Object)(object)((Component)val.transform.GetChild(1)).gameObject);
val.transform.GetChild(0).localPosition = new Vector3(41f, 0f, 0f);
}
((Object)val).name = name;
val.transform.parent = templateGO.transform.parent;
Transform transform = val.transform;
Vector3 localPosition = templateGO.transform.localPosition;
transform.localPosition = new Vector3(num, yPos, ((Vector3)(ref localPosition))[2]);
val.transform.localRotation = templateGO.transform.localRotation;
val.transform.localScale = templateGO.transform.localScale;
statTMs[name] = val.GetComponent<TextMesh>();
statTMs[text + name] = ((Component)val.transform.GetChild(0)).GetComponent<TextMesh>();
if (!ltime)
{
statTMs["record" + name] = ((Component)val.transform.GetChild(1)).GetComponent<TextMesh>();
}
AddLine(((Component)val.transform.GetChild(1)).gameObject);
}
private static void AddLine(GameObject templateGO)
{
//IL_0040: Unknown result type (might be due to invalid IL or missing references)
//IL_0057: Unknown result type (might be due to invalid IL or missing references)
//IL_006e: Unknown result type (might be due to invalid IL or missing references)
//IL_008a: Unknown result type (might be due to invalid IL or missing references)
//IL_008f: Unknown result type (might be due to invalid IL or missing references)
GameObject val = Object.Instantiate<GameObject>(templateGO);
((Object)val).name = "line";
val.transform.parent = templateGO.transform.parent;
val.transform.localPosition = new Vector3(-1.2f, -1.75f, 0f);
val.transform.localRotation = templateGO.transform.localRotation;
val.transform.localScale = templateGO.transform.localScale;
TextMesh component = val.GetComponent<TextMesh>();
component.color = Color32.op_Implicit(new Color32((byte)2, (byte)2, (byte)10, (byte)133));
component.text = "--------------------------------------------------------";
}
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 Dictionary<string, Texture2D> _fishTextures;
private static Dictionary<int, Texture2D> _badgeRings;
private static bool _fishBadgesLoaded;
private static bool _portBadgesLoaded;
private const string LIB_FILE = "SailadexREBridge.dll";
private const string ASSETS_DIR = "Assets";
private const string BELLS_AUDIO_FILE = "twoBells.wav";
private static readonly List<string> assetPaths = new List<string>
{
Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)SAD_Plugin.Instance).Info.Location), "Assets"),
Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)SAD_Plugin.Instance).Info.Location))
};
public static bool BadgesLoaded => _fishBadgesLoaded && _portBadgesLoaded;
public static AudioClip NotificationSound { get; private set; }
public static Dictionary<string, Material> Materials { get; private set; }
public static string FindAssetPath(string fileName)
{
foreach (string assetPath in assetPaths)
{
string text = Path.Combine(assetPath, fileName);
if (File.Exists(text))
{
return text;
}
}
return null;
}
public static void Start()
{
Materials = new Dictionary<string, Material>();
_textures = new Dictionary<string, Texture2D>();
_fishTextures = new Dictionary<string, Texture2D>();
_badgeRings = new Dictionary<int, Texture2D>();
((MonoBehaviour)SAD_Plugin.Instance).StartCoroutine(LoadAssetsAsync());
}
internal static void LoadBridge()
{
try
{
string text = FindAssetPath("SailadexREBridge.dll");
if (text == null)
{
SAD_Plugin.LogError("Assembly file not found: SailadexREBridge.dll");
return;
}
SAD_Plugin.REBridge_Assembly = Assembly.LoadFrom(text);
SAD_Plugin.LogDebug("Loaded assembly: " + SAD_Plugin.REBridge_Assembly.FullName);
}
catch (Exception ex)
{
SAD_Plugin.LogError("Failed to load assembly: " + ex.Message);
}
}
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("Assets loaded");
}
private static IEnumerator LoadAudio()
{
string clipPath = FindAssetPath("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.LogDebug("Audio loaded.");
}
finally
{
((IDisposable)webRequest)?.Dispose();
}
}
private static IEnumerator LoadFishBadges()
{
yield return ((MonoBehaviour)SAD_Plugin.Instance).StartCoroutine(LoadBadgeRings());
yield return ((MonoBehaviour)SAD_Plugin.Instance).StartCoroutine(LoadFishTextures());
yield return ((MonoBehaviour)SAD_Plugin.Instance).StartCoroutine(GenerateFishBadges());
_fishBadgesLoaded = true;
SAD_Plugin.LogDebug("Fish badges loaded.");
}
private static IEnumerator LoadBadgeRings()
{
int[] amountNums = new int[3] { 25, 50, 100 };
List<Coroutine> ringCoroutines = new List<Coroutine>();
int[] array = amountNums;
for (int i = 0; i < array.Length; i++)
{
int amount = array[i];
string ringName = amount + "Fish";
string path = FindAssetPath(ringName + ".png");
ringCoroutines.Add(((MonoBehaviour)SAD_Plugin.Instance).StartCoroutine(LoadBadgeRing(path, amount)));
}
foreach (Coroutine item in ringCoroutines)
{
yield return item;
}
}
private static IEnumerator LoadBadgeRing(string path, int amount)
{
if (!File.Exists(path))
{
SAD_Plugin.LogError("Badge ring 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 badge ring from bytes: " + path);
}
else
{
_badgeRings[amount] = texture2D;
}
}
}
private static IEnumerator LoadFishTextures()
{
List<Coroutine> fishCoroutines = new List<Coroutine>();
string[] fishNames = FishCaughtUI.FishNames;
foreach (string fishName in fishNames)
{
string path = FindAssetPath(fishName + ".png");
fishCoroutines.Add(((MonoBehaviour)SAD_Plugin.Instance).StartCoroutine(LoadFishTexture(path, fishName)));
}
foreach (Coroutine item in fishCoroutines)
{
yield return item;
}
}
private static IEnumerator LoadFishTexture(string path, string fishName)
{
if (!File.Exists(path))
{
SAD_Plugin.LogError("Fish texture 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 fish texture from bytes: " + path);
}
else
{
_fishTextures[fishName] = texture2D;
}
}
}
private static IEnumerator GenerateFishBadges()
{
int[] amountNums = new int[3] { 25, 50, 100 };
string[] fishNames = FishCaughtUI.FishNames;
foreach (string fishName in fishNames)
{
if (!_fishTextures.ContainsKey(fishName))
{
SAD_Plugin.LogError("Fish texture not found for: " + fishName);
continue;
}
Texture2D fishTexture = _fishTextures[fishName];
Dictionary<string, Texture2D> scaledFishTextures = new Dictionary<string, Texture2D>();
for (int j = 0; j < amountNums.Length; j++)
{
int amount = amountNums[j];
if (!_badgeRings.ContainsKey(amount))
{
SAD_Plugin.LogError($"Badge ring not found for amount: {amount}");
continue;
}
Texture2D ringTexture = _badgeRings[amount];
string badgeName = fishName + amount;
string sizeKey = $"{((Texture)ringTexture).width}x{((Texture)ringTexture).height}";
if (!scaledFishTextures.TryGetValue(sizeKey, out var scaledFishTexture))
{
scaledFishTexture = ScaleTexture(fishTexture, ((Texture)ringTexture).width, ((Texture)ringTexture).height);
scaledFishTextures.Add(sizeKey, scaledFishTexture);
}
Texture2D combinedTexture = CombineTextures(scaledFishTexture, ringTexture);
((Object)combinedTexture).name = badgeName;
_textures[badgeName] = combinedTexture;
Materials[badgeName] = CreateMaterial(combinedTexture);
scaledFishTexture = null;
}
foreach (Texture2D scaledTexture in scaledFishTextures.Values)
{
Object.DestroyImmediate((Object)(object)scaledTexture);
}
yield return null;
}
string[] totalFishBadgeNames = FishCaughtUI.TotalFishBadgeNames;
foreach (string caughtBadge in totalFishBadgeNames)
{
string path = FindAssetPath(caughtBadge + ".png");
yield return ((MonoBehaviour)SAD_Plugin.Instance).StartCoroutine(LoadTexture(path, caughtBadge));
}
}
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;
}
private static IEnumerator LoadPortBadges()
{
List<Coroutine> textureCoroutines = new List<Coroutine>();
foreach (string pbName in Region.AllBadgeNames)
{
string path = FindAssetPath(pbName + ".png");
textureCoroutines.Add(((MonoBehaviour)SAD_Plugin.Instance).StartCoroutine(LoadTexture(path, pbName)));
}
foreach (Coroutine item in textureCoroutines)
{
yield return item;
}
_portBadgesLoaded = true;
SAD_Plugin.LogDebug("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_00bc: Unknown result type (might be due to invalid IL or missing references)
//IL_00c6: Expected O, but got Unknown
ConfigFile config = ((BaseUnityPlugin)SAD_Plugin.Instance).Config;
fishCaughtUIEnabled = config.Bind<bool>("Enable/Disable UI", "Fish Caught UI", true, (ConfigDescription)null);
portsVisitedUIEnabled = config.Bind<bool>("Enable/Disable UI", "Ports Visited UI", true, (ConfigDescription)null);
statsUIEnabled = config.Bind<bool>("Enable/Disable UI", "Stats UI", true, (ConfigDescription)null);
fishNamesHidden = config.Bind<bool>("Gameplay Settings", "Hide Fish Names Before Caught", true, (ConfigDescription)null);
portNamesHidden = config.Bind<bool>("Gameplay Settings", "Hide Port Names Before Visited", false, (ConfigDescription)null);
updateMilesSailed = config.Bind<string>("Gameplay 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>()));
notificationsEnabled = config.Bind<bool>("Notification Settings", "Notification on badge earned", true, (ConfigDescription)null);
notificationSoundVolume = config.Bind<float>("Notification Settings", "Notification Volume", 0.2f, "Above 1f is loud and not recommended. Set to 0f to disable.");
}
}
internal static class Extensions
{
public static T GetPrivateField<T>(this object obj, string field)
{
return (T)Traverse.Create(obj).Field(field).GetValue();
}
public static void SetPrivateField(this object obj, string field, object value)
{
Traverse.Create(obj).Field(field).SetValue(value);
}
public static T GetPrivateProperty<T>(this object obj, string property)
{
return (T)Traverse.Create(obj).Property(property, (object[])null).GetValue();
}
public static T GetStaticProperty<T>(this object obj, string property)
{
return (T)Traverse.Create(obj.GetType()).Property(property, (object[])null).GetValue();
}
public static object InvokePrivateMethod(this object obj, string method, params object[] parameters)
{
return AccessTools.Method(obj.GetType(), method, (Type[])null, (Type[])null).Invoke(obj, parameters);
}
}
public class NotificationUiQueue : MonoBehaviour
{
private Coroutine _queueCoroutine;
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>();
_queueCoroutine = null;
_audioSource = ((Component)this).gameObject.AddComponent<AudioSource>();
_audioSource.volume = Configs.notificationSoundVolume.Value;
_audioSource.spatialBlend = 1f;
_audioSource.minDistance = 10f;
_audioSource.maxDistance = 20f;
}
private IEnumerator ProcessQueue()
{
while (_queue.Count > 0)
{
NotificationUi.instance.ShowNotification(_queue.Dequeue());
if (Configs.notificationSoundVolume.Value > 0f)
{
_audioSource.PlayOneShot(AssetsLoader.NotificationSound);
}
yield return (object)new WaitForSeconds(3f);
}
_queueCoroutine = null;
}
public void QueueNotification(string message)
{
_queue.Enqueue(message);
if (_queueCoroutine == null)
{
_queueCoroutine = ((MonoBehaviour)this).StartCoroutine(ProcessQueue());
}
}
}
[BepInPlugin("com.raddude.sailadex", "Sail-a-dex", "2.0.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class SAD_Plugin : BaseUnityPlugin
{
public const string PLUGIN_GUID = "com.raddude.sailadex";
public const string PLUGIN_NAME = "Sail-a-dex";
public const string PLUGIN_VERSION = "2.0.0";
public const string PASSAGEDUDE_GUID = "pr0skynesis.passagedude";
public const string RANDOMENCOUNTERS_GUID = "com.raddude.randomencounters";
internal static ManualLogSource _logger;
internal static BaseUnityPlugin RE_PluginInstance { get; private set; }
internal static Assembly REBridge_Assembly { get; set; }
internal static SAD_Plugin Instance { get; private set; }
internal static Harmony HarmonyInstance { get; private set; }
public static void LogDebug(string message)
{
_logger.LogDebug((object)message);
}
public static void LogInfo(string message)
{
_logger.LogInfo((object)message);
}
public static void LogWarning(string message)
{
_logger.LogWarning((object)message);
}
public 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.raddude.sailadex");
bool flag = false;
foreach (KeyValuePair<string, PluginInfo> pluginInfo in Chainloader.PluginInfos)
{
BepInPlugin metadata = pluginInfo.Value.Metadata;
if (metadata.GUID.Equals("pr0skynesis.passagedude"))
{
LogInfo("PassageDude mod found");
flag = true;
PassageDude.PatchMod();
}
if (metadata.GUID.Equals("com.raddude.randomencounters") && metadata.Version >= new Version(2, 0, 0))
{
LogInfo("RandomEncounters mod found");
RE_PluginInstance = pluginInfo.Value.Instance;
AssetsLoader.LoadBridge();
Type type = AccessTools.TypeByName("EncounterTracker");
AccessTools.Method(type, "TrackEncounters", (Type[])null, (Type[])null).Invoke(null, null);
}
if (flag && (Object)(object)RE_PluginInstance != (Object)null)
{
break;
}
}
}
}
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; }
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 LoadPortsVisitedUI()
{
ModData.GetDictEntry("Sail-a-dex.VisitedPorts", _visitedPorts);
ModData.GetDictEntry("Sail-a-dex.PortBadges", _portBadges);
}
public void SavePortsVisitedUI()
{
ModData.AddDictEntry("Sail-a-dex.VisitedPorts", _visitedPorts);
ModData.AddDictEntry("Sail-a-dex.PortBadges", _portBadges);
}
}
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;
internal string lastPortVisited;
private int trackerTimer;
internal string lastStorm;
private const int TRACKER_TIMER_VALUE = 1000;
private const float MILES_CONVERSION_FACTOR = 137.487f;
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",
() => REConfigs.IsFlotsamEnabled
},
{
"DenseFogEncounters",
() => REConfigs.IsDenseFogEnabled
},
{
"SeaLifeEncounters",
() => REConfigs.IsSeaLifeModEnabled
},
{
"FishingBonanzaEncounters",
() => REConfigs.IsFishingBonanzaEnabled
},
{
"IntenseStormEncounters",
() => REConfigs.IsIntenseStormEnabled
}
};
public static StatsUI Instance { get; private set; }
public bool IsUnderway { get; internal set; }
public static IReadOnlyDictionary<string, Func<bool>> RandomEncounterStats => _randomEncounterStats;
public static List<float> RandomEncounterStatYPos { get; set; }
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;
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<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;
}
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) * 137.487f;
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<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 LoadStatsUI()
{
ModData.GetDictEntry("Sail-a-dex.IntStats", _intStats);
ModData.GetDictEntry("Sail-a-dex.FloatStats", _floatStats);
ModData.GetDictEntry("Sail-a-dex.BoolArrayStats", _boolArrayStats);
IsUnderway = ModData.GetEntry<bool>("Sail-a-dex.IsUnderway");
lastPortVisited = ModData.GetEntry<string>("Sail-a-dex.LastPortVisited");
lastStorm = ModData.GetEntry<string>("Sail-a-dex.LastStorm");
}
public void SaveStatsUI()
{
ModData.AddDictEntry("Sail-a-dex.IntStats", _intStats);
ModData.AddDictEntry("Sail-a-dex.FloatStats", _floatStats);
ModData.AddDictEntry("Sail-a-dex.BoolArrayStats", _boolArrayStats);
ModData.AddEntry("Sail-a-dex.IsUnderway", IsUnderway);
ModData.AddEntry("Sail-a-dex.LastPortVisited", lastPortVisited);
ModData.AddEntry("Sail-a-dex.LastStorm", lastStorm);
}
}