Decompiled source of SODQoL v1.1.4

SOD.QoL.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using HarmonyLib;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem.Collections.Generic;
using Rewired;
using SOD.Common;
using SOD.Common.BepInEx;
using SOD.Common.BepInEx.Configuration;
using SOD.Common.Extensions;
using UnityEngine;
using UnityEngine.UI;
using UniverseLib;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("SOD.QoL")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+872c0082fbfe7438be0ea9a58f8673449b915cac")]
[assembly: AssemblyProduct("SOD.QoL")]
[assembly: AssemblyTitle("SOD.QoL")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace SOD.QoL
{
	public interface IPluginBindings : IConversationBindings, IMainMenuBindings, IMapBindings, IGameplayPatchBindings
	{
	}
	public interface IGameplayPatchBindings
	{
		[Binding(true, "Fixes the player never getting tired.", "QoL.Gameplay.FixTiredness")]
		bool FixTiredness { get; set; }

		[Binding(12, "The percentage that is taken of alertness and added to energy restore for caffeine items. (12 seems balanced)", "QoL.Gameplay.PercentageEnergyRestore")]
		int PercentageEnergyRestore { get; set; }
	}
	public interface IConversationBindings
	{
		[Binding(true, "Allow ending conversations with menu key", "QoL.Conversations.CanEndWithMenuKey")]
		bool EndConversationPatch { get; set; }
	}
	public interface IMainMenuBindings
	{
		[Binding(true, "Resume the game from paused state when exiting the mainmenu with menu key", "QoL.MainMenu.UnpauseGameWithMenuKey")]
		bool UnpauseGameOnMainMenuExit { get; set; }

		[Binding(true, "Skips the press any key screen at the start of the game if no joysticks are connected.", "QoL.MainMenu.SkipPressAnyKeyScreenIfNotUsingJoysticks")]
		bool SkipPressAnyKeyScreenIfNotUsingJoysticks { get; set; }
	}
	public interface IMapBindings
	{
		[Binding(true, "Fixes the center on player after zooming and moving the camera.", "QoL.Map.FixCenterOnPlayer")]
		bool FixCenterOnPlayer { get; set; }

		[Binding(true, "Zooms the minimap out by default?", "QoL.Map.ZoomOutOnStart")]
		bool ZoomOutOnStart { get; set; }

		[Binding(true, "Enlarge player marker?", "QoL.Map.EnlargePlayerMarker")]
		bool EnlargePlayerMarker { get; set; }

		[Binding("(2.5, 2.5)", "Player marker size. Game default: (1,1)", "QoL.Map.PlayerMarkerSize")]
		string PlayerMarkerSize { get; set; }

		[Binding(true, "Change player marker color?", "QoL.Map.ChangePlayerMarkerColor")]
		bool ChangePlayerMarkerColor { get; set; }

		[Binding("#008000", "The hex color code for the player marker, default: Green", "QoL.Map.PlayerMarkerColor")]
		string PlayerMarkerColor { get; set; }
	}
	[BepInPlugin("Venomaus.SOD.QoL", "QoL", "1.1.4")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : PluginController<Plugin, IPluginBindings>
	{
		public const string PLUGIN_GUID = "Venomaus.SOD.QoL";

		public const string PLUGIN_NAME = "QoL";

		public const string PLUGIN_VERSION = "1.1.4";

		public override void Load()
		{
			base.Harmony.PatchAll(Assembly.GetExecutingAssembly());
			PluginController<Plugin, IPluginBindings>.Log.LogInfo((object)"Plugin is patched.");
			Lib.SaveGame.OnAfterNewGame += SaveGame_OnAfterNewGame;
		}

		private void SaveGame_OnAfterNewGame(object sender, EventArgs e)
		{
			UnlockBusinessDoors();
		}

		private static void UnlockBusinessDoors()
		{
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Expected O, but got Unknown
			int num = 0;
			Enumerator<Company> enumerator = CityData.Instance.companyDirectory.GetEnumerator();
			while (enumerator.MoveNext())
			{
				Company current = enumerator.Current;
				if (!((Object)(object)current.placeOfBusiness.thisAsAddress != (Object)null) || !current.IsOpenAtThisTime(SessionData.Instance.gameTime))
				{
					continue;
				}
				Enumerator<NodeAccess> enumerator2 = ((NewGameLocation)current.address).entrances.GetEnumerator();
				while (enumerator2.MoveNext())
				{
					NodeAccess current2 = enumerator2.Current;
					if ((Object)(object)current2.door != (Object)null)
					{
						current2.door.SetLocked(false, (Actor)null, false);
					}
				}
				Enumerator<NewRoom> enumerator3 = ((NewGameLocation)current.address).rooms.GetEnumerator();
				while (enumerator3.MoveNext())
				{
					enumerator3.Current.SetMainLights(true, "SOD.QoL: Unlock business door on new game.", (Actor)null, true, true);
				}
				current.SetOpen(true, true);
				num++;
			}
			ManualLogSource log = PluginController<Plugin, IPluginBindings>.Log;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(27, 1, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Unlocked \"");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(num);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("\" business doors.");
			}
			log.LogInfo(val);
		}
	}
}
namespace SOD.QoL.Patches
{
	internal class CitizenBehaviourPatches
	{
		[HarmonyPatch(typeof(CitizenBehaviour), "GameWorldCheck")]
		internal class CitizenBehaviour_GameWorldCheck
		{
			internal readonly struct PlayerState
			{
				public float Energy { get; }

				public float WellRested { get; }

				public float Alertness { get; }

				public float TickChange { get; }

				public PlayerState(float energy, float wellRested, float alertness, float tickChange)
				{
					Energy = energy;
					WellRested = wellRested;
					Alertness = alertness;
					TickChange = tickChange;
				}
			}

			[HarmonyPrefix]
			internal static void Prefix(CitizenBehaviour __instance, ref PlayerState __state)
			{
				if (((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.FixTiredness)
				{
					float tickChange = SessionData.Instance.gameTime - __instance.timeOnLastGameWorldUpdate;
					__state = new PlayerState(((Human)Player.Instance).energy, ((Human)Player.Instance).wellRested, ((Human)Player.Instance).alertness, tickChange);
				}
			}

			[HarmonyPostfix]
			internal static void Postfix(ref PlayerState __state)
			{
				//IL_0069: Unknown result type (might be due to invalid IL or missing references)
				//IL_006f: Invalid comparison between Unknown and I4
				if (!((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.FixTiredness)
				{
					return;
				}
				((Human)Player.Instance).energy = __state.Energy;
				((Human)Player.Instance).alertness = __state.Alertness;
				((Human)Player.Instance).wellRested = __state.WellRested;
				if (Player.Instance.spendingTimeMode && InteractionController.Instance.lockedInInteraction != null && (int)InteractionController.Instance.lockedInInteraction.preset.specialCaseFlag == 1)
				{
					if (((Human)Player.Instance).energy >= 0.8f)
					{
						((Human)Player.Instance).AddWellRested(__state.TickChange / 2f);
					}
					((Human)Player.Instance).AddEnergy(__state.TickChange / 4f);
					return;
				}
				Chapter val = default(Chapter);
				int num = default(int);
				if (!Game.Instance.disableSurvivalStatusesInStory || !Toolbox.Instance.IsStoryMissionActive(ref val, ref num))
				{
					Player instance = Player.Instance;
					((Human)instance).alertness = ((Human)instance).alertness + GameplayControls.Instance.playerTirednessRate * (0f - __state.TickChange);
					((Human)Player.Instance).alertness = Mathf.Clamp01(((Human)Player.Instance).alertness);
					Player.Instance.StatusCheckEndOfFrame();
					((Human)Player.Instance).AddEnergy(GameplayControls.Instance.playerTirednessRate * (0f - __state.TickChange));
				}
				((Human)Player.Instance).AddWellRested(__state.TickChange * -0.5f);
			}
		}
	}
	internal class ControlDetectControllerPatches
	{
		[HarmonyPatch(typeof(ControlDetectController), "Start")]
		internal class ControlDetectController_Start
		{
			[HarmonyPrefix]
			private static void Prefix(ControlDetectController __instance)
			{
				if (((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.SkipPressAnyKeyScreenIfNotUsingJoysticks)
				{
					Il2CppStringArray joystickNames = Input.GetJoystickNames();
					if (joystickNames != null && ((Il2CppArrayBase<string>)(object)joystickNames).Length > 0)
					{
						__instance.loadSceneTriggered = false;
						return;
					}
					PlayerPrefs.SetInt("controlMethod", 1);
					__instance.loadSceneTriggered = true;
				}
			}
		}
	}
	internal class FirstPersonItemControllerPatches
	{
		[HarmonyPatch(typeof(FirstPersonItemController), "Update")]
		internal class FirstPersonItemController_Update
		{
			internal readonly struct PlayerState
			{
				public float Alertness { get; }

				public float Energy { get; }

				public Interactable Interactable { get; }

				public PlayerState(float alertness, float energy, Interactable interactable)
				{
					Alertness = alertness;
					Energy = energy;
					Interactable = interactable;
				}
			}

			[HarmonyPrefix]
			internal static void Prefix(FirstPersonItemController __instance, ref PlayerState __state)
			{
				if (!((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.FixTiredness || (Object)(object)Player.Instance == (Object)null || (Object)(object)BioScreenController.Instance == (Object)null)
				{
					return;
				}
				if (__instance.isConsuming && !__instance.takeOneActive && BioScreenController.Instance.selectedSlot != null && BioScreenController.Instance.selectedSlot.interactableID > -1)
				{
					Interactable interactable = BioScreenController.Instance.selectedSlot.GetInteractable();
					if (interactable != null && interactable.cs > 0f)
					{
						__state = new PlayerState(((Human)Player.Instance).alertness, ((Human)Player.Instance).energy, interactable);
					}
				}
				else
				{
					__state = new PlayerState(((Human)Player.Instance).alertness, ((Human)Player.Instance).energy, null);
				}
			}

			[HarmonyPostfix]
			internal static void Postfix(ref PlayerState __state)
			{
				//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f0: Invalid comparison between Unknown and I4
				if (!((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.FixTiredness || (Object)(object)Player.Instance == (Object)null)
				{
					return;
				}
				((Human)Player.Instance).alertness = __state.Alertness;
				((Human)Player.Instance).energy = __state.Energy;
				if (__state.Interactable == null || !(__state.Interactable.cs > 0f))
				{
					return;
				}
				Interactable interactable = __state.Interactable;
				object obj;
				if (interactable == null)
				{
					obj = null;
				}
				else
				{
					InteractablePreset preset = interactable.preset;
					obj = ((preset != null) ? preset.retailItem : null);
				}
				if ((SoCustomComparison)obj != (SoCustomComparison)null)
				{
					Player instance = Player.Instance;
					((Human)instance).alertness = ((Human)instance).alertness + interactable.preset.retailItem.alertness / interactable.preset.consumableAmount * Time.deltaTime;
					((Human)Player.Instance).alertness = Mathf.Clamp01(((Human)Player.Instance).alertness);
					Player.Instance.StatusCheckEndOfFrame();
					if ((int)interactable.preset.retailItem.desireCategory == 2 && interactable.preset.retailItem.energy <= 0f)
					{
						interactable.preset.retailItem.energy = (float)Math.Round(interactable.preset.retailItem.alertness / 100f * (float)((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.PercentageEnergyRestore, 2);
					}
					Player instance2 = Player.Instance;
					((Human)instance2).energy = ((Human)instance2).energy + interactable.preset.retailItem.energy / interactable.preset.consumableAmount * Time.deltaTime;
					((Human)Player.Instance).energy = Mathf.Clamp01(((Human)Player.Instance).energy);
					Player.Instance.StatusCheckEndOfFrame();
				}
			}
		}

		[HarmonyPatch(typeof(FirstPersonItemController), "TakeOne")]
		internal class FirstPersonItemController_TakeOne
		{
			[HarmonyPrefix]
			internal static bool Prefix(FirstPersonItemController __instance)
			{
				//IL_0074: Unknown result type (might be due to invalid IL or missing references)
				if (!((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.FixTiredness)
				{
					return true;
				}
				if (BioScreenController.Instance.selectedSlot != null && BioScreenController.Instance.selectedSlot.interactableID > -1)
				{
					Interactable interactable = BioScreenController.Instance.selectedSlot.GetInteractable();
					if (interactable != null)
					{
						InteractablePreset preset = interactable.preset;
						if ((SoCustomComparison)(object)((preset != null) ? preset.takeOneEvent : null) != (SoCustomComparison)null)
						{
							AudioController.Instance.Play2DSound(interactable.preset.takeOneEvent, (List<FMODParam>)null, 1f);
						}
					}
				}
				if (!__instance.takeOneActive)
				{
					RuntimeHelper.StartCoroutine(TakeOneExecute(__instance));
				}
				return false;
			}

			private static IEnumerator TakeOneExecute(FirstPersonItemController __instance)
			{
				float progress = 0f;
				__instance.takeOneActive = true;
				__instance.SetConsuming(true);
				Interactable consumable = null;
				if (BioScreenController.Instance.selectedSlot != null && BioScreenController.Instance.selectedSlot.interactableID > -1)
				{
					consumable = BioScreenController.Instance.selectedSlot.GetInteractable();
				}
				while (progress < 1f && consumable != null && consumable.cs > 0f)
				{
					float num = Time.deltaTime / 1.8f;
					if ((SoCustomComparison)(object)consumable.preset.retailItem != (SoCustomComparison)null)
					{
						((Human)Player.Instance).AddNourishment(consumable.preset.retailItem.nourishment * num);
						((Human)Player.Instance).AddHydration(consumable.preset.retailItem.hydration * num);
						HandleEnergyAndAlertness(consumable, num);
						((Human)Player.Instance).AddExcitement(consumable.preset.retailItem.excitement * num);
						((Human)Player.Instance).AddChores(consumable.preset.retailItem.chores * num);
						((Human)Player.Instance).AddHygiene(consumable.preset.retailItem.hygiene * num);
						((Human)Player.Instance).AddBladder(consumable.preset.retailItem.bladder * num);
						((Human)Player.Instance).AddHeat(consumable.preset.retailItem.heat * num);
						((Human)Player.Instance).AddDrunk(consumable.preset.retailItem.drunk * num);
						((Human)Player.Instance).AddSick(consumable.preset.retailItem.sick * num);
						((Human)Player.Instance).AddHeadache(consumable.preset.retailItem.headache * num);
						((Human)Player.Instance).AddWet(consumable.preset.retailItem.wet * num);
						((Human)Player.Instance).AddBrokenLeg(consumable.preset.retailItem.brokenLeg * num);
						((Human)Player.Instance).AddBruised(consumable.preset.retailItem.bruised * num);
						((Human)Player.Instance).AddBlackEye(consumable.preset.retailItem.blackEye * num);
						((Human)Player.Instance).AddBlackedOut(consumable.preset.retailItem.blackedOut * num);
						((Human)Player.Instance).AddNumb(consumable.preset.retailItem.numb * num);
						((Human)Player.Instance).AddBleeding(consumable.preset.retailItem.bleeding * num);
						((Human)Player.Instance).AddBreath(consumable.preset.retailItem.breath * num);
						((Human)Player.Instance).AddStarchAddiction(consumable.preset.retailItem.starchAddiction * num);
						((Human)Player.Instance).AddPoisoned(consumable.preset.retailItem.poisoned * num, (Human)null);
						((Actor)Player.Instance).AddHealth(consumable.preset.retailItem.health * num, true, false);
					}
					progress += num;
					yield return null;
				}
				if (consumable != null)
				{
					Interactable obj = consumable;
					obj.cs -= 1f;
					if (consumable.cs <= 0f)
					{
						__instance.OnConsumableFinished(consumable);
						if (consumable.preset.destroyWhenAllConsumed)
						{
							__instance.EmptySlot(BioScreenController.Instance.selectedSlot, false, true, true, false);
							int childCount = __instance.rightHandObjectParent.GetChildCount();
							List<Transform> list = new List<Transform>();
							for (int i = 0; i < childCount; i++)
							{
								list.Add(__instance.rightHandObjectParent.GetChild(i));
							}
							foreach (Transform item in list)
							{
								Object.Destroy((Object)(object)((Component)item).gameObject);
							}
						}
					}
				}
				__instance.takeOneActive = false;
				__instance.SetConsuming(false);
				if (consumable.cs <= 0f)
				{
					__instance.RefreshHeldObjects();
				}
			}

			private static void HandleEnergyAndAlertness(Interactable consumable, float num)
			{
				//IL_0051: Unknown result type (might be due to invalid IL or missing references)
				//IL_0057: Invalid comparison between Unknown and I4
				Player instance = Player.Instance;
				((Human)instance).alertness = ((Human)instance).alertness + consumable.preset.retailItem.alertness * num;
				((Human)Player.Instance).alertness = Mathf.Clamp01(((Human)Player.Instance).alertness);
				Player.Instance.StatusCheckEndOfFrame();
				if ((int)consumable.preset.retailItem.desireCategory == 2 && consumable.preset.retailItem.energy <= 0f)
				{
					consumable.preset.retailItem.energy = (float)Math.Round(consumable.preset.retailItem.alertness / 100f * (float)((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.PercentageEnergyRestore, 2);
				}
				Player instance2 = Player.Instance;
				((Human)instance2).energy = ((Human)instance2).energy + consumable.preset.retailItem.energy * num;
				((Human)Player.Instance).energy = Mathf.Clamp01(((Human)Player.Instance).energy);
				Player.Instance.StatusCheckEndOfFrame();
			}
		}
	}
	internal class InputPatches
	{
		[HarmonyPatch(typeof(InputController), "Update")]
		internal class InputController_Update
		{
			[HarmonyPrefix]
			internal static bool Prefix(InputController __instance)
			{
				try
				{
					if (!((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.EndConversationPatch && !((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.UnpauseGameOnMainMenuExit)
					{
						return true;
					}
					if (!((Behaviour)__instance).enabled || !ReInput.isReady || PopupMessageController.Instance.active)
					{
						return true;
					}
					if (__instance.player != null && __instance.player.GetButtonDown("Menu"))
					{
						if (((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.EndConversationPatch && SessionData.Instance.startedGame && SessionData.Instance.play && !MainMenuController.Instance.mainMenuActive && ((Actor)Player.Instance).interactingWith != null && ((Actor)Player.Instance).interactingWith.objectRef != null && TypeExtensions.IsAssignableFrom(((Actor)Player.Instance).interactingWith.objectRef, typeof(Actor)))
						{
							ActionController.Instance.Return((Interactable)null, (NewNode)null, (Actor)(object)Player.Instance);
							return false;
						}
						if (((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.UnpauseGameOnMainMenuExit && SessionData.Instance.startedGame && !SessionData.Instance.play && MainMenuController.Instance.mainMenuActive && ((Object)(object)CityConstructor.Instance == (Object)null || !CityConstructor.Instance.preSimActive))
						{
							SessionData.Instance.ResumeGame();
							MainMenuController.Instance.EnableMainMenu(false, true, true, (Component)1);
							return false;
						}
					}
					return true;
				}
				catch (Exception)
				{
					return true;
				}
			}
		}
	}
	internal class MapPatches
	{
		[HarmonyPatch(typeof(MapController), "Setup")]
		internal class MapController_Setup
		{
			[HarmonyPrefix]
			internal static void Prefix()
			{
				//IL_0020: 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)
				//IL_002b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0079: Unknown result type (might be due to invalid IL or missing references)
				if (((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.ChangePlayerMarkerColor)
				{
					Color color = GetColor(((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.PlayerMarkerColor);
					PrefabControls.Instance.characterMarkerColor = color;
				}
				if (((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.EnlargePlayerMarker)
				{
					var (num, num2) = ExtractFloats(((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.PlayerMarkerSize);
					PrefabControls.Instance.playerMarker.transform.localScale = new Vector3(num, num2, 1f);
				}
			}

			[HarmonyPostfix]
			internal static void Postfix(MapController __instance)
			{
				//IL_0018: Unknown result type (might be due to invalid IL or missing references)
				//IL_0052: Unknown result type (might be due to invalid IL or missing references)
				if (((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.ZoomOutOnStart)
				{
					float x = __instance.zoomController.zoomLimit.x;
					__instance.zoomController.SetPivotPoint(0f, (ZoomPivot)1);
					__instance.zoomController.SetZoom(x);
					((Transform)((Component)__instance.zoomController).GetComponent<RectTransform>()).localScale = new Vector3(x, x, 1f);
				}
			}

			private static Color GetColor(string hexColor)
			{
				//IL_0066: Unknown result type (might be due to invalid IL or missing references)
				hexColor = hexColor.TrimStart('#');
				if (hexColor.Length != 6)
				{
					PluginController<Plugin, IPluginBindings>.Log.LogWarning((object)"Invalid hex color code in configuration, it should be in the format #RRGGBB. Falling back to default green color.");
					hexColor = "008000";
				}
				int num = int.Parse(hexColor.Substring(0, 2), NumberStyles.HexNumber);
				int num2 = int.Parse(hexColor.Substring(2, 2), NumberStyles.HexNumber);
				int num3 = int.Parse(hexColor.Substring(4, 2), NumberStyles.HexNumber);
				return new Color((float)num, (float)num2, (float)num3);
			}

			private static (float x, float y) ExtractFloats(string input)
			{
				string pattern = "\\((-?\\d+(\\.\\d+)?), (-?\\d+(\\.\\d+)?)\\)";
				Match match = Regex.Match(input, pattern);
				if (match.Success)
				{
					float item = float.Parse(match.Groups[1].Value, CultureInfo.InvariantCulture);
					float item2 = float.Parse(match.Groups[3].Value, CultureInfo.InvariantCulture);
					return (item, item2);
				}
				PluginController<Plugin, IPluginBindings>.Log.LogWarning((object)"Invalid player marker size configuration, using the default value (2.5, 2.5)");
				return (2.5f, 2.5f);
			}
		}

		[HarmonyPatch(typeof(MapController), "CentreOnObject")]
		internal class MapController_CentreOnObject
		{
			private static bool _calledBefore;

			[HarmonyPostfix]
			internal static void Postfix(MapController __instance, RectTransform mapObj, bool instant, bool showPointer)
			{
				if (((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.FixCenterOnPlayer)
				{
					if (_calledBefore)
					{
						_calledBefore = false;
						return;
					}
					_calledBefore = true;
					__instance.CentreOnObject(mapObj, instant, showPointer);
				}
			}
		}
	}
	internal class RoutePlotPatches
	{
		[HarmonyPatch(typeof(EvidenceLocationalControls), "OnPlotRoute")]
		internal class EvidenceLocationalControls_OnPlotRoute
		{
			[HarmonyPrefix]
			internal static bool Prefix(EvidenceLocationalControls __instance)
			{
				//IL_0025: Unknown result type (might be due to invalid IL or missing references)
				//IL_0099: Unknown result type (might be due to invalid IL or missing references)
				//IL_009e: 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_00ad: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
				Vector3Int? val = null;
				if (MapController.Instance.playerRoute != null)
				{
					val = MapController.Instance.playerRoute.end.nodeCoord;
					MapController.Instance.playerRoute.Remove();
					if ((Object)(object)__instance.plotRouteButton != (Object)null)
					{
						((Graphic)((Selectable)__instance.plotRouteButton.button).image).color = __instance.plotRouteButton.baseColour;
					}
				}
				MapController.Instance.PlotPlayerRoute(__instance.parentWindow.passedEvidence);
				if (val.HasValue)
				{
					Vector3Int nodeCoord = MapController.Instance.playerRoute.end.nodeCoord;
					Vector3Int? val2 = val;
					if (val2.HasValue && nodeCoord == val2.GetValueOrDefault())
					{
						MapController.Instance.playerRoute.Remove();
					}
				}
				return false;
			}
		}
	}
	internal class ToolboxPatches
	{
		[HarmonyPatch(typeof(Toolbox), "LoadAll")]
		internal static class Toolbox_LoadAll
		{
			[HarmonyPostfix]
			internal static void Postfix(Toolbox __instance)
			{
				//IL_0087: Unknown result type (might be due to invalid IL or missing references)
				//IL_008d: Expected O, but got Unknown
				if (!((PluginController<Plugin, IPluginBindings>)PluginController<Plugin, IPluginBindings>.Instance).Config.FixTiredness)
				{
					return;
				}
				bool flag = default(bool);
				foreach (RetailItemPreset item in EnumerableExtensions.Where<RetailItemPreset>(__instance.allItems, (Func<RetailItemPreset, bool>)((RetailItemPreset a) => (int)a.desireCategory == 2)))
				{
					if (item.energy <= 0f)
					{
						item.energy = (float)Math.Round(item.alertness / 100f * 12f, 2);
						ManualLogSource log = PluginController<Plugin, IPluginBindings>.Log;
						BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(44, 2, ref flag);
						if (flag)
						{
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Adjusted energy restore amount for \"");
							((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(((Object)item).name);
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral("\" to \"");
							((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(item.energy);
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral("\".");
						}
						log.LogInfo(val);
					}
				}
			}
		}
	}
}