Decompiled source of EchoPERSONALUSE1 v1.0.0

GeneralImprovements.dll

Decompiled 2 years ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using GeneralImprovements.Items;
using GeneralImprovements.NetcodePatcher;
using GeneralImprovements.OtherMods;
using GeneralImprovements.Patches;
using GeneralImprovements.Utilities;
using HarmonyLib;
using TMPro;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.UI;

[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.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("GeneralImprovements")]
[assembly: AssemblyConfiguration("Deploy")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+03142f3ebb0a34a34390bb07d2505d38f6d03b34")]
[assembly: AssemblyProduct("GeneralImprovements")]
[assembly: AssemblyTitle("GeneralImprovements")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: NetcodePatchedAssembly]
internal class <Module>
{
	static <Module>()
	{
	}
}
namespace GeneralImprovements
{
	internal static class Metadata
	{
		public const string GUID = "ShaosilGaming.GeneralImprovements";

		public const string PLUGIN_NAME = "GeneralImprovements";

		public const string VERSION = "1.0.27";
	}
	[BepInPlugin("ShaosilGaming.GeneralImprovements", "GeneralImprovements", "1.0.27")]
	public class Plugin : BaseUnityPlugin
	{
		private const string ExtraMonitorsSection = "ExtraMonitors";

		private const string FixesSection = "Fixes";

		private const string GameLaunchSection = "GameLaunch";

		private const string InventorySection = "Inventory";

		private const string MechanicsSection = "Mechanics";

		private const string ShipSection = "Ship";

		private const string TeleportersSection = "Teleporters";

		private const string TerminalSection = "Terminal";

		private const string ToolsSection = "Tools";

		private const string UISection = "UI";

		public static ManualLogSource MLS { get; private set; }

		public static ConfigEntry<bool> ShowBlueMonitorBackground { get; private set; }

		public static ConfigEntry<int> ShipTotalMonitorNum { get; private set; }

		public static ConfigEntry<int> ShipTimeMonitorNum { get; private set; }

		public static ConfigEntry<int> ShipWeatherMonitorNum { get; private set; }

		public static ConfigEntry<int> ShipSalesMonitorNum { get; private set; }

		public static ConfigEntry<bool> FancyWeatherMonitor { get; private set; }

		public static ConfigEntry<bool> SyncExtraMonitorsPower { get; private set; }

		public static ConfigEntry<bool> CenterAlignMonitorText { get; private set; }

		public static ConfigEntry<bool> FixInternalFireExits { get; private set; }

		public static ConfigEntry<bool> FixItemsFallingThrough { get; private set; }

		public static ConfigEntry<bool> FixPersonalScanner { get; private set; }

		public static ConfigEntry<bool> ScanHeldPlayerItems { get; private set; }

		public static ConfigEntry<bool> SkipStartupScreen { get; private set; }

		public static ConfigEntry<string> AutoSelectLaunchMode { get; private set; }

		public static ConfigEntry<bool> PickupInOrder { get; private set; }

		public static ConfigEntry<bool> RearrangeOnDrop { get; private set; }

		public static ConfigEntry<bool> TwoHandedInSlotOne { get; private set; }

		public static ConfigEntry<float> ScrollDelay { get; private set; }

		public static ConfigEntry<int> StartingMoneyPerPlayer { get; private set; }

		public static int StartingMoneyPerPlayerVal => Math.Clamp(StartingMoneyPerPlayer.Value, -1, 1000);

		public static ConfigEntry<int> MinimumStartingMoney { get; private set; }

		public static int MinimumStartingMoneyVal => Math.Clamp(MinimumStartingMoney.Value, StartingMoneyPerPlayerVal, 1000);

		public static ConfigEntry<bool> AllowQuotaRollover { get; private set; }

		public static ConfigEntry<bool> AddHealthRechargeStation { get; private set; }

		public static ConfigEntry<bool> HideClipboardAndStickyNote { get; private set; }

		public static ConfigEntry<int> SnapObjectsByDegrees { get; private set; }

		public static ConfigEntry<string> FreeRotateKey { get; private set; }

		public static ConfigEntry<string> CounterClockwiseKey { get; private set; }

		public static ConfigEntry<bool> ShipMapCamDueNorth { get; private set; }

		public static ConfigEntry<int> RegularTeleporterCooldown { get; private set; }

		public static ConfigEntry<int> InverseTeleporterCooldown { get; private set; }

		public static ConfigEntry<int> TerminalHistoryItemCount { get; private set; }

		public static ConfigEntry<bool> TerminalFastCamSwitch { get; private set; }

		public static ConfigEntry<string> ScannableTools { get; private set; }

		public static List<Type> ScannableToolVals { get; private set; } = new List<Type>();


		public static ConfigEntry<bool> ToolsDoNotAttractLightning { get; private set; }

		public static ConfigEntry<bool> ShowUIReticle { get; private set; }

		public static ConfigEntry<bool> HideEmptySubtextOfScanNodes { get; private set; }

		private void Awake()
		{
			//IL_0278: Unknown result type (might be due to invalid IL or missing references)
			//IL_0282: Expected O, but got Unknown
			//IL_02b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bb: Expected O, but got Unknown
			//IL_02ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f4: Expected O, but got Unknown
			//IL_0323: Unknown result type (might be due to invalid IL or missing references)
			//IL_032d: Expected O, but got Unknown
			//IL_047d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0487: Expected O, but got Unknown
			//IL_051e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0528: Expected O, but got Unknown
			//IL_0554: Unknown result type (might be due to invalid IL or missing references)
			//IL_055e: Expected O, but got Unknown
			//IL_058b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0595: Expected O, but got Unknown
			//IL_0620: Unknown result type (might be due to invalid IL or missing references)
			//IL_062a: Expected O, but got Unknown
			//IL_0642: Unknown result type (might be due to invalid IL or missing references)
			//IL_0661: Unknown result type (might be due to invalid IL or missing references)
			//IL_066b: Expected O, but got Unknown
			//IL_0683: Unknown result type (might be due to invalid IL or missing references)
			//IL_06a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_06ac: Expected O, but got Unknown
			//IL_06fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0704: Expected O, but got Unknown
			//IL_0731: Unknown result type (might be due to invalid IL or missing references)
			//IL_073b: Expected O, but got Unknown
			//IL_0765: Unknown result type (might be due to invalid IL or missing references)
			//IL_076f: Expected O, but got Unknown
			string[] array = (from int e in Enum.GetValues(typeof(Key))
				where e < 106
				select Enum.GetName(typeof(Key), e)).Concat(from int e in Enum.GetValues(typeof(ShipBuildModeManagerPatch.MouseButton))
				select Enum.GetName(typeof(ShipBuildModeManagerPatch.MouseButton), e)).ToArray();
			int[] array2 = (from n in Enumerable.Range(0, 24)
				select n * 15 into n
				where n == 0 || 360 % n == 0
				select n).ToArray();
			List<Type> list = new List<Type>();
			list.Add(typeof(BoomboxItem));
			list.Add(typeof(ExtensionLadderItem));
			list.Add(typeof(FlashlightItem));
			list.Add(typeof(JetpackItem));
			list.Add(typeof(LockPicker));
			list.Add(typeof(RadarBoosterItem));
			list.Add(typeof(Shovel));
			list.Add(typeof(SprayPaintItem));
			list.Add(typeof(StunGrenadeItem));
			list.Add(typeof(TetraChemicalItem));
			list.Add(typeof(WalkieTalkie));
			list.Add(typeof(PatcherTool));
			List<Type> list2 = list;
			string text = string.Join(", ", new string[1] { "All" }.Concat(list2.Select((Type t) => t.Name)));
			MLS = ((BaseUnityPlugin)this).Logger;
			string text2 = "0 = DISABLED. 1-4 are the top row monitors above the ship starting lever, from left to right. 5-6 are below 3 and 4, respectively.";
			ShowBlueMonitorBackground = ((BaseUnityPlugin)this).Config.Bind<bool>("ExtraMonitors", "ShowBlueMonitorBackground", true, "If set to true, keeps the vanilla blue backgrounds on the extra monitors. Set to false for black.");
			ShipTotalMonitorNum = ((BaseUnityPlugin)this).Config.Bind<int>("ExtraMonitors", "ShipTotalMonitorNum", 0, new ConfigDescription("Displays the sum of all scrap value on the ship on the specified monitor. " + text2, (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 6), Array.Empty<object>()));
			ShipTimeMonitorNum = ((BaseUnityPlugin)this).Config.Bind<int>("ExtraMonitors", "ShipTimeMonitorNum", 0, new ConfigDescription("Displays current time on the specified monitor. " + text2, (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 6), Array.Empty<object>()));
			ShipWeatherMonitorNum = ((BaseUnityPlugin)this).Config.Bind<int>("ExtraMonitors", "ShipWeatherMonitorNum", 0, new ConfigDescription("Displays the current moon's weather on the specified monitor. " + text2, (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 6), Array.Empty<object>()));
			ShipSalesMonitorNum = ((BaseUnityPlugin)this).Config.Bind<int>("ExtraMonitors", "ShipSalesMonitorNum", 0, new ConfigDescription("Displays info about current sales on the specified monitor. " + text2, (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 6), Array.Empty<object>()));
			FancyWeatherMonitor = ((BaseUnityPlugin)this).Config.Bind<bool>("ExtraMonitors", "FancyWeatherMonitor", true, "If set to true and paired with ShowShipWeatherMonitor, the weather monitor will display ASCII art instead of text descriptions.");
			SyncExtraMonitorsPower = ((BaseUnityPlugin)this).Config.Bind<bool>("ExtraMonitors", "SyncExtraMonitorsPower", true, "If set to true, The smaller monitors above the map screen will turn off and on when the map screen power is toggled.");
			CenterAlignMonitorText = ((BaseUnityPlugin)this).Config.Bind<bool>("ExtraMonitors", "CenterAlignMonitorText", true, "If set to true, all small monitors in the ship will have their text center aligned, instead of left.");
			FixInternalFireExits = ((BaseUnityPlugin)this).Config.Bind<bool>("Fixes", "FixInternalFireExits", true, "If set to true, the player will face the interior of the facility when entering through a fire entrance.");
			FixItemsFallingThrough = ((BaseUnityPlugin)this).Config.Bind<bool>("Fixes", "FixItemsFallingThrough", true, "Fixes items falling through furniture on the ship when loading the game.");
			FixPersonalScanner = ((BaseUnityPlugin)this).Config.Bind<bool>("Fixes", "FixPersonalScanner", false, "If set to true, will tweak the behavior of the scan action and more reliably ping items closer to you, and the ship/main entrance.");
			ScanHeldPlayerItems = ((BaseUnityPlugin)this).Config.Bind<bool>("Fixes", "ScanHeldPlayerItems", false, "If this and FixPersonalScanner are set to true, the scanner will also ping items in other players' hands.");
			SkipStartupScreen = ((BaseUnityPlugin)this).Config.Bind<bool>("GameLaunch", "SkipStartupScreen", true, "Skips the main menu loading screen bootup animation.");
			AutoSelectLaunchMode = ((BaseUnityPlugin)this).Config.Bind<string>("GameLaunch", "AutoSelectLaunchMode", string.Empty, new ConfigDescription("If set to 'ONLINE' or 'LAN', will automatically launch the correct mode, saving you from having to click the menu option when the game loads.", (AcceptableValueBase)(object)new AcceptableValueList<string>(new string[3]
			{
				string.Empty,
				"ONLINE",
				"LAN"
			}), Array.Empty<object>()));
			PickupInOrder = ((BaseUnityPlugin)this).Config.Bind<bool>("Inventory", "PickupInOrder", true, "When picking up items, will always put them in left - right order.");
			RearrangeOnDrop = ((BaseUnityPlugin)this).Config.Bind<bool>("Inventory", "RearrangeOnDrop", true, "When dropping items, will rearrange other inventory items to ensure slots are filled left - right.");
			TwoHandedInSlotOne = ((BaseUnityPlugin)this).Config.Bind<bool>("Inventory", "TwoHandedInSlotOne", true, "When picking up a two handed item, it will always place it in slot 1 and shift things to the right if needed. Makes selling quicker when paired with RearrangeOnDrop.");
			ScrollDelay = ((BaseUnityPlugin)this).Config.Bind<float>("Inventory", "ScrollDelay", 0.1f, new ConfigDescription("The minimum time you must wait to scroll to another item in your inventory. Vanilla: 0.3.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.05f, 0.3f), Array.Empty<object>()));
			StartingMoneyPerPlayer = ((BaseUnityPlugin)this).Config.Bind<int>("Mechanics", "StartingMoneyPerPlayer", -1, new ConfigDescription("[Host Only] How much starting money the group gets per player. Set to -1 to disable. Adjusts money as players join and leave, until the game starts.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(-1, 1000), Array.Empty<object>()));
			MinimumStartingMoney = ((BaseUnityPlugin)this).Config.Bind<int>("Mechanics", "MinimumStartingMoney", 30, new ConfigDescription("[Host Only] When paired with StartingMoneyPerPlayer, will ensure a group always starts with at least this much money. Must be at least the value of StartingMoneyPerPlayer.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(-1, 1000), Array.Empty<object>()));
			AllowQuotaRollover = ((BaseUnityPlugin)this).Config.Bind<bool>("Mechanics", "AllowQuotaRollover", false, "[Host Required] If set to true, will keep the surplus money remaining after selling things to the company, and roll it over to the next quota. If clients do not set this, they will see visual desyncs.");
			AddHealthRechargeStation = ((BaseUnityPlugin)this).Config.Bind<bool>("Mechanics", "AddHealthRechargeStation", false, "[Host Only] If set to true, a medical charging station will be above the ship's battery charger, and can be used to heal to full.");
			HideClipboardAndStickyNote = ((BaseUnityPlugin)this).Config.Bind<bool>("Ship", "HideClipboardAndStickyNote", false, "If set to true, the game will not show the clipboard or sticky note when the game loads.");
			SnapObjectsByDegrees = ((BaseUnityPlugin)this).Config.Bind<int>("Ship", "SnapObjectsByDegrees", 45, new ConfigDescription("Build mode will switch to snap turning (press instead of hold) by this many degrees at a time. Setting it to 0 uses vanilla behavior.", (AcceptableValueBase)(object)new AcceptableValueList<int>(array2), Array.Empty<object>()));
			ConfigFile config = ((BaseUnityPlugin)this).Config;
			Key val = (Key)53;
			FreeRotateKey = config.Bind<string>("Ship", "FreeRotateKey", ((object)(Key)(ref val)).ToString(), new ConfigDescription("If SnapObjectsByDegrees > 0, configures which modifer key activates free rotation.", (AcceptableValueBase)(object)new AcceptableValueList<string>(array), Array.Empty<object>()));
			ConfigFile config2 = ((BaseUnityPlugin)this).Config;
			val = (Key)51;
			CounterClockwiseKey = config2.Bind<string>("Ship", "CounterClockwiseKey", ((object)(Key)(ref val)).ToString(), new ConfigDescription("If SnapObjectsByDegrees > 0, configures which modifier key spins it CCW.", (AcceptableValueBase)(object)new AcceptableValueList<string>(array), Array.Empty<object>()));
			ShipMapCamDueNorth = ((BaseUnityPlugin)this).Config.Bind<bool>("Ship", "ShipMapCamDueNorth", false, "If set to true, the ship's map camera will rotate so that it faces north evenly, instead of showing everything at an angle.");
			RegularTeleporterCooldown = ((BaseUnityPlugin)this).Config.Bind<int>("Teleporters", "RegularTeleporterCooldown", 10, new ConfigDescription("How many seconds to wait in between button presses for the REGULAR teleporter. Vanilla = 10.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 300), Array.Empty<object>()));
			InverseTeleporterCooldown = ((BaseUnityPlugin)this).Config.Bind<int>("Teleporters", "InverseTeleporterCooldown", 10, new ConfigDescription("How many seconds to wait in between button presses for the INVERSE teleporter. Vanilla = 210.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 300), Array.Empty<object>()));
			TerminalHistoryItemCount = ((BaseUnityPlugin)this).Config.Bind<int>("Terminal", "TerminalHistoryItemCount", 20, new ConfigDescription("How many items to keep in your terminal's command history. Previous terminal commands may be navigated by using the up/down arrow keys.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>()));
			TerminalFastCamSwitch = ((BaseUnityPlugin)this).Config.Bind<bool>("Terminal", "TerminalFastCamSwitch", true, "If set to true, will allow use of the left/right arrow keys to quickly cycle through radar cameras while using the terminal.");
			ScannableTools = ((BaseUnityPlugin)this).Config.Bind<string>("Tools", "ScannableTools", string.Empty, "A comma separated list of which tools, if any, should be scannable. Accepted values: " + text);
			ToolsDoNotAttractLightning = ((BaseUnityPlugin)this).Config.Bind<bool>("Tools", "ToolsDoNotAttractLightning", false, "[Host Only] If set to true, all useful tools (jetpacks, keys, radar boosters, shovels & signs, tzp inhalant, and zap guns) will no longer attract lighning.");
			HideEmptySubtextOfScanNodes = ((BaseUnityPlugin)this).Config.Bind<bool>("UI", "HideEmptySubtextOfScanNodes", true, "If set to true, will hide the subtext section of scannables that do not have subtext or scrap value.");
			ShowUIReticle = ((BaseUnityPlugin)this).Config.Bind<bool>("UI", "ShowUIReticle", false, "If set to true, the HUD will display a small dot so you can see exactly where you are pointing at all times.");
			if (MinimumStartingMoney.Value < StartingMoneyPerPlayer.Value)
			{
				MinimumStartingMoney.Value = StartingMoneyPerPlayer.Value;
			}
			List<string> list3 = new List<string>();
			string[] source = ScannableTools.Value.Replace(" ", "").Split(',');
			if (source.Any((string s) => s.ToUpper() == "ALL"))
			{
				ScannableToolVals = list2;
			}
			else
			{
				string[] array3 = ScannableTools.Value.Replace(" ", "").Split(',');
				foreach (string scannableTool in array3)
				{
					Type type = list2.FirstOrDefault((Type g) => g.Name.ToUpper().Contains(scannableTool.ToUpper()));
					if (type == null)
					{
						MLS.LogWarning((object)("Could not find item type " + scannableTool + " when trying to add a scan node! Check your spelling and the acceptable values."));
						continue;
					}
					ScannableToolVals.Add(type);
					list3.Add(scannableTool);
				}
				ScannableTools.Value = string.Join(',', list3.ToArray());
			}
			MLS.LogDebug((object)"Configuration Initialized.");
			Harmony.CreateAndPatchAll(typeof(DepositItemsDeskPatch), (string)null);
			MLS.LogDebug((object)"DepositItemsDesk patched.");
			Harmony.CreateAndPatchAll(typeof(EntranceTeleportPatch), (string)null);
			MLS.LogDebug((object)"EntranceTeleport patched.");
			Harmony.CreateAndPatchAll(typeof(GameNetworkManagerPatch), (string)null);
			MLS.LogDebug((object)"GameNetworkManager patched.");
			Harmony.CreateAndPatchAll(typeof(GrabbableObjectsPatch), (string)null);
			MLS.LogDebug((object)"GrabbableObjects patched.");
			Harmony.CreateAndPatchAll(typeof(HUDManagerPatch), (string)null);
			MLS.LogDebug((object)"HUDManager patched.");
			Harmony.CreateAndPatchAll(typeof(ManualCameraRendererPatch), (string)null);
			MLS.LogDebug((object)"ManualCameraRenderer patched.");
			Harmony.CreateAndPatchAll(typeof(MenuPatches), (string)null);
			MLS.LogDebug((object)"Menus patched.");
			Harmony.CreateAndPatchAll(typeof(PlayerControllerBPatch), (string)null);
			MLS.LogDebug((object)"PlayerControllerB patched.");
			Harmony.CreateAndPatchAll(typeof(RoundManagerPatch), (string)null);
			MLS.LogDebug((object)"RoundManager patched.");
			Harmony.CreateAndPatchAll(typeof(ShipBuildModeManagerPatch), (string)null);
			MLS.LogDebug((object)"ShipBuildModeManager patched.");
			Harmony.CreateAndPatchAll(typeof(ShipTeleporterPatch), (string)null);
			MLS.LogDebug((object)"ShipTeleporter patched.");
			Harmony.CreateAndPatchAll(typeof(StartOfRoundPatch), (string)null);
			MLS.LogDebug((object)"StartOfRound patched.");
			Harmony.CreateAndPatchAll(typeof(TerminalAccessibleObjectPatch), (string)null);
			MLS.LogDebug((object)"TerminalAccessibleObject patched.");
			Harmony.CreateAndPatchAll(typeof(TerminalPatch), (string)null);
			MLS.LogDebug((object)"Terminal patched.");
			Harmony.CreateAndPatchAll(typeof(TimeOfDayPatch), (string)null);
			MLS.LogDebug((object)"TimeOfDay patched.");
			ReservedItemSlotCoreHelper.Initialize();
			AdvancedCompanyHelper.Initialize();
			AssetBundleHelper.Initialize();
			GameNetworkManagerPatch.PatchNetcode();
			MLS.LogInfo((object)"GeneralImprovements v1.0.27 fully loaded.");
		}
	}
}
namespace GeneralImprovements.Utilities
{
	internal static class AssetBundleHelper
	{
		private static AssetBundle _bundle;

		public static Sprite Reticle { get; private set; }

		public static GameObject MedStationPrefab { get; private set; }

		public static void Initialize()
		{
			if ((Object)(object)_bundle == (Object)null)
			{
				string text = Path.Combine(new FileInfo(Assembly.GetExecutingAssembly().Location).DirectoryName, "assets");
				if (!new FileInfo(text).Exists)
				{
					Plugin.MLS.LogError((object)"Could not find asset bundle!");
					return;
				}
				_bundle = AssetBundle.LoadFromFile(text);
				Plugin.MLS.LogInfo((object)"Loading assets...");
				Reticle = _bundle.LoadAsset<Sprite>("reticle.png");
				MedStationPrefab = _bundle.LoadAsset<GameObject>("MedStation.prefab");
			}
		}
	}
	internal static class ItemHelper
	{
		private static IReadOnlyList<NetworkPrefab> AllPrefabs => NetworkManager.Singleton.NetworkConfig.Prefabs.Prefabs;

		public static void AlterFancyLampPrefab()
		{
			NetworkPrefab val = ((IEnumerable<NetworkPrefab>)AllPrefabs).FirstOrDefault((Func<NetworkPrefab, bool>)((NetworkPrefab p) => ((Object)p.Prefab).name == "FancyLamp"));
			if (val != null)
			{
				Plugin.MLS.LogInfo((object)"Adding ToggleableFancyLamp behavior to FancyLamp prefab.");
				PhysicsProp component = val.Prefab.GetComponent<PhysicsProp>();
				ToggleableFancyLamp toggleableFancyLamp = val.Prefab.AddComponent<ToggleableFancyLamp>();
				ItemHelper.CopyGrabbablePrefab<ToggleableFancyLamp>((GrabbableObject)(object)component, toggleableFancyLamp);
				((GrabbableObject)toggleableFancyLamp).itemProperties.toolTips = new string[1] { "[LMB] : Toggle Light" };
				((GrabbableObject)toggleableFancyLamp).itemProperties.syncUseFunction = true;
				Object.Destroy((Object)(object)component);
				NetworkPrefab? obj = ((IEnumerable<NetworkPrefab>)AllPrefabs).FirstOrDefault((Func<NetworkPrefab, bool>)((NetworkPrefab p) => ((Object)p.Prefab).name == "FlashlightItem"));
				FlashlightItem val2 = ((obj != null) ? obj.Prefab.GetComponent<FlashlightItem>() : null);
				if ((Object)(object)val2 != (Object)null && (Object)(object)val2.flashlightAudio != (Object)null && val2.flashlightClips != null && val2.flashlightClips.Length != 0)
				{
					AudioSource dest = val.Prefab.AddComponent<AudioSource>();
					CopyAudioSource(val2.flashlightAudio, dest);
					toggleableFancyLamp.AudioClips = val2.flashlightClips;
				}
			}
		}

		public static void CopyGrabbablePrefab<T>(GrabbableObject baseObj, T newObj) where T : GrabbableObject
		{
			((GrabbableObject)newObj).customGrabTooltip = baseObj.customGrabTooltip;
			((GrabbableObject)newObj).floorYRot = baseObj.floorYRot;
			((GrabbableObject)newObj).grabbable = baseObj.grabbable;
			((GrabbableObject)newObj).grabbableToEnemies = baseObj.grabbableToEnemies;
			((GrabbableObject)newObj).isInElevator = baseObj.isInElevator;
			((GrabbableObject)newObj).isInFactory = baseObj.isInFactory;
			((GrabbableObject)newObj).isInShipRoom = baseObj.isInShipRoom;
			((GrabbableObject)newObj).itemProperties = baseObj.itemProperties;
			((GrabbableObject)newObj).propBody = baseObj.propBody;
			((GrabbableObject)newObj).propColliders = baseObj.propColliders;
			((GrabbableObject)newObj).radarIcon = baseObj.radarIcon;
			((GrabbableObject)newObj).useCooldown = baseObj.useCooldown;
		}

		public static void CopyAudioSource(AudioSource original, AudioSource dest)
		{
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			dest.clip = original.clip;
			dest.dopplerLevel = original.dopplerLevel;
			dest.ignoreListenerPause = original.ignoreListenerPause;
			dest.ignoreListenerVolume = original.ignoreListenerVolume;
			dest.loop = original.loop;
			dest.maxDistance = original.maxDistance;
			dest.minDistance = original.minDistance;
			dest.mute = original.mute;
			dest.outputAudioMixerGroup = original.outputAudioMixerGroup;
			dest.panStereo = original.panStereo;
			dest.pitch = original.pitch;
			dest.playOnAwake = original.playOnAwake;
			dest.priority = original.priority;
			dest.reverbZoneMix = original.reverbZoneMix;
			dest.rolloffMode = original.rolloffMode;
			dest.spatialBlend = original.spatialBlend;
			dest.spatialize = original.spatialize;
			dest.spatializePostEffects = original.spatializePostEffects;
			dest.spread = original.spread;
			dest.time = original.time;
			dest.timeSamples = original.timeSamples;
			dest.velocityUpdateMode = original.velocityUpdateMode;
			dest.volume = original.volume;
		}
	}
	internal static class SceneHelper
	{
		private static Image _totalMonitorBg;

		private static TextMeshProUGUI _totalMonitorText;

		private static Image _timeMonitorBG;

		private static TextMeshProUGUI _timeMonitorText;

		private static Image _weatherMonitorBG;

		private static TextMeshProUGUI _weatherMonitorText;

		private static Image _salesMonitorBG;

		private static TextMeshProUGUI _salesMonitorText;

		private static int _curWeatherAnimIndex = 0;

		private static int _curWeatherOverlayIndex = 0;

		private static string[] _curWeatherAnimations = new string[0];

		private static string[] _curWeatherOverlays = new string[0];

		private static float _animTimer = 0f;

		private static float _animCycle = 0.2f;

		private static bool _hasOverlays = false;

		private static float _overlayTimer = 0f;

		private static bool _showingOverlay = false;

		private static float _overlayCycle;

		public static GameObject MedStation;

		public static int MaxHealth;

		public static void CreateExtraMonitors()
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: 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_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: 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_032b: Unknown result type (might be due to invalid IL or missing references)
			//IL_033f: Unknown result type (might be due to invalid IL or missing references)
			//IL_035f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0373: Unknown result type (might be due to invalid IL or missing references)
			//IL_0393: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03db: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_040f: Unknown result type (might be due to invalid IL or missing references)
			//IL_042f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0443: Unknown result type (might be due to invalid IL or missing references)
			//IL_0260: Unknown result type (might be due to invalid IL or missing references)
			//IL_0274: Unknown result type (might be due to invalid IL or missing references)
			//IL_0279: Unknown result type (might be due to invalid IL or missing references)
			//IL_028f: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_057c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0581: Unknown result type (might be due to invalid IL or missing references)
			//IL_0597: Unknown result type (might be due to invalid IL or missing references)
			//IL_059c: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_05b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_05b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_05cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_05d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_05e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0604: Unknown result type (might be due to invalid IL or missing references)
			//IL_0609: Unknown result type (might be due to invalid IL or missing references)
			//IL_0621: Unknown result type (might be due to invalid IL or missing references)
			//IL_0626: Unknown result type (might be due to invalid IL or missing references)
			//IL_0628: Unknown result type (might be due to invalid IL or missing references)
			Image profitQuotaMonitorBGImage = StartOfRound.Instance.profitQuotaMonitorBGImage;
			TextMeshProUGUI profitQuotaMonitorText = StartOfRound.Instance.profitQuotaMonitorText;
			Image deadlineMonitorBGImage = StartOfRound.Instance.deadlineMonitorBGImage;
			TextMeshProUGUI deadlineMonitorText = StartOfRound.Instance.deadlineMonitorText;
			((TMP_Text)profitQuotaMonitorText).rectTransform.sizeDelta = ((Graphic)profitQuotaMonitorBGImage).rectTransform.sizeDelta;
			((TMP_Text)profitQuotaMonitorText).transform.position = ((Component)profitQuotaMonitorBGImage).transform.TransformPoint(Vector3.back);
			((TMP_Text)profitQuotaMonitorText).fontSize = ((TMP_Text)profitQuotaMonitorText).fontSize * 0.9f;
			((TMP_Text)profitQuotaMonitorText).margin = Vector4.one * 5f;
			((TMP_Text)deadlineMonitorText).rectTransform.sizeDelta = ((Graphic)deadlineMonitorBGImage).rectTransform.sizeDelta;
			((TMP_Text)deadlineMonitorText).transform.position = ((Component)deadlineMonitorBGImage).transform.TransformPoint(Vector3.back);
			((TMP_Text)deadlineMonitorText).fontSize = ((TMP_Text)deadlineMonitorText).fontSize * 0.9f;
			((TMP_Text)deadlineMonitorText).margin = Vector4.one * 5f;
			if (Plugin.CenterAlignMonitorText.Value)
			{
				((TMP_Text)profitQuotaMonitorText).alignment = (TextAlignmentOptions)514;
				((TMP_Text)deadlineMonitorText).alignment = (TextAlignmentOptions)514;
			}
			if (Plugin.ShipTotalMonitorNum.Value > 0)
			{
				_totalMonitorBg = Object.Instantiate<Image>(profitQuotaMonitorBGImage, ((Component)profitQuotaMonitorBGImage).transform.parent);
				((Object)_totalMonitorBg).name = "TotalMonitorBG";
				_totalMonitorText = Object.Instantiate<TextMeshProUGUI>(profitQuotaMonitorText, ((TMP_Text)profitQuotaMonitorText).transform.parent);
				((Object)_totalMonitorText).name = "TotalMonitorText";
			}
			if (Plugin.ShipTimeMonitorNum.Value > 0)
			{
				_timeMonitorBG = Object.Instantiate<Image>(profitQuotaMonitorBGImage, ((Component)profitQuotaMonitorBGImage).transform.parent);
				((Object)_timeMonitorBG).name = "TimeMonitorBG";
				_timeMonitorText = Object.Instantiate<TextMeshProUGUI>(profitQuotaMonitorText, ((TMP_Text)profitQuotaMonitorText).transform.parent);
				((Object)_timeMonitorText).name = "TimeMonitorText";
			}
			if (Plugin.ShipWeatherMonitorNum.Value > 0)
			{
				_weatherMonitorBG = Object.Instantiate<Image>(profitQuotaMonitorBGImage, ((Component)profitQuotaMonitorBGImage).transform.parent);
				((Object)_weatherMonitorBG).name = "WeatherMonitorBG";
				_weatherMonitorText = Object.Instantiate<TextMeshProUGUI>(profitQuotaMonitorText, ((TMP_Text)profitQuotaMonitorText).transform.parent);
				((Object)_weatherMonitorText).name = "WeatherMonitorText";
				if (Plugin.FancyWeatherMonitor.Value)
				{
					((TMP_Text)_weatherMonitorText).alignment = (TextAlignmentOptions)4097;
					Transform transform = ((TMP_Text)_weatherMonitorText).transform;
					transform.localPosition += new Vector3(25f, 0f, -10f);
					Transform transform2 = ((TMP_Text)_weatherMonitorText).transform;
					transform2.localEulerAngles += new Vector3(-2f, 1f, 0f);
				}
			}
			if (Plugin.ShipSalesMonitorNum.Value > 0)
			{
				_salesMonitorBG = Object.Instantiate<Image>(profitQuotaMonitorBGImage, ((Component)profitQuotaMonitorBGImage).transform.parent);
				((Object)_salesMonitorBG).name = "SalesMonitorBG";
				_salesMonitorText = Object.Instantiate<TextMeshProUGUI>(profitQuotaMonitorText, ((TMP_Text)profitQuotaMonitorText).transform.parent);
				((Object)_salesMonitorText).name = "SalesMonitorText";
			}
			List<KeyValuePair<Vector3, Vector3>> list = new List<KeyValuePair<Vector3, Vector3>>
			{
				new KeyValuePair<Vector3, Vector3>(new Vector3(0f, 465f, -22f), new Vector3(-18f, 0f, 0f)),
				new KeyValuePair<Vector3, Vector3>(new Vector3(470f, 465f, -22f), new Vector3(-18f, 0f, 0f)),
				new KeyValuePair<Vector3, Vector3>(new Vector3(970f, 485f, -128f), new Vector3(-18f, 25f, 5f)),
				new KeyValuePair<Vector3, Vector3>(new Vector3(1390f, 525f, -329f), new Vector3(-18f, 25f, 5f)),
				new KeyValuePair<Vector3, Vector3>(new Vector3(1025f, 30f, -115f), new Vector3(-1f, 25f, 5f)),
				new KeyValuePair<Vector3, Vector3>(new Vector3(1445f, 72f, -320f), new Vector3(-1f, 27f, 5f))
			};
			List<Tuple<int, Component, Component>> source = new List<Tuple<int, Component, Component>>
			{
				new Tuple<int, Component, Component>(Plugin.ShipTotalMonitorNum.Value, (Component)(object)_totalMonitorBg, (Component)(object)_totalMonitorText),
				new Tuple<int, Component, Component>(Plugin.ShipTimeMonitorNum.Value, (Component)(object)_timeMonitorBG, (Component)(object)_timeMonitorText),
				new Tuple<int, Component, Component>(Plugin.ShipWeatherMonitorNum.Value, (Component)(object)_weatherMonitorBG, (Component)(object)_weatherMonitorText),
				new Tuple<int, Component, Component>(Plugin.ShipSalesMonitorNum.Value, (Component)(object)_salesMonitorBG, (Component)(object)_salesMonitorText)
			};
			HashSet<int> hashSet = new HashSet<int>();
			int i;
			for (i = 1; i <= list.Count; i++)
			{
				Tuple<int, Component, Component> tuple = source.FirstOrDefault((Tuple<int, Component, Component> m) => m.Item1 == i);
				if (tuple != null)
				{
					if (!hashSet.Contains(i))
					{
						Plugin.MLS.LogInfo((object)$"Creating monitor at position {i}");
						hashSet.Add(i);
						Vector3 key = list[i - 1].Key;
						Vector3 value = list[i - 1].Value;
						Transform transform3 = tuple.Item2.transform;
						transform3.localPosition += key;
						Transform transform4 = tuple.Item2.transform;
						transform4.localEulerAngles += value;
						Transform transform5 = tuple.Item3.transform;
						transform5.localPosition += key + new Vector3(0f, 0f, -1f);
						Transform transform6 = tuple.Item3.transform;
						transform6.localEulerAngles += value;
					}
					else
					{
						Plugin.MLS.LogError((object)$"Already created monitor at position {i} - skipping extra call! Check your config to ensure you do not have duplicate monitor assignments.");
					}
				}
			}
			if (!Plugin.ShowBlueMonitorBackground.Value)
			{
				if ((Object)(object)profitQuotaMonitorBGImage != (Object)null)
				{
					((Component)profitQuotaMonitorBGImage).gameObject.SetActive(false);
				}
				if ((Object)(object)deadlineMonitorBGImage != (Object)null)
				{
					((Component)deadlineMonitorBGImage).gameObject.SetActive(false);
				}
				foreach (Tuple<int, Component, Component> item in source.Where((Tuple<int, Component, Component> m) => (Object)(object)m.Item2 != (Object)null))
				{
					item.Item2.gameObject.SetActive(false);
				}
			}
			UpdateShipTotalMonitor();
			UpdateTimeMonitor();
			UpdateWeatherMonitor();
			UpdateSalesMonitor();
		}

		public static void UpdateShipTotalMonitor()
		{
			if (Plugin.ShipTotalMonitorNum.Value != 0 && !((Object)(object)_totalMonitorText == (Object)null))
			{
				List<GrabbableObject> list = (from o in Object.FindObjectsOfType<GrabbableObject>()
					where o.itemProperties.isScrap && o.isInShipRoom && o.isInElevator
					select o).ToList();
				int num = list.Sum((GrabbableObject o) => o.scrapValue);
				((TMP_Text)_totalMonitorText).text = $"SCRAP IN SHIP:\n${num}";
				Plugin.MLS.LogInfo((object)$"Set ship scrap total to ${num} ({list.Count} items).");
			}
		}

		public static void UpdateTimeMonitor()
		{
			if (Plugin.ShipTimeMonitorNum.Value > 0 && (Object)(object)HUDManager.Instance?.clockNumber != (Object)null)
			{
				Plugin.MLS.LogDebug((object)"Updating time display.");
				if (TimeOfDay.Instance.movingGlobalTimeForward)
				{
					((TMP_Text)_timeMonitorText).text = "TIME:\n" + ((TMP_Text)HUDManager.Instance.clockNumber).text.Replace('\n', ' ');
				}
				else
				{
					((TMP_Text)_timeMonitorText).text = "TIME:\nPENDING";
				}
			}
		}

		public static void UpdateWeatherMonitor()
		{
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Expected I4, but got Unknown
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Invalid comparison between Unknown and I4
			if (Plugin.ShipWeatherMonitorNum.Value <= 0 || !((Object)(object)_weatherMonitorText != (Object)null))
			{
				return;
			}
			Plugin.MLS.LogInfo((object)"Updating weather monitor");
			if (Plugin.FancyWeatherMonitor.Value)
			{
				LevelWeatherType? val = StartOfRound.Instance.currentLevel?.currentWeather;
				if (1 == 0)
				{
				}
				string[] curWeatherAnimations = val switch
				{
					0L => WeatherASCIIArt.ClearAnimations, 
					2L => WeatherASCIIArt.RainAnimations, 
					3L => WeatherASCIIArt.RainAnimations, 
					4L => WeatherASCIIArt.FoggyAnimations, 
					5L => WeatherASCIIArt.FloodedAnimations, 
					6L => WeatherASCIIArt.EclipsedAnimations, 
					_ => new string[1] { string.Empty }, 
				};
				if (1 == 0)
				{
				}
				_curWeatherAnimations = curWeatherAnimations;
				SelectableLevel currentLevel = StartOfRound.Instance.currentLevel;
				_hasOverlays = currentLevel != null && (int)currentLevel.currentWeather == 2;
				if (_hasOverlays)
				{
					_overlayTimer = 0f;
					_overlayCycle = Random.Range(0.1f, 3f);
					_curWeatherOverlays = WeatherASCIIArt.LightningOverlays;
					_curWeatherOverlayIndex = Random.Range(0, _curWeatherOverlays.Length);
				}
				_showingOverlay = false;
				_curWeatherAnimIndex = 0;
				_animTimer = 0f;
				((TMP_Text)_weatherMonitorText).text = _curWeatherAnimations[_curWeatherAnimIndex];
			}
			else
			{
				TextMeshProUGUI weatherMonitorText = _weatherMonitorText;
				SelectableLevel currentLevel2 = StartOfRound.Instance.currentLevel;
				((TMP_Text)weatherMonitorText).text = "WEATHER:\n" + (((currentLevel2 != null) ? ((object)(LevelWeatherType)(ref currentLevel2.currentWeather)).ToString() : null) ?? string.Empty);
			}
		}

		public static void AnimateWeatherMonitor()
		{
			if (!Plugin.FancyWeatherMonitor.Value || (Object)(object)_weatherMonitorText == (Object)null || _curWeatherAnimations.Length < 2)
			{
				return;
			}
			Action action = delegate
			{
				StringBuilder stringBuilder = new StringBuilder();
				string[] array = _curWeatherAnimations[_curWeatherAnimIndex].Split(Environment.NewLine);
				string[] source = (_showingOverlay ? _curWeatherOverlays[_curWeatherOverlayIndex] : string.Empty).Split(Environment.NewLine);
				for (int i = 0; i < array.Length; i++)
				{
					string text = array[i];
					string text2 = source.ElementAtOrDefault(i);
					for (int j = 0; j < text.Length; j++)
					{
						bool flag = !string.IsNullOrWhiteSpace(text2) && text2.Length > j && text2[j] != ' ';
						stringBuilder.Append(flag ? $"<color=#ffe100>{text2[j]}</color>" : $"{text[j]}");
					}
					stringBuilder.AppendLine();
				}
				((TMP_Text)_weatherMonitorText).text = stringBuilder.ToString();
			};
			_animTimer += Time.deltaTime;
			if (_animTimer >= _animCycle)
			{
				_curWeatherAnimIndex = (_curWeatherAnimIndex + 1) % _curWeatherAnimations.Length;
				_animTimer = 0f;
				action();
			}
			if (!_hasOverlays)
			{
				return;
			}
			_overlayTimer += Time.deltaTime;
			if (_overlayTimer >= (_showingOverlay ? 0.5f : _overlayCycle))
			{
				_overlayTimer = 0f;
				_showingOverlay = !_showingOverlay;
				if (!_showingOverlay)
				{
					_overlayCycle = Random.Range(0.1f, 3f);
					_curWeatherOverlayIndex = Random.Range(0, _curWeatherOverlays.Length);
				}
				action();
			}
		}

		public static void UpdateSalesMonitor()
		{
			if (Plugin.ShipSalesMonitorNum.Value > 0 && (Object)(object)_salesMonitorText != (Object)null)
			{
				Plugin.MLS.LogDebug((object)"Updating sales display.");
				((TMP_Text)_salesMonitorText).text = "SALES COMING SOON!";
			}
		}

		public static void ToggleExtraMonitorPower(bool on)
		{
			if (Plugin.SyncExtraMonitorsPower.Value)
			{
				bool value = Plugin.ShowBlueMonitorBackground.Value;
				if ((Object)(object)_totalMonitorBg != (Object)null && value)
				{
					((Component)_totalMonitorBg).gameObject.SetActive(on);
				}
				if ((Object)(object)_totalMonitorText != (Object)null)
				{
					((Component)_totalMonitorText).gameObject.SetActive(on);
				}
				if ((Object)(object)_timeMonitorBG != (Object)null && value)
				{
					((Component)_timeMonitorBG).gameObject.SetActive(on);
				}
				if ((Object)(object)_timeMonitorText != (Object)null)
				{
					((Component)_timeMonitorText).gameObject.SetActive(on);
				}
				if ((Object)(object)_weatherMonitorBG != (Object)null && value)
				{
					((Component)_weatherMonitorBG).gameObject.SetActive(on);
				}
				if ((Object)(object)_weatherMonitorText != (Object)null)
				{
					((Component)_weatherMonitorText).gameObject.SetActive(on);
				}
				if ((Object)(object)_salesMonitorBG != (Object)null && value)
				{
					((Component)_salesMonitorBG).gameObject.SetActive(on);
				}
				if ((Object)(object)_salesMonitorText != (Object)null)
				{
					((Component)_salesMonitorText).gameObject.SetActive(on);
				}
			}
		}

		public static void CreateMedStation()
		{
			//IL_0065: 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)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0201: Unknown result type (might be due to invalid IL or missing references)
			//IL_020b: Expected O, but got Unknown
			//IL_020d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0217: Expected O, but got Unknown
			//IL_0219: Unknown result type (might be due to invalid IL or missing references)
			//IL_0223: Expected O, but got Unknown
			if (!Plugin.AddHealthRechargeStation.Value || !((Object)(object)AssetBundleHelper.MedStationPrefab != (Object)null))
			{
				return;
			}
			MedStationItem medStationItem = null;
			if (((NetworkBehaviour)StartOfRound.Instance).IsHost)
			{
				Plugin.MLS.LogInfo((object)"Adding medical station to ship.");
				MedStation = Object.Instantiate<GameObject>(AssetBundleHelper.MedStationPrefab, new Vector3(2.75f, 3.4f, -16.561f), Quaternion.Euler(-90f, 0f, 0f), StartOfRound.Instance.elevatorTransform);
				medStationItem = MedStation.GetComponent<MedStationItem>();
				((NetworkBehaviour)medStationItem).NetworkObject.Spawn(false);
			}
			else
			{
				Plugin.MLS.LogInfo((object)"Finding medical station in ship");
				medStationItem = Object.FindObjectOfType<MedStationItem>();
				MedStationItem medStationItem2 = medStationItem;
				MedStation = ((medStationItem2 != null) ? ((Component)medStationItem2).gameObject : null);
				if ((Object)(object)MedStation == (Object)null)
				{
					Plugin.MLS.LogWarning((object)"Could not find existing med station! Ensure the host has AddHealthRechargeStation set to true.");
					return;
				}
			}
			InteractTrigger component = ((Component)Object.FindObjectOfType<ItemCharger>()).GetComponent<InteractTrigger>();
			MedStation.GetComponent<AudioSource>().outputAudioMixerGroup = ((Component)component).GetComponent<AudioSource>().outputAudioMixerGroup;
			BoxCollider component2 = ((Component)component).GetComponent<BoxCollider>();
			component2.center = Vector3.zero;
			component2.size = new Vector3(1f, 0.8f, 0.8f);
			Transform val = MedStation.transform.Find("Trigger");
			((Component)val).tag = ((Component)component).tag;
			((Component)val).gameObject.layer = ((Component)component).gameObject.layer;
			InteractTrigger val2 = ((Component)val).gameObject.AddComponent<InteractTrigger>();
			val2.hoverTip = "Heal";
			val2.disabledHoverTip = "(Health Full)";
			val2.hoverIcon = component.hoverIcon;
			val2.specialCharacterAnimation = true;
			val2.animationString = component.animationString;
			val2.lockPlayerPosition = true;
			val2.playerPositionNode = component.playerPositionNode;
			val2.onInteract = new InteractEvent();
			val2.onCancelAnimation = new InteractEvent();
			val2.onInteractEarly = new InteractEvent();
			((UnityEvent<PlayerControllerB>)(object)val2.onInteractEarly).AddListener((UnityAction<PlayerControllerB>)delegate
			{
				medStationItem.HealLocalPlayer();
			});
			ScanNodeProperties val3 = ((Component)MedStation.transform.Find("ScanNode")).gameObject.AddComponent<ScanNodeProperties>();
			((Component)val3).gameObject.layer = LayerMask.NameToLayer("ScanNode");
			val3.minRange = 0;
			val3.maxRange = 6;
			val3.nodeType = 0;
			val3.headerText = "Med Station";
			val3.subText = "Fully heal yourself";
		}
	}
	internal static class WeatherASCIIArt
	{
		public static string[] ClearAnimations = new string[2] { "\\   ___   /\r\n  -|    |-\r\n/   ---   \\\r\n  CLEAR!", "\\   ___   /\r\n-  |    | -\r\n/   ---   \\\r\n  CLEAR!" };

		public static string[] RainAnimations = new string[2] { "/~~~~~~\\\r\n\\~~~~~~/\r\n    | | | |\r\n  | | | |", "/~~~~~~\\\r\n\\~~~~~~/\r\n  | | | |\r\n    | | | |" };

		public static string[] FoggyAnimations = new string[1] { "~~~~~~~~\r\n~~~~~~~~\r\n~~~~~~~~\r\n~~~~~~~~" };

		public static string[] FloodedAnimations = new string[2] { "/~~~~~~\\\r\n\\~~~~~~/\r\n    | | | |\r\n~~~~~~~~", "/~~~~~~\\\r\n\\~~~~~~/\r\n~~~~~~~~\r\n~~~~~~~~" };

		public static string[] EclipsedAnimations = new string[15]
		{
			"   -----\r\n  |         |\r\n  |         |\r\n   -----", "   -----\r\n  |         |\r\n  |         |\r\n   -----", "   -----\r\n  |         |\r\n  |         |\r\n   -----", "   -----\r\n\\|         |\r\n/|         |\r\n   -----", "   -----\r\n-\\        |\r\n-/        |\r\n   -----", "   -----\r\n/-\\      |\r\n\\-/      |\r\n   -----", "   -----\r\n  /-\\    |\r\n  \\-/    |\r\n   -----", "   -----\r\n  | /-\\ |\r\n  | \\-/ |\r\n   -----", "   -----\r\n  | /-\\ |\r\n  | \\-/ |\r\n   -----", "   -----\r\n  | /-\\ |\r\n  | \\-/ |\r\n   -----",
			"   -----\r\n  |    /-\\\r\n  |    \\-/\r\n   -----", "   -----\r\n  |      /-\\\r\n  |      \\-/\r\n   -----", "   -----\r\n  |        /-\r\n  |        \\-\r\n   -----", "   -----\r\n  |         /-\r\n  |         \\-\r\n   -----", "   -----\r\n  |         |/\r\n  |         |\\\r\n   -----"
		};

		public static string[] LightningOverlays = new string[2] { "  \\\r\n   \\\r\n     /\r\n   *", "     /\r\n    /\r\n       \\\r\n        *" };
	}
}
namespace GeneralImprovements.Patches
{
	internal static class DepositItemsDeskPatch
	{
		[HarmonyPatch(typeof(DepositItemsDesk), "Start")]
		[HarmonyPostfix]
		private static void Start(DepositItemsDesk __instance)
		{
			((Component)__instance).GetComponentInChildren<InteractTrigger>().cooldownTime = 0.1f;
		}
	}
	internal static class EntranceTeleportPatch
	{
		private static FieldInfo _exitPoint;

		private static FieldInfo ExitPoint
		{
			get
			{
				if (_exitPoint == null)
				{
					_exitPoint = typeof(EntranceTeleport).GetField("exitPoint", BindingFlags.Instance | BindingFlags.NonPublic);
				}
				return _exitPoint;
			}
		}

		[HarmonyPatch(typeof(EntranceTeleport), "TeleportPlayer")]
		[HarmonyPostfix]
		private static void TeleportPlayer(EntranceTeleport __instance)
		{
			if (Plugin.FixInternalFireExits.Value && __instance.entranceId != 0 && __instance.isEntranceToBuilding)
			{
				FlipPlayer(__instance, GameNetworkManager.Instance.localPlayerController);
			}
		}

		[HarmonyPatch(typeof(EntranceTeleport), "TeleportPlayerClientRpc")]
		[HarmonyPostfix]
		private static void TeleportPlayerClientRpc(EntranceTeleport __instance, int playerObj)
		{
			if (Plugin.FixInternalFireExits.Value && __instance.entranceId != 0 && __instance.isEntranceToBuilding)
			{
				PlayerControllerB val = __instance.playersManager.allPlayerScripts[playerObj];
				if (!((NetworkBehaviour)val).IsOwner)
				{
					FlipPlayer(__instance, val);
				}
			}
		}

		private static void FlipPlayer(EntranceTeleport instance, PlayerControllerB player)
		{
			//IL_000c: 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)
			//IL_0016: 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_002f: 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)
			Vector3 eulerAngles = ((Transform)ExitPoint.GetValue(instance)).eulerAngles;
			((Component)player).transform.rotation = Quaternion.Euler(eulerAngles.x, eulerAngles.y + 180f, eulerAngles.z);
		}
	}
	internal static class GameNetworkManagerPatch
	{
		public static void PatchNetcode()
		{
			Type[] types = Assembly.GetExecutingAssembly().GetTypes();
			Type[] array = types;
			foreach (Type type in array)
			{
				MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic);
				MethodInfo[] array2 = methods;
				foreach (MethodInfo methodInfo in array2)
				{
					object[] customAttributes = methodInfo.GetCustomAttributes(typeof(RuntimeInitializeOnLoadMethodAttribute), inherit: false);
					if (customAttributes.Length != 0)
					{
						methodInfo.Invoke(null, null);
					}
				}
			}
		}

		[HarmonyPatch(typeof(GameNetworkManager), "Start")]
		[HarmonyPostfix]
		private static void Start(GameNetworkManager __instance)
		{
			if (Plugin.AddHealthRechargeStation.Value && (Object)(object)AssetBundleHelper.MedStationPrefab != (Object)null)
			{
				AssetBundleHelper.MedStationPrefab.AddComponent<MedStationItem>();
				NetworkManager.Singleton.AddNetworkPrefab(AssetBundleHelper.MedStationPrefab);
			}
			ItemHelper.AlterFancyLampPrefab();
		}

		[HarmonyPatch(typeof(GameNetworkManager), "Disconnect")]
		[HarmonyPrefix]
		private static void Disconnect(GameNetworkManager __instance)
		{
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			StartOfRound instance = StartOfRound.Instance;
			if (instance == null || !((NetworkBehaviour)instance).IsHost)
			{
				return;
			}
			List<GrabbableObject> list = (from g in Object.FindObjectsOfType<GrabbableObject>()
				where g.isHeld
				select g).ToList();
			foreach (GrabbableObject item in list)
			{
				Plugin.MLS.LogInfo((object)("Server disconnecting - dropping " + ((Object)item).name));
				((Component)item).transform.position = item.GetItemFloorPosition(default(Vector3));
			}
		}
	}
	internal static class GrabbableObjectsPatch
	{
		private static HashSet<GrabbableObject> _itemsToKeepInPlace = new HashSet<GrabbableObject>();

		[HarmonyPatch(typeof(GrabbableObject), "Start")]
		[HarmonyPrefix]
		private static void Start_Pre(GrabbableObject __instance)
		{
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b9: Expected O, but got Unknown
			//IL_03ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ef: Unknown result type (might be due to invalid IL or missing references)
			if (__instance is ClipboardItem || (__instance is PhysicsProp && __instance.itemProperties.itemName == "Sticky note"))
			{
				if (Plugin.HideClipboardAndStickyNote.Value)
				{
					((Component)__instance).gameObject.SetActive(false);
				}
				else if (__instance is ClipboardItem)
				{
					((Component)__instance).transform.SetPositionAndRotation(new Vector3(11.02f, 2.45f, -13.4f), Quaternion.Euler(0f, 180f, 90f));
				}
				__instance.scrapPersistedThroughRounds = false;
			}
			if (!__instance.itemProperties.isScrap)
			{
				ScanNodeProperties componentInChildren = ((Component)__instance).GetComponentInChildren<ScanNodeProperties>();
				if (componentInChildren != null)
				{
					string subText = componentInChildren.subText;
					__instance.SetScrapValue(0);
					if (subText != null && !subText.ToLower().StartsWith("value"))
					{
						componentInChildren.subText = subText;
					}
				}
				else
				{
					__instance.scrapValue = 0;
				}
			}
			if (!__instance.itemProperties.canBeGrabbedBeforeGameStart)
			{
				__instance.itemProperties.canBeGrabbedBeforeGameStart = true;
			}
			if ((Object)(object)__instance.itemProperties != (Object)null)
			{
				string[] source = new string[2] { "Flask", "Whoopie Cushion" };
				string[] source2 = new string[8] { "Jetpack", "Key", "Radar-booster", "Shovel", "Stop sign", "TZP-Inhalant", "Yield sign", "Zap gun" };
				if (source.Any((string n) => __instance.itemProperties.itemName.Equals(n, StringComparison.OrdinalIgnoreCase)) || (Plugin.ToolsDoNotAttractLightning.Value && source2.Any((string t) => __instance.itemProperties.itemName.Equals(t, StringComparison.OrdinalIgnoreCase))))
				{
					Plugin.MLS.LogInfo((object)("Item " + __instance.itemProperties.itemName + " being set to NON conductive."));
					__instance.itemProperties.isConductiveMetal = false;
				}
			}
			if (Plugin.FixItemsFallingThrough.Value && __instance.isInShipRoom && __instance.isInElevator && __instance.scrapPersistedThroughRounds)
			{
				Plugin.MLS.LogDebug((object)("KEEPING " + ((Object)__instance).name + " IN PLACE"));
				_itemsToKeepInPlace.Add(__instance);
			}
			if (__instance.itemProperties.minValue > __instance.itemProperties.maxValue)
			{
				int minValue = __instance.itemProperties.minValue;
				__instance.itemProperties.minValue = __instance.itemProperties.maxValue;
				__instance.itemProperties.maxValue = minValue;
			}
			if (Plugin.ScannableToolVals.Any((Type t) => ((object)__instance).GetType() == t) && (Object)(object)((Component)__instance).GetComponent<ScanNodeProperties>() == (Object)null)
			{
				GameObject val = new GameObject("ScanNode", new Type[2]
				{
					typeof(ScanNodeProperties),
					typeof(BoxCollider)
				});
				val.layer = LayerMask.NameToLayer("ScanNode");
				val.transform.parent = ((Component)__instance).transform;
				val.transform.SetLocalPositionAndRotation(Vector3.zero, Quaternion.identity);
				ScanNodeProperties component = val.GetComponent<ScanNodeProperties>();
				component.nodeType = 0;
				component.minRange = 1;
				component.maxRange = 13;
				component.headerText = __instance.itemProperties.itemName;
			}
		}

		[HarmonyPatch(typeof(GrabbableObject), "Start")]
		[HarmonyPostfix]
		private static void Start_Post(GrabbableObject __instance)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			if (_itemsToKeepInPlace.Contains(__instance))
			{
				__instance.fallTime = 1f;
				__instance.reachedFloorTarget = false;
				__instance.targetFloorPosition = ((Component)__instance).transform.localPosition;
				_itemsToKeepInPlace.Remove(__instance);
			}
		}
	}
	internal static class HUDManagerPatch
	{
		private static MethodInfo _attemptScanNodeMethod;

		private static MethodInfo AttemptScanNodeMethod => _attemptScanNodeMethod ?? (_attemptScanNodeMethod = typeof(HUDManager).GetMethod("AttemptScanNode", BindingFlags.Instance | BindingFlags.NonPublic));

		[HarmonyPatch(typeof(HUDManager), "Start")]
		[HarmonyPostfix]
		private static void Start(ref float ___playerPingingScan)
		{
			___playerPingingScan = -1f;
		}

		[HarmonyPatch(typeof(HUDManager), "AssignNewNodes")]
		[HarmonyPrefix]
		private static bool AssignNewNodes(HUDManager __instance, PlayerControllerB playerScript, ref int ___scannedScrapNum, List<ScanNodeProperties> ___nodesOnScreen)
		{
			if (!Plugin.FixPersonalScanner.Value)
			{
				return true;
			}
			___nodesOnScreen.Clear();
			___scannedScrapNum = 0;
			Plane[] camPlanes = GeometryUtility.CalculateFrustumPlanes(playerScript.gameplayCamera);
			IOrderedEnumerable<KeyValuePair<float, ScanNodeProperties>> orderedEnumerable = from s in (from s in Object.FindObjectsOfType<ScanNodeProperties>()
					select new KeyValuePair<float, ScanNodeProperties>(Vector3.Distance(((Component)s).transform.position, ((Component)playerScript).transform.position), s)).Where(delegate(KeyValuePair<float, ScanNodeProperties> s)
				{
					//IL_00a0: 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)
					Collider component = ((Component)s.Value).GetComponent<Collider>();
					if (component != null && component.enabled)
					{
						goto IL_0062;
					}
					if (Plugin.ScanHeldPlayerItems.Value)
					{
						GrabbableObject componentInParent = ((Component)s.Value).GetComponentInParent<GrabbableObject>();
						if (componentInParent != null && !componentInParent.isPocketed && (Object)(object)componentInParent.playerHeldBy != (Object)null && (Object)(object)componentInParent.playerHeldBy != (Object)(object)playerScript)
						{
							goto IL_0062;
						}
					}
					goto IL_00b6;
					IL_00b6:
					int result = 0;
					goto IL_00b7;
					IL_0062:
					if (!(s.Key >= (float)s.Value.minRange) || !(s.Key <= (float)s.Value.maxRange))
					{
						goto IL_00b6;
					}
					result = (GeometryUtility.TestPlanesAABB(camPlanes, new Bounds(((Component)s.Value).transform.position, Vector3.one)) ? 1 : 0);
					goto IL_00b7;
					IL_00b7:
					return (byte)result != 0;
				})
				orderby s.Key
				select s;
			foreach (KeyValuePair<float, ScanNodeProperties> item in orderedEnumerable)
			{
				AttemptScanNodeMethod.Invoke(__instance, new object[3] { item.Value, 0, playerScript });
				if (___nodesOnScreen.Count >= __instance.scanElements.Length)
				{
					break;
				}
			}
			return false;
		}

		[HarmonyPatch(typeof(HUDManager), "UpdateScanNodes")]
		[HarmonyPostfix]
		private static void UpdateScanNodes(RectTransform[] ___scanElements, Dictionary<RectTransform, ScanNodeProperties> ___scanNodes)
		{
			if (!Plugin.HideEmptySubtextOfScanNodes.Value || ___scanElements == null)
			{
				return;
			}
			foreach (RectTransform item in ___scanElements.Where((RectTransform s) => ((Component)s).gameObject.activeSelf))
			{
				TextMeshProUGUI val = ((IEnumerable<TextMeshProUGUI>)((Component)item).GetComponentsInChildren<TextMeshProUGUI>()).FirstOrDefault((Func<TextMeshProUGUI, bool>)((TextMeshProUGUI t) => ((Object)t).name.ToUpper() == "SUBTEXT"));
				Transform val2 = ((val != null) ? ((TMP_Text)val).transform.parent.Find("SubTextBox") : null);
				if ((Object)(object)val2 != (Object)null && (Object)(object)val != (Object)null && ___scanNodes.ContainsKey(item) && (Object)(object)___scanNodes[item] != (Object)null)
				{
					bool flag = string.IsNullOrWhiteSpace(((TMP_Text)val).text) || ((TMP_Text)val).text.ToUpper().Contains("VALUE: $0");
					((Component)val2).gameObject.SetActive(!flag);
					((Behaviour)val).enabled = !flag;
				}
			}
		}

		[HarmonyPatch(typeof(HUDManager), "SetClock")]
		[HarmonyPostfix]
		private static void SetClock(TextMeshProUGUI ___clockNumber)
		{
			SceneHelper.UpdateTimeMonitor();
		}

		[HarmonyPatch(typeof(HUDManager), "CanPlayerScan")]
		[HarmonyPostfix]
		private static void CanPlayerScan(ref bool __result)
		{
			__result = __result && !(ShipBuildModeManager.Instance?.InBuildMode ?? false);
		}
	}
	internal static class ManualCameraRendererPatch
	{
		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		[HarmonyPostfix]
		private static void updateMapTarget(int ___setRadarTargetIndex, bool ___calledFromRPC, bool __result)
		{
			ManualCameraRenderer mapScreen = StartOfRound.Instance.mapScreen;
			bool inTerminalMenu = GameNetworkManager.Instance.localPlayerController.inTerminalMenu;
			TerminalNode currentNode = TerminalPatch.Instance.currentNode;
			bool flag = ((currentNode != null) ? ((Object)currentNode).name : null) == "SwitchedCam";
			bool flag2 = mapScreen.radarTargets != null && mapScreen.radarTargets[___setRadarTargetIndex] != null;
			if (!__result && !___calledFromRPC && inTerminalMenu && flag && flag2)
			{
				Plugin.MLS.LogInfo((object)"Updating terminal node text to player name");
				string name = mapScreen.radarTargets[___setRadarTargetIndex].name;
				TMP_InputField screenText = TerminalPatch.Instance.screenText;
				screenText.text = screenText.text + "Switched radar to " + name + ".\n\n";
				TerminalPatch.Instance.currentText = TerminalPatch.Instance.screenText.text;
				TerminalPatch.Instance.textAdded = 0;
				TerminalPatch.Instance.screenText.ActivateInputField();
				((Selectable)TerminalPatch.Instance.screenText).Select();
				TerminalPatch.Instance.scrollBarVertical.value = 0f;
			}
		}

		[HarmonyPatch(typeof(ManualCameraRenderer), "SwitchScreenOn")]
		[HarmonyPostfix]
		private static void SwitchScreenOn(bool on)
		{
			if (Plugin.SyncExtraMonitorsPower.Value)
			{
				if ((Object)(object)StartOfRound.Instance.profitQuotaMonitorBGImage != (Object)null)
				{
					((Component)StartOfRound.Instance.profitQuotaMonitorBGImage).gameObject.SetActive(on);
				}
				if ((Object)(object)StartOfRound.Instance.profitQuotaMonitorText != (Object)null)
				{
					((Component)StartOfRound.Instance.profitQuotaMonitorText).gameObject.SetActive(on);
				}
				if ((Object)(object)StartOfRound.Instance.deadlineMonitorText != (Object)null)
				{
					((Component)StartOfRound.Instance.deadlineMonitorText).gameObject.SetActive(on);
				}
				if ((Object)(object)StartOfRound.Instance.deadlineMonitorBGImage != (Object)null)
				{
					((Component)StartOfRound.Instance.deadlineMonitorBGImage).gameObject.SetActive(on);
				}
				SceneHelper.ToggleExtraMonitorPower(on);
			}
		}
	}
	internal static class MenuPatches
	{
		[HarmonyPatch(typeof(InitializeGame), "Start")]
		[HarmonyPrefix]
		private static void Start_Initialize(InitializeGame __instance)
		{
			if (Plugin.SkipStartupScreen.Value)
			{
				__instance.runBootUpScreen = false;
			}
		}

		[HarmonyPatch(typeof(PreInitSceneScript), "SkipToFinalSetting")]
		[HarmonyPrefix]
		private static bool SkipToFinalSetting(PreInitSceneScript __instance)
		{
			string text = Plugin.AutoSelectLaunchMode.Value?.ToUpper();
			bool flag = !string.IsNullOrWhiteSpace(text) && (text.Contains("ON") || text.Contains("LAN"));
			bool flag2 = flag && text.Contains("ON");
			if (flag)
			{
				Plugin.MLS.LogInfo((object)("Automatically launching " + (flag2 ? "ONLINE" : "LAN") + " mode."));
				__instance.ChooseLaunchOption(flag2);
				__instance.launchSettingsPanelsContainer.SetActive(false);
				return false;
			}
			return true;
		}
	}
	internal static class PlayerControllerBPatch
	{
		private static FieldInfo _timeSinceSwitchingSlotsField;

		private static float _originalCursorScale;

		private static FieldInfo TimeSinceSwitchingSlotsField
		{
			get
			{
				if (_timeSinceSwitchingSlotsField == null)
				{
					_timeSinceSwitchingSlotsField = typeof(PlayerControllerB).GetField("timeSinceSwitchingSlots", BindingFlags.Instance | BindingFlags.NonPublic);
				}
				return _timeSinceSwitchingSlotsField;
			}
		}

		[HarmonyPatch(typeof(PlayerControllerB), "ConnectClientToPlayerObject")]
		[HarmonyPostfix]
		[HarmonyPriority(600)]
		private static void ConnectClientToPlayerObject(PlayerControllerB __instance)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			_originalCursorScale = ((Component)__instance.cursorIcon).transform.localScale.x;
			SceneHelper.MaxHealth = __instance.health;
		}

		[HarmonyPatch(typeof(PlayerControllerB), "FirstEmptyItemSlot")]
		[HarmonyPrefix]
		private static bool FirstEmptyItemSlot(PlayerControllerB __instance, ref int __result)
		{
			if (!Plugin.PickupInOrder.Value || ReservedItemSlotCoreHelper.Assembly != null || AdvancedCompanyHelper.IsActive)
			{
				return true;
			}
			__result = -1;
			for (int i = 0; i < __instance.ItemSlots.Length; i++)
			{
				if ((Object)(object)__instance.ItemSlots[i] == (Object)null)
				{
					__result = i;
					break;
				}
			}
			return false;
		}

		[HarmonyPatch(typeof(PlayerControllerB), "GrabObjectClientRpc")]
		[HarmonyPrefix]
		private static void GrabObjectClientRpc(PlayerControllerB __instance, bool grabValidated, NetworkObjectReference grabbedObject)
		{
			NetworkObject val = default(NetworkObject);
			if (Plugin.TwoHandedInSlotOne.Value && grabValidated && ((NetworkObjectReference)(ref grabbedObject)).TryGet(ref val, (NetworkManager)null))
			{
				GrabbableObject componentInChildren = ((Component)val).gameObject.GetComponentInChildren<GrabbableObject>();
				if (componentInChildren.itemProperties.twoHanded)
				{
					Plugin.MLS.LogDebug((object)"Two handed item being grabbed!");
					ShiftRightFromSlot(__instance, 0);
				}
			}
		}

		[HarmonyPatch(typeof(PlayerControllerB), "PlaceObjectClientRpc")]
		[HarmonyPatch(typeof(PlayerControllerB), "ThrowObjectClientRpc")]
		[HarmonyPatch(typeof(PlayerControllerB), "DespawnHeldObjectClientRpc")]
		[HarmonyPatch(typeof(PlayerControllerB), "DestroyItemInSlotClientRpc")]
		[HarmonyPostfix]
		private static void ItemLeftSlot(PlayerControllerB __instance)
		{
			if (!Plugin.RearrangeOnDrop.Value || AdvancedCompanyHelper.IsActive)
			{
				return;
			}
			for (int i = __instance.currentItemSlot; i < __instance.ItemSlots.Length - 1; i++)
			{
				if (!((Object)(object)__instance.ItemSlots[i] == (Object)null))
				{
					continue;
				}
				for (int j = i + 1; j < __instance.ItemSlots.Length; j++)
				{
					if (!ReservedItemSlotCoreHelper.IsReservedItemSlot(__instance, j) && (Object)(object)__instance.ItemSlots[j] != (Object)null)
					{
						ShiftSlots(__instance, i, j);
						break;
					}
				}
			}
			GrabbableObject val = __instance.ItemSlots[__instance.currentItemSlot];
			if ((Object)(object)val != (Object)null)
			{
				val.EquipItem();
				__instance.twoHanded = false;
				__instance.twoHandedAnimation = false;
				__instance.playerBodyAnimator.ResetTrigger("Throw");
				__instance.playerBodyAnimator.SetBool("Grab", true);
				if (!string.IsNullOrEmpty(val.itemProperties.grabAnim))
				{
					__instance.playerBodyAnimator.SetBool(val.itemProperties.grabAnim, true);
				}
				if (__instance.twoHandedAnimation != val.itemProperties.twoHandedAnimation)
				{
					__instance.playerBodyAnimator.ResetTrigger("SwitchHoldAnimationTwoHanded");
					__instance.playerBodyAnimator.SetTrigger("SwitchHoldAnimationTwoHanded");
				}
				__instance.playerBodyAnimator.ResetTrigger("SwitchHoldAnimation");
				__instance.playerBodyAnimator.SetTrigger("SwitchHoldAnimation");
				__instance.playerBodyAnimator.SetBool("GrabValidated", true);
				__instance.playerBodyAnimator.SetBool("cancelHolding", false);
				__instance.twoHandedAnimation = val.itemProperties.twoHandedAnimation;
				__instance.isHoldingObject = true;
				__instance.currentlyHeldObjectServer = val;
			}
		}

		[HarmonyPatch(typeof(PlayerControllerB), "ScrollMouse_performed")]
		[HarmonyPostfix]
		private static void ScrollMouse_performed(PlayerControllerB __instance)
		{
			float num = Math.Clamp(Plugin.ScrollDelay.Value, 0.05f, 0.3f);
			if ((float)TimeSinceSwitchingSlotsField.GetValue(__instance) < 0.1f)
			{
				TimeSinceSwitchingSlotsField.SetValue(__instance, 0.3f - num);
			}
		}

		[HarmonyPatch(typeof(QuickMenuManager), "OpenQuickMenu")]
		[HarmonyPrefix]
		private static bool OpenQuickMenu(QuickMenuManager __instance)
		{
			ShipBuildModeManager instance = ShipBuildModeManager.Instance;
			if (instance != null && instance.InBuildMode)
			{
				Plugin.MLS.LogInfo((object)"Cancelling build mode and returning false!");
				ShipBuildModeManager.Instance.CancelBuildMode(true);
				return false;
			}
			return true;
		}

		[HarmonyPatch(typeof(PlayerControllerB), "SetItemInElevator")]
		[HarmonyPostfix]
		private static void SetItemInElevator()
		{
			SceneHelper.UpdateShipTotalMonitor();
		}

		[HarmonyPatch(typeof(PlayerControllerB), "SetHoverTipAndCurrentInteractTrigger")]
		[HarmonyPostfix]
		private static void SetHoverTipAndCurrentInteractTrigger(PlayerControllerB __instance)
		{
			//IL_00aa: 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_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			if (Plugin.ShowUIReticle.Value && (Object)(object)AssetBundleHelper.Reticle != (Object)null)
			{
				if (!((Behaviour)__instance.cursorIcon).enabled)
				{
					__instance.cursorIcon.sprite = AssetBundleHelper.Reticle;
					((Graphic)__instance.cursorIcon).color = new Color(1f, 1f, 1f, 0.1f);
					((Behaviour)__instance.cursorIcon).enabled = true;
					((Component)__instance.cursorIcon).transform.localScale = Vector3.one * 0.05f;
				}
				else if (((Component)__instance.cursorIcon).transform.localScale.x < _originalCursorScale)
				{
					((Component)__instance.cursorIcon).transform.localScale = Vector3.one * _originalCursorScale;
					((Graphic)__instance.cursorIcon).color = Color.white;
					__instance.cursorIcon.sprite = __instance.hoveringOverTrigger?.hoverIcon ?? __instance.cursorIcon.sprite;
					if ((Object)(object)__instance.cursorIcon.sprite == (Object)(object)AssetBundleHelper.Reticle)
					{
						((Behaviour)__instance.cursorIcon).enabled = false;
					}
				}
			}
			if (!Plugin.AddHealthRechargeStation.Value || !((Object)(object)SceneHelper.MedStation != (Object)null))
			{
				return;
			}
			InteractTrigger hoveringOverTrigger = __instance.hoveringOverTrigger;
			if ((Object)(object)((hoveringOverTrigger != null) ? ((Component)hoveringOverTrigger).transform.parent : null) == (Object)(object)SceneHelper.MedStation.transform)
			{
				if (__instance.health > SceneHelper.MaxHealth)
				{
					SceneHelper.MaxHealth = __instance.health;
				}
				else
				{
					__instance.hoveringOverTrigger.interactable = __instance.health < SceneHelper.MaxHealth;
				}
			}
		}

		private static void ShiftRightFromSlot(PlayerControllerB player, int slot)
		{
			if ((Object)(object)player.ItemSlots[slot] != (Object)null)
			{
				if ((Object)(object)player.ItemSlots[slot + 1] != (Object)null)
				{
					ShiftRightFromSlot(player, slot + 1);
				}
				ShiftSlots(player, slot + 1, slot);
			}
		}

		private static void ShiftSlots(PlayerControllerB player, int newSlot, int oldSlot)
		{
			Plugin.MLS.LogDebug((object)$"Shifting slot {oldSlot} to {newSlot}");
			if (((NetworkBehaviour)player).IsOwner)
			{
				HUDManager.Instance.itemSlotIcons[newSlot].sprite = player.ItemSlots[oldSlot].itemProperties.itemIcon;
				((Behaviour)HUDManager.Instance.itemSlotIcons[newSlot]).enabled = true;
				((Behaviour)HUDManager.Instance.itemSlotIcons[oldSlot]).enabled = false;
			}
			player.ItemSlots[newSlot] = player.ItemSlots[oldSlot];
			player.ItemSlots[oldSlot] = null;
		}
	}
	internal static class RoundManagerPatch
	{
		private static bool _gotShipNode;

		public static ScanNodeProperties CurShipNode { get; private set; }

		[HarmonyPatch(typeof(RoundManager), "SyncScrapValuesClientRpc")]
		[HarmonyPostfix]
		private static void SyncScrapValuesClientRpc()
		{
			List<GrabbableObject> source = (from o in Object.FindObjectsOfType<GrabbableObject>()
				where !o.isInShipRoom && !o.isInElevator && o.itemProperties.minValue > 0
				select o).ToList();
			RoundManager.Instance.totalScrapValueInLevel = source.Sum((GrabbableObject i) => i.scrapValue);
		}

		[HarmonyPatch(typeof(RoundManager), "FinishGeneratingNewLevelClientRpc")]
		[HarmonyPostfix]
		private static void FinishGeneratingNewLevelClientRpc(RoundManager __instance)
		{
			if (!_gotShipNode)
			{
				CurShipNode = ((IEnumerable<ScanNodeProperties>)Object.FindObjectsOfType<ScanNodeProperties>()).FirstOrDefault((Func<ScanNodeProperties, bool>)((ScanNodeProperties s) => s.headerText == "Ship"));
				if ((Object)(object)CurShipNode != (Object)null)
				{
					Plugin.MLS.LogInfo((object)"Disabling ship scan node until landed.");
					((Component)CurShipNode).gameObject.SetActive(false);
					_gotShipNode = true;
				}
			}
		}

		[HarmonyPatch(typeof(RoundManager), "DespawnPropsAtEndOfRound")]
		[HarmonyPostfix]
		private static void DespawnPropsAtEndOfRound()
		{
			SceneHelper.UpdateTimeMonitor();
		}

		public static void EnableAndAttachShipScanNode()
		{
			if ((Object)(object)CurShipNode != (Object)null)
			{
				Plugin.MLS.LogInfo((object)"Enabling ship scan node again and parenting it to the terminal.");
				((Component)CurShipNode).gameObject.SetActive(true);
				((Component)CurShipNode).transform.parent = ((Component)TerminalPatch.Instance).transform;
				_gotShipNode = false;
			}
		}
	}
	internal static class ShipBuildModeManagerPatch
	{
		public enum MouseButton
		{
			MouseLeft,
			MouseRight,
			MouseMiddle,
			MouseBackButton,
			MouseForwardButton
		}

		[CompilerGenerated]
		private sealed class <>c__DisplayClass10_1
		{
			public KeyControl control;

			internal bool <Awake>b__5()
			{
				return ((ButtonControl)control).isPressed;
			}
		}

		[CompilerGenerated]
		private sealed class <>c__DisplayClass10_2
		{
			public KeyControl control;

			internal bool <Awake>b__6()
			{
				return ((ButtonControl)control).isPressed;
			}
		}

		private static IReadOnlyDictionary<MouseButton, ButtonControl> _mouseButtonMappings;

		private static int _snapObjectsByDegrees;

		private static float _curObjectDegrees;

		private static string _rotateKey;

		private static string _freeRotateModifierKey;

		private static string _ccwModifierKey;

		private static InputAction _rotateAction;

		private static Func<bool> _freeRotateHeld;

		private static Func<bool> _ccwHeld;

		[HarmonyPatch(typeof(ShipBuildModeManager), "Awake")]
		[HarmonyPostfix]
		private static void Awake(ShipBuildModeManager __instance)
		{
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Expected O, but got I4
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: Expected O, but got I4
			//IL_0196: Unknown result type (might be due to invalid IL or missing references)
			//IL_019b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc->IL00dc: Incompatible stack types: O vs I4
			//IL_00da->IL00dc: Incompatible stack types: I4 vs O
			//IL_00da->IL00dc: Incompatible stack types: O vs I4
			//IL_0185->IL0185: Incompatible stack types: O vs I4
			//IL_0183->IL0185: Incompatible stack types: I4 vs O
			//IL_0183->IL0185: Incompatible stack types: O vs I4
			_mouseButtonMappings = new Dictionary<MouseButton, ButtonControl>
			{
				{
					MouseButton.MouseLeft,
					Mouse.current.leftButton
				},
				{
					MouseButton.MouseRight,
					Mouse.current.rightButton
				},
				{
					MouseButton.MouseMiddle,
					Mouse.current.middleButton
				},
				{
					MouseButton.MouseBackButton,
					Mouse.current.backButton
				},
				{
					MouseButton.MouseForwardButton,
					Mouse.current.forwardButton
				}
			};
			UpdateRotateAction(__instance);
			Key keyCode;
			if (Enum.TryParse<MouseButton>(Plugin.FreeRotateKey.Value, out var freeRotateMouseButton))
			{
				_freeRotateModifierKey = freeRotateMouseButton.ToString();
				_freeRotateHeld = () => _mouseButtonMappings[freeRotateMouseButton].isPressed;
			}
			else
			{
				<>c__DisplayClass10_1 CS$<>8__locals1 = new <>c__DisplayClass10_1();
				object obj = CS$<>8__locals1;
				Keyboard current = Keyboard.current;
				int num;
				if (Enum.TryParse<Key>(Plugin.FreeRotateKey.Value, out Key result))
				{
					obj = result;
					num = (int)obj;
				}
				else
				{
					num = 53;
					obj = num;
					num = (int)obj;
				}
				((<>c__DisplayClass10_1)num).control = current[(Key)obj];
				keyCode = CS$<>8__locals1.control.keyCode;
				_freeRotateModifierKey = ((object)(Key)(ref keyCode)).ToString();
				_freeRotateHeld = () => ((ButtonControl)CS$<>8__locals1.control).isPressed;
			}
			if (Enum.TryParse<MouseButton>(Plugin.CounterClockwiseKey.Value, out var ccwMouseButton))
			{
				_ccwModifierKey = ccwMouseButton.ToString();
				_ccwHeld = () => _mouseButtonMappings[ccwMouseButton].isPressed;
			}
			else
			{
				<>c__DisplayClass10_2 CS$<>8__locals2 = new <>c__DisplayClass10_2();
				object obj2 = CS$<>8__locals2;
				Keyboard current2 = Keyboard.current;
				int num2;
				if (Enum.TryParse<Key>(Plugin.CounterClockwiseKey.Value, out Key result2))
				{
					obj2 = result2;
					num2 = (int)obj2;
				}
				else
				{
					num2 = 51;
					obj2 = num2;
					num2 = (int)obj2;
				}
				((<>c__DisplayClass10_2)num2).control = current2[(Key)obj2];
				keyCode = CS$<>8__locals2.control.keyCode;
				_ccwModifierKey = ((object)(Key)(ref keyCode)).ToString();
				_ccwHeld = () => ((ButtonControl)CS$<>8__locals2.control).isPressed;
			}
			Plugin.MLS.LogInfo((object)("Snap keys initialized. Rotate: " + _rotateKey + ". Free rotate modifier: " + _freeRotateModifierKey + ". CCW modifier: " + _ccwModifierKey));
			List<int> source = (from n in Enumerable.Range(0, 24)
				select n * 15 into n
				where n == 0 || 360 % n == 0
				select n).ToList();
			_snapObjectsByDegrees = source.OrderBy((int n) => Math.Abs(n - Plugin.SnapObjectsByDegrees.Value)).First();
			Plugin.MLS.LogInfo((object)$"Using {_snapObjectsByDegrees} degrees for build mode snapping");
		}

		[HarmonyPatch(typeof(ShipBuildModeManager), "CreateGhostObjectAndHighlight")]
		[HarmonyPostfix]
		private static void CreateGhostObjectAndHighlight(ShipBuildModeManager __instance)
		{
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: 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_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			if (__instance.InBuildMode && _snapObjectsByDegrees != 0)
			{
				UpdateRotateAction(__instance);
				if (!StartOfRound.Instance.localPlayerUsingController)
				{
					((TMP_Text)HUDManager.Instance.buildModeControlTip).text = "Confirm: [B]   |   Rotate: [" + _rotateKey + "]   |   Store: [X]\nFree Rotate: Hold [" + _freeRotateModifierKey + "]   |   CCW: Hold [" + _ccwModifierKey + "]";
				}
				Vector3 eulerAngles = __instance.ghostObject.eulerAngles;
				if (_freeRotateHeld())
				{
					_curObjectDegrees = eulerAngles.y;
					return;
				}
				_curObjectDegrees = (float)Math.Round(eulerAngles.y / (float)_snapObjectsByDegrees) * (float)_snapObjectsByDegrees;
				__instance.ghostObject.rotation = Quaternion.Euler(eulerAngles.x, _curObjectDegrees, eulerAngles.z);
				((Component)__instance.selectionOutlineMesh).transform.eulerAngles = __instance.ghostObject.eulerAngles;
			}
		}

		[HarmonyPatch(typeof(ShipBuildModeManager), "Update")]
		[HarmonyPostfix]
		private static void Update(ShipBuildModeManager __instance)
		{
			//IL_00e0: 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_00ff: 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)
			if (!__instance.InBuildMode || _snapObjectsByDegrees == 0 || !_rotateAction.IsPressed())
			{
				return;
			}
			if (_freeRotateHeld())
			{
				if (_ccwHeld())
				{
					_curObjectDegrees -= Time.deltaTime * 155f;
				}
				else
				{
					_curObjectDegrees = __instance.ghostObject.eulerAngles.y;
				}
			}
			else if (_rotateAction.WasPressedThisFrame())
			{
				_curObjectDegrees = (float)Math.Round(_curObjectDegrees / (float)_snapObjectsByDegrees) * (float)_snapObjectsByDegrees;
				_curObjectDegrees += _snapObjectsByDegrees * ((!_ccwHeld()) ? 1 : (-1));
			}
			__instance.ghostObject.rotation = Quaternion.Euler(__instance.ghostObject.eulerAngles.x, _curObjectDegrees, __instance.ghostObject.eulerAngles.z);
		}

		private static void UpdateRotateAction(ShipBuildModeManager instance)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			InputAction rotateAction;
			if (!StartOfRound.Instance.localPlayerUsingController)
			{
				rotateAction = IngamePlayerSettings.Instance.playerInput.actions.FindAction("ReloadBatteries", false);
			}
			else
			{
				MovementActions movement = instance.playerActions.Movement;
				rotateAction = ((MovementActions)(ref movement)).InspectItem;
			}
			_rotateAction = rotateAction;
			_rotateKey = InputActionRebindingExtensions.GetBindingDisplayString(_rotateAction, (DisplayStringOptions)0, (string)null);
		}
	}
	internal static class ShipTeleporterPatch
	{
		private static PlayerControllerB _lastPlayerTeleported;

		[HarmonyPatch(typeof(ShipTeleporter), "Awake")]
		[HarmonyPrefix]
		private static void Awake_Pre(ShipTeleporter __instance)
		{
			int num = Math.Clamp(Plugin.RegularTeleporterCooldown.Value, 0, 300);
			int num2 = Math.Clamp(Plugin.InverseTeleporterCooldown.Value, 0, 300);
			__instance.cooldownAmount = (__instance.isInverseTeleporter ? num2 : num);
		}

		[HarmonyPatch(typeof(ShipTeleporter), "Awake")]
		[HarmonyPostfix]
		private static void Awake_Post(ShipTeleporter __instance)
		{
			if (__instance.isInverseTeleporter)
			{
				((Component)__instance).GetComponentInChildren<InteractTrigger>().hoverTip = "Beam out : [E]";
			}
		}

		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		[HarmonyPostfix]
		private static void beamUpPlayer(bool __result)
		{
			if (__result)
			{
				_lastPlayerTeleported = StartOfRound.Instance.mapScreen.targetedPlayer;
			}
			else if ((Object)(object)_lastPlayerTeleported?.deadBody?.grabBodyObject != (Object)null)
			{
				_lastPlayerTeleported.SetItemInElevator(true, true, _lastPlayerTeleported.deadBody.grabBodyObject);
			}
		}
	}
	internal static class StartOfRoundPatch
	{
		private static MethodInfo _updatePlayerPositionClientRpcMethod;

		private static MethodInfo UpdatePlayerPositionClientRpcMethod
		{
			get
			{
				if (_updatePlayerPositionClientRpcMethod == null)
				{
					_updatePlayerPositionClientRpcMethod = typeof(PlayerControllerB).GetMethod("UpdatePlayerPositionClientRpc", BindingFlags.Instance | BindingFlags.NonPublic);
				}
				return _updatePlayerPositionClientRpcMethod;
			}
		}

		[HarmonyPatch(typeof(StartOfRound), "Start")]
		[HarmonyPostfix]
		[HarmonyPriority(600)]
		private static void Start(StartOfRound __instance)
		{
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			if (!((NetworkBehaviour)__instance).IsHost && __instance.inShipPhase)
			{
				GrabbableObject[] array = Object.FindObjectsOfType<GrabbableObject>();
				GrabbableObject[] array2 = array;
				foreach (GrabbableObject val in array2)
				{
					val.isInElevator = true;
					val.isInShipRoom = true;
					val.scrapPersistedThroughRounds = true;
				}
			}
			if (Plugin.ShipMapCamDueNorth.Value)
			{
				Plugin.MLS.LogInfo((object)"Rotating ship map camera to face north");
				Vector3 eulerAngles = ((Component)__instance.mapScreen.mapCamera).transform.eulerAngles;
				((Component)__instance.mapScreen.mapCamera).transform.rotation = Quaternion.Euler(eulerAngles.x, 90f, eulerAngles.z);
			}
			SceneHelper.CreateExtraMonitors();
			SceneHelper.CreateMedStation();
			__instance.maxShipItemCapacity = 999;
		}

		[HarmonyPatch(typeof(StartOfRound), "OnShipLandedMiscEvents")]
		[HarmonyPostfix]
		private static void OnShipLandedMiscEvents()
		{
			RoundManagerPatch.EnableAndAttachShipScanNode();
		}

		[HarmonyPatch(typeof(StartOfRound), "ShipLeave")]
		[HarmonyPrefix]
		private static void ShipLeave()
		{
			if ((Object)(object)RoundManagerPatch.CurShipNode != (Object)null)
			{
				RoundManagerPatch.CurShipNode.subText = "BYE LOL";
			}
		}

		[HarmonyPatch(typeof(StartOfRound), "ShipHasLeft")]
		[HarmonyPrefix]
		private static void ShipHasLeft()
		{
			if ((Object)(object)RoundManagerPatch.CurShipNode != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)RoundManagerPatch.CurShipNode).gameObject);
			}
		}

		[HarmonyPatch(typeof(StartOfRound), "SetMapScreenInfoToCurrentLevel")]
		[HarmonyPostfix]
		private static void SetMapScreenInfoToCurrentLevel()
		{
			SceneHelper.UpdateWeatherMonitor();
		}

		[HarmonyPatch(typeof(StartOfRound), "SwitchMapMonitorPurpose")]
		[HarmonyPostfix]
		private static void SwitchMapMonitorPurpose(StartOfRound __instance, bool displayInfo)
		{
			ManualCameraRenderer mapScreen = __instance.mapScreen;
			if (!displayInfo && !string.IsNullOrWhiteSpace(mapScreen?.radarTargets[mapScreen.targetTransformIndex]?.name))
			{
				((TMP_Text)__instance.mapScreenPlayerName).text = "MONITORING: " + __instance.mapScreen.radarTargets[__instance.mapScreen.targetTransformIndex].name;
			}
		}

		[HarmonyPatch(typeof(StartOfRound), "OnClientConnect")]
		[HarmonyPrefix]
		private static void OnClientConnect(StartOfRound __instance)
		{
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			if (!((NetworkBehaviour)__instance).IsServer)
			{
				return;
			}
			TerminalPatch.AdjustGroupCredits(adding: true);
			foreach (PlayerControllerB item in __instance.allPlayerScripts.Where((PlayerControllerB p) => p.isPlayerControlled))
			{
				UpdatePlayerPositionClientRpcMethod.Invoke(item, new object[5]
				{
					item.thisPlayerBody.localPosition,
					item.isInElevator,
					item.isInHangarShipRoom,
					item.isExhausted,
					item.thisController.isGrounded
				});
				if (item.performingEmote)
				{
					item.StartPerformingEmoteClientRpc();
				}
			}
		}

		[HarmonyPatch(typeof(StartOfRound), "OnClientDisconnect")]
		[HarmonyPostfix]
		private static void OnClientDisconnect()
		{
			TerminalPatch.AdjustGroupCredits(adding: false);
		}

		[HarmonyPatch(typeof(StartOfRound), "SyncShipUnlockablesClientRpc")]
		[HarmonyPostfix]
		private static void SyncShipUnlockablesClientRpc()
		{
			SceneHelper.UpdateShipTotalMonitor();
		}

		[HarmonyPatch(typeof(StartOfRound), "ResetShip")]
		[HarmonyPostfix]
		private static void ResetShip(StartOfRound __instance)
		{
			SceneHelper.UpdateShipTotalMonitor();
			TerminalPatch.SetStartingMoneyPerPlayer(force: true);
			SceneHelper.MaxHealth = __instance.localPlayerController?.health ?? 100;
		}

		[HarmonyPatch(typeof(StartOfRound), "LoadShipGrabbableItems")]
		[HarmonyPostfix]
		private static void LoadShipGrabbableItems()
		{
			SceneHelper.UpdateShipTotalMonitor();
		}

		[HarmonyPatch(typeof(StartOfRound), "Update")]
		[HarmonyPostfix]
		private static void Update()
		{
			SceneHelper.AnimateWeatherMonitor();
		}
	}
	internal static class TerminalAccessibleObjectPatch
	{
		private static FieldInfo _mapRadarTextField;

		private static FieldInfo MapRadarTextField => _mapRadarTextField ?? (_mapRadarTextField = typeof(TerminalAccessibleObject).GetField("mapRadarText", BindingFlags.Instance | BindingFlags.NonPublic));

		[HarmonyPatch(typeof(TerminalAccessibleObject), "Start")]
		[HarmonyPostfix]
		private static void Start(TerminalAccessibleObject __instance)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Expected O, but got Unknown
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: 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_0057: 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_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			if (Plugin.ShipMapCamDueNorth.Value)
			{
				TextMeshProUGUI val = (TextMeshProUGUI)MapRadarTextField.GetValue(__instance);
				((TMP_Text)val).rectTransform.pivot = new Vector2(0.5f, 0.5f);
				Vector3 eulerAngles = ((Transform)((TMP_Text)val).rectTransform).eulerAngles;
				((Transform)((TMP_Text)val).rectTransform).rotation = Quaternion.Euler(eulerAngles.x, eulerAngles.y, 225f);
				Transform transform = ((TMP_Text)val).transform;
				transform.position += new Vector3(1f, 0f, -1f);
			}
		}
	}
	internal static class TerminalPatch
	{
		private static int _currentCredits = 0;

		private static List<string> _commandHistory = new List<string>();

		private static int _historyCount;

		private static int _curHistoryIndex = 0;

		public static Terminal Instance;

		[HarmonyPatch(typeof(Terminal), "Start")]
		[HarmonyPrefix]
		private static void Start(Terminal __instance)
		{
			Instance = __instance;
			_historyCount = Math.Clamp(Plugin.TerminalHistoryItemCount.Value, 0, 100);
			SetStartingMoneyPerPlayer(force: false);
			IEnumerable<TerminalNode> enumerable = __instance.terminalNodes?.specialNodes?.Where((TerminalNode n) => n.displayText.Contains("Switched radar to player.") || n.terminalEvent == "switchCamera");
			if (enumerable == null)
			{
				return;
			}
			foreach (TerminalNode item in enumerable)
			{
				item.displayText = string.Empty;
			}
		}

		[HarmonyPatch(typeof(Terminal), "BeginUsingTerminal")]
		[HarmonyPostfix]
		private static void BeginUsingTerminal(Terminal __instance)
		{
			((Component)__instance.terminalUIScreen).gameObject.SetActive(true);
			((Selectable)__instance.screenText).Select();
			__instance.screenText.ActivateInputField();
			_curHistoryIndex = _commandHistory.Count;
		}

		[HarmonyPatch(typeof(Terminal), "OnSubmit")]
		[HarmonyPrefix]
		[HarmonyBefore(new string[] { "AdvancedCompany" })]
		private static void OnSubmit(Terminal __instance)
		{
			if (_historyCount <= 0 || __instance.textAdded < 3)
			{
				return;
			}
			string text = __instance.screenText.text.Substring(__instance.screenText.text.Length - __instance.textAdded).Trim();
			if (!_commandHistory.Any() || _commandHistory.Last().ToUpper() != text.ToUpper())
			{
				_commandHistory.Add(text);
				if (_commandHistory.Count > _historyCount)
				{
					_commandHistory.RemoveAt(0);
				}
			}
			_curHistoryIndex = _commandHistory.Count;
		}

		[HarmonyPatch(typeof(Terminal), "TextPostProcess")]
		[HarmonyPrefix]
		private static void TextPostProcess_Pre(ref string modifiedDisplayText, TerminalNode node)
		{
			if (modifiedDisplayText.Contains("[scanForItems]"))
			{
				Random fixedRandom = new Random(StartOfRound.Instance.randomMapSeed + 91);
				List<GrabbableObject> list = (from o in Object.FindObjectsOfType<GrabbableObject>()
					where !o.isInShipRoom && !o.isInElevator && o.itemProperties.minValue > 0
					select o).ToList();
				float multiplier = RoundManager.Instance.scrapValueMultiplier;
				int num = (int)Math.Round(list.Sum((GrabbableObject i) => (float)fixedRandom.Next(i.itemProperties.minValue, i.itemProperties.maxValue) * multiplier));
				modifiedDisplayText = modifiedDisplayText.Replace("[scanForItems]", $"There are {list.Count} objects outside the ship, totalling at an approximate value of ${num}.");
			}
		}

		[HarmonyPatch(typeof(Terminal), "TextPostProcess")]
		[HarmonyPostfix]
		private static void TextPostProcess_Post(string modifiedDisplayText, ref string __result)
		{
			__result = __result.Replace("\nn\n", "\n\n\n");
		}

		[HarmonyPatch(typeof(Terminal), "Update")]
		[HarmonyPostfix]
		private static void Update(Terminal __instance)
		{
			if (!(GameNetworkManager.Instance?.localPlayerController?.inTerminalMenu).GetValueOrDefault())
			{
				return;
			}
			bool wasPressedThisFrame = ((ButtonControl)Keyboard.current[(Key)63]).wasPressedThisFrame;
			bool wasPressedThisFrame2 = ((ButtonControl)Keyboard.current[(Key)62]).wasPressedThisFrame;
			bool wasPressedThisFrame3 = ((ButtonControl)Keyboard.current[(Key)64]).wasPressedThisFrame;
			bool wasPressedThisFrame4 = ((ButtonControl)Keyboard.current[(Key)61]).wasPressedThisFrame;
			if ((wasPressedThisFrame || wasPressedThisFrame3) && _commandHistory.Any())
			{
				_curHistoryIndex += ((!wasPressedThisFrame) ? 1 : (-1));
				if (_curHistoryIndex < 0)
				{
					_curHistoryIndex = 0;
				}
				else if (_curHistoryIndex >= _commandHistory.Count)
				{
					_curHistoryIndex = _commandHistory.Count - 1;
				}
				string text = _commandHistory.ElementAt(_curHistoryIndex);
				__instance.screenText.text = __instance.screenText.text.Substring(0, __instance.screenText.text.Length - __instance.textAdded) + text;
				__instance.screenText.caretPosition = __instance.screenText.text.Length;
				__instance.textAdded = text.Length;
			}
			else
			{
				if (!Plugin.TerminalFastCamSwitch.Value || !(wasPressedThisFrame4 || wasPressedThisFrame2))
				{
					return;
				}
				int targetTransformIndex = StartOfRound.Instance.mapScreen.targetTransformIndex;
				int num = targetTransformIndex;
				PlayerControllerB component;
				do
				{
					num += ((!wasPressedThisFrame4) ? 1 : (-1));
					if (num < 0)
					{
						num = StartOfRound.Instance.mapScreen.radarTargets.Count - 1;
					}
					else if (num >= StartOfRound.Instance.mapScreen.radarTargets.Count)
					{
						num = 0;
					}
					component = ((Component)StartOfRound.Instance.mapScreen.radarTargets[num].transform).gameObject.GetComponent<PlayerControllerB>();
				}
				while ((Object)(object)component != (Object)null && !component.isPlayerControlled && !component.isPlayerDead && (Object)(object)component.redirectToEnemy == (Object)null && num != targetTransformIndex);
				if (num != targetTransformIndex)
				{
					StartOfRound.Instance.mapScreen.SwitchRadarTargetAndSync(num);
					__instance.LoadNewNode(__instance.terminalNodes.specialNodes[20]);
				}
			}
		}

		public static void SetStartingMoneyPerPlayer(bool force)
		{
			if (((NetworkBehaviour)Instance).IsServer && Plugin.StartingMoneyPerPlayerVal >= 0)
			{
				bool flag = ES3.KeyExists("GroupCredits", GameNetworkManager.Instance.currentSaveFileName);
				if (!flag || force)
				{
					_currentCredits = Math.Clamp(Plugin.StartingMoneyPerPlayerVal * (StartOfRound.Instance.connectedPlayersAmount + 1), Plugin.MinimumStartingMoneyVal, int.MaxValue);
					Plugin.MLS.LogInfo((object)$"Setting starting money to {_currentCredits} ({Plugin.StartingMoneyPerPlayerVal} per player x {StartOfRound.Instance.connectedPlayersAmount + 1} current players), with a minimium of {Plugin.MinimumStartingMoneyVal}.");
					TimeOfDay.Instance.quotaVariables.startingCredits = _currentCredits;
					Instance.groupCredits = Math.Clamp(_currentCredits, 0, _currentCredits);
					Instance.SyncGroupCreditsServerRpc(Instance.groupCredits, Instance.numberOfItemsInDropship);
				}
				else
				{
					_currentCredits = ES3.Load<int>("GroupCredits", GameNetworkManager.Instance.currentSaveFileName, Plugin.StartingMoneyPerPlayerVal);
				}
			}
		}

		public static void AdjustGroupCredits(bool adding)
		{
			if (!((NetworkBehaviour)Instance).IsServer || Plugin.StartingMoneyPerPlayerVal < 0 || !StartOfRound.Instance.inShipPhase || StartOfRound.Instance.gameStats.daysSpent != 0)
			{
				return;
			}
			int num = StartOfRound.Instance.connectedPlayersAmount + ((!adding) ? 1 : 2);
			int num2 = (int)MathF.Floor((float)Plugin.MinimumStartingMoneyVal / (float)Plugin.StartingMoneyPerPlayerVal) + (adding ? 1 : 0);
			if (num >= num2)
			{
				_currentCredits += Plugin.StartingMoneyPerPlayerVal * (adding ? 1 : (-1));
				Plugin.MLS.LogInfo((object)string.Format("{0} {1} {2} group credits.", adding ? "Adding" : "Subtracting", Plugin.StartingMoneyPerPlayerVal, adding ? "to" : "from"));
				Instance.groupCredits = Math.Clamp(_currentCredits, 0, _currentCredits);
				if (!adding)
				{
					Instance.SyncGroupCreditsServerRpc(Instance.groupCredits, Instance.numberOfItemsInDropship);
				}
			}
		}
	}
	internal static class TimeOfDayPatch
	{
		private static int _leftoverFunds;

		[HarmonyPatch(typeof(TimeOfDay), "SetNewProfitQuota")]
		[HarmonyPrefix]
		private static bool SetNewProfitQuota(TimeOfDay __instance)
		{
			if (Plugin.AllowQuotaRollover.Value)
			{
				if (__instance.timeUntilDeadline > 0f)
				{
					return false;
				}
				_leftoverFunds = __instance.quotaFulfilled - __instance.profitQuota;
				Plugin.MLS.LogInfo((object)$"Storing surplus quota on server: ${_leftoverFunds}");
			}
			return true;
		}

		[HarmonyPatch(typeof(TimeOfDay), "SyncNewProfitQuotaClientRpc")]
		[HarmonyPrefix]
		private static void SyncNewProfitQuotaClientRpc_Pre(TimeOfDay __instance)
		{
			if (Plugin.AllowQuotaRollover.Value && !((NetworkBehaviour)__instance).IsServer)
			{
				_leftoverFunds = __instance.quotaFulfilled - __instance.profitQuota;
				Plugin.MLS.LogInfo((object)$"Storing surplus quota on client: ${_leftoverFunds}");
			}
		}

		[HarmonyPatch(typeof(TimeOfDay), "SyncNewProfitQuotaClientRpc")]
		[HarmonyPostfix]
		private static void SyncNewProfitQuotaClientRpc_Post(TimeOfDay __instance)
		{
			if (Plugin.AllowQuotaRollover.Value)
			{
				Plugin.MLS.LogInfo((object)$"Applying surplus quota to fulfilled: ${_leftoverFunds}");
				__instance.quotaFulfilled = _leftoverFunds;
			}
		}
	}
}
namespace GeneralImprovements.OtherMods
{
	internal static class AdvancedCompanyHelper
	{
		public static bool IsActive { get; private set; }

		public static void Initialize()
		{
			IsActive = AppDomain.CurrentDomain.GetAssemblies().Any((Assembly a) => a.FullN