Decompiled source of CaptainDTweaks v1.0.4

CaptainDTweaks.dll

Decompiled 7 months ago
using System;
using System.Collections;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using SailwindModdingHelper;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")]
[assembly: AssemblyCompany("CaptainDTweaks")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Tweaks and fixes for the game Sailwind")]
[assembly: AssemblyFileVersion("1.0.4.0")]
[assembly: AssemblyInformationalVersion("1.0.4+6b304c41f8246f81ca30f21a58123d75d8769117")]
[assembly: AssemblyProduct("CaptainDTweaks")]
[assembly: AssemblyTitle("CaptainDTweaks")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.4.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace CaptainDTweaks
{
	[BepInPlugin("com.captaind54321.tweaks", "CaptainD's Tweaks", "1.0.4")]
	[BepInDependency("com.app24.sailwindmoddinghelper", "2.0.2")]
	public class Plugin : BaseUnityPlugin
	{
		public const string PLUGIN_GUID = "com.captaind54321.tweaks";

		public const string PLUGIN_NAME = "CaptainD's Tweaks";

		public const string PLUGIN_VERSION = "1.0.4";

		internal static Plugin instance;

		internal static ManualLogSource logger;

		internal static ConfigEntry<bool> foodOverflow;

		internal static ConfigEntry<bool> noDirt;

		internal static ConfigEntry<bool> supplyDemand;

		internal static Harmony harmony;

		private void Awake()
		{
			instance = this;
			logger = ((BaseUnityPlugin)this).Logger;
			foodOverflow = ((BaseUnityPlugin)this).Config.Bind<bool>("Settings", "Food Overflow", true, "Makes eating food that would put your hunger above 100% not waste the excess, and instead \"overflow\" your hunger value, and then prevent eating until hunger is below 100% again");
			noDirt = ((BaseUnityPlugin)this).Config.Bind<bool>("Settings", "No Dirt", false, "Prevents dirt from accumulating on boats. NOTE: Does not clean already dirty boats.");
			supplyDemand = ((BaseUnityPlugin)this).Config.Bind<bool>("Settings", "Display Demand", true, "Makes the trade book display islands' supply or demand for commodities, as well as price.");
			harmony = Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "com.captaind54321.tweaks");
		}

		private void OnDestroy()
		{
			logger.LogInfo((object)"Destroying and unpatching com.captaind54321.tweaks");
			harmony.UnpatchSelf();
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "CaptainDTweaks";

		public const string PLUGIN_NAME = "CaptainDTweaks";

		public const string PLUGIN_VERSION = "1.0.4";
	}
}
namespace CaptainDTweaks.Patches
{
	[HarmonyPatch(typeof(IslandMarket))]
	internal static class MarketPatches
	{
		[HarmonyPatch("UpdateSelfPriceReport")]
		[HarmonyPostfix]
		public static void AddSupplyValues(ref IslandMarket __instance)
		{
			IslandMarket val = __instance;
			int portIndex = val.GetPortIndex();
			SupplyPriceReport supplyPriceReport = new SupplyPriceReport(val.knownPrices[portIndex]);
			supplyPriceReport.supplyValues = new float[val.currentSupply.Length];
			for (int i = 0; i < val.currentSupply.Length; i++)
			{
				supplyPriceReport.supplyValues[i] = val.currentSupply[i] - val.supplyPurchaseLimit + 1f;
			}
			val.knownPrices[portIndex] = (PriceReport)(object)supplyPriceReport;
		}

		[HarmonyPatch("ReceivePriceReports")]
		[HarmonyPrefix]
		public static bool ReceivePriceReports(PriceReport[] reports, ref PriceReport[] ___knownPrices, ref IslandMarket __instance)
		{
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Expected O, but got Unknown
			for (int i = 0; i < reports.Length; i++)
			{
				if (reports[i] != null && reports[i].approved && (___knownPrices[i] == null || ___knownPrices[i].day <= reports[i].day))
				{
					if (reports[i] is SupplyPriceReport)
					{
						___knownPrices[i] = (PriceReport)(object)new SupplyPriceReport((SupplyPriceReport)(object)reports[i]);
					}
					else
					{
						___knownPrices[i] = new PriceReport(reports[i]);
					}
				}
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(TraderBoat))]
	internal static class TraderBoatPatches
	{
		[HarmonyPatch("UpdateCarriedPriceReports")]
		[HarmonyPrefix]
		public static bool UpdateReportsFix(ref PriceReport[] ___carriedPriceReports, ref IslandMarket ___currentIslandMarket)
		{
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Expected O, but got Unknown
			for (int i = 0; i < ___carriedPriceReports.Length; i++)
			{
				if (___currentIslandMarket.knownPrices[i] != null && ___currentIslandMarket.knownPrices[i].approved && (___carriedPriceReports[i] == null || ___currentIslandMarket.knownPrices[i].day >= ___carriedPriceReports[i].day))
				{
					if (___currentIslandMarket.knownPrices[i] is SupplyPriceReport)
					{
						___carriedPriceReports[i] = (PriceReport)(object)new SupplyPriceReport((SupplyPriceReport)(object)___currentIslandMarket.knownPrices[i]);
					}
					else
					{
						___carriedPriceReports[i] = new PriceReport(___currentIslandMarket.knownPrices[i]);
					}
				}
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(EconomyUI))]
	internal static class TradeUIPatches
	{
		internal class UIHolder
		{
			public TextMesh islandNames;

			public TextMesh daysAgo;

			public GameObject headers;

			public GameObject vertLines;

			public GameObject shortVertLine;

			public void SetActive(bool active)
			{
				((Component)islandNames).gameObject.SetActive(active);
				((Component)daysAgo).gameObject.SetActive(active);
				headers.SetActive(active);
				vertLines.SetActive(active);
				shortVertLine.SetActive(active);
			}

			public bool CheckNull()
			{
				return (Object)(object)islandNames == (Object)null || (Object)(object)daysAgo == (Object)null || (Object)(object)headers == (Object)null || (Object)(object)vertLines == (Object)null || (Object)(object)shortVertLine == (Object)null;
			}
		}

		private static UIHolder vanillaUI;

		private static UIHolder modUI;

		private static TextMesh supplyText;

		[HarmonyPatch("Awake")]
		[HarmonyPrefix]
		public static void WakeUp(ref GameObject ___ui)
		{
			Plugin.logger.LogInfo((object)"CaptainDTweaks.DemandViewer: Beginning to modify trade UI.");
			Transform val = ___ui.transform.Find("good details (right panel)/details UI");
			if ((Object)(object)val == (Object)null)
			{
				Plugin.logger.LogError((object)"CaptainDTweaks.DemandViewer: Could not find UI subsection");
				return;
			}
			GameObject gameObject = ((Component)val).gameObject;
			if ((Object)(object)gameObject == (Object)null)
			{
				Plugin.logger.LogError((object)"CaptainDTweaks.DemandViewer: Cannot find good details UI section");
				return;
			}
			vanillaUI = new UIHolder();
			try
			{
				vanillaUI.islandNames = ((Component)gameObject.transform.Find("static text (islands)")).GetComponent<TextMesh>();
				vanillaUI.daysAgo = ((Component)gameObject.transform.Find("text (days ago)")).GetComponent<TextMesh>();
				vanillaUI.headers = ((Component)gameObject.transform.GetChild(8)).gameObject;
				vanillaUI.vertLines = ((Component)gameObject.transform.GetChild(13)).gameObject;
				vanillaUI.shortVertLine = ((Component)gameObject.transform.GetChild(15)).gameObject;
			}
			catch
			{
				Plugin.logger.LogError((object)"CaptainDTweaks.DemandViewer: Failed to find one or more text components!");
				return;
			}
			if (vanillaUI.CheckNull())
			{
				Plugin.logger.LogError((object)"CaptainDTweaks.DemandViewer: cannot find one or more UI components!");
			}
			modUI = new UIHolder();
			modUI.islandNames = ((Component)Object.Instantiate<TextMesh>(vanillaUI.islandNames, gameObject.transform)).GetComponent<TextMesh>();
			modUI.daysAgo = ((Component)Object.Instantiate<TextMesh>(vanillaUI.daysAgo, gameObject.transform)).GetComponent<TextMesh>();
			modUI.headers = Object.Instantiate<GameObject>(vanillaUI.headers, gameObject.transform);
			modUI.vertLines = Object.Instantiate<GameObject>(vanillaUI.vertLines, gameObject.transform);
			modUI.shortVertLine = Object.Instantiate<GameObject>(vanillaUI.shortVertLine, gameObject.transform);
			supplyText = Object.Instantiate<TextMesh>(modUI.daysAgo, gameObject.transform);
			SetTransX(((Component)modUI.islandNames).transform, 0.37f);
			SetTransX(((Component)modUI.daysAgo).transform, 0.25f);
			SetTransX(((Component)supplyText).transform, 0.07f);
			SetTransX(modUI.headers.transform, 0.45f);
			modUI.headers.GetComponent<TextMesh>().text = "days ago  supply        buy         sell       profit";
			SetTransX(modUI.vertLines.transform, 0.39f);
			modUI.vertLines.GetComponent<TextMesh>().text = "       |        |           |            |            |";
			SetTransX(modUI.shortVertLine.transform, 0.35f);
			Plugin.logger.LogInfo((object)"CaptainDTweaks.DemandViewer: Sucessfully set up UI!");
		}

		private static void SetTransX(Transform transform, float x)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			Vector3 localPosition = transform.localPosition;
			localPosition.x = x;
			transform.localPosition = localPosition;
		}

		[HarmonyPatch("OpenUI")]
		[HarmonyPrefix]
		public static void OpenRightUI(ref TextMesh ___textIslandNames, ref TextMesh ___textDaysAgo)
		{
			if (vanillaUI == null || modUI == null)
			{
				Plugin.logger.LogError((object)"CaptainDTweaks.DemandViewer.OpenUI(): UI elements not instantiated correctly! Aborting!");
				return;
			}
			modUI.SetActive(Plugin.supplyDemand.Value);
			((Component)supplyText).gameObject.SetActive(Plugin.supplyDemand.Value);
			vanillaUI.SetActive(!Plugin.supplyDemand.Value);
			___textIslandNames = (Plugin.supplyDemand.Value ? modUI : vanillaUI).islandNames;
			___textDaysAgo = (Plugin.supplyDemand.Value ? modUI : vanillaUI).daysAgo;
		}

		[HarmonyPatch("ShowGoodPage")]
		[HarmonyPostfix]
		public static void DisplaySupply(int goodIndex, ref int[][] ___bookmarkIslands, ref int ___currentBookmark, ref IslandMarket ___currentIsland)
		{
			if ((Object)(object)supplyText == (Object)null)
			{
				Plugin.logger.LogError((object)"CaptainDTweaks.DemandViewer: SupplyText not instantiated! Cannot update!");
				return;
			}
			ShipItem good = PrefabsDirectory.instance.GetGood(goodIndex);
			Good component = ((Component)good).GetComponent<Good>();
			supplyText.text = "";
			for (int i = 0; i < ___bookmarkIslands[___currentBookmark].Length; i++)
			{
				int num = ___bookmarkIslands[___currentBookmark][i];
				SupplyPriceReport supplyPriceReport = ___currentIsland.knownPrices[num] as SupplyPriceReport;
				TextMesh obj = supplyText;
				obj.text = obj.text + ((supplyPriceReport != null && supplyPriceReport.supplyValues != null) ? Mathf.FloorToInt(supplyPriceReport.supplyValues[goodIndex]).ToString() : "-") + "\n";
			}
		}
	}
	[HarmonyPatch(typeof(SaveLoadManager))]
	public class SaveTweaks
	{
		[HarmonyPatch("LoadGame")]
		[HarmonyPostfix]
		public static void Load(ref TraderBoat[] ___traderBoats)
		{
			CaptainDSaveContainer captainDSaveContainer = default(CaptainDSaveContainer);
			if (!ModSave.Load<CaptainDSaveContainer>(((BaseUnityPlugin)Plugin.instance).Info, ref captainDSaveContainer))
			{
				Plugin.logger.LogWarning((object)"CaptainDTweaks.DemandViewer: Save file loading failed. File is either corrupt or does not exist. If this is the first time loading this save with this mod, this is normal.");
				return;
			}
			if (captainDSaveContainer.playerReports != null)
			{
				for (int i = 0; i < GameState.playerKnownPrices.Length; i++)
				{
					if (captainDSaveContainer.playerReports[i] != null)
					{
						GameState.playerKnownPrices[i] = (PriceReport)(object)captainDSaveContainer.playerReports[i];
					}
				}
			}
			Port[] ports = Port.ports;
			foreach (Port val in ports)
			{
				if (!Object.op_Implicit((Object)(object)val))
				{
					continue;
				}
				IslandMarket component = ((Component)val).GetComponent<IslandMarket>();
				if (!Object.op_Implicit((Object)(object)component))
				{
					continue;
				}
				for (int k = 0; k < component.knownPrices.Length; k++)
				{
					if (captainDSaveContainer.marketKnownReports[val.portIndex][k] != null)
					{
						component.knownPrices[k] = (PriceReport)(object)captainDSaveContainer.marketKnownReports[val.portIndex][k];
					}
				}
			}
			for (int l = 0; l < ___traderBoats.Length; l++)
			{
				for (int m = 0; m < captainDSaveContainer.traderBoatReports[l].Length; m++)
				{
					if (captainDSaveContainer.traderBoatReports[l][m] != null)
					{
						___traderBoats[l].carriedPriceReports[m] = (PriceReport)(object)captainDSaveContainer.traderBoatReports[l][m];
					}
				}
			}
		}

		[HarmonyPatch("DoSaveGame")]
		[HarmonyPostfix]
		public static IEnumerator SaveGame(IEnumerator original)
		{
			original.MoveNext();
			CaptainDSaveContainer mySave = new CaptainDSaveContainer();
			TraderBoat[] traderBoats = Extensions.GetPrivateField<TraderBoat[]>((object)SaveLoadManager.instance, "traderBoats");
			Port[] ports = Port.ports;
			if (GameState.playerKnownPrices != null)
			{
				mySave.playerReports = new SupplyPriceReport[GameState.playerKnownPrices.Length];
			}
			mySave.marketKnownReports = new SupplyPriceReport[ports.Length][];
			mySave.traderBoatReports = new SupplyPriceReport[traderBoats.Length][];
			if (GameState.playerKnownPrices != null)
			{
				for (int k = 0; k < GameState.playerKnownPrices.Length; k++)
				{
					if (GameState.playerKnownPrices[k] != null)
					{
						mySave.playerReports[k] = GameState.playerKnownPrices[k] as SupplyPriceReport;
						PriceReport temp = new PriceReport(GameState.playerKnownPrices[k]);
						GameState.playerKnownPrices[k] = temp;
					}
				}
			}
			Port[] array = ports;
			foreach (Port port in array)
			{
				if (!Object.op_Implicit((Object)(object)port))
				{
					continue;
				}
				IslandMarket market = ((Component)port).GetComponent<IslandMarket>();
				if (!Object.op_Implicit((Object)(object)market))
				{
					continue;
				}
				SupplyPriceReport[] reports = new SupplyPriceReport[market.knownPrices.Length];
				for (int i = 0; i < market.knownPrices.Length; i++)
				{
					if (market.knownPrices[i] != null)
					{
						reports[i] = market.knownPrices[i] as SupplyPriceReport;
						market.knownPrices[i] = new PriceReport(market.knownPrices[i]);
					}
				}
				mySave.marketKnownReports[port.portIndex] = reports;
			}
			for (int j = 0; j < traderBoats.Length; j++)
			{
				PriceReport[] reports2 = traderBoats[j].carriedPriceReports;
				mySave.traderBoatReports[j] = new SupplyPriceReport[reports2.Length];
				for (int l = 0; l < reports2.Length; l++)
				{
					if (reports2[l] != null)
					{
						mySave.traderBoatReports[j][l] = reports2[l] as SupplyPriceReport;
						reports2[l] = new PriceReport(reports2[l]);
					}
				}
				traderBoats[j].carriedPriceReports = reports2;
			}
			ModSave.Save(((BaseUnityPlugin)Plugin.instance).Info, (object)mySave);
			yield return original;
		}
	}
	[Serializable]
	public class CaptainDSaveContainer
	{
		public SupplyPriceReport[] playerReports;

		public SupplyPriceReport[][] marketKnownReports;

		public SupplyPriceReport[][] traderBoatReports;
	}
	[Serializable]
	public class SupplyPriceReport : PriceReport
	{
		public float[] supplyValues;

		public SupplyPriceReport()
		{
		}

		public SupplyPriceReport(PriceReport report)
			: base(report)
		{
			if (report is SupplyPriceReport)
			{
				supplyValues = ((SupplyPriceReport)(object)report).supplyValues?.Clone() as float[];
			}
		}

		public SupplyPriceReport(SupplyPriceReport report)
			: base((PriceReport)(object)report)
		{
			if (report.supplyValues == null)
			{
				Plugin.logger.LogError((object)"SupplyPriceReport: report.supplyValues is null");
			}
			supplyValues = report.supplyValues.Clone() as float[];
		}
	}
	internal class NeedsInfo
	{
		public float food;

		public float water;

		public NeedsInfo(float food, float water)
		{
			this.food = ((food > 100f) ? Math.Min(food, 200f) : (-1f));
			this.water = ((water > 100f) ? Math.Min(water, 200f) : (-1f));
		}
	}
	[HarmonyPatch(typeof(PlayerNeeds))]
	internal static class PlayerNeedsPatch
	{
		[HarmonyPatch("LateUpdate")]
		public static void Prefix(ref NeedsInfo __state)
		{
			if (Plugin.foodOverflow.Value)
			{
				__state = new NeedsInfo(PlayerNeeds.food, PlayerNeeds.water);
				PlayerNeeds.food = Math.Min(PlayerNeeds.food, 100f);
				PlayerNeeds.water = Math.Min(PlayerNeeds.water, 100f);
			}
		}

		[HarmonyPatch("LateUpdate")]
		public static void Postfix(ref NeedsInfo __state)
		{
			if (Plugin.foodOverflow.Value)
			{
				if (__state.food > 0f)
				{
					float num = 100f - PlayerNeeds.food;
					PlayerNeeds.food = __state.food - num;
				}
				if (__state.water > 0f)
				{
					float num2 = 100f - PlayerNeeds.water;
					PlayerNeeds.water = __state.water - num2;
				}
			}
		}
	}
	[HarmonyPatch(typeof(ShipItemFood))]
	internal static class EatingPatch
	{
		[HarmonyPatch("OnAltHeld")]
		public static bool Prefix()
		{
			if (!Plugin.foodOverflow.Value)
			{
				return true;
			}
			return PlayerNeeds.food < 100f;
		}
	}
	[HarmonyPatch(typeof(ShipItemBottle))]
	internal static class DrinkingPatch
	{
		[HarmonyPatch("OnAltHeld")]
		public static bool Prefix()
		{
			if (!Plugin.foodOverflow.Value)
			{
				return true;
			}
			return PlayerNeeds.water < 100f;
		}
	}
	[HarmonyPatch(typeof(PlayerNeedsUI))]
	internal static class NeedsUIPatch
	{
		[HarmonyPatch("UpdateBars")]
		public static void Prefix(ref NeedsInfo __state)
		{
			__state = new NeedsInfo(PlayerNeeds.food, PlayerNeeds.water);
			PlayerNeeds.food = Math.Min(PlayerNeeds.food, 100f);
			PlayerNeeds.water = Math.Min(PlayerNeeds.water, 100f);
		}

		[HarmonyPatch("UpdateBars")]
		public static void Postfix(ref NeedsInfo __state)
		{
			if (__state.food > 0f)
			{
				PlayerNeeds.food = __state.food;
			}
			if (__state.water > 0f)
			{
				PlayerNeeds.water = __state.water;
			}
		}
	}
	[HarmonyPatch(typeof(CleanableObject))]
	internal static class NoDirt
	{
		[HarmonyPatch("ApplyDailyDirt")]
		public static bool Prefix(CleanableObject __instance)
		{
			if (Plugin.noDirt.Value)
			{
				__instance.CleanFully();
			}
			return !Plugin.noDirt.Value;
		}
	}
}