Decompiled source of ButteryFixes v1.17.25

ButteryFixes.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using ButteryFixes.Utility;
using DunGen;
using DunGen.Graph;
using GameNetcodeStuff;
using HarmonyLib;
using LobbyCompatibility.Enums;
using LobbyCompatibility.Features;
using Microsoft.CodeAnalysis;
using TMPro;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.Events;
using UnityEngine.Rendering;
using UnityEngine.Rendering.HighDefinition;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using UnityEngine.VFX;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: AssemblyCompany("ButteryFixes")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Bundle of miscellaneous vanilla-compatible fixes")]
[assembly: AssemblyFileVersion("1.17.25.0")]
[assembly: AssemblyInformationalVersion("1.17.25+c12ecca51bad77b50efb7dc7fde5c51081433abc")]
[assembly: AssemblyProduct("ButteryFixes")]
[assembly: AssemblyTitle("ButteryFixes")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.17.25.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace ButteryFixes
{
	internal class Compatibility
	{
		internal const string GUID_LETHAL_FIXES = "uk.1a3.lethalfixes";

		internal const string GUID_GENERAL_IMPROVEMENTS = "ShaosilGaming.GeneralImprovements";

		internal const string GUID_BETTER_SPRAY_PAINT = "taffyko.BetterSprayPaint";

		internal const string GUID_EVERYTHING_CAN_DIE = "nwnt.EverythingCanDie";

		internal const string GUID_MORE_COMPANY = "me.swipez.melonloader.morecompany";

		internal const string GUID_TOUCHSCREEN = "me.pm.TheDeadSnake";

		internal const string GUID_REBALANCED_MOONS = "dopadream.lethalcompany.rebalancedmoons";

		internal const string GUID_CRUISER_ADDITIONS = "4902.Cruiser_Additions";

		internal const string GUID_TERMINAL_STUFF = "darmuh.TerminalStuff";

		internal const string GUID_LOBBY_COMPATIBILITY = "BMX.LobbyCompatibility";

		internal const string GUID_NO_LOST_SIGNAL = "Tomatobird.NoLostSignal";

		internal const string GUID_DROP_SHIP_DELIVERY_CAP_MODIFIER = "com.github.Sylkadi.DropShipDeliveryCapModifier";

		internal const string GUID_VERSION55_COMPANY_CRUISER = "scandal.v55cruiser";

		internal const string GUID_V70_POWERED_LIGHTS_FIX = "watergun.v72lightfix";

		internal const string GUID_CUSTOM_RESOLUTION = "Tomatobird.CustomResolution";

		internal const string GUID_SCIENCE_BIRD_TWEAKS = "ScienceBird.ScienceBirdTweaks";

		internal const string GUID_AUTO_SCROLL = "AutoScroll";

		internal static bool INSTALLED_GENERAL_IMPROVEMENTS;

		internal static bool INSTALLED_MORE_COMPANY;

		internal static bool INSTALLED_EVERYTHING_CAN_DIE;

		internal static bool INSTALLED_REBALANCED_MOONS;

		internal static bool INSTALLED_V55_CRUISER;

		internal static bool DISABLE_SPRAY_PAINT_PATCHES;

		internal static bool DISABLE_INTERACT_FIX;

		internal static bool DISABLE_PRICE_TEXT_FITTING;

		internal static bool DISABLE_SIGNAL_PATCH;

		internal static bool DISABLE_PURCHASE_CAP_PATCH;

		internal static bool DISABLE_RESOLUTION_PATCHES;

		internal static void Init()
		{
			if (Chainloader.PluginInfos.ContainsKey("ShaosilGaming.GeneralImprovements"))
			{
				INSTALLED_GENERAL_IMPROVEMENTS = true;
				Plugin.Logger.LogInfo((object)"CROSS-COMPATIBILITY - GeneralImprovements detected");
			}
			if (Chainloader.PluginInfos.ContainsKey("taffyko.BetterSprayPaint"))
			{
				DISABLE_SPRAY_PAINT_PATCHES = true;
				Plugin.Logger.LogInfo((object)"CROSS-COMPATIBILITY - Spray paint patches will be disabled");
			}
			if (Chainloader.PluginInfos.ContainsKey("nwnt.EverythingCanDie"))
			{
				INSTALLED_EVERYTHING_CAN_DIE = true;
				Plugin.Logger.LogInfo((object)"CROSS-COMPATIBILITY - Everything Can Die detected");
			}
			if (Chainloader.PluginInfos.ContainsKey("me.swipez.melonloader.morecompany"))
			{
				INSTALLED_MORE_COMPANY = true;
				Plugin.Logger.LogInfo((object)"CROSS-COMPATIBILITY - More Company detected");
			}
			if (Chainloader.PluginInfos.ContainsKey("me.pm.TheDeadSnake"))
			{
				DISABLE_INTERACT_FIX = true;
				Plugin.Logger.LogInfo((object)"CROSS-COMPATIBILITY - Touchscreen detected");
			}
			if (Chainloader.PluginInfos.ContainsKey("dopadream.lethalcompany.rebalancedmoons"))
			{
				INSTALLED_REBALANCED_MOONS = true;
				Plugin.Logger.LogInfo((object)"CROSS-COMPATIBILITY - Rebalanced Moons detected");
			}
			if (INSTALLED_GENERAL_IMPROVEMENTS || Chainloader.PluginInfos.ContainsKey("darmuh.TerminalStuff"))
			{
				Plugin.Logger.LogInfo((object)"CROSS-COMPATIBILITY - Price text patch will be disabled");
				DISABLE_PRICE_TEXT_FITTING = true;
			}
			if (Chainloader.PluginInfos.ContainsKey("BMX.LobbyCompatibility"))
			{
				Plugin.Logger.LogInfo((object)"CROSS-COMPATIBILITY - Lobby Compatibility detected");
				LobbyCompatibility.Init();
			}
			if (Chainloader.PluginInfos.ContainsKey("Tomatobird.NoLostSignal"))
			{
				DISABLE_SIGNAL_PATCH = true;
				Plugin.Logger.LogInfo((object)"CROSS-COMPATIBILITY - NoLostSignal detected");
			}
			if (INSTALLED_GENERAL_IMPROVEMENTS || Chainloader.PluginInfos.ContainsKey("com.github.Sylkadi.DropShipDeliveryCapModifier"))
			{
				DISABLE_PURCHASE_CAP_PATCH = true;
				Plugin.Logger.LogInfo((object)"CROSS-COMPATIBILITY - Purchase cap patch (x12) will be disabled");
			}
			if (Chainloader.PluginInfos.ContainsKey("scandal.v55cruiser"))
			{
				INSTALLED_V55_CRUISER = true;
				Plugin.Logger.LogInfo((object)"CROSS-COMPATIBILITY - Version-55 Company Cruiser detected");
			}
			if (Chainloader.PluginInfos.ContainsKey("Tomatobird.CustomResolution"))
			{
				DISABLE_RESOLUTION_PATCHES = true;
				Plugin.Logger.LogInfo((object)"CROSS-COMPATIBILITY - CustomResolution detected");
			}
		}
	}
	internal enum FilmGrains
	{
		None = -1,
		MenusOnly,
		Full
	}
	internal class Configuration
	{
		private static ConfigFile configFile;

		internal static ConfigEntry<bool> makeConductive;

		internal static ConfigEntry<bool> fixJumpCheese;

		internal static ConfigEntry<bool> showApparatusValue;

		internal static ConfigEntry<bool> scanImprovements;

		internal static ConfigEntry<bool> fixSurfacePrices;

		internal static ConfigEntry<bool> lockInTerminal;

		internal static ConfigEntry<bool> filterDecor;

		internal static ConfigEntry<bool> typeGordion;

		internal static ConfigEntry<bool> playermodelPatches;

		internal static ConfigEntry<bool> patchLadders;

		internal static ConfigEntry<bool> adjustCooldowns;

		internal static ConfigEntry<bool> noBodyNoSignal;

		internal static ConfigEntry<bool> theGoldenGoblet;

		internal static ConfigEntry<bool> charredBodies;

		internal static ConfigEntry<bool> bodiesCollectSelf;

		internal static ConfigEntry<bool> cadaverHUD;

		internal static ConfigEntry<bool> chemistryFlasks;

		internal static ConfigEntry<FilmGrains> restoreFilmGrain;

		internal static void Init(ConfigFile cfg)
		{
			configFile = cfg;
			CompatibilityConfig();
			GameplayConfig();
			VisualConfig();
			ExtraConfig();
			MigrateLegacyConfigs();
		}

		private static void CompatibilityConfig()
		{
			patchLadders = configFile.Bind<bool>("Compatibility", "PatchLadders", true, "Fixes stamina being wasted if you hold the sprint button on ladders. This will prevent other mods (Better Ladders, Fast Climbing, Better Stamina, General Improvements, etc.) from allowing ladder sprint as a feature.");
			bodiesCollectSelf = configFile.Bind<bool>("Compatibility", "BodiesCollectSelf", true, "Bodies will automatically collect themselves when teleported to the ship, or when players die inside of the ship.");
		}

		private static void GameplayConfig()
		{
			makeConductive = configFile.Bind<bool>("Gameplay", "MakeConductive", true, "(Host only) Makes some metallic items that are non-conductive in vanilla actually conductive. This fix applies sensibly to the existing items, but you can disable it if you are used to vanilla's properties.");
			fixJumpCheese = configFile.Bind<bool>("Gameplay", "FixJumpCheese", true, "(Host only) Enabling this makes enemies hear players jumping and landing on the floor. This fixes the exploit where you can silently move past dogs with sprinting speed by spamming the jump button.");
			fixSurfacePrices = configFile.Bind<bool>("Gameplay", "FixSurfacePrices", true, "(Host only) Fixes individual bee hives not having separate prices from one another. (In vanilla, all hives fall into two price classes depending on distance from ship) This also fixes sapsucker eggs having inconsistent prices on identical seeds.");
		}

		private static void VisualConfig()
		{
			restoreFilmGrain = configFile.Bind<FilmGrains>("Visual", "RestoreFilmGrain", FilmGrains.None, "Restores film grain effects from pre-release versions of the game. WARNING: Be aware that this might cause white screens on certain hardware.");
			showApparatusValue = configFile.Bind<bool>("Visual", "ShowApparatusValue", false, "Actually show the apparatus' value on the scanner instead of \"???\" (in vanilla, it is always $80)");
			playermodelPatches = configFile.Bind<bool>("Visual", "PlayermodelPatches", true, "Fixes some issues with dead bodies not displaying badges, using the wrong suit, not having attachments (bee and bunny), etc.\nIf you use ModelReplacementAPI I would strongly suggest disabling this if you run into issues!");
		}

		private static void ExtraConfig()
		{
			scanImprovements = configFile.Bind<bool>("Extra", "ScanImprovements", true, "Allows the \"scan\" command on the terminal to count the value of items on your ship while parked at Gordion. Butlers' knives will be visible on the map and \"scan\" command before they are killed. When infected by Cadavers, you will be able to see a red dot when spectating yourself on the ship's radar, just like other players.");
			lockInTerminal = configFile.Bind<bool>("Extra", "LockInTerminal", false, "The camera will be frozen when you use the terminal, and typing should be more immediately responsive.\nThis will also lock the camera when charging items, pulling the lever, or sitting in the sofa chair.");
			filterDecor = configFile.Bind<bool>("Extra", "FilterDecor", true, "Decorations (suits, furniture, etc.) you have already purchased will be filtered out of the shop's list on the terminal, potentially allowing you to see the unused \"[No items available]\" text.\n(Also fixes the missing bullet points.)");
			typeGordion = configFile.Bind<bool>("Extra", "TypeGordion", false, "You can type \"Gordion\" into the terminal (in place of \"company\") when using the route/info commands.");
			adjustCooldowns = configFile.Bind<bool>("Extra", "AdjustCooldowns", true, "Changes the cooldown on some items and interactable furniture to prevent sounds overlapping in strange ways.");
			noBodyNoSignal = configFile.Bind<bool>("Extra", "NoBodyNoSignal", false, "When a player's corpse is completely destroyed (eaten by a Forest Keeper, suffocated by quicksand, etc.) the radar will display the \"No signal!\" screen instead of spectating the location where they died.");
			theGoldenGoblet = configFile.Bind<bool>("Extra", "TheGoldenGoblet", false, "Renames the \"Golden cup\" to \"Golden goblet\"");
			chemistryFlasks = configFile.Bind<bool>("Extra", "ChemistryFlasks", false, "Renames the \"Flask\" to \"Chemistry flask\" like the original v45 release poem.");
			charredBodies = configFile.Bind<bool>("Extra", "CharredBodies", true, "When a player dies to any sort of explosion, their corpse will appear burnt, much like Cruiser explosions. (This also applies to electrocution from the electric chair.) \"PlayermodelPatches\" is *required* for this to work!");
			cadaverHUD = configFile.Bind<bool>("Extra", "CadaverHUD", false, "Displays filter quality in multiplayer, as well as the \"triple threat\" warning when you are about to bloom. This *DOES NOT* display fever warnings or change time-of-death in multiplayer.");
		}

		private static void MigrateLegacyConfigs()
		{
			(string, string)[] array = new(string, string)[18]
			{
				("Gameplay", "KillOldBirds"),
				("Visual", "FancyEntranceDoors"),
				("Visual", "RestoreShipIcon"),
				("Gameplay", "LimitSpawnChance"),
				("Gameplay", "UnlimitedOldBirds"),
				("Gameplay", "MaskHornetsPower"),
				("Gameplay", "RandomizeDefaultSeed"),
				("Gameplay", "FixGiantSight"),
				("Compatibility", "PatchPocketLights"),
				("Audio", "RestoreArtificeAmbience"),
				("Visual", "DisableLODFade"),
				("Compatibility", "AutoCollect"),
				("Compatibility", "EndOrbitEarly"),
				("Visual", "ForceMaxQuality"),
				("Gameplay", "KeysAreScrap"),
				("Gameplay", "FixFireExits"),
				("Audio", "MusicDopplerLevel"),
				("Extra", "AlterBestiary")
			};
			for (int i = 0; i < array.Length; i++)
			{
				(string, string) tuple = array[i];
				try
				{
					configFile.Bind<string>(tuple.Item1, tuple.Item2, string.Empty, "Legacy setting, doesn't work");
					configFile.Remove(configFile[tuple.Item1, tuple.Item2].Definition);
				}
				catch
				{
					Plugin.Logger.LogWarning((object)("Can't delete \"" + tuple.Item1 + "\" - \"" + tuple.Item2 + "\" from config"));
				}
			}
			if (!scanImprovements.Value)
			{
				if (configFile.Bind<bool>("Extra", "ScanOnShip", false, "Legacy setting, doesn't work").Value)
				{
					scanImprovements.Value = true;
				}
				configFile.Remove(configFile["Extra", "ScanOnShip"].Definition);
			}
			if (fixSurfacePrices.Value)
			{
				if (!configFile.Bind<bool>("Gameplay", "FixHivePrices", true, "Legacy setting, doesn't work").Value)
				{
					fixSurfacePrices.Value = false;
				}
				configFile.Remove(configFile["Gameplay", "FixHivePrices"].Definition);
			}
			configFile.Save();
		}
	}
	internal static class LobbyCompatibility
	{
		internal static void Init()
		{
			PluginHelper.RegisterPlugin("butterystancakes.lethalcompany.butteryfixes", Version.Parse("1.17.25"), (CompatibilityLevel)0, (VersionStrictness)0);
		}
	}
	[BepInPlugin("butterystancakes.lethalcompany.butteryfixes", "Buttery Fixes", "1.17.25")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		internal const string PLUGIN_GUID = "butterystancakes.lethalcompany.butteryfixes";

		internal const string PLUGIN_NAME = "Buttery Fixes";

		internal const string PLUGIN_VERSION = "1.17.25";

		internal static ManualLogSource Logger;

		private void Awake()
		{
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			Logger = ((BaseUnityPlugin)this).Logger;
			Compatibility.Init();
			Configuration.Init(((BaseUnityPlugin)this).Config);
			if (RestoreFilmGrain.GetTextures())
			{
				SceneManager.sceneLoaded += RestoreFilmGrain.OverrideVolumes;
			}
			new Harmony("butterystancakes.lethalcompany.butteryfixes").PatchAll();
			SceneManager.sceneLoaded += SceneOverrides.OnSceneLoaded;
			SceneManager.sceneUnloaded += delegate
			{
				GlobalReferences.caveTiles.Clear();
			};
			RenderPipelineManager.beginCameraRendering += RenderingOverrides.OnBeginCameraRendering;
			RenderPipelineManager.endCameraRendering += RenderingOverrides.OnEndCameraRendering;
			Logger.LogInfo((object)"Buttery Fixes v1.17.25 loaded");
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "ButteryFixes";

		public const string PLUGIN_NAME = "ButteryFixes";

		public const string PLUGIN_VERSION = "1.17.25";
	}
}
namespace ButteryFixes.Utility
{
	internal static class CruiserAnimator
	{
		private static Dictionary<PlayerControllerB, Transform> keyHolders = new Dictionary<PlayerControllerB, Transform>();

		private static readonly Vector3 serverHolderPos = new Vector3(-0.04170258f, 6.530248E-05f, -0.03752365f);

		private static readonly Quaternion serverHolderRot = Quaternion.Euler(13.794f, -3.466f, -159.053f);

		private static readonly Quaternion armsMetarigParentRot = Quaternion.Euler(90f, 0f, 0f);

		private static readonly Quaternion armsMetarigRot = Quaternion.Euler(-90f, 0f, 0f);

		private static readonly Vector3 localArmsPos = new Vector3(0f, -0.008f, -0.43f);

		private static readonly Quaternion localArmsRot = Quaternion.Euler(84.78056f, 0f, 0f);

		private static readonly Quaternion playerBodyRot = Quaternion.Euler(-90f, 0f, 0f);

		internal static void AnimateKeyForCruiser(VehicleController cruiser)
		{
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: 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_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			if (!keyHolders.TryGetValue(cruiser.currentDriver, out var value) && (Object)(object)GameNetworkManager.Instance != (Object)null && !GameNetworkManager.Instance.isDisconnecting)
			{
				if (cruiser.localPlayerInControl)
				{
					if ((Object)(object)cruiser.currentDriver.localItemHolder != (Object)null)
					{
						value = new GameObject("ButteryFixes_LocalCarKeyHolder").transform;
						value.SetParent(cruiser.currentDriver.localItemHolder.parent, false);
						value.SetLocalPositionAndRotation(new Vector3(-0.002f, 0.036f, -0.042f), Quaternion.Euler(-3.616f, -2.302f, -179.855f));
					}
				}
				else if ((Object)(object)cruiser.currentDriver.serverItemHolder != (Object)null)
				{
					value = new GameObject("ButteryFixes_ServerCarKeyHolder").transform;
					value.SetParent(cruiser.currentDriver.serverItemHolder.parent, false);
					value.SetLocalPositionAndRotation(serverHolderPos, serverHolderRot);
				}
				if ((Object)(object)value != (Object)null)
				{
					Transform obj = value;
					obj.position += value.rotation * new Vector3(0f - cruiser.positionOffset.x, 0f - cruiser.positionOffset.y, cruiser.positionOffset.z);
					keyHolders.Add(cruiser.currentDriver, value);
				}
			}
			if ((Object)(object)value != (Object)null)
			{
				((Component)cruiser.keyObject).transform.SetPositionAndRotation(value.position, value.rotation);
			}
		}

		internal static void Reset()
		{
			keyHolders.Clear();
		}

		internal static void ResetPlayerAnimator(PlayerControllerB player)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			((Component)player.playerModelArmsMetarig.parent).transform.localRotation = armsMetarigParentRot;
			player.playerModelArmsMetarig.localRotation = armsMetarigRot;
			player.localArmsTransform.SetLocalPositionAndRotation(localArmsPos, localArmsRot);
			((Component)player.playerBodyAnimator).transform.SetLocalPositionAndRotation(Vector3.zero, playerBodyRot);
		}
	}
	internal static class EnemyRadar
	{
		internal class RadarButler
		{
			internal ButlerEnemyAI butler;

			internal Transform radarIcon;

			internal Transform knife;

			internal bool dying;
		}

		private static List<RadarButler> allButlers = new List<RadarButler>(7);

		private static Transform infectionDot;

		internal static void SpawnButler(ButlerEnemyAI butler)
		{
			if (!((Object)(object)GameNetworkManager.Instance == (Object)null) && !GameNetworkManager.Instance.isDisconnecting)
			{
				List<RadarButler> list = allButlers;
				RadarButler obj = new RadarButler
				{
					butler = butler
				};
				GameObject itemRadarIconPrefab = StartOfRound.Instance.itemRadarIconPrefab;
				GameObject mapPropsContainer = RoundManager.Instance.mapPropsContainer;
				obj.radarIcon = Object.Instantiate<GameObject>(itemRadarIconPrefab, (mapPropsContainer != null) ? mapPropsContainer.transform : null).transform;
				obj.knife = ((Component)((EnemyAI)butler).creatureAnimator).transform.Find("Rig 1/Arms/RightArm/upperRightArmContainer/upper_arm.R_target/Knife");
				list.Add(obj);
				Plugin.Logger.LogDebug((object)$"Radar: Butler #{((Object)butler).GetInstanceID()} registered");
			}
		}

		internal static void Reset()
		{
			if (allButlers.Count > 0)
			{
				for (int num = allButlers.Count - 1; num >= 0; num--)
				{
					if ((Object)(object)allButlers[num]?.radarIcon != (Object)null)
					{
						Object.Destroy((Object)(object)((Component)allButlers[num].radarIcon).gameObject);
					}
				}
				allButlers.Clear();
				Plugin.Logger.LogDebug((object)"Radar: No more butlers");
			}
			CureLocalPlayer();
		}

		internal static void Refresh()
		{
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: 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_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			if (allButlers.Count <= 0)
			{
				return;
			}
			for (int num = allButlers.Count - 1; num >= 0; num--)
			{
				if (allButlers[num] == null || (Object)(object)allButlers[num].radarIcon == (Object)null)
				{
					allButlers.RemoveAt(num);
					Plugin.Logger.LogDebug((object)$"Radar: Butler at index {num} is missing, this shouldn't happen");
				}
				else if (((EnemyAI)allButlers[num].butler).isEnemyDead)
				{
					if (!allButlers[num].dying)
					{
						allButlers[num].dying = true;
						((MonoBehaviour)StartOfRound.Instance).StartCoroutine(ButlerDeathAnimation(allButlers[num]));
						allButlers[num].radarIcon.position = ((Component)allButlers[num].butler).transform.position + Vector3.up * 0.5f;
						Plugin.Logger.LogDebug((object)$"Radar: Butler #{((Object)allButlers[num].butler).GetInstanceID()} just died");
					}
				}
				else
				{
					Vector3 position = allButlers[num].knife.position;
					if (allButlers[num].knife.localScale.x < 0.025f)
					{
						position.x = ((Component)allButlers[num].butler).transform.position.x;
						position.z = ((Component)allButlers[num].butler).transform.position.z;
					}
					allButlers[num].radarIcon.position = position;
				}
			}
		}

		private static IEnumerator ButlerDeathAnimation(RadarButler butler)
		{
			yield return (object)new WaitForSeconds(1.1f);
			if (butler == null)
			{
				yield break;
			}
			while (butler != null && !((EnemyAI)butler.butler).creatureAnimator.GetBool("popFinish"))
			{
				yield return null;
			}
			if (butler != null)
			{
				if ((Object)(object)butler.radarIcon != (Object)null)
				{
					Object.Destroy((Object)(object)((Component)butler.radarIcon).gameObject);
				}
				allButlers.Remove(butler);
				Plugin.Logger.LogDebug((object)$"Radar: Butler #{((Object)butler.butler).GetInstanceID()} dropped knife");
			}
		}

		internal static int CountButlers()
		{
			return allButlers.Count;
		}

		internal static void InfectLocalPlayer(CadaverGrowthAI cadaverGrowthAI)
		{
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: 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)
			if ((Object)(object)GameNetworkManager.Instance == (Object)null || GameNetworkManager.Instance.isDisconnecting)
			{
				return;
			}
			if ((Object)(object)infectionDot == (Object)null)
			{
				if ((Object)(object)cadaverGrowthAI?.scanNodePrefab == (Object)null)
				{
					return;
				}
				infectionDot = Object.Instantiate<Transform>(cadaverGrowthAI.scanNodePrefab.transform.Find("MapDot (2)"), GameNetworkManager.Instance.localPlayerController.bodyParts[5]);
				infectionDot.SetLocalPositionAndRotation(new Vector3(0f, 0.23112391f, -0.007852852f), Quaternion.Euler(0f, 99.461f, 0f));
				infectionDot.localScale = new Vector3(0.21584508f, 0.20841183f, 0.21113071f);
			}
			if (!((Component)infectionDot).gameObject.activeSelf)
			{
				((Component)infectionDot).gameObject.SetActive(true);
				Plugin.Logger.LogDebug((object)"Radar: Local player is infected");
			}
		}

		internal static void CureLocalPlayer()
		{
			if ((Object)(object)infectionDot != (Object)null && ((Component)infectionDot).gameObject.activeSelf)
			{
				((Component)infectionDot).gameObject.SetActive(false);
				Plugin.Logger.LogDebug((object)"Radar: Infection is over");
			}
		}
	}
	internal static class GlobalReferences
	{
		internal const int NUM_LEVELS = 13;

		internal static readonly string[] INTERIOR_WHITELIST = new string[4] { "Level1Flow", "Level1Flow3Exits", "Level2Flow", "Level3Flow" };

		private static Terminal _terminal;

		private static HangarShipDoor _hangarShipDoor;

		private static StartMatchLever _startMatchLever;

		private static MoldSpreadManager _moldSpreadManager;

		internal static Dictionary<string, EnemyType> allEnemiesList = new Dictionary<string, EnemyType>();

		internal static Mesh playerBody;

		internal static Material scavengerSuitBurnt;

		internal static bool crashedJetpackAsLocalPlayer;

		internal static GameObject smokeParticle;

		internal static Transform shipNode;

		internal static Vector3 shipNodeOffset;

		internal static readonly Vector3 shipDefaultPos = new Vector3(1.2714634f, 0.27843857f, -7.5f);

		internal static Animator shipAnimator;

		internal static VehicleController vehicleController;

		internal static CadaverGrowthAI cadaverGrowthAI;

		internal static int lockingCamera;

		internal static bool sittingInArmchair;

		internal static PlayerControllerB friedPlayer;

		internal static PlayerControllerB gibbedPlayer;

		internal static List<Bounds> caveTiles = new List<Bounds>();

		internal static Vector3 mainEntrancePos;

		internal static Bounds mineStartBounds;

		internal static Renderer viewmodelArms;

		internal static Camera shipCamera;

		internal static Camera securityCamera;

		internal static List<GrabbableObject> microwavedItems = new List<GrabbableObject>();

		internal static PlayerControllerB lastDriver;

		internal static Vector3 lastLightningStrike = new Vector3(3000f, 0f, 3000f);

		internal static float lightningLastStruck;

		internal static bool forceMaxQuality;

		internal static bool localPlayerHasBackFlowers;

		internal static bool playerJustCoughed;

		internal static BreakerBox breakerBox;

		internal static float meteorRPCReceivedTime;

		internal static Mesh sphere;

		internal static Material pumpkinMatPlastic;

		internal static DressGirlAI girl;

		internal static bool girlUpdating;

		internal static Renderer girlRenderer;

		internal static Terminal Terminal
		{
			get
			{
				if ((Object)(object)_terminal == (Object)null)
				{
					_terminal = Object.FindAnyObjectByType<Terminal>();
				}
				return _terminal;
			}
		}

		internal static HangarShipDoor HangarShipDoor
		{
			get
			{
				if ((Object)(object)_hangarShipDoor == (Object)null)
				{
					_hangarShipDoor = Object.FindAnyObjectByType<HangarShipDoor>();
				}
				return _hangarShipDoor;
			}
		}

		internal static StartMatchLever StartMatchLever
		{
			get
			{
				if ((Object)(object)_startMatchLever == (Object)null)
				{
					_startMatchLever = Object.FindAnyObjectByType<StartMatchLever>();
				}
				return _startMatchLever;
			}
		}

		internal static MoldSpreadManager MoldSpreadManager
		{
			get
			{
				if ((Object)(object)_moldSpreadManager == (Object)null)
				{
					_moldSpreadManager = Object.FindAnyObjectByType<MoldSpreadManager>();
				}
				return _moldSpreadManager;
			}
		}
	}
	internal class HeartHack : MonoBehaviour
	{
		internal LoopShapeKey loopShapeKey;

		private float time;

		private void LateUpdate()
		{
			if ((Object)(object)loopShapeKey != (Object)null)
			{
				time += Time.deltaTime * loopShapeKey.fearMultiplier;
				if ((Object)(object)loopShapeKey.skinnedMeshRenderer != (Object)null && ((Behaviour)loopShapeKey).enabled)
				{
					loopShapeKey.skinnedMeshRenderer.SetBlendShapeWeight(0, Mathf.PingPong(time * 156f, 100f));
					loopShapeKey.skinnedMeshRenderer.SetBlendShapeWeight(1, Mathf.PingPong(time * 120f, 100f));
				}
			}
			else
			{
				loopShapeKey = ((Component)this).GetComponent<LoopShapeKey>();
				if ((Object)(object)loopShapeKey == (Object)null)
				{
					Plugin.Logger.LogWarning((object)("Error initializing heartbeat animation for " + ((Object)this).name));
					((Behaviour)this).enabled = false;
				}
			}
		}
	}
	public static class NonPatchFunctions
	{
		internal static bool[] playerWasLastSprinting = new bool[50];

		internal static int hives;

		internal static IEnumerator ShellsAppearAfterDelay(ShotgunItem shotgun)
		{
			bool wasHeldByEnemy = ((GrabbableObject)shotgun).isHeldByEnemy;
			float timeSinceStart = Time.realtimeSinceStartup;
			yield return (object)new WaitForSeconds(((GrabbableObject)shotgun).isHeldByEnemy ? 0.85f : 1.9f);
			if (((GrabbableObject)shotgun).isHeldByEnemy)
			{
				((Renderer)shotgun.shotgunShellLeft).forceRenderingOff = false;
				((Renderer)shotgun.shotgunShellLeft).enabled = true;
				((Renderer)shotgun.shotgunShellRight).forceRenderingOff = false;
				((Renderer)shotgun.shotgunShellRight).enabled = true;
			}
			else if (((Renderer)shotgun.shotgunShellLeft).enabled)
			{
				((Renderer)shotgun.shotgunShellRight).enabled = true;
			}
			else
			{
				((Renderer)shotgun.shotgunShellLeft).enabled = true;
			}
			yield return (object)new WaitForSeconds(((GrabbableObject)shotgun).isHeldByEnemy ? 0.66f : 0.75f);
			if (!wasHeldByEnemy)
			{
				yield return (object)new WaitUntil((Func<bool>)(() => !shotgun.isReloading || Time.realtimeSinceStartup - timeSinceStart > 3f));
			}
			((Renderer)shotgun.shotgunShellLeft).forceRenderingOff = true;
			((Renderer)shotgun.shotgunShellRight).forceRenderingOff = true;
			Plugin.Logger.LogDebug((object)$"Finished animating shotgun shells (held by enemy: {((GrabbableObject)shotgun).isHeldByEnemy})");
		}

		internal static void FakeFootstepAlert(PlayerControllerB player)
		{
			//IL_0077: 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)
			bool flag = player.isInHangarShipRoom && StartOfRound.Instance.hangarDoorsClosed;
			if ((int)player.actualClientId < playerWasLastSprinting.Length && (((NetworkBehaviour)player).IsOwner ? player.isSprinting : playerWasLastSprinting[(uint)player.actualClientId]))
			{
				RoundManager.Instance.PlayAudibleNoise(((Component)player).transform.position, 22f, 0.6f, 0, flag, 3322);
			}
			else
			{
				RoundManager.Instance.PlayAudibleNoise(((Component)player).transform.position, 17f, 0.4f, 0, flag, 3322);
			}
		}

		internal static void ForceRefreshAllHelmetLights(PlayerControllerB player, bool forceOff = false)
		{
			for (int i = 0; i < player.allHelmetLights.Length; i++)
			{
				bool flag = false;
				if (!forceOff)
				{
					if ((Object)(object)player.ItemOnlySlot != (Object)null)
					{
						GrabbableObject itemOnlySlot = player.ItemOnlySlot;
						FlashlightItem val = (FlashlightItem)(object)((itemOnlySlot is FlashlightItem) ? itemOnlySlot : null);
						if ((Object)(object)val != (Object)null && val.flashlightTypeID == i && ((GrabbableObject)val).isPocketed && ((GrabbableObject)val).isBeingUsed && ((GrabbableObject)val).insertedBattery.charge > 0f)
						{
							flag = true;
						}
					}
					if (!flag)
					{
						for (int j = 0; j < player.ItemSlots.Length; j++)
						{
							if ((Object)(object)player.ItemSlots[j] != (Object)null)
							{
								GrabbableObject obj = player.ItemSlots[j];
								FlashlightItem val2 = (FlashlightItem)(object)((obj is FlashlightItem) ? obj : null);
								if ((Object)(object)val2 != (Object)null && val2.flashlightTypeID == i && ((GrabbableObject)val2).isPocketed && ((GrabbableObject)val2).isBeingUsed && ((GrabbableObject)val2).insertedBattery.charge > 0f)
								{
									flag = true;
									break;
								}
							}
						}
					}
				}
				if (((Behaviour)player.allHelmetLights[i]).enabled != flag)
				{
					((Behaviour)player.allHelmetLights[i]).enabled = flag;
					Plugin.Logger.LogDebug((object)$"Fixed erroneous active state of {player.playerUsername}'s helmet light \"{((Object)player.allHelmetLights[i]).name}\" (now {flag})");
				}
			}
		}

		internal static void SmokingHotCorpse(Transform body)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: 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_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			SkinnedMeshRenderer skinnedMeshRenderer = default(SkinnedMeshRenderer);
			if ((Object)(object)GlobalReferences.smokeParticle == (Object)null || !((Component)body).TryGetComponent<SkinnedMeshRenderer>(ref skinnedMeshRenderer))
			{
				return;
			}
			foreach (Transform item in body)
			{
				if (((Object)item).name.StartsWith(((Object)GlobalReferences.smokeParticle).name))
				{
					return;
				}
			}
			GameObject obj = Object.Instantiate<GameObject>(GlobalReferences.smokeParticle, ((Component)body).transform);
			obj.transform.SetLocalPositionAndRotation(Vector3.zero, Quaternion.identity);
			obj.transform.localScale = Vector3.one;
			ShapeModule shape = obj.GetComponent<ParticleSystem>().shape;
			((ShapeModule)(ref shape)).skinnedMeshRenderer = skinnedMeshRenderer;
			Plugin.Logger.LogDebug((object)"Smoke from freshly burnt corpse");
		}

		public static int RerollHivePrice(int price, Vector3 pos)
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			hives++;
			if (!Configuration.fixSurfacePrices.Value || StartOfRound.Instance.isChallengeFile)
			{
				return price;
			}
			Random random = new Random(StartOfRound.Instance.randomMapSeed + 1314 + hives);
			int num = random.Next(50, 150);
			if (Vector3.Distance(pos, StartOfRound.Instance.shipLandingPosition.position) < 40f)
			{
				num = random.Next(40, 100);
			}
			Plugin.Logger.LogDebug((object)$"Hive price recalculated: ${price} -> ${num}");
			return num;
		}

		internal static IEnumerator InteractionTemporarilyLocksCamera(InteractTrigger trigger)
		{
			if ((Object)(object)trigger == (Object)null)
			{
				yield break;
			}
			float startTime = Time.realtimeSinceStartup;
			while ((Object)(object)trigger.playerScriptInSpecialAnimation != (Object)(object)GameNetworkManager.Instance.localPlayerController && Time.realtimeSinceStartup - startTime < 2f)
			{
				yield return null;
			}
			if ((Object)(object)trigger.playerScriptInSpecialAnimation != (Object)(object)GameNetworkManager.Instance.localPlayerController)
			{
				Plugin.Logger.LogDebug((object)"Failed to lock animation for local player, who never entered animation state");
				yield break;
			}
			GlobalReferences.lockingCamera++;
			yield return (object)new WaitForSeconds(trigger.animationWaitTime);
			if (GlobalReferences.lockingCamera > 0)
			{
				GlobalReferences.lockingCamera--;
			}
		}

		public static Vector3 GetTrueExitPoint(bool ignore = true, bool ignore2 = false)
		{
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			if (RoundManager.Instance.currentDungeonType == 4 && (Object)(object)RoundManager.Instance.currentMineshaftElevator != (Object)null && !((Bounds)(ref GlobalReferences.mineStartBounds)).Contains(((Component)StartOfRound.Instance.mapScreen.mapCamera).transform.position - Vector3.up * 3.75f))
			{
				return RoundManager.Instance.currentMineshaftElevator.elevatorBottomPoint.position;
			}
			return GlobalReferences.mainEntrancePos;
		}

		internal static void ClearMicrowave()
		{
			for (int i = 0; i < GlobalReferences.microwavedItems.Count; i++)
			{
				if (!((Object)(object)GlobalReferences.microwavedItems[i] == (Object)null))
				{
					GlobalReferences.microwavedItems[i].rotateObject = false;
				}
			}
			GlobalReferences.microwavedItems.Clear();
		}

		public static PlayerControllerB CruiserCreditsPlayer()
		{
			if ((Object)(object)GlobalReferences.lastDriver != (Object)null)
			{
				return GlobalReferences.lastDriver;
			}
			return GameNetworkManager.Instance.localPlayerController;
		}

		internal static IEnumerator LightningShakesBody(DeadBodyInfo deadBodyInfo)
		{
			yield return (object)new WaitForFixedUpdate();
			if (Time.realtimeSinceStartup - GlobalReferences.lightningLastStruck <= 2f && (Object)(object)deadBodyInfo?.playerScript != (Object)null && Vector3.Distance(GlobalReferences.lastLightningStrike, deadBodyInfo.playerScript.positionOfDeath) <= 7f)
			{
				Plugin.Logger.LogDebug((object)("Player \"" + deadBodyInfo.playerScript.playerUsername + "\" was likely struck by lightning, shake rigidbodies"));
				ShakeRigidbodies obj = ((Component)deadBodyInfo).gameObject.AddComponent<ShakeRigidbodies>();
				obj.rigidBodies = (from rb in ((Component)deadBodyInfo).GetComponentsInChildren<Rigidbody>()
					where ((Component)rb).gameObject.layer == 20 && !((Object)rb).name.EndsWith("lower") && !((Object)rb).name.StartsWith("shin")
					select rb).ToArray();
				obj.shakeTimer = 5f;
				obj.shakeIntensity = 4755f;
			}
		}

		internal static IEnumerator TryAutoCollectBody(DeadBodyInfo deadBodyInfo)
		{
			float timeOfDeath = Time.realtimeSinceStartup;
			while (Time.realtimeSinceStartup - timeOfDeath <= 2f && (Object)(object)deadBodyInfo?.grabBodyObject == (Object)null)
			{
				yield return null;
			}
			if ((Object)(object)deadBodyInfo != (Object)null && !deadBodyInfo.deactivated && (Object)(object)deadBodyInfo.grabBodyObject != (Object)null && !deadBodyInfo.grabBodyObject.deactivated && (Object)(object)deadBodyInfo.playerScript != (Object)null)
			{
				deadBodyInfo.playerScript.SetItemInElevator(true, true, deadBodyInfo.grabBodyObject);
				RoundManager.Instance.CollectNewScrapForThisRound(deadBodyInfo.grabBodyObject);
				Plugin.Logger.LogDebug((object)("Player \"" + deadBodyInfo.playerScript?.playerUsername + "\" automatically collected themself"));
			}
		}

		internal static IEnumerator ResyncCompanyRandomOnDelay(DepositItemsDesk depositItemsDesk)
		{
			yield return (object)new WaitUntil((Func<bool>)(() => StartOfRound.Instance.shipDoorsEnabled));
			if ((Object)(object)depositItemsDesk != (Object)null)
			{
				depositItemsDesk.CompanyLevelRandom = new Random(StartOfRound.Instance.randomMapSeed + 39);
			}
		}
	}
	internal class PlayerGibsLinker : MonoBehaviour
	{
		private void Start()
		{
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: 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_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: 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)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: 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_01c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0213: Unknown result type (might be due to invalid IL or missing references)
			//IL_022b: Unknown result type (might be due to invalid IL or missing references)
			//IL_023b: Unknown result type (might be due to invalid IL or missing references)
			//IL_024d: Unknown result type (might be due to invalid IL or missing references)
			//IL_025d: Unknown result type (might be due to invalid IL or missing references)
			//IL_026f: Unknown result type (might be due to invalid IL or missing references)
			//IL_027f: Unknown result type (might be due to invalid IL or missing references)
			//IL_028a: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)GlobalReferences.gibbedPlayer != (Object)null))
			{
				return;
			}
			if (Configuration.playermodelPatches.Value)
			{
				UnlockableItem val = StartOfRound.Instance.unlockablesList.unlockables[GlobalReferences.gibbedPlayer.currentSuitID];
				Renderer[] componentsInChildren = ((Component)this).GetComponentsInChildren<Renderer>();
				foreach (Renderer val2 in componentsInChildren)
				{
					if (((Object)val2).name == "Head (2)")
					{
						val2.sharedMaterial = val.suitMaterial;
						if ((Object)(object)val.headCostumeObject != (Object)null)
						{
							Transform transform = Object.Instantiate<GameObject>(val.headCostumeObject, ((Component)val2).transform.position, ((Component)val2).transform.rotation, ((Component)val2).transform).transform;
							((Component)transform).transform.SetLocalPositionAndRotation(new Vector3(0.06989373f, 0.0544735f, -0.6852454f), Quaternion.Euler(96.69699f, 0f, 0f));
							((Component)transform).transform.localScale = new Vector3(((Component)transform).transform.localScale.x / ((Component)val2).transform.lossyScale.x, ((Component)transform).transform.localScale.y / ((Component)val2).transform.lossyScale.y, ((Component)transform).transform.localScale.z / ((Component)val2).transform.lossyScale.z) * 0.9f;
						}
					}
					else if (val2 is SkinnedMeshRenderer)
					{
						val2.sharedMaterials = (Material[])(object)new Material[2]
						{
							val.suitMaterial,
							val2.sharedMaterials[1]
						};
						if (((Object)val2).name == "RendedBodyTorsoMesh" && (Object)(object)val.lowerTorsoCostumeObject != (Object)null)
						{
							Transform transform2 = Object.Instantiate<GameObject>(val.lowerTorsoCostumeObject, ((Component)val2).transform.position, ((Component)val2).transform.rotation, ((Component)val2).transform).transform;
							((Component)transform2).transform.SetLocalPositionAndRotation(new Vector3(0.55988234f, -0.046097063f, -5.0041165f), Quaternion.Euler(88.184f, -51.554f, -51.067f));
							((Component)transform2).transform.localScale = new Vector3(((Component)transform2).transform.localScale.x / ((Component)val2).transform.lossyScale.x, ((Component)transform2).transform.localScale.y / ((Component)val2).transform.lossyScale.y, ((Component)transform2).transform.localScale.z / ((Component)val2).transform.lossyScale.z);
						}
					}
				}
				Plugin.Logger.LogDebug((object)("Apply suit to " + GlobalReferences.gibbedPlayer.playerUsername + "'s gibs"));
			}
			GlobalReferences.gibbedPlayer = null;
		}
	}
	internal static class ReflectionCache
	{
		internal static readonly FieldInfo LOCAL_PLAYER_CONTROLLER = AccessTools.Field(typeof(GameNetworkManager), "localPlayerController");

		internal static readonly FieldInfo IS_IN_HANGAR_SHIP_ROOM = AccessTools.Field(typeof(PlayerControllerB), "isInHangarShipRoom");

		internal static readonly FieldInfo VEHICLE_CONTROLLER = AccessTools.Field(typeof(GlobalReferences), "vehicleController");

		internal static readonly FieldInfo CURRENT_MINESHAFT_ELEVATOR = AccessTools.Field(typeof(RoundManager), "currentMineshaftElevator");

		internal static readonly FieldInfo CADAVER_GROWTH_AI = AccessTools.Field(typeof(GlobalReferences), "cadaverGrowthAI");

		internal static readonly MethodInfo FIND_OBJECT_OF_TYPE_VEHICLE_CONTROLLER = AccessTools.Method(typeof(Object), "FindObjectOfType", (Type[])null, new Type[1] { typeof(VehicleController) });

		internal static readonly MethodInfo FIND_OBJECT_OF_TYPE_MOLD_SPREAD_MANAGER = AccessTools.Method(typeof(Object), "FindObjectOfType", (Type[])null, new Type[1] { typeof(MoldSpreadManager) });

		internal static readonly MethodInfo FIND_OBJECT_OF_TYPE_MINESHAFT_ELEVATOR_CONTROLLER = AccessTools.Method(typeof(Object), "FindObjectOfType", (Type[])null, new Type[1] { typeof(MineshaftElevatorController) });

		internal static readonly MethodInfo FIND_OBJECT_OF_TYPE_CADAVER_GROWTH_AI = AccessTools.Method(typeof(Object), "FindObjectOfType", (Type[])null, new Type[1] { typeof(CadaverGrowthAI) });

		internal static readonly MethodInfo MOLD_SPREAD_MANAGER = AccessTools.DeclaredPropertyGetter(typeof(GlobalReferences), "MoldSpreadManager");

		internal static readonly MethodInfo SET_SCRAP_VALUE = AccessTools.Method(typeof(GrabbableObject), "SetScrapValue", (Type[])null, (Type[])null);

		internal static readonly MethodInfo TRACK_GIFT_BOX_ON_CLIENT = AccessTools.Method(typeof(ScrapTracker), "TrackGiftBoxOnClient", (Type[])null, (Type[])null);

		internal static readonly MethodInfo ROUND_MANAGER_INSTANCE = AccessTools.DeclaredPropertyGetter(typeof(RoundManager), "Instance");

		internal static readonly MethodInfo DAMAGE_PLAYER = AccessTools.Method(typeof(PlayerControllerB), "DamagePlayer", (Type[])null, (Type[])null);

		internal static readonly MethodInfo KILL_PLAYER = AccessTools.Method(typeof(PlayerControllerB), "KillPlayer", (Type[])null, (Type[])null);
	}
	internal static class RenderingOverrides
	{
		private static bool? armsNotRendering;

		public static void OnBeginCameraRendering(ScriptableRenderContext context, Camera camera)
		{
			ResetRendering();
			if ((Object)(object)GlobalReferences.viewmodelArms == (Object)null)
			{
				armsNotRendering = null;
			}
			else if ((Object)(object)camera == (Object)(object)GlobalReferences.shipCamera || (Object)(object)camera == (Object)(object)GlobalReferences.securityCamera)
			{
				armsNotRendering = GlobalReferences.viewmodelArms.forceRenderingOff;
				GlobalReferences.viewmodelArms.forceRenderingOff = true;
			}
		}

		public static void OnEndCameraRendering(ScriptableRenderContext context, Camera camera)
		{
			ResetRendering();
		}

		private static void ResetRendering()
		{
			if (armsNotRendering.HasValue && (Object)(object)GlobalReferences.viewmodelArms != (Object)null)
			{
				GlobalReferences.viewmodelArms.forceRenderingOff = armsNotRendering.Value;
				armsNotRendering = null;
			}
		}
	}
	internal static class RestoreFilmGrain
	{
		private static Texture scanline;

		private static Texture scanlineBlue;

		internal static bool GetTextures()
		{
			try
			{
				AssetBundle obj = AssetBundle.LoadFromFile(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "filmgrain"));
				scanline = obj.LoadAsset<Texture>("scanline");
				scanlineBlue = obj.LoadAsset<Texture>("scanlineBlue");
				obj.Unload(false);
				return true;
			}
			catch
			{
				Plugin.Logger.LogError((object)"Encountered some error loading assets from bundle \"filmgrain\". Did you install the plugin correctly?");
				return false;
			}
		}

		internal static void OverrideVolumes(Scene scene, LoadSceneMode mode)
		{
			if (Configuration.restoreFilmGrain.Value == FilmGrains.None || (Object)(object)scanline == (Object)null || (Object)(object)scanlineBlue == (Object)null)
			{
				return;
			}
			Volume[] array = Object.FindObjectsByType<Volume>((FindObjectsInactive)1, (FindObjectsSortMode)0);
			Bloom val2 = default(Bloom);
			foreach (Volume val in array)
			{
				if ((Object)(object)val.sharedProfile == (Object)null || (((Object)val.sharedProfile).name != "UIEffects" && Configuration.restoreFilmGrain.Value == FilmGrains.MenusOnly))
				{
					continue;
				}
				switch (((Object)val.sharedProfile).name)
				{
				case "UIEffects":
					ApplyFilmGrain(val.sharedProfile, 0.085f, 0.06f, scanline, (FilmGrainLookup)10);
					val.sharedProfile.TryGet<Bloom>(ref val2);
					if ((Object)(object)val2 != (Object)null)
					{
						((VolumeComponent)val2).active = true;
						Plugin.Logger.LogDebug((object)("Bloom: " + ((Object)val.sharedProfile).name));
					}
					break;
				case "IngameHUD":
					ApplyFilmGrain(val.sharedProfile, 0f, 0.49f, scanline, (FilmGrainLookup)10);
					break;
				case "FlashbangedFilter":
					ApplyFilmGrain(val.sharedProfile, 1f, 0.818f, null, (FilmGrainLookup)9);
					break;
				case "InsanityVolume":
					ApplyFilmGrain(val.sharedProfile, 0.374f, 0.558f, null, (FilmGrainLookup)9);
					break;
				case "WakeUpVolume":
					ApplyFilmGrain(val.sharedProfile, 0.112f, 0.524f, scanline, (FilmGrainLookup)10);
					break;
				case "ScanVolume":
					ApplyFilmGrain(val.sharedProfile, 0.073f, 0.49f, scanlineBlue, (FilmGrainLookup)10);
					break;
				}
			}
		}

		private static void ApplyFilmGrain(VolumeProfile profile, float intensity, float response, Texture texture = null, FilmGrainLookup type = (FilmGrainLookup)10)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			FilmGrain val = default(FilmGrain);
			profile.TryGet<FilmGrain>(ref val);
			if ((Object)(object)val == (Object)null)
			{
				val = profile.Add<FilmGrain>(false);
			}
			if ((Object)(object)texture != (Object)null)
			{
				((VolumeParameter<Texture>)(object)val.texture).Override(texture);
				((VolumeParameter<FilmGrainLookup>)(object)val.type).Override((FilmGrainLookup)10);
			}
			else
			{
				((VolumeParameter<FilmGrainLookup>)(object)val.type).Override(type);
			}
			((VolumeParameter<float>)(object)val.intensity).Override(intensity);
			((VolumeParameter<float>)(object)val.response).Override(response);
			if (((Object)profile).name == "InsanityVolume")
			{
				((VolumeParameter)val.response).overrideState = false;
			}
			Plugin.Logger.LogDebug((object)("Film grain: " + ((Object)profile).name));
		}
	}
	internal static class SceneOverrides
	{
		internal static void OnSceneLoaded(Scene scene, LoadSceneMode mode)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Invalid comparison between Unknown and I4
			//IL_0b5e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0252: Unknown result type (might be due to invalid IL or missing references)
			//IL_025d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0267: Unknown result type (might be due to invalid IL or missing references)
			//IL_0dc3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0d18: Unknown result type (might be due to invalid IL or missing references)
			//IL_0c28: Unknown result type (might be due to invalid IL or missing references)
			//IL_0d61: Unknown result type (might be due to invalid IL or missing references)
			//IL_0d7a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0904: Unknown result type (might be due to invalid IL or missing references)
			//IL_0909: Unknown result type (might be due to invalid IL or missing references)
			//IL_0920: Unknown result type (might be due to invalid IL or missing references)
			//IL_0932: Unknown result type (might be due to invalid IL or missing references)
			//IL_0941: Unknown result type (might be due to invalid IL or missing references)
			//IL_094d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0957: Unknown result type (might be due to invalid IL or missing references)
			//IL_0964: Unknown result type (might be due to invalid IL or missing references)
			//IL_097a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0984: Unknown result type (might be due to invalid IL or missing references)
			//IL_098e: Unknown result type (might be due to invalid IL or missing references)
			//IL_099b: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02df: Unknown result type (might be due to invalid IL or missing references)
			//IL_0e9d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0ea4: Expected O, but got Unknown
			//IL_09ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a52: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a61: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a74: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a80: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a8a: Unknown result type (might be due to invalid IL or missing references)
			//IL_10a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_10ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_10b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_10b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0401: Unknown result type (might be due to invalid IL or missing references)
			//IL_0317: Unknown result type (might be due to invalid IL or missing references)
			//IL_0326: Unknown result type (might be due to invalid IL or missing references)
			//IL_0339: Unknown result type (might be due to invalid IL or missing references)
			//IL_0348: Unknown result type (might be due to invalid IL or missing references)
			//IL_0cc3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0cd2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0728: Unknown result type (might be due to invalid IL or missing references)
			//IL_072f: Expected O, but got Unknown
			//IL_037d: Unknown result type (might be due to invalid IL or missing references)
			//IL_038c: Unknown result type (might be due to invalid IL or missing references)
			//IL_039f: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ae: Unknown result type (might be due to invalid IL or missing references)
			if ((int)mode != 1)
			{
				return;
			}
			GameObject obj = GameObject.Find("/Environment/Map");
			Transform val = ((obj != null) ? obj.transform : null);
			Transform val2 = ((val != null) ? val.Find("DiageticAmbiance/BigMachine") : null);
			List<string> list = new List<string>();
			GameObject val3 = GameObject.Find("/Environment/ScanNodes/ScanNode");
			int num = 0;
			switch (((Scene)(ref scene)).name)
			{
			case "Level1Experimentation":
			{
				Plugin.Logger.LogDebug((object)"Detected landing on Experimentation");
				if ((Object)(object)val2 != (Object)null)
				{
					val2.localPosition = new Vector3(-96.45731f, val2.localPosition.y, val2.localPosition.z);
					Plugin.Logger.LogDebug((object)"Experimentation - Fixed factory ambience");
				}
				GameObject obj11 = GameObject.Find("/Environment/ReverbTriggers (1)/Cube (7)");
				Transform val11 = ((obj11 != null) ? obj11.transform : null);
				if ((Object)(object)val11 != (Object)null)
				{
					val11.localPosition = new Vector3(-147.8f, val11.localPosition.y, -81.2f);
					val11.localScale = new Vector3(129.6264f, val11.localScale.y, 184.7249f);
					GameObject obj12 = GameObject.Find("/Environment/ReverbTriggers (1)/Cube (9)");
					Transform val12 = ((obj12 != null) ? obj12.transform : null);
					if ((Object)(object)val12 != (Object)null)
					{
						val12.localPosition = new Vector3(-145.4f, val12.localPosition.y, -42.1f);
						val12.localScale = new Vector3(171.2598f, val12.localScale.y, 326.2066f);
						GameObject obj13 = GameObject.Find("/Environment/ReverbTriggers (1)/Cube (8)");
						Transform val13 = ((obj13 != null) ? obj13.transform : null);
						if ((Object)(object)val13 != (Object)null)
						{
							val13.localPosition = new Vector3(-117.39f, val13.localPosition.y, -87.23f);
							val13.localScale = new Vector3(10.4316f, val13.localScale.y, 15.95104f);
							Plugin.Logger.LogDebug((object)"Experimentation - Adjusted water tower fog triggers");
						}
					}
				}
				GameObject obj14 = GameObject.Find("/Environment/SteelDoor");
				Transform val14 = ((obj14 != null) ? obj14.transform : null);
				if ((Object)(object)val14 != (Object)null)
				{
					val14.localPosition = new Vector3(-194.668f, 19.788f, val14.localPosition.z);
					Transform obj15 = val14.Find("DoorMesh/Cube");
					InteractTrigger val15 = ((obj15 != null) ? ((Component)obj15).GetComponent<InteractTrigger>() : null);
					if ((Object)(object)val15 != (Object)null)
					{
						val15.hoverTip = val15.hoverTip.Replace("[ LMB ]", "[LMB]");
					}
					Plugin.Logger.LogDebug((object)"Experimentation - Fixed old back entrance");
				}
				object obj16;
				if (val == null)
				{
					obj16 = null;
				}
				else
				{
					Transform obj17 = val.Find("Cube (1)");
					obj16 = ((obj17 != null) ? ((Component)obj17).GetComponent<Renderer>() : null);
				}
				Renderer val16 = (Renderer)obj16;
				if ((Object)(object)val16 != (Object)null)
				{
					val16.enabled = false;
					Plugin.Logger.LogDebug((object)"Experimentation - Hide untextured geometry");
				}
				object obj18;
				if (val == null)
				{
					obj18 = null;
				}
				else
				{
					Transform obj19 = val.Find("ModelsIntroScene/Cube.007/Buttresses.001");
					obj18 = ((obj19 != null) ? ((Component)obj19).gameObject : null);
				}
				GameObject val17 = (GameObject)obj18;
				if ((Object)(object)val17 != (Object)null)
				{
					val17.AddComponent<MeshCollider>();
					Plugin.Logger.LogDebug((object)"Experimentation - Fix buttress collision");
				}
				list.AddRange(new <>z__ReadOnlyArray<string>(new string[38]
				{
					"BendingPipe", "Bolt", "CatwalkChunk", "CatwalkChunk.004", "CatwalkChunk.005", "CatwalkRailPost", "CatwalkStairTile", "ChainlinkFenceBend", "ChainlinkFenceCut", "CordConnector",
					"Cube.001", "Cube.004", "Cube.006", "Girder1", "GridPlate", "LadderFrame", "LongCord1", "LongCord2", "LongCord3", "LongCord4",
					"MeterBoxDevice", "MiscShelf1", "MiscShelf2", "NurbsPath", "Pipework2", "PlayerScaleCube.001", "PlayerScaleRef", "PlayerScaleRef.001", "RaisedCementPlatform", "Scaffolding",
					"SiloTall", "SpawnRoom", "StandardDoorSize", "StandardDoorSize.001", "StandardDoorSize.002", "TelephonePoleCordsC", "TrainCarRailLowDetail", "ValveWithHandle.001"
				}));
				break;
			}
			case "Level2Assurance":
				Plugin.Logger.LogDebug((object)"Detected landing on Assurance");
				list.AddRange(new <>z__ReadOnlyArray<string>(new string[6] { "ChainlinkFenceCut", "NurbsPath", "Pipework2", "PlayerScaleCube.001", "PlayerScaleRef", "PlayerScaleRef.001" }));
				num = 1;
				break;
			case "Level3Vow":
				Plugin.Logger.LogDebug((object)"Detected landing on Vow");
				break;
			case "Level4March":
			{
				Plugin.Logger.LogDebug((object)"Detected landing on March");
				Transform val18 = ((val != null) ? val.Find("Trees") : null);
				if (!((Object)(object)val18 != (Object)null))
				{
					break;
				}
				MeshFilter? obj20 = ((IEnumerable<MeshFilter>)((Component)val18).GetComponentsInChildren<MeshFilter>()).FirstOrDefault((Func<MeshFilter, bool>)delegate(MeshFilter meshFilter)
				{
					if (((Object)meshFilter).name == "WychElmA_LOD1")
					{
						Mesh sharedMesh = meshFilter.sharedMesh;
						if (((sharedMesh != null) ? ((Object)sharedMesh).name : null) == "WychElmTreeALOD1")
						{
							return (Object)(object)((Component)meshFilter).GetComponent<Renderer>() != (Object)null;
						}
					}
					return false;
				});
				GameObject val19 = ((obj20 != null) ? ((Component)obj20).gameObject : null);
				foreach (Transform item in val18)
				{
					Transform val20 = item;
					if (!((Object)val20).name.StartsWith("WychElmA"))
					{
						continue;
					}
					Transform obj21 = val20.Find("WychElmA_LOD1");
					Renderer val21 = ((obj21 != null) ? ((Component)obj21).GetComponent<Renderer>() : null);
					if ((Object)(object)val21 != (Object)null)
					{
						val21.enabled = true;
						Plugin.Logger.LogDebug((object)("March - Enable LOD \"" + ((Object)val21).name + "\" for \"" + ((Object)val20).name + "\""));
					}
					else
					{
						if (!((Object)(object)val19 != (Object)null))
						{
							continue;
						}
						LODGroup component3 = ((Component)val20).GetComponent<LODGroup>();
						if (!((Object)(object)component3 == (Object)null))
						{
							LOD[] lODs = component3.GetLODs();
							if (lODs.Length >= 2 && (lODs[1].renderers == null || lODs[1].renderers.Length == 0 || !((Object)(object)lODs[1].renderers[0] != (Object)null)))
							{
								lODs[1].renderers = (Renderer[])(object)new Renderer[1] { Object.Instantiate<GameObject>(val19, val20).GetComponent<Renderer>() };
								component3.SetLODs(lODs);
								Plugin.Logger.LogDebug((object)("March - Add LOD1 \"" + ((Object)lODs[1].renderers[0]).name + "\" to \"" + ((Object)val20).name + "\""));
							}
						}
					}
				}
				break;
			}
			case "Level5Rend":
			{
				Plugin.Logger.LogDebug((object)"Detected landing on Rend");
				object obj5;
				if (val == null)
				{
					obj5 = null;
				}
				else
				{
					Transform obj6 = val.Find("CementFacility1/Cube.002");
					obj5 = ((obj6 != null) ? ((Component)obj6).gameObject : null);
				}
				GameObject val6 = (GameObject)obj5;
				if ((Object)(object)val6 != (Object)null)
				{
					GameObject val7 = new GameObject("Cube.002 (2)");
					val7.transform.SetParent(val6.transform.parent);
					val7.transform.SetLocalPositionAndRotation(new Vector3(-24.297f, val6.transform.localPosition.y, 19.699f), val6.transform.localRotation);
					val7.transform.localScale = new Vector3(val6.transform.localScale.x, 0.655802f, val6.transform.localScale.z);
					val7.layer = val6.layer;
					val7.AddComponent<MeshFilter>().sharedMesh = val6.GetComponent<MeshCollider>().sharedMesh;
					Renderer component2 = val6.GetComponent<Renderer>();
					((Renderer)val7.AddComponent<MeshRenderer>()).sharedMaterial = component2.sharedMaterial;
					component2.enabled = false;
					Plugin.Logger.LogDebug((object)"Rend - Adjust fire exit visuals");
				}
				if ((Object)(object)val2 != (Object)null)
				{
					val2.localPosition = new Vector3(63.55667f, -18.09991f, -139.49373f);
					Plugin.Logger.LogDebug((object)"Rend - Fixed factory ambience");
				}
				break;
			}
			case "Level6Dine":
			{
				Plugin.Logger.LogDebug((object)"Detected landing on Dine");
				Transform val8 = ((val != null) ? val.Find("KillTrigger (4)") : null);
				if ((Object)(object)val8 != (Object)null)
				{
					val8.localPosition = new Vector3(148.11f, val8.localPosition.y, 83.61f);
					val8.localScale = new Vector3(35.3778f, val8.localScale.y, val8.localScale.z);
					Plugin.Logger.LogDebug((object)"Dine - Fixed death pit");
				}
				if (!((Object)(object)val != (Object)null))
				{
					break;
				}
				string[] array = new string[7] { "Cube.001", "Cube.001 (1)", "Cube.001 (2)", "Cube.001 (5)", "Cube.001 (6)", "GridPlate", "GridPlate (3)" };
				foreach (string text in array)
				{
					Transform obj7 = val.Find(text);
					if (obj7 != null)
					{
						((Component)obj7).gameObject.SetActive(false);
					}
				}
				Plugin.Logger.LogDebug((object)"Dine - Hide out-of-bounds objects");
				break;
			}
			case "Level7Offense":
				Plugin.Logger.LogDebug((object)"Detected landing on Offense");
				if ((Object)(object)val2 != (Object)null)
				{
					val2.localPosition = new Vector3(27.601871f, 24.056633f, -67.70342f);
					Plugin.Logger.LogDebug((object)"Offense - Fixed factory ambience");
				}
				list.AddRange(new <>z__ReadOnlyArray<string>(new string[13]
				{
					"ChainlinkFenceCut", "CreeperVine", "MiscShelf1", "NurbsPath", "Pipework2", "PlayerScaleCube.001", "PlayerScaleRef", "PlayerScaleRef.001", "LargePipeCorner (1)", "LargePipeCorner (2)",
					"Girder1 (4)", "ChainlinkFence (18)", "SiloShort"
				}));
				num = 2;
				break;
			case "Level8Titan":
				Plugin.Logger.LogDebug((object)"Detected landing on Titan");
				if ((Object)(object)val2 != (Object)null)
				{
					val2.localPosition = new Vector3(-36.07f, 55.12f, 26.15f);
					Plugin.Logger.LogDebug((object)"Titan - Fixed factory ambience");
				}
				break;
			case "Level9Artifice":
			{
				Plugin.Logger.LogDebug((object)"Detected landing on Artifice");
				object obj8;
				if (val == null)
				{
					obj8 = null;
				}
				else
				{
					Transform obj9 = val.Find("WarehouseV1 (2)/CircularRoofBeam");
					obj8 = ((obj9 != null) ? ((Component)obj9).gameObject : null);
				}
				GameObject val9 = (GameObject)obj8;
				if ((Object)(object)val9 != (Object)null)
				{
					val9.SetActive(false);
					Plugin.Logger.LogDebug((object)"Artifice - Hide out-of-bounds objects");
				}
				GameObject obj10 = GameObject.Find("/Environment/FireExit/FireExitDoorContainer/FireExitDoor");
				Transform val10 = ((obj10 != null) ? obj10.transform : null);
				if ((Object)(object)val10 != (Object)null)
				{
					val10.localPosition = new Vector3(12.356f, val10.localPosition.y, -13.3f);
					Plugin.Logger.LogDebug((object)"Artifice - Adjust fire exit position");
				}
				break;
			}
			case "Level10Adamance":
			{
				Plugin.Logger.LogDebug((object)"Detected landing on Adamance");
				if ((Object)(object)val2 != (Object)null)
				{
					val2.localPosition = new Vector3(-108.44491f, -3.2953954f, 8.043371f);
					Plugin.Logger.LogDebug((object)"Adamance - Fixed factory ambience");
				}
				GameObject val5 = GameObject.Find("/Environment/Props/QuicksandSign");
				if ((Object)(object)val5 != (Object)null)
				{
					BoxCollider obj4 = val5.AddComponent<BoxCollider>();
					obj4.center = new Vector3(-0.0035005957f, -0.012053336f, 2.0186164f);
					obj4.size = new Vector3(1.5744015f, 0.14966871f, 4.2035575f);
					Plugin.Logger.LogDebug((object)"Adamance - Fix sign collision");
				}
				break;
			}
			case "Level11Embrion":
				Plugin.Logger.LogDebug((object)"Detected landing on Embrion");
				if ((Object)(object)val2 != (Object)null)
				{
					val2.localPosition = new Vector3(202.6046f, 14.0158f, 3.280455f);
					Plugin.Logger.LogDebug((object)"Embrion - Fixed factory ambience");
				}
				break;
			case "CompanyBuilding":
			{
				Plugin.Logger.LogDebug((object)"Detected landing on Gordion");
				if ((Object)(object)val3 != (Object)null)
				{
					val3.SetActive(false);
					Plugin.Logger.LogDebug((object)"Gordion - Disabled \"Main entrance\" scan node");
				}
				object obj2;
				if (val == null)
				{
					obj2 = null;
				}
				else
				{
					Transform obj3 = val.Find("GiantDrill/SteelBolt");
					if (obj3 == null)
					{
						obj2 = null;
					}
					else
					{
						MeshRenderer component = ((Component)obj3).GetComponent<MeshRenderer>();
						obj2 = ((component != null) ? ((Renderer)component).sharedMaterial : null);
					}
				}
				Material val4 = (Material)obj2;
				if ((Object)(object)val4 != (Object)null)
				{
					HDMaterial.SetAlphaClipping(val4, true);
					Plugin.Logger.LogDebug((object)"Gordion - Fixed drill bolts");
				}
				break;
			}
			default:
				Plugin.Logger.LogInfo((object)"Landed on unknown moon");
				break;
			}
			if (list.Count > 0)
			{
				Transform val22 = ((val != null) ? val.Find("ModelsIntroScene") : null);
				foreach (Transform item2 in val22)
				{
					Transform val23 = item2;
					if (list.Remove(((Object)val23).name))
					{
						((Component)val23).gameObject.SetActive(false);
					}
				}
				Plugin.Logger.LogDebug((object)"Hide out-of-bounds objects (Experimentation and leftovers)");
				if (list.Count > 0)
				{
					int num2 = 0;
					foreach (string item3 in list)
					{
						Transform val24 = val22.Find(item3);
						if ((Object)(object)val24 != (Object)null)
						{
							((Component)val24).gameObject.SetActive(!((Component)val24).gameObject.activeSelf);
							num2++;
						}
					}
					if (list.Count != num2)
					{
						Plugin.Logger.LogWarning((object)$"Failed to hide {list.Count} objects:");
						foreach (string item4 in list)
						{
							Plugin.Logger.LogWarning((object)("- \"" + item4 + "\""));
						}
					}
				}
			}
			if (num > 0)
			{
				Transform val25 = ((val != null) ? val.Find("Ladder1.5x (1)") : null);
				if ((Object)(object)val25 != (Object)null)
				{
					Renderer[] componentsInChildren = ((Component)val25).GetComponentsInChildren<Renderer>();
					for (int i = 0; i < componentsInChildren.Length; i++)
					{
						componentsInChildren[i].enabled = false;
					}
					if (num >= 2)
					{
						Collider[] componentsInChildren2 = ((Component)val25).GetComponentsInChildren<Collider>();
						for (int i = 0; i < componentsInChildren2.Length; i++)
						{
							componentsInChildren2[i].enabled = false;
						}
					}
					Plugin.Logger.LogDebug((object)"Hide out-of-bounds ladder (Assurance/Offense)");
				}
			}
			if (!Compatibility.INSTALLED_GENERAL_IMPROVEMENTS)
			{
				ScanNodeProperties? obj22 = ((IEnumerable<ScanNodeProperties>)Object.FindObjectsByType<ScanNodeProperties>((FindObjectsSortMode)0)).FirstOrDefault((Func<ScanNodeProperties, bool>)((ScanNodeProperties scanNodeProperties) => scanNodeProperties.headerText == "Ship"));
				GlobalReferences.shipNode = ((obj22 != null) ? ((Component)obj22).transform : null);
				if ((Object)(object)GlobalReferences.shipNode != (Object)null)
				{
					GlobalReferences.shipNodeOffset = GlobalReferences.shipNode.position - GlobalReferences.shipDefaultPos;
				}
			}
			if ((Object)(object)StartOfRound.Instance != (Object)null)
			{
				StartOfRound.Instance.mapScreen.checkedForContourMap = false;
			}
		}
	}
	public static class ScrapTracker
	{
		private static List<GrabbableObject> allTrackedItems = new List<GrabbableObject>();

		internal static int TotalValue { get; private set; }

		internal static void Reset()
		{
			allTrackedItems.Clear();
			TotalValue = 0;
		}

		internal static void Track(GrabbableObject grabbableObject, bool addValue = true)
		{
			if ((Object)(object)GameNetworkManager.Instance == (Object)null || GameNetworkManager.Instance.isDisconnecting || (Object)(object)grabbableObject == (Object)null || (Object)(object)((NetworkBehaviour)grabbableObject).NetworkObject == (Object)null || !((NetworkBehaviour)grabbableObject).NetworkObject.IsSpawned || !grabbableObject.itemProperties.isScrap || grabbableObject.deactivated || grabbableObject.scrapPersistedThroughRounds || grabbableObject is RagdollGrabbableObject)
			{
				return;
			}
			GiftBoxItem val = (GiftBoxItem)(object)((grabbableObject is GiftBoxItem) ? grabbableObject : null);
			if (val != null && ((NetworkBehaviour)val).IsServer)
			{
				Plugin.Logger.LogDebug((object)("Scrap tracker: Can't track \"" + ((Object)grabbableObject).name + "\" with Track()"));
			}
			else if (!allTrackedItems.Contains(grabbableObject))
			{
				allTrackedItems.Add(grabbableObject);
				if (addValue)
				{
					TotalValue += grabbableObject.scrapValue;
				}
				Plugin.Logger.LogDebug((object)$"Scrap tracker: Tracking \"{((Object)grabbableObject).name}\" worth ${grabbableObject.scrapValue}");
			}
		}

		internal static void Untrack(GrabbableObject grabbableObject)
		{
			if ((Object)(object)grabbableObject != (Object)null)
			{
				allTrackedItems.Remove(grabbableObject);
			}
		}

		internal static void CountButlers()
		{
			ButlerEnemyAI[] array = Object.FindObjectsByType<ButlerEnemyAI>((FindObjectsSortMode)0);
			foreach (ButlerEnemyAI val in array)
			{
				if (!((EnemyAI)val).isEnemyDead)
				{
					GameObject knifePrefab = val.knifePrefab;
					KnifeItem val2 = ((knifePrefab != null) ? knifePrefab.GetComponent<KnifeItem>() : null);
					if ((Object)(object)val2 != (Object)null)
					{
						TotalValue += ((GrabbableObject)val2).scrapValue;
						Plugin.Logger.LogDebug((object)$"Did not kill Butler (${((GrabbableObject)val2).scrapValue})");
					}
				}
			}
		}

		internal static void TrackGiftBoxOnServer(GiftBoxItem giftBoxItem)
		{
			if (!((Object)(object)GameNetworkManager.Instance == (Object)null) && !GameNetworkManager.Instance.isDisconnecting && !allTrackedItems.Contains((GrabbableObject)(object)giftBoxItem))
			{
				allTrackedItems.Add((GrabbableObject)(object)giftBoxItem);
				TotalValue = Mathf.Max(TotalValue + ((GrabbableObject)giftBoxItem).scrapValue, TotalValue + giftBoxItem.objectInPresentValue);
			}
		}

		public static void TrackGiftBoxOnClient(GiftBoxItem giftBoxItem, GrabbableObject objectInPresent)
		{
			if ((Object)(object)GameNetworkManager.Instance == (Object)null || GameNetworkManager.Instance.isDisconnecting)
			{
				return;
			}
			if ((Object)(object)giftBoxItem == (Object)null)
			{
				Plugin.Logger.LogWarning((object)"Gift box is null on client after being opened");
				return;
			}
			try
			{
				if (!allTrackedItems.Contains((GrabbableObject)(object)giftBoxItem))
				{
					allTrackedItems.Add((GrabbableObject)(object)giftBoxItem);
					if (((GrabbableObject)giftBoxItem).scrapValue > 0)
					{
						TotalValue += ((GrabbableObject)giftBoxItem).scrapValue;
					}
				}
				if (((GrabbableObject)giftBoxItem).isInShipRoom)
				{
					RoundManager.Instance.scrapCollectedInLevel = Mathf.Max(RoundManager.Instance.scrapCollectedInLevel - ((GrabbableObject)giftBoxItem).scrapValue, 0);
				}
				if ((Object)(object)objectInPresent != (Object)null)
				{
					if (!allTrackedItems.Contains(objectInPresent))
					{
						allTrackedItems.Add(objectInPresent);
					}
					if (((GrabbableObject)giftBoxItem).isInShipRoom || objectInPresent.isInShipRoom || (Object)(object)((Component)objectInPresent).transform.parent == (Object)(object)StartOfRound.Instance.elevatorTransform)
					{
						RoundManager.Instance.CollectNewScrapForThisRound(objectInPresent);
					}
				}
				if (!((NetworkBehaviour)giftBoxItem).IsServer)
				{
					TotalValue = Mathf.Max(TotalValue - Mathf.Max(((GrabbableObject)giftBoxItem).scrapValue, 0) + (((Object)(object)objectInPresent != (Object)null) ? objectInPresent.scrapValue : 0), TotalValue);
				}
			}
			catch (Exception arg)
			{
				Plugin.Logger.LogWarning((object)$"An error occurred while trying to open gift box on client\n{arg}");
			}
		}
	}
	internal static class ScriptableObjectOverrides
	{
		internal static void OverrideEnemyTypes()
		{
			//IL_04bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_0418: Unknown result type (might be due to invalid IL or missing references)
			//IL_0428: Unknown result type (might be due to invalid IL or missing references)
			//IL_0432: Unknown result type (might be due to invalid IL or missing references)
			//IL_0358: Unknown result type (might be due to invalid IL or missing references)
			//IL_0363: Unknown result type (might be due to invalid IL or missing references)
			//IL_0378: Unknown result type (might be due to invalid IL or missing references)
			//IL_0380: Unknown result type (might be due to invalid IL or missing references)
			//IL_0391: Unknown result type (might be due to invalid IL or missing references)
			//IL_0396: Unknown result type (might be due to invalid IL or missing references)
			//IL_039b: 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_03b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03be: Unknown result type (might be due to invalid IL or missing references)
			string[] array = new string[2] { "BushWolf", "GiantKiwi" };
			foreach (KeyValuePair<string, EnemyType> allEnemies in GlobalReferences.allEnemiesList)
			{
				bool flag = false;
				switch (allEnemies.Key)
				{
				case "RadMech":
				{
					ScanNodeProperties componentInChildren2 = allEnemies.Value.nestSpawnPrefab.GetComponentInChildren<ScanNodeProperties>();
					if ((Object)(object)componentInChildren2 != (Object)null)
					{
						componentInChildren2.requiresLineOfSight = false;
						((Component)componentInChildren2).transform.localPosition = new Vector3(0f, ((Component)componentInChildren2).transform.localPosition.y, 0f);
						Plugin.Logger.LogDebug((object)(allEnemies.Value.enemyName + ": Scan on both sides"));
					}
					break;
				}
				case "Blob":
					if (!Compatibility.INSTALLED_EVERYTHING_CAN_DIE)
					{
						allEnemies.Value.canDie = false;
						Plugin.Logger.LogDebug((object)(allEnemies.Value.enemyName + ": Don't \"die\" when crushed by spike trap"));
					}
					break;
				case "ForestGiant":
				{
					ScanNodeProperties componentInChildren = allEnemies.Value.enemyPrefab.GetComponentInChildren<ScanNodeProperties>();
					if ((Object)(object)componentInChildren != (Object)null)
					{
						componentInChildren.headerText = "Forest Keeper";
						Plugin.Logger.LogDebug((object)(allEnemies.Value.enemyName + ": Rename scan node"));
					}
					break;
				}
				case "ClaySurgeon":
				case "DressGirl":
					flag = true;
					break;
				case "CaveDweller":
					((GrabbableObject)allEnemies.Value.enemyPrefab.GetComponent<CaveDwellerPhysicsProp>()).itemProperties.isConductiveMetal = false;
					Plugin.Logger.LogDebug((object)("Conductive: " + allEnemies.Value.enemyName + " (False)"));
					break;
				case "SandWorm":
					allEnemies.Value.canBeDestroyed = false;
					Plugin.Logger.LogDebug((object)(allEnemies.Value.enemyName + ": Don't get eaten by other worms"));
					break;
				case "SpringMan":
				{
					GameObject enemyPrefab2 = allEnemies.Value.enemyPrefab;
					Transform val = ((enemyPrefab2 != null) ? enemyPrefab2.transform.Find("SpringManModel/MapDot (2)") : null);
					if ((Object)(object)val != (Object)null)
					{
						float num = (val.localScale.x + val.localScale.z) / 2f;
						Transform obj = val;
						obj.localPosition += (num - val.localScale.y / 2f) * Vector3.up;
						val.localScale = new Vector3(val.localScale.x, num, val.localScale.z);
						Plugin.Logger.LogDebug((object)(allEnemies.Value.enemyName + ": Fix radar appearance"));
					}
					break;
				}
				case "Crawler":
				{
					GameObject enemyPrefab = allEnemies.Value.enemyPrefab;
					Transform val = ((enemyPrefab != null) ? enemyPrefab.transform.Find("CrawlerModel/MapDot") : null);
					if ((Object)(object)val != (Object)null)
					{
						val.localPosition = new Vector3(val.localPosition.x, 2f, val.localPosition.z);
						Plugin.Logger.LogDebug((object)(allEnemies.Value.enemyName + ": Fix radar appearance"));
					}
					break;
				}
				}
				allEnemies.Value.numberSpawned = 0;
				allEnemies.Value.hasSpawnedAtLeastOne = false;
				if ((Object)(object)allEnemies.Value.enemyPrefab != (Object)null && Array.IndexOf(array, allEnemies.Key) < 0)
				{
					LODGroup[] componentsInChildren = allEnemies.Value.enemyPrefab.GetComponentsInChildren<LODGroup>();
					foreach (LODGroup val2 in componentsInChildren)
					{
						if ((int)val2.fadeMode != 0)
						{
							val2.fadeMode = (LODFadeMode)0;
							Plugin.Logger.LogDebug((object)(allEnemies.Value.enemyName + ": Fixed LOD fade for \"" + ((Object)val2).name + "\""));
						}
					}
				}
				if (!flag)
				{
					continue;
				}
				Renderer[] componentsInChildren2 = allEnemies.Value.enemyPrefab.GetComponentsInChildren<Renderer>();
				foreach (Renderer val3 in componentsInChildren2)
				{
					if (((Component)val3).gameObject.layer == 19)
					{
						val3.shadowCastingMode = (ShadowCastingMode)0;
					}
				}
			}
		}

		internal static void OverrideSelectableLevels()
		{
			SelectableLevel[] levels = StartOfRound.Instance.levels;
			foreach (SelectableLevel val in levels)
			{
				switch (((Object)val).name)
				{
				case "VowLevel":
					val.LevelDescription = val.LevelDescription.Replace("Rough terrain. Teeming with plant-life.", "Rough terrain.").Replace("A competitive ecosystem supports aggressive lifeforms.", "Diverse, teeming with plant-life.");
					Plugin.Logger.LogDebug((object)"Vow: Description");
					break;
				case "OffenseLevel":
					if ((Object)(object)val.videoReel != (Object)null && ((Object)val.videoReel).name == "MapView220Ass")
					{
						val.videoReel = null;
						Plugin.Logger.LogDebug((object)"Offense: Video reel");
					}
					break;
				case "TitanLevel":
					if (!Chainloader.PluginInfos.ContainsKey("AutoScroll"))
					{
						val.LevelDescription = val.LevelDescription.Replace("This moon was mined for resources. It's easy to get lost here.", "It's easy to get lost here.").Replace("Dangerous entities have been rumored to take residence in the vast network of tunnels.", "Dangerous entities rumored to reside in its vast tunnels.");
						Plugin.Logger.LogDebug((object)"Titan: Description");
					}
					break;
				case "EmbrionLevel":
					val.LevelDescription = val.LevelDescription.Replace("Embrion is devoid", "Devoid");
					Plugin.Logger.LogDebug((object)"Embrion: Description");
					break;
				}
			}
		}

		internal static void OverrideItems()
		{
			//IL_051e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0407: Unknown result type (might be due to invalid IL or missing references)
			//IL_040c: Unknown result type (might be due to invalid IL or missing references)
			//IL_040e: Unknown result type (might be due to invalid IL or missing references)
			//IL_041f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0458: Unknown result type (might be due to invalid IL or missing references)
			//IL_0466: Unknown result type (might be due to invalid IL or missing references)
			Dictionary<string, bool> dictionary = new Dictionary<string, bool>
			{
				{ "ControlPad", false },
				{ "DustPan", true },
				{ "FancyCup", true },
				{ "LockPicker", true },
				{ "Shotgun", true },
				{ "SprayPaint", true }
			};
			Dictionary<string, bool> dictionary2 = new Dictionary<string, bool>
			{
				{ "Airhorn", false },
				{ "CashRegister", false },
				{ "ChemicalJug", true },
				{ "ClownHorn", false },
				{ "ComedyMask", false },
				{ "RubberDuck", false },
				{ "TragedyMask", false }
			};
			Dictionary<string, bool> dictionary3 = new Dictionary<string, bool>
			{
				{ "BabyKiwiEgg", false },
				{ "PillBottle", true },
				{ "SodaCanRed", true },
				{ "SprayPaint", true },
				{ "WeedKillerBottle", true }
			};
			foreach (Item items in StartOfRound.Instance.allItemsList.itemsList)
			{
				if ((Object)(object)items == (Object)null)
				{
					Plugin.Logger.LogWarning((object)"Encountered a missing item in StartOfRound.allItemsList; this is probably an issue with another mod");
					continue;
				}
				GameObject spawnPrefab = items.spawnPrefab;
				ScanNodeProperties val = ((spawnPrefab != null) ? spawnPrefab.GetComponentInChildren<ScanNodeProperties>() : null);
				switch (((Object)items).name)
				{
				case "BabyKiwiEgg":
					((GrabbableObject)items.spawnPrefab.GetComponent<KiwiBabyItem>()).isInFactory = false;
					Plugin.Logger.LogDebug((object)"Factory: Egg");
					break;
				case "BottleBin":
				{
					GameObject spawnPrefab4 = items.spawnPrefab;
					object obj5;
					if (spawnPrefab4 == null)
					{
						obj5 = null;
					}
					else
					{
						Transform obj6 = spawnPrefab4.transform.Find("BinFullOfBottles_lowDetail");
						obj5 = ((obj6 != null) ? ((Component)obj6).GetComponent<Renderer>() : null);
					}
					Renderer val2 = (Renderer)obj5;
					if ((Object)(object)val2 != (Object)null && val2.sharedMaterials != null && val2.sharedMaterials.Length == 2 && (Object)(object)val2.sharedMaterials[1] != (Object)null && ((Object)val2.sharedMaterials[1]).name.StartsWith("BottleBin"))
					{
						Vector2 textureScale = val2.sharedMaterials[1].GetTextureScale("_BaseColorMap");
						if (textureScale.x == 2f && textureScale.y == 0.4f)
						{
							((Vector2)(ref textureScale))..ctor(8.2f, 0.7f);
							Material val4 = Object.Instantiate<Material>(val2.sharedMaterials[1]);
							val4.SetTextureScale("_BaseColorMap", textureScale);
							val4.SetTextureScale("_MainTex", textureScale);
							val2.sharedMaterials = (Material[])(object)new Material[2]
							{
								val2.sharedMaterials[0],
								val4
							};
							Plugin.Logger.LogDebug((object)"LoD: Bottles");
						}
					}
					break;
				}
				case "CashRegister":
					if (Configuration.adjustCooldowns.Value)
					{
						((GrabbableObject)items.spawnPrefab.GetComponent<NoisemakerProp>()).useCooldown = 2.35f;
						Plugin.Logger.LogDebug((object)"Cooldown: Cash register");
					}
					break;
				case "ClownHorn":
					if (Configuration.adjustCooldowns.Value)
					{
						((GrabbableObject)items.spawnPrefab.GetComponent<NoisemakerProp>()).useCooldown = 0.35f;
						Plugin.Logger.LogDebug((object)"Cooldown: Clown horn");
					}
					break;
				case "ExtensionLadder":
					items.spawnPrefab.GetComponentInChildren<KillLocalPlayer>().causeOfDeath = (CauseOfDeath)1;
					Plugin.Logger.LogDebug((object)"Cause of death: Extension ladder");
					break;
				case "FancyLamp":
					items.verticalOffset = 0f;
					break;
				case "ProFlashlight":
				case "Flashlight":
				{
					FlashlightItem component2 = items.spawnPrefab.GetComponent<FlashlightItem>();
					Material[] sharedMaterials = ((Renderer)component2.flashlightMesh).sharedMaterials;
					sharedMaterials[1] = component2.bulbDark;
					((Renderer)component2.flashlightMesh).sharedMaterials = sharedMaterials;
					Plugin.Logger.LogDebug((object)("Bulb off: " + items.itemName));
					break;
				}
				case "Hairdryer":
					if (Configuration.adjustCooldowns.Value)
					{
						((GrabbableObject)items.spawnPrefab.GetComponent<NoisemakerProp>()).useCooldown = 1.35f;
						Plugin.Logger.LogDebug((object)"Cooldown: Hairdryer");
					}
					break;
				case "Knife":
				{
					KnifeItem component3 = items.spawnPrefab.GetComponent<KnifeItem>();
					if ((Object)(object)val != (Object)null)
					{
						val.scrapValue = ((GrabbableObject)component3).scrapValue;
						val.subText = $"Value: ${val.scrapValue}";
						Plugin.Logger.LogDebug((object)"Scan node: Kitchen knife");
					}
					break;
				}
				case "RedLocustHive":
					((GrabbableObject)items.spawnPrefab.GetComponent<PhysicsProp>()).isInFactory = false;
					Plugin.Logger.LogDebug((object)"Factory: Hive");
					break;
				case "SeveredHeart":
				{
					LoopShapeKey[] componentsInChildren = items.spawnPrefab.GetComponentsInChildren<LoopShapeKey>();
					if (componentsInChildren != null && componentsInChildren.Length != 0)
					{
						LoopShapeKey[] array = componentsInChildren;
						foreach (LoopShapeKey val3 in array)
						{
							if ((Object)(object)((Component)val3).GetComponent<HeartHack>() == (Object)null)
							{
								((Component)val3).gameObject.AddComponent<HeartHack>().loopShapeKey = val3;
							}
						}
						Plugin.Logger.LogDebug((object)"Animation: Heart");
					}
					LODGroup component = items.spawnPrefab.GetComponent<LODGroup>();
					LOD[] lODs = component.GetLODs();
					if (lODs.Length > 1 && (lODs[1].renderers.Length < 1 || (Object)(object)lODs[1].renderers[0] == (Object)null))
					{
						ref LOD reference = ref lODs[1];
						Renderer[] array2 = new Renderer[1];
						GameObject spawnPrefab3 = items.spawnPrefab;
						object obj3;
						if (spawnPrefab3 == null)
						{
							obj3 = null;
						}
						else
						{
							Transform obj4 = spawnPrefab3.transform.Find("HeartLOD1");
							obj3 = ((obj4 != null) ? ((Component)obj4).GetComponent<Renderer>() : null);
						}
						array2[0] = (Renderer)obj3;
						reference.renderers = (Renderer[])(object)array2;
						component.SetLODs(lODs);
						component.size = 55f;
						Plugin.Logger.LogDebug((object)"LoDs: Heart");
					}
					break;
				}
				case "SeveredThigh":
				{
					GameObject spawnPrefab2 = items.spawnPrefab;
					object obj;
					if (spawnPrefab2 == null)
					{
						obj = null;
					}
					else
					{
						Transform obj2 = spawnPrefab2.transform.Find("SeveredThighLOD1");
						obj = ((obj2 != null) ? ((Component)obj2).GetComponent<MeshRenderer>() : null);
					}
					Renderer val2 = (Renderer)obj;
					if ((Object)(object)val2 != (Object)null && val2.sharedMaterials != null && val2.sharedMaterials.Length == 4 && (Object)(object)val2.sharedMaterials[1] != (Object)null && ((Object)val2.sharedMaterials[1]).name.Contains("Bone") && (Object)(object)val2.sharedMaterials[2] != (Object)null && ((Object)val2.sharedMaterials[2]).name.Contains("Hand"))
					{
						val2.sharedMaterials = (Material[])(object)new Material[4]
						{
							val2.sharedMaterials[0],
							val2.sharedMaterials[2],
							val2.sharedMaterials[1],
							val2.sharedMaterials[3]
						};
						Plugin.Logger.LogDebug((object)"LoD: Knee");
					}
					break;
				}
				case "SeveredTongue":
					items.syncDiscardFunction = true;
					Plugin.Logger.LogDebug((object)"Sync: Tongue");
					break;
				}
				if ((Object)(object)items.spawnPrefab != (Object)null)
				{
					bool flag = false;
					Renderer[] componentsInChildren2 = items.spawnPrefab.GetComponentsInChildren<Renderer>();
					foreach (Renderer val5 in componentsInChildren2)
					{
						if (val5.enabled && ((Component)val5).gameObject.layer == 13)
						{
							val5.enabled = false;
							flag = true;
						}
					}
					if (flag)
					{
						Plugin.Logger.LogDebug((object)("Invisible trigger: " + items.itemName));
					}
					if ((Object)(object)items.spawnPrefab.GetComponent<Rigidbody>() != (Object)null && (Object)(object)val != (Object)null && (Object)(object)((Component)val).GetComponent<Rigidbody>() == (Object)null)
					{
						((Component)val).gameObject.AddComponent<Rigidbody>().isKinematic = true;
						Plugin.Logger.LogDebug((object)("Scan node rigidbody: " + items.itemName));
					}
				}
				if (dictionary3.ContainsKey(((Object)items).name))
				{
					items.canBeInspected = dictionary3[((Object)items).name];
					Plugin.Logger.LogDebug((object)$"Inspectable: {items.itemName} ({items.canBeInspected})");
				}
				if (items.canBeInspected)
				{
					if (items.toolTips == null)
					{
						Plugin.Logger.LogWarning((object)("Item \"" + ((Object)items).name + "\" is missing toolTips"));
					}
					else if (items.toolTips.Length < 3)
					{
						bool flag2 = false;
						string[] toolTips = items.toolTips;
						for (int i = 0; i < toolTips.Length; i++)
						{
							if (toolTips[i].StartsWith("Inspect"))
							{
								flag2 = true;
								break;
							}
						}
						if (!flag2)
						{
							items.toolTips = CollectionExtensions.AddToArray<string>(items.toolTips, "Inspect : [Z]");
							Plugin.Logger.LogDebug((object)("Inspect tooltip: " + items.itemName));
						}
					}
				}
				if (dictionary.ContainsKey(((Object)items).name))
				{
					items.isConductiveMetal = dictionary[((Object)items).name] && Configuration.makeConductive.Value;
					Plugin.Logger.LogDebug((object)$"Conductive: {items.itemName} ({items.isConductiveMetal})");
				}
				if (dictionary2.ContainsKey(((Object)items).name) && !Compatibility.INSTALLED_GENERAL_IMPROVEMENTS)
				{
					items.canBeGrabbedBeforeGameStart = dictionary2[((Object)items).name];
					Plugin.Logger.LogDebug((object)$"Hold before ship has landed: {items.itemName} ({items.canBeGrabbedBeforeGameStart})");
				}
			}
		}

		internal static void RenameItems()
		{
			foreach (Item items in StartOfRound.Instance.allItemsList.itemsList)
			{
				GameObject spawnPrefab = items.spawnPrefab;
				ScanNodeProperties val = ((spawnPrefab != null) ? spawnPrefab.GetComponentInChildren<ScanNodeProperties>() : null);
				string name = ((Object)items).name;
				if (!(name == "FancyCup"))
				{
					if (name == "Flask" && Configuration.chemistryFlasks.Value)
					{
						if ((Object)(object)val != (Object)null)
						{
							val.headerText = val.headerText.Replace("Flask", "Chemistry flask");
							Plugin.Logger.LogDebug((object)"Scan node: Flask");
						}
						items.itemName = items.itemName.Replace("Flask", "Chemistry flask");
						Plugin.Logger.LogDebug((object)"Name: Flask");
					}
				}
				else if (Configuration.theGoldenGoblet.Value)
				{
					if ((Object)(object)val != (Object)null)
					{
						val.headerText = val.headerText.Replace("Golden cup", "Golden goblet");
						Plugin.Logger.LogDebug((object)"Scan node: Golden cup");
					}
					items.itemName = items.itemName.Replace("Golden cup", "Golden goblet");
					Plugin.Logger.LogDebug((object)"Name: Golden cup");
				}
			}
		}

		internal static void OverrideUnlockables()
		{
			foreach (UnlockableItem unlockable in StartOfRound.Instance.unlockablesList.unlockables)
			{
				switch (unlockable.unlockableName)
				{
				case "JackOLantern":
				{
					if (Configuration.adjustCooldowns.Value)
					{
						unlockable.prefabObject.GetComponentInChildren<InteractTrigger>().cooldownTime = 0.45f;
						Plugin.Logger.LogDebug((object)"Cooldown: Jack o' Lantern");
					}
					Transform val2 = unlockable.prefabObject.transform.Find("PumpkinMesh");
					if ((Object)(object)val2 != (Object)null)
					{
						MeshFilter component = ((Component)val2).GetComponent<MeshFilter>();
						GlobalReferences.sphere = ((component != null) ? component.sharedMesh : null);
						MeshRenderer component2 = ((Component)val2).GetComponent<MeshRenderer>();
						GlobalReferences.pumpkinMatPlastic = ((component2 != null) ? ((Renderer)component2).sharedMaterial : null);
					}
					break;
				}
				case "Plushie pajama man":
					if (Configuration.adjustCooldowns.Value)
					{
						unlockable.prefabObject.GetComponentInChildren<InteractTrigger>().cooldownTime = 0.2f;
						Plugin.Logger.LogDebug((object)"Cooldown: Plushie pajama man");
					}
					break;
				case "Inverse Teleporter":
					if (!Compatibility.INSTALLED_GENERAL_IMPROVEMENTS)
					{
						InteractTrigger buttonTrigger = unlockable.prefabObject.GetComponentInChildren<ShipTeleporter>().buttonTrigger;
						buttonTrigger.hoverTip = buttonTrigger.hoverTip.Replace("Beam up", "Beam out");
						Plugin.Logger.LogDebug((object)"Text: Inverse teleporter");
					}
					break;
				case "Microwave":
				{
					Transform obj = unlockable.prefabObject.transform.Find("MicrowaveBody");
					((Component)obj).gameObject.layer = 8;
					Plugin.Logger.LogDebug((object)"Collision: Microwave");
					InteractTrigger component3 = ((Component)obj.Find("MicrowaveDoor/DoorButtonClose")).GetComponent<InteractTrigger>();
					component3.hoverTip = component3.hoverTip.Replace("Store item", "Use microwave");
					Plugin.Logger.LogDebug((object)"Text: Microwave");
					break;
				}
				case "Fridge":
				{
					Transform[] componentsInChildren = unlockable.prefabObject.GetComponentsInChildren<Transform>();
					foreach (Transform val in componentsInChildren)
					{
						if (((Object)val).name == "FridgeBody" || ((Component)val).gameObject.layer == 6)
						{
							((Component)val).gameObject.layer = 8;
						}
						else if ((Object)(object)((Component)val).GetComponent<PlaceableObjectsSurface>() != (Object)null)
						{
							((Component)val).GetComponent<Collider>().isTrigger = false;
						}
					}
					Plugin.Logger.LogDebug((object)"Collision: Fridge");
					break;
				}
				}
			}
		}
	}
	internal static class TileOverrides
	{
		private static readonly Vector3 MINESHAFT_FIRE_EXIT_SCALE = new Vector3(1.176471f, 1.176471f, 1.176471f);

		internal static void OverrideTiles(IndoorMapType[] indoorMapTypes)
		{
			//IL_04d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0689: Unknown result type (might be due to invalid IL or missing references)
			//IL_0785: Unknown result type (might be due to invalid IL or missing references)
			//IL_0288: Unknown result type (might be due to invalid IL or missing references)
			//IL_0293: Unknown result type (might be due to invalid IL or missing references)
			//IL_029d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0710: Unknown result type (might be due to invalid IL or missing references)
			//IL_06af: Unknown result type (might be due to invalid IL or missing references)
			//IL_06ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_06c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_09aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_09b0: Invalid comparison between Unknown and I4
			//IL_09fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b6e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b79: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b88: Unknown result type (might be due to invalid IL or missing references)
			//IL_0bd5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0be0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0bef: Unknown result type (might be due to invalid IL or missing references)
			//IL_080b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0831: Unknown result type (might be due to invalid IL or missing references)
			//IL_083c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0846: Unknown result type (might be due to invalid IL or missing references)
			//IL_08c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_08d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_08e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_08eb: 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_03b5: Unknown result type (might be due to invalid IL or missing references)
			Transform val = null;
			Transform val2 = null;
			Transform val3 = null;
			Transform val4 = null;
			bool flag = false;
			bool flag2 = false;
			foreach (GameObject allTile in GetAllTiles(indoorMapTypes))
			{
				switch (((Object)allTile).name)
				{
				case "DoubleDoorRoom":
					flag = true;
					break;
				case "MediumRoomHallway1B":
					flag = true;
					val4 = allTile.transform.Find("Vents (2)/Vent (1)");
					if ((Object)(object)val4 != (Object)