Decompiled source of ButteryFixes v1.10.8

ButteryFixes.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
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 Microsoft.CodeAnalysis;
using TMPro;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.Rendering;
using UnityEngine.Rendering.HighDefinition;
using UnityEngine.SceneManagement;

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace ButteryFixes
{
	internal class Compatibility
	{
		internal const string GUID_FAST_CLIMBING = "inoyu.FastClimbing";

		internal const string GUID_BETTER_LADDERS = "e3s1.BetterLadders";

		internal const string GUID_GENERAL_IMPROVEMENTS = "ShaosilGaming.GeneralImprovements";

		internal const string GUID_MODEL_REPLACEMENT_API = "meow.ModelReplacementAPI";

		internal const string GUID_STARLANCER_AI_FIX = "AudioKnight.StarlancerAIFix";

		internal const string GUID_BETTER_SPRAY_PAINT = "taffyko.BetterSprayPaint";

		internal const string GUID_EVERYTHING_CAN_DIE = "nwnt.EverythingCanDie";

		internal const string GUID_LETHAL_QUANTITIES = "LethalQuantities";

		internal const string GUID_ARTIFICE_BLIZZARD = "butterystancakes.lethalcompany.artificeblizzard";

		internal const string GUID_CELESTIAL_TINT = "CelestialTint";

		internal static bool INSTALLED_GENERAL_IMPROVEMENTS;

		internal static bool INSTALLED_EVERYTHING_CAN_DIE;

		internal static bool INSTALLED_LETHAL_QUANTITIES;

		internal static bool INSTALLED_ARTIFICE_BLIZZARD;

		internal static bool DISABLE_LADDER_PATCH;

		internal static bool DISABLE_PLAYERMODEL_PATCHES;

		internal static bool DISABLE_ENEMY_MESH_PATCH;

		internal static bool DISABLE_SPRAY_PAINT_PATCHES;

		internal static bool DISABLE_SUN;

		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("inoyu.FastClimbing") || Chainloader.PluginInfos.ContainsKey("e3s1.BetterLadders"))
			{
				Plugin.Logger.LogInfo((object)"CROSS-COMPATIBILITY - Ladder patch will be disabled");
				DISABLE_LADDER_PATCH = true;
			}
			if (Chainloader.PluginInfos.ContainsKey("meow.ModelReplacementAPI"))
			{
				DISABLE_PLAYERMODEL_PATCHES = true;
				Plugin.Logger.LogInfo((object)"CROSS-COMPATIBILITY - Playermodel patches will be disabled");
			}
			if (Chainloader.PluginInfos.ContainsKey("AudioKnight.StarlancerAIFix"))
			{
				DISABLE_ENEMY_MESH_PATCH = true;
				Plugin.Logger.LogInfo((object)"CROSS-COMPATIBILITY - EnableEnemyMesh patch will be disabled");
			}
			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("LethalQuantities"))
			{
				INSTALLED_LETHAL_QUANTITIES = true;
				Plugin.Logger.LogInfo((object)"CROSS-COMPATIBILITY - Lethal Quantities detected");
			}
			if (Chainloader.PluginInfos.ContainsKey("butterystancakes.lethalcompany.artificeblizzard"))
			{
				INSTALLED_ARTIFICE_BLIZZARD = true;
				Plugin.Logger.LogInfo((object)"CROSS-COMPATIBILITY - Artifice Blizzard detected");
			}
			if (Chainloader.PluginInfos.ContainsKey("CelestialTint"))
			{
				DISABLE_SUN = true;
				Plugin.Logger.LogInfo((object)"CROSS-COMPATIBILITY - Celestial Tint detected");
			}
		}
	}
	internal enum MusicDopplerLevel
	{
		Vanilla = -1,
		None,
		Reduced
	}
	internal enum GameResolution
	{
		DontChange = -1,
		Low,
		High
	}
	internal class Configuration
	{
		private static ConfigFile configFile;

		internal static ConfigEntry<MusicDopplerLevel> musicDopplerLevel;

		internal static ConfigEntry<GameResolution> gameResolution;

		internal static ConfigEntry<bool> makeConductive;

		internal static ConfigEntry<bool> maskHornetsPower;

		internal static ConfigEntry<bool> fixJumpCheese;

		internal static ConfigEntry<bool> keysAreScrap;

		internal static ConfigEntry<bool> showApparatusValue;

		internal static ConfigEntry<bool> randomizeDefaultSeed;

		internal static ConfigEntry<bool> scanOnShip;

		internal static ConfigEntry<bool> fixFireExits;

		internal static ConfigEntry<bool> unlimitedOldBirds;

		internal static ConfigEntry<bool> restoreShipIcon;

		internal static ConfigEntry<bool> limitSpawnChance;

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

		private static void GameplayConfig()
		{
			randomizeDefaultSeed = configFile.Bind<bool>("Gameplay", "RandomizeDefaultSeed", true, "(Host only) Randomizes the seed when starting a new save file, rather than always using the default of 0. (This changes starting weather and shop sales.)");
			fixFireExits = configFile.Bind<bool>("Gameplay", "FixFireExits", true, "Fix fire exit rotation so you are always facing away from the door when you leave. This applies to interiors, as well as the exteriors of the original game's moons.");
			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.");
			keysAreScrap = configFile.Bind<bool>("Gameplay", "KeysAreScrap", false, "(Host only) Enabling this will allow you to sell keys for $3 as listed, but will also cause them to be lost if all players die. If this is disabled, they will no longer show \"Value: $3\" on the scanner, instead.");
			limitSpawnChance = configFile.Bind<bool>("Gameplay", "LimitSpawnChance", true, "(Host only) Prevents enemy spawn weight from exceeding 100 (likely the intended maximum) if its spawn curves would normally allow it to do so.\nThis will prevent some enemy types from spawning out of control on certain maps.");
			unlimitedOldBirds = configFile.Bind<bool>("Gameplay", "UnlimitedOldBirds", false, "(Host only) Allows Old Birds to continue spawning even once all the ones presently on the map have \"woken up\", like in vanilla. This will cause them to appear out of nowhere, since they don't have a proper spawning animation\nThis will also allow outdoor spawns to \"overflow\" when you unplug the apparatus, since that doesn't add Old Birds to the power count in vanilla.");
			maskHornetsPower = configFile.Bind<bool>("Gameplay", "MaskHornetsPower", false, "(Host only) Mask hornets internally have the same power level as butlers, but because they spawn in a non-standard way, they don't contribute to the indoor power. Enabling this will prevent additional monsters spawning to replace dead butlers.");
			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.");
		}

		private static void VisualConfig()
		{
			gameResolution = configFile.Bind<GameResolution>("Visual", "GameResolution", GameResolution.DontChange, "The internal resolution rendered by the game. There are unused resolution presets in the game data that you can enable using this option.\n\"DontChange\" makes no changes - vanilla is 860x520, but this setting is also compatible with other resolution mods.\n\"Low\" is 620x350. \"High\" is 970x580.");
			restoreShipIcon = configFile.Bind<bool>("Visual", "RestoreShipIcon", true, "Show the ship icon on the radar (next to the compass) when it is following an outside player. This doesn't display properly in vanilla (bug?)");
			showApparatusValue = configFile.Bind<bool>("Visual", "ShowApparatusValue", false, "Actually show the apparatus' value on the scanner instead of \"???\" (in vanilla, it is always $80)");
		}

		private static void AudioConfig()
		{
			musicDopplerLevel = configFile.Bind<MusicDopplerLevel>("Audio", "MusicDopplerLevel", MusicDopplerLevel.Reduced, "Controls how much Unity's simulated \"Doppler effect\" applies to music sources like the dropship, boombox, etc. (This is what causes pitch distortion when moving towards/away from the source of the music)\n\"Vanilla\" makes no changes. \"Reduced\" will make the effect more subtle. \"None\" will disable it completely (so music always plays at the correct pitch)");
		}

		private static void ExtraConfig()
		{
			scanOnShip = configFile.Bind<bool>("Extra", "ScanOnShip", false, "Allows the \"scan\" command on the terminal to count the number and value of the items on your ship, when in orbit or parked at Gordion.");
		}

		private static void MigrateLegacyConfigs()
		{
			configFile.Bind<bool>("Gameplay", "KillOldBirds", true, "Legacy setting, doesn't work");
			configFile.Remove(configFile["Gameplay", "KillOldBirds"].Definition);
			configFile.Bind<bool>("Visual", "FancyEntranceDoors", false, "Legacy setting, use \"Chameleon\" instead");
			configFile.Remove(configFile["Visual", "FancyEntranceDoors"].Definition);
		}
	}
	[BepInPlugin("butterystancakes.lethalcompany.butteryfixes", "Buttery Fixes", "1.10.8")]
	[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
	{
		private const string PLUGIN_GUID = "butterystancakes.lethalcompany.butteryfixes";

		private const string PLUGIN_NAME = "Buttery Fixes";

		private const string PLUGIN_VERSION = "1.10.8";

		internal static ManualLogSource Logger;

		private void Awake()
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			Logger = ((BaseUnityPlugin)this).Logger;
			Compatibility.Init();
			Configuration.Init(((BaseUnityPlugin)this).Config);
			new Harmony("butterystancakes.lethalcompany.butteryfixes").PatchAll();
			SceneManager.sceneLoaded += SceneOverrides.OnSceneLoaded;
			Logger.LogInfo((object)"Buttery Fixes v1.10.8 loaded");
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "ButteryFixes";

		public const string PLUGIN_NAME = "ButteryFixes";

		public const string PLUGIN_VERSION = "1.10.8";
	}
}
namespace ButteryFixes.Utility
{
	internal static class GlobalReferences
	{
		internal const int NUM_LEVELS = 13;

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

		internal static float dopplerLevelMult = 1f;

		internal static Mesh tragedyMask;

		internal static Mesh tragedyMaskLOD;

		internal static Mesh tragedyMaskEyesFilled;

		internal static Material tragedyMaskMat;

		internal static AudioClip[] tragedyMaskRandomClips;

		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 bool patchScanNodes;

		internal static int scrapNotCollected = -1;

		internal static int scrapEaten;

		internal static Animator shipAnimator;

		internal static AudioClip[] woodenDoorOpen;

		internal static AudioClip[] woodenDoorClose;

		internal static Light sunlight;
	}
	public static class NonPatchFunctions
	{
		internal static bool[] playerWasLastSprinting = new bool[50];

		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})");
		}

		public static void ShotgunPreProcess(Vector3 shotgunPosition, ref int num, ref RaycastHit[] results)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			int num2 = 0;
			HashSet<EnemyAI> hashSet = new HashSet<EnemyAI>();
			List<RaycastHit> list = new List<RaycastHit>();
			List<RaycastHit> list2 = new List<RaycastHit>();
			list2.AddRange(from hit in results.Take(num)
				orderby Vector3.Distance(shotgunPosition, ((RaycastHit)(ref hit)).point)
				select hit);
			RaycastHit[] array = list2.ToArray();
			EnemyAICollisionDetect val = default(EnemyAICollisionDetect);
			for (int i = 0; i < num; i++)
			{
				if (!((Component)((RaycastHit)(ref array[i])).transform).TryGetComponent<EnemyAICollisionDetect>(ref val) || val.onlyCollideWhenGrounded)
				{
					continue;
				}
				EnemyAI mainScript = val.mainScript;
				if (!hashSet.Add(mainScript))
				{
					continue;
				}
				EnemyType enemyType = mainScript.enemyType;
				if (!enemyType.canDie || ((Object)enemyType).name == "DocileLocustBees")
				{
					list.Add(array[i]);
				}
				else if (!mainScript.isEnemyDead)
				{
					results[num2] = array[i];
					num2++;
					if (num2 == 10)
					{
						num = 10;
						return;
					}
				}
			}
			if (list.Count > 0)
			{
				foreach (RaycastHit item in list.OrderByDescending((RaycastHit invincible) => ((Component)((RaycastHit)(ref invincible)).transform).GetComponent<EnemyAICollisionDetect>().mainScript is BlobAI))
				{
					results[num2] = item;
					num2++;
					if (num2 == 10)
					{
						num = 10;
						return;
					}
				}
			}
			num = num2;
		}

		internal static void FakeFootstepAlert(PlayerControllerB player)
		{
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			bool flag = player.isInHangarShipRoom && StartOfRound.Instance.hangarDoorsClosed;
			if (((NetworkBehaviour)player).IsOwner ? player.isSprinting : playerWasLastSprinting[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 ConvertMaskToTragedy(Transform mask)
		{
			Transform val = mask.Find("Mesh");
			if ((Object)(object)val != (Object)null && (Object)(object)GlobalReferences.tragedyMask != (Object)null && (Object)(object)GlobalReferences.tragedyMaskMat != (Object)null)
			{
				((Component)val).GetComponent<MeshFilter>().mesh = GlobalReferences.tragedyMask;
				((Renderer)((Component)val).GetComponent<MeshRenderer>()).sharedMaterial = GlobalReferences.tragedyMaskMat;
				Transform obj = val.Find("EyesFilled");
				MeshFilter val2 = ((obj != null) ? ((Component)obj).GetComponent<MeshFilter>() : null);
				if ((Object)(object)val2 != (Object)null && (Object)(object)GlobalReferences.tragedyMaskEyesFilled != (Object)null)
				{
					val2.mesh = GlobalReferences.tragedyMaskEyesFilled;
					Transform obj2 = mask.Find("ComedyMaskLOD1");
					MeshFilter val3 = ((obj2 != null) ? ((Component)obj2).GetComponent<MeshFilter>() : null);
					if ((Object)(object)val3 != (Object)null && (Object)(object)GlobalReferences.tragedyMaskLOD != (Object)null)
					{
						val3.mesh = GlobalReferences.tragedyMaskLOD;
						((Renderer)((Component)val3).GetComponent<MeshRenderer>()).sharedMaterial = GlobalReferences.tragedyMaskMat;
						Plugin.Logger.LogDebug((object)"All mask meshes replaced successfully");
					}
					else
					{
						Plugin.Logger.LogWarning((object)"Failed to replace mask eyes");
					}
				}
				else
				{
					Plugin.Logger.LogWarning((object)"Failed to replace mask LOD");
				}
			}
			else
			{
				Plugin.Logger.LogWarning((object)"Failed to replace mask mesh");
			}
		}

		internal static void ForceRefreshAllHelmetLights(PlayerControllerB player, bool forceOff = false)
		{
			for (int i = 0; i < player.allHelmetLights.Length; i++)
			{
				bool flag = false;
				if (!forceOff)
				{
					for (int j = 0; j < player.ItemSlots.Length; j++)
					{
						if ((Object)(object)player.ItemSlots[j] != (Object)null)
						{
							GrabbableObject obj = player.ItemSlots[j];
							FlashlightItem val = (FlashlightItem)(object)((obj is FlashlightItem) ? obj : null);
							if ((Object)(object)val != (Object)null && val.flashlightTypeID == i && ((GrabbableObject)val).isPocketed && ((GrabbableObject)val).isBeingUsed && ((GrabbableObject)val).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})");
				}
			}
		}

		public static void SpawnProbabilitiesPostProcess(ref List<int> spawnProbabilities, List<SpawnableEnemyWithRarity> enemies)
		{
			if (spawnProbabilities.Count != enemies.Count)
			{
				Plugin.Logger.LogWarning((object)"SpawnProbabilities is a different size from the current enemies list. This should never happen outside of mod conflicts!");
			}
			for (int i = 0; i < spawnProbabilities.Count && i < enemies.Count; i++)
			{
				EnemyType enemyType = enemies[i].enemyType;
				if (enemyType.requireNestObjectsToSpawn && spawnProbabilities[i] > 0 && !Object.FindObjectsOfType<EnemyAINestSpawnObject>().Any((EnemyAINestSpawnObject nest) => (Object)(object)nest.enemyType == (Object)(object)enemyType))
				{
					Plugin.Logger.LogDebug((object)("Enemy \"" + enemyType.enemyName + "\" spawning is disabled; no nests present on map"));
					spawnProbabilities[i] = 0;
				}
				else if (Configuration.limitSpawnChance.Value && spawnProbabilities[i] > 100 && StartOfRound.Instance.currentLevelID < 13)
				{
					Plugin.Logger.LogDebug((object)$"Enemy \"{enemyType.enemyName}\" is exceeding maximum spawn weight ({spawnProbabilities[i]} > 100)");
					spawnProbabilities[i] = 100;
				}
			}
		}

		public static void OldBirdSpawnsFromApparatus()
		{
			if (!Configuration.unlimitedOldBirds.Value && GlobalReferences.allEnemiesList.TryGetValue("RadMech", out var value))
			{
				EnemyType obj = value;
				obj.numberSpawned++;
				RoundManager instance = RoundManager.Instance;
				instance.currentOutsideEnemyPower += value.PowerLevel;
				Plugin.Logger.LogDebug((object)"Old Bird spawned from apparatus");
			}
		}

		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 void BabyEatsScrap(GrabbableObject grabObj)
		{
			if (grabObj.itemProperties.isScrap)
			{
				GlobalReferences.scrapEaten += grabObj.scrapValue;
			}
		}
	}
	internal static class ReflectionCache
	{
		internal static readonly FieldInfo IS_IN_HANGAR_SHIP_ROOM = AccessTools.Field(typeof(PlayerControllerB), "isInHangarShipRoom");

		internal static readonly FieldInfo ENEMY_COLLIDERS = AccessTools.Field(typeof(ShotgunItem), "enemyColliders");

		internal static readonly FieldInfo SPAWN_PROBABILITIES = AccessTools.Field(typeof(RoundManager), "SpawnProbabilities");

		internal static readonly FieldInfo CURRENT_LEVEL = AccessTools.Field(typeof(RoundManager), "currentLevel");

		internal static readonly MethodInfo SPAWN_PROBABILITIES_POST_PROCESS = AccessTools.Method(typeof(NonPatchFunctions), "SpawnProbabilitiesPostProcess", (Type[])null, (Type[])null);
	}
	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_070e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0243: Unknown result type (might be due to invalid IL or missing references)
			//IL_024e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0258: Unknown result type (might be due to invalid IL or missing references)
			//IL_0868: Unknown result type (might be due to invalid IL or missing references)
			//IL_081d: Unknown result type (might be due to invalid IL or missing references)
			//IL_07c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_08e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_029f: 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_02c1: 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_0690: Unknown result type (might be due to invalid IL or missing references)
			//IL_069f: Unknown result type (might be due to invalid IL or missing references)
			//IL_06b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_06be: Unknown result type (might be due to invalid IL or missing references)
			//IL_06c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0ad8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0add: Unknown result type (might be due to invalid IL or missing references)
			//IL_0ae2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0ae7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0952: Unknown result type (might be due to invalid IL or missing references)
			//IL_0959: Expected O, but got Unknown
			//IL_03e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0308: Unknown result type (might be due to invalid IL or missing references)
			//IL_0317: Unknown result type (might be due to invalid IL or missing references)
			//IL_032a: 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_036e: Unknown result type (might be due to invalid IL or missing references)
			//IL_037d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0390: 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)
			if ((int)mode != 1)
			{
				return;
			}
			bool flag = Configuration.fixFireExits.Value;
			GameObject obj = GameObject.Find("/Environment/Map/DiageticAmbiance/BigMachine");
			Transform val = ((obj != null) ? obj.transform : null);
			List<string> list = new List<string>();
			string text = string.Empty;
			switch (((Scene)(ref scene)).name)
			{
			case "Level1Experimentation":
			{
				Plugin.Logger.LogDebug((object)"Detected landing on Experimentation");
				if ((Object)(object)val != (Object)null)
				{
					val.localPosition = new Vector3(-112.04f, val.localPosition.y, val.localPosition.z);
					Plugin.Logger.LogDebug((object)"Experimentation - Fixed factory ambience");
				}
				GameObject obj3 = GameObject.Find("/Environment/ReverbTriggers (1)/Cube (7)");
				Transform val3 = ((obj3 != null) ? obj3.transform : null);
				if ((Object)(object)val3 != (Object)null)
				{
					val3.localPosition = new Vector3(-147.8f, val3.localPosition.y, -81.2f);
					val3.localScale = new Vector3(129.6264f, val3.localScale.y, 184.7249f);
					GameObject obj4 = GameObject.Find("/Environment/ReverbTriggers (1)/Cube (9)");
					Transform val4 = ((obj4 != null) ? obj4.transform : null);
					if ((Object)(object)val4 != (Object)null)
					{
						val4.localPosition = new Vector3(-145.4f, val4.localPosition.y, -42.1f);
						val4.localScale = new Vector3(171.2598f, val4.localScale.y, 326.2066f);
						GameObject obj5 = GameObject.Find("/Environment/ReverbTriggers (1)/Cube (8)");
						Transform val5 = ((obj5 != null) ? obj5.transform : null);
						if ((Object)(object)val5 != (Object)null)
						{
							val5.localPosition = new Vector3(-117.39f, val5.localPosition.y, -87.23f);
							val5.localScale = new Vector3(10.4316f, val5.localScale.y, 15.95104f);
							Plugin.Logger.LogDebug((object)"Experimentation - Adjusted water tower fog triggers");
						}
					}
				}
				GameObject obj6 = GameObject.Find("/Environment/SteelDoor");
				Transform val6 = ((obj6 != null) ? obj6.transform : null);
				if ((Object)(object)val6 != (Object)null)
				{
					val6.localPosition = new Vector3(-194.668f, 19.788f, val6.localPosition.z);
					Plugin.Logger.LogDebug((object)"Experimentation - Fixed old back entrance");
				}
				GameObject obj7 = GameObject.Find("/Environment/Map/Cube (1)");
				Renderer val7 = ((obj7 != null) ? obj7.GetComponent<Renderer>() : null);
				if ((Object)(object)val7 != (Object)null)
				{
					val7.enabled = false;
					Plugin.Logger.LogDebug((object)"Experimentation - Hide untextured geometry");
				}
				list.AddRange(new <>z__ReadOnlyArray<string>(new string[40]
				{
					"BendingPipe", "Bolt", "CatwalkChunk", "CatwalkChunk.004", "CatwalkChunk.005", "CatwalkRailPost", "CatwalkStairTile", "ChainlinkFenceBend", "ChainlinkFenceCut", "CordConnector",
					"Cube.001", "Cube.004", "Cube.006", "Cube.007/HangarRoomBeams.001", "Cube.007/SiloWithLadder.001", "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" }));
				break;
			case "Level3Vow":
				Plugin.Logger.LogDebug((object)"Detected landing on Vow");
				flag = false;
				break;
			case "Level4March":
				Plugin.Logger.LogDebug((object)"Detected landing on March");
				break;
			case "Level5Rend":
				Plugin.Logger.LogDebug((object)"Detected landing on Rend");
				text = "/Environment/Map/SnowCabin/FancyDoorMapModel/SteelDoor (1)/DoorMesh/Cube";
				break;
			case "Level6Dine":
			{
				Plugin.Logger.LogDebug((object)"Detected landing on Dine");
				GameObject obj2 = GameObject.Find("/Environment/Map/KillTrigger (4)");
				Transform val2 = ((obj2 != null) ? obj2.transform : null);
				if ((Object)(object)val2 != (Object)null)
				{
					val2.localPosition = new Vector3(148.11f, val2.localPosition.y, 83.61f);
					val2.localScale = new Vector3(35.3778f, val2.localScale.y, val2.localScale.z);
					Plugin.Logger.LogDebug((object)"Dine - Fixed death pit");
				}
				break;
			}
			case "Level7Offense":
				Plugin.Logger.LogDebug((object)"Detected landing on Offense");
				if ((Object)(object)val != (Object)null)
				{
					val.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[11]
				{
					"ChainlinkFenceCut", "CreeperVine", "MiscShelf1", "NurbsPath", "Pipework2", "PlayerScaleCube.001", "PlayerScaleRef", "PlayerScaleRef.001", "LargePipeCorner (1)", "LargePipeCorner (2)",
					"Girder1 (4)"
				}));
				break;
			case "Level8Titan":
				Plugin.Logger.LogDebug((object)"Detected landing on Titan");
				if ((Object)(object)val != (Object)null)
				{
					val.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");
				break;
			case "Level10Adamance":
				Plugin.Logger.LogDebug((object)"Detected landing on Adamance");
				if ((Object)(object)val != (Object)null)
				{
					val.localPosition = new Vector3(-108.44491f, -3.2953954f, 8.043371f);
					Plugin.Logger.LogDebug((object)"Adamance - Fixed factory ambience");
				}
				flag = false;
				text = "/Environment/SnowCabin/FancyDoorMapModel/SteelDoor (1)/DoorMesh/Cube";
				break;
			case "Level11Embrion":
				Plugin.Logger.LogDebug((object)"Detected landing on Embrion");
				if ((Object)(object)val != (Object)null)
				{
					val.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");
				break;
			default:
				Plugin.Logger.LogInfo((object)"Landed on unknown moon");
				flag = false;
				break;
			}
			if (flag)
			{
				EntranceTeleport[] array = Object.FindObjectsOfType<EntranceTeleport>();
				foreach (EntranceTeleport val8 in array)
				{
					if (val8.isEntranceToBuilding && val8.entranceId > 0)
					{
						val8.entrancePoint.localRotation = Quaternion.Euler(0f, 180f, 0f);
						Plugin.Logger.LogDebug((object)$"Fixed rotation of external fire exit #{val8.entranceId}");
					}
				}
			}
			if (list.Count > 0)
			{
				GameObject obj8 = GameObject.Find("Environment/Map/ModelsIntroScene");
				Transform val9 = ((obj8 != null) ? obj8.transform : null);
				foreach (Transform item in val9)
				{
					Transform val10 = item;
					if (list.Remove(((Object)val10).name))
					{
						((Component)val10).gameObject.SetActive(false);
					}
				}
				Plugin.Logger.LogDebug((object)"Hide out-of-bounds objects (Experimentation and leftovers)");
				if (list.Count > 0)
				{
					int num = 0;
					foreach (string item2 in list)
					{
						Transform val11 = val9.Find(item2);
						if ((Object)(object)val11 != (Object)null)
						{
							((Component)val11).gameObject.SetActive(!((Component)val11).gameObject.activeSelf);
							num++;
						}
					}
					if (list.Count != num)
					{
						Plugin.Logger.LogWarning((object)$"Failed to hide {list.Count} objects:");
						foreach (string item3 in list)
						{
							Plugin.Logger.LogWarning((object)("- \"" + item3 + "\""));
						}
					}
				}
			}
			if (!Compatibility.INSTALLED_GENERAL_IMPROVEMENTS)
			{
				ScanNodeProperties? obj9 = ((IEnumerable<ScanNodeProperties>)Object.FindObjectsOfType<ScanNodeProperties>()).FirstOrDefault((Func<ScanNodeProperties, bool>)((ScanNodeProperties scanNodeProperties) => scanNodeProperties.headerText == "Ship"));
				GlobalReferences.shipNode = ((obj9 != null) ? ((Component)obj9).transform : null);
				if ((Object)(object)GlobalReferences.shipNode != (Object)null)
				{
					GlobalReferences.shipNodeOffset = GlobalReferences.shipNode.position - GlobalReferences.shipDefaultPos;
				}
			}
			if (!string.IsNullOrEmpty(text) && GlobalReferences.woodenDoorOpen != null && GlobalReferences.woodenDoorOpen.Length != 0 && GlobalReferences.woodenDoorClose != null && GlobalReferences.woodenDoorClose.Length != 0)
			{
				GameObject obj10 = GameObject.Find(text);
				AnimatedObjectTrigger val12 = ((obj10 != null) ? obj10.GetComponent<AnimatedObjectTrigger>() : null);
				if ((Object)(object)val12 != (Object)null)
				{
					val12.boolFalseAudios = GlobalReferences.woodenDoorClose;
					val12.boolTrueAudios = GlobalReferences.woodenDoorOpen;
					Plugin.Logger.LogDebug((object)"Overwritten cabin door SFX with wooden variants");
				}
			}
		}
	}
	internal static class ScriptableObjectOverrides
	{
		internal static void OverrideEnemyTypes()
		{
			foreach (KeyValuePair<string, EnemyType> allEnemies in GlobalReferences.allEnemiesList)
			{
				switch (allEnemies.Key)
				{
				case "RadMech":
					if (!Configuration.unlimitedOldBirds.Value)
					{
						if (Compatibility.INSTALLED_LETHAL_QUANTITIES)
						{
							Plugin.Logger.LogWarning((object)"Config setting \"UnlimitedOldBirds\" is disabled, but you have Lethal Quantities installed. This usually prevents Old Birds from being able to spawn due to a conflict. The config setting will be ignored for this session, but consider enabling it to hide this warning in the future.");
							allEnemies.Value.requireNestObjectsToSpawn = false;
						}
						else
						{
							allEnemies.Value.requireNestObjectsToSpawn = true;
							Plugin.Logger.LogDebug((object)(allEnemies.Value.enemyName + ": Require \"nest\" to spawn"));
						}
					}
					else
					{
						allEnemies.Value.requireNestObjectsToSpawn = false;
					}
					break;
				case "MaskedPlayerEnemy":
					allEnemies.Value.isOutsideEnemy = false;
					Plugin.Logger.LogDebug((object)(allEnemies.Value.enemyName + ": Subtract from indoor power, not outdoor power"));
					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":
				{
					allEnemies.Value.enemyPrefab.GetComponent<NavMeshAgent>().speed = 0f;
					Plugin.Logger.LogDebug((object)(allEnemies.Value.enemyName + ": Don't slide around on fresh spawn"));
					Renderer[] componentsInChildren = allEnemies.Value.enemyPrefab.GetComponentsInChildren<Renderer>();
					foreach (Renderer val in componentsInChildren)
					{
						if (((Component)val).gameObject.layer == 19)
						{
							val.shadowCastingMode = (ShadowCastingMode)0;
						}
					}
					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;
				}
				allEnemies.Value.numberSpawned = 0;
			}
		}

		internal static void OverrideSelectableLevels()
		{
			GameObject val = null;
			SelectableLevel val2 = null;
			SelectableLevel[] levels = StartOfRound.Instance.levels;
			foreach (SelectableLevel val3 in levels)
			{
				switch (((Object)val3).name)
				{
				case "OffenseLevel":
					val3.videoReel = null;
					Plugin.Logger.LogDebug((object)"Offense: Video reel");
					break;
				case "RendLevel":
				{
					SpawnableMapObject val4 = ((IEnumerable<SpawnableMapObject>)val3.spawnableMapObjects).FirstOrDefault((Func<SpawnableMapObject, bool>)delegate(SpawnableMapObject spawnableMapObject)
					{
						GameObject prefabToSpawn = spawnableMapObject.prefabToSpawn;
						return ((prefabToSpawn != null) ? ((Object)prefabToSpawn).name : null) == "SpikeRoofTrapHazard";
					});
					if (val4 != null)
					{
						val4.requireDistanceBetweenSpawns = true;
						Plugin.Logger.LogDebug((object)"Rend: Space spike traps");
					}
					break;
				}
				case "ArtificeLevel":
					val2 = val3;
					break;
				}
				if (!Compatibility.DISABLE_SUN && (Object)(object)val == (Object)null && ((Object)val3.planetPrefab).name.StartsWith("Moon2"))
				{
					val = val3.planetPrefab;
				}
			}
			if (!Compatibility.INSTALLED_ARTIFICE_BLIZZARD && (Object)(object)val != (Object)null && (Object)(object)val2 != (Object)null)
			{
				val2.planetPrefab = val;
				Plugin.Logger.LogDebug((object)"Artifice: Planet/moon");
			}
		}

		internal static void OverrideItems()
		{
			Dictionary<string, bool> dictionary = new Dictionary<string, bool>
			{
				{ "DustPan", true },
				{ "FancyCup", true },
				{ "LockPicker", true },
				{ "MoldPan", true },
				{ "Phone", true },
				{ "Shotgun", true },
				{ "SoccerBall", false },
				{ "SprayPaint", true },
				{ "ToiletPaperRolls", false }
			};
			Dictionary<string, bool> dictionary2 = new Dictionary<string, bool>
			{
				{ "Airhorn", false },
				{ "CashRegister", false },
				{ "ChemicalJug", true },
				{ "ClownHorn", false },
				{ "ComedyMask", false },
				{ "TragedyMask", false }
			};
			Dictionary<string, bool> dictionary3 = new Dictionary<string, bool>
			{
				{ "ExtensionLadder", false },
				{ "MagnifyingGlass", true },
				{ "PillBottle", true },
				{ "RadarBooster", false },
				{ "SprayPaint", true },
				{ "WeedKillerBottle", true }
			};
			AudioClip val = null;
			AudioClip val2 = null;
			AudioClip val3 = null;
			List<Item> list = new List<Item>();
			List<Item> list2 = new List<Item>();
			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;
				}
				bool flag = false;
				GameObject spawnPrefab = items.spawnPrefab;
				ScanNodeProperties val4 = ((spawnPrefab != null) ? spawnPrefab.GetComponentInChildren<ScanNodeProperties>() : null);
				switch (((Object)items).name)
				{
				case "Boombox":
					items.spawnPrefab.GetComponent<BoomboxItem>().boomboxAudio.dopplerLevel = 0.3f * GlobalReferences.dopplerLevelMult;
					Plugin.Logger.LogDebug((object)"Doppler level: Boombox");
					break;
				case "BottleBin":
					val2 = items.grabSFX;
					break;
				case "ToyCube":
				case "Brush":
				case "PillBottle":
				case "Toothpaste":
				case "Remote":
				case "SteeringWheel":
					list2.Add(items);
					break;
				case "Candy":
					items.grabSFX = null;
					Plugin.Logger.LogDebug((object)("Audio: " + items.itemName));
					break;
				case "ClownHorn":
					((GrabbableObject)items.spawnPrefab.GetComponent<NoisemakerProp>()).useCooldown = 0.4f;
					Plugin.Logger.LogDebug((object)"Cooldown: Clown horn");
					break;
				case "EasterEgg":
				case "MapDevice":
				case "ZapGun":
				case "Cog1":
					flag = true;
					break;
				case "MetalSheet":
				case "GarbageLid":
				case "FancyCup":
					list.Add(items);
					break;
				case "FancyLamp":
					items.verticalOffset = 0f;
					break;
				case "FishTestProp":
					flag = true;
					break;
				case "Flashlight":
				case "ProFlashlight":
				{
					FlashlightItem component = items.spawnPrefab.GetComponent<FlashlightItem>();
					Material[] sharedMaterials = ((Renderer)component.flashlightMesh).sharedMaterials;
					sharedMaterials[1] = component.bulbDark;
					((Renderer)component.flashlightMesh).sharedMaterials = sharedMaterials;
					Plugin.Logger.LogDebug((object)("Bulb off: " + items.itemName));
					break;
				}
				case "Hairdryer":
					((GrabbableObject)items.spawnPrefab.GetComponent<NoisemakerProp>()).useCooldown = 2f;
					Plugin.Logger.LogDebug((object)"Cooldown: Hairdryer");
					break;
				case "Key":
					if (Configuration.keysAreScrap.Value)
					{
						items.isScrap = true;
						Plugin.Logger.LogDebug((object)"Scrap: Key");
						break;
					}
					((GrabbableObject)items.spawnPrefab.GetComponent<KeyItem>()).scrapValue = 0;
					if ((Object)(object)val4 != (Object)null)
					{
						val4.subText = string.Empty;
						val4.scrapValue = 0;
						Plugin.Logger.LogDebug((object)"Scan node: Key");
					}
					break;
				case "Knife":
				{
					KnifeItem component2 = items.spawnPrefab.GetComponent<KnifeItem>();
					if ((Object)(object)val4 != (Object)null)
					{
						val4.scrapValue = ((GrabbableObject)component2).scrapValue;
						val4.subText = $"Value: ${val4.scrapValue}";
						Plugin.Logger.LogDebug((object)"Scan node: Kitchen knife");
					}
					if (items.minValue == 70 && items.maxValue == 210)
					{
						items.maxValue = 105;
					}
					break;
				}
				case "Mug":
					val3 = items.dropSFX;
					break;
				case "RedLocustHive":
					flag = true;
					((GrabbableObject)items.spawnPrefab.GetComponent<PhysicsProp>()).isInFactory = false;
					Plugin.Logger.LogDebug((object)"Factory: Hive");
					if (items.minValue == 90 && items.maxValue == 140)
					{
						items.minValue = 100;
						items.maxValue = 375;
					}
					break;
				case "Shotgun":
					if (items.minValue == 30 && items.maxValue == 100)
					{
						items.minValue = 63;
						items.maxValue = 225;
					}
					break;
				case "TeaKettle":
					val = items.grabSFX;
					break;
				case "TragedyMask":
				{
					GlobalReferences.tragedyMaskRandomClips = items.spawnPrefab.GetComponent<RandomPeriodicAudioPlayer>()?.randomClips;
					Transform obj = items.spawnPrefab.transform.Find("MaskMesh");
					MeshFilter val5 = ((obj != null) ? ((Component)obj).GetComponent<MeshFilter>() : null);
					if (!((Object)(object)val5 != (Object)null))
					{
						break;
					}
					Transform obj2 = ((Component)val5).transform.Find("EyesFilled");
					MeshFilter val6 = ((obj2 != null) ? ((Component)obj2).GetComponent<MeshFilter>() : null);
					if ((Object)(object)val6 != (Object)null && (Object)(object)GlobalReferences.tragedyMaskEyesFilled != (Object)null)
					{
						val6.mesh = GlobalReferences.tragedyMaskEyesFilled;
						Transform obj3 = ((Component)val5).transform.Find("ComedyMaskLOD");
						MeshFilter val7 = ((obj3 != null) ? ((Component)obj3).GetComponent<MeshFilter>() : null);
						if ((Object)(object)val7 != (Object)null && (Object)(object)GlobalReferences.tragedyMaskLOD != (Object)null)
						{
							val7.mesh = GlobalReferences.tragedyMaskLOD;
							Plugin.Logger.LogDebug((object)"Meshes: Tragedy");
						}
					}
					break;
				}
				case "WeedKillerBottle":
					items.spawnPrefab.GetComponent<AudioSource>().rolloffMode = (AudioRolloffMode)0;
					Plugin.Logger.LogDebug((object)"Audio rolloff: Weed killer");
					break;
				}
				if (flag)
				{
					items.spawnPrefab.GetComponent<AudioSource>().rolloffMode = (AudioRolloffMode)1;
					Plugin.Logger.LogDebug((object)("Audio rolloff: " + items.itemName));
				}
				if ((Object)(object)items.spawnPrefab != (Object)null)
				{
					bool flag2 = false;
					Renderer[] componentsInChildren = items.spawnPrefab.GetComponentsInChildren<Renderer>();
					foreach (Renderer val8 in componentsInChildren)
					{
						if (val8.enabled && ((Component)val8).gameObject.layer == 13)
						{
							val8.enabled = false;
							flag2 = true;
						}
					}
					if (flag2)
					{
						Plugin.Logger.LogDebug((object)("Invisible trigger: " + items.itemName));
					}
					if ((Object)(object)items.spawnPrefab.GetComponent<Rigidbody>() != (Object)null && (Object)(object)val4 != (Object)null && (Object)(object)((Component)val4).GetComponent<Rigidbody>() == (Object)null)
					{
						((Component)val4).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 flag3 = false;
						string[] toolTips = items.toolTips;
						for (int i = 0; i < toolTips.Length; i++)
						{
							if (toolTips[i].StartsWith("Inspect"))
							{
								flag3 = true;
								break;
							}
						}
						if (!flag3)
						{
							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})");
				}
			}
			if ((Object)(object)val != (Object)null)
			{
				foreach (Item item in list)
				{
					item.grabSFX = val;
					Plugin.Logger.LogDebug((object)("Audio: " + item.itemName));
				}
			}
			if (!((Object)(object)val2 != (Object)null))
			{
				return;
			}
			foreach (Item item2 in list2)
			{
				item2.grabSFX = val2;
				Plugin.Logger.LogDebug((object)("Audio: " + item2.itemName));
				if (((Object)item2).name == "PillBottle" && (Object)(object)val3 != (Object)null)
				{
					item2.dropSFX = val3;
				}
			}
		}

		internal static void OverrideUnlockables()
		{
			foreach (UnlockableItem unlockable in StartOfRound.Instance.unlockablesList.unlockables)
			{
				switch (unlockable.unlockableName)
				{
				case "Record player":
					unlockable.prefabObject.GetComponentInChildren<AnimatedObjectTrigger>().thisAudioSource.dopplerLevel = GlobalReferences.dopplerLevelMult;
					Plugin.Logger.LogDebug((object)"Doppler level: Record player");
					break;
				case "Disco Ball":
					unlockable.prefabObject.GetComponentInChildren<CozyLights>().turnOnAudio.dopplerLevel = 0.92f * GlobalReferences.dopplerLevelMult;
					Plugin.Logger.LogDebug((object)"Doppler level: Disco ball");
					break;
				case "JackOLantern":
					unlockable.prefabObject.GetComponentInChildren<InteractTrigger>().cooldownTime = 0.5f;
					Plugin.Logger.LogDebug((object)"Cooldown: Jack o' Lantern");
					break;
				case "Plushie pajama man":
					unlockable.prefabObject.GetComponentInChildren<InteractTrigger>().cooldownTime = 0.54f;
					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;
				}
			}
		}
	}
	internal static class TileOverrides
	{
		internal static void OverrideTiles(IndoorMapType[] indoorMapTypes)
		{
			//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_020a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0216: Unknown result type (might be due to invalid IL or missing references)
			//IL_0225: Unknown result type (might be due to invalid IL or missing references)
			foreach (GameObject allTile in GetAllTiles(indoorMapTypes))
			{
				switch (((Object)allTile).name)
				{
				case "DoubleDoorRoom":
				case "MediumRoomHallway1B":
				{
					Transform val2 = allTile.transform.Find("AnomalySpawns");
					if ((Object)(object)val2 != (Object)null)
					{
						((Component)val2).gameObject.SetActive(false);
						Plugin.Logger.LogDebug((object)(((Object)allTile).name + ": Removed obsolete triggers (fix spray paint)"));
					}
					break;
				}
				case "ManorStartRoom":
				{
					if (GlobalReferences.woodenDoorOpen != null && GlobalReferences.woodenDoorOpen.Length >= 1 && GlobalReferences.woodenDoorClose != null && GlobalReferences.woodenDoorClose.Length >= 1)
					{
						break;
					}
					Transform obj2 = allTile.transform.Find("Doorways");
					object obj3;
					if (obj2 == null)
					{
						obj3 = null;
					}
					else
					{
						Doorway componentInChildren = ((Component)obj2).GetComponentInChildren<Doorway>();
						if (componentInChildren == null)
						{
							obj3 = null;
						}
						else
						{
							List<GameObjectWeight> connectorPrefabWeights = componentInChildren.ConnectorPrefabWeights;
							if (connectorPrefabWeights == null)
							{
								obj3 = null;
							}
							else
							{
								GameObjectWeight? obj4 = ((IEnumerable<GameObjectWeight>)connectorPrefabWeights).FirstOrDefault((Func<GameObjectWeight, bool>)((GameObjectWeight prefab) => ((Object)prefab.GameObject).name == "FancyDoorMapSpawn"));
								if (obj4 == null)
								{
									obj3 = null;
								}
								else
								{
									SpawnSyncedObject component = obj4.GameObject.GetComponent<SpawnSyncedObject>();
									if (component == null)
									{
										obj3 = null;
									}
									else
									{
										GameObject spawnPrefab = component.spawnPrefab;
										obj3 = ((spawnPrefab != null) ? spawnPrefab.GetComponentInChildren<AnimatedObjectTrigger>() : null);
									}
								}
							}
						}
					}
					AnimatedObjectTrigger val3 = (AnimatedObjectTrigger)obj3;
					if ((Object)(object)val3 != (Object)null)
					{
						GlobalReferences.woodenDoorClose = val3.boolFalseAudios;
						GlobalReferences.woodenDoorOpen = val3.boolTrueAudios;
						Plugin.Logger.LogDebug((object)"Cached wooden door SFX");
					}
					else
					{
						Plugin.Logger.LogWarning((object)"Could not find fancy door prefab");
					}
					break;
				}
				case "KitchenTile":
				{
					string[] array = new string[2] { "TablesMisc/ArrangementA/coffeeTable", "TablesMisc/ArrangementB/coffeeTable (1)" };
					foreach (string text in array)
					{
						Transform obj = allTile.transform.Find(text);
						BoxCollider val = ((obj != null) ? ((Component)obj).GetComponent<BoxCollider>() : null);
						if ((Object)(object)val != (Object)null)
						{
							val.center = new Vector3(val.center.x, val.center.y, 3.48f);
							val.size = new Vector3(val.size.x, val.size.y, 4f);
							Plugin.Logger.LogDebug((object)(((Object)allTile).name + ": Adjusted collider on prop \"" + ((Object)val).name + "\""));
						}
					}
					break;
				}
				}
				if (!((Object)allTile).name.StartsWith("Cave") && !((Object)allTile).name.Contains("Tunnel"))
				{
					continue;
				}
				ParticleSystemRenderer[] componentsInChildren = allTile.GetComponentsInChildren<ParticleSystemRenderer>();
				foreach (ParticleSystemRenderer val4 in componentsInChildren)
				{
					if ((Object)(object)((Renderer)val4).sharedMaterial != (Object)null && ((Object)((Renderer)val4).sharedMaterial).name.StartsWith("RainParticle") && !((Object)val4).name.StartsWith("RainHit"))
					{
						val4.renderMode = (ParticleSystemRenderMode)3;
						Plugin.Logger.LogDebug((object)(((Object)allTile).name + ": Fix drip billboarding"));
					}
				}
			}
		}

		private static List<GameObject> GetAllTiles(IndoorMapType[] indoorMapTypes)
		{
			List<TileSet> list = new List<TileSet>();
			HashSet<GameObject> hashSet = new HashSet<GameObject>();
			foreach (IndoorMapType val in indoorMapTypes)
			{
				foreach (GraphNode node in val.dungeonFlow.Nodes)
				{
					list.AddRange(node.TileSets);
				}
				foreach (GraphLine line in val.dungeonFlow.Lines)
				{
					foreach (DungeonArchetype dungeonArchetype in line.DungeonArchetypes)
					{
						list.AddRange(dungeonArchetype.TileSets);
					}
				}
				foreach (TileSet item in list)
				{
					foreach (GameObjectChance weight in item.TileWeights.Weights)
					{
						if (hashSet.Add(weight.Value))
						{
							Plugin.Logger.LogDebug((object)("Cached reference to tile \"" + ((Object)weight.Value).name + "\""));
						}
					}
				}
			}
			HashSet<GameObject> hashSet2 = hashSet;
			List<GameObject> list2 = new List<GameObject>(hashSet2.Count);
			list2.AddRange(hashSet2);
			return list2;
		}
	}
}
namespace ButteryFixes.Patches.Player
{
	[HarmonyPatch]
	internal class BodyPatches
	{
		private static bool dontCheckBadges = true;

		[HarmonyPatch(typeof(DeadBodyInfo), "Start")]
		[HarmonyPostfix]
		private static void DeadBodyInfoPostStart(DeadBodyInfo __instance)
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Invalid comparison between Unknown and I4
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Invalid comparison between Unknown and I4
			//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0258: Unknown result type (might be due to invalid IL or missing references)
			//IL_026c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0323: Unknown result type (might be due to invalid IL or missing references)
			//IL_032a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0360: Unknown result type (might be due to invalid IL or missing references)
			//IL_0374: 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_0398: Unknown result type (might be due to invalid IL or missing references)
			//IL_03aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03df: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)__instance.grabBodyObject != (Object)null && __instance.playerScript.isInHangarShipRoom)
			{
				__instance.playerScript.SetItemInElevator(true, true, __instance.grabBodyObject);
			}
			if (Compatibility.DISABLE_PLAYERMODEL_PATCHES)
			{
				return;
			}
			if ((int)__instance.causeOfDeath == 14)
			{
				__instance.MakeCorpseBloody();
			}
			SkinnedMeshRenderer componentInChildren = ((Component)__instance).GetComponentInChildren<SkinnedMeshRenderer>();
			if (!((Object)(object)componentInChildren != (Object)null) || !((Object)(object)StartOfRound.Instance != (Object)null))
			{
				return;
			}
			UnlockableItem val = StartOfRound.Instance.unlockablesList.unlockables[__instance.playerScript.currentSuitID];
			if (val == null)
			{
				return;
			}
			try
			{
				Material val2 = ((Renderer)componentInChildren).sharedMaterials[0];
				bool flag = (int)__instance.causeOfDeath == 3;
				if (!flag && GlobalReferences.crashedJetpackAsLocalPlayer && (Object)(object)__instance.playerScript == (Object)(object)GameNetworkManager.Instance.localPlayerController)
				{
					flag = true;
					GlobalReferences.crashedJetpackAsLocalPlayer = false;
					__instance.setMaterialToPlayerSuit = false;
					Plugin.Logger.LogInfo((object)"Local player spawned a body after a jetpack crashed, caught in time to burn it");
				}
				if (flag)
				{
					if ((Object)(object)val2 != (Object)(object)GlobalReferences.scavengerSuitBurnt)
					{
						val2 = (((Renderer)componentInChildren).sharedMaterial = GlobalReferences.scavengerSuitBurnt);
						NonPatchFunctions.SmokingHotCorpse(((Component)__instance).transform);
					}
					else
					{
						dontCheckBadges = true;
						__instance.ChangeMesh(GlobalReferences.playerBody, (Material)null);
						dontCheckBadges = false;
					}
				}
				bool flag2 = false;
				Renderer val3 = default(Renderer);
				if ((Object)(object)__instance.detachedHeadObject != (Object)null && ((Component)__instance.detachedHeadObject).TryGetComponent<Renderer>(ref val3))
				{
					if (((Object)__instance.detachedHeadObject).name != "DecapitatedLegs")
					{
						val3.sharedMaterial = val2;
					}
					else
					{
						flag2 = true;
						Material[] sharedMaterials = val3.sharedMaterials;
						sharedMaterials[0] = val2;
						val3.materials = sharedMaterials;
					}
					Plugin.Logger.LogDebug((object)"Fixed helmet material on player corpse");
				}
				if ((Object)(object)val.headCostumeObject == (Object)null && (Object)(object)val.lowerTorsoCostumeObject == (Object)null)
				{
					return;
				}
				Transform val4 = ((Component)__instance).transform.Find("spine.001");
				if ((Object)(object)val.lowerTorsoCostumeObject != (Object)null)
				{
					Transform val5 = (flag2 ? __instance.detachedHeadObject : val4);
					if ((Object)(object)val5 != (Object)null)
					{
						GameObject val6 = Object.Instantiate<GameObject>(val.lowerTorsoCostumeObject, val5.position, val5.rotation, val5);
						if (!__instance.setMaterialToPlayerSuit || flag)
						{
							Renderer[] componentsInChildren = val6.GetComponentsInChildren<Renderer>();
							for (int i = 0; i < componentsInChildren.Length; i++)
							{
								componentsInChildren[i].sharedMaterial = val2;
							}
						}
						if (flag2)
						{
							val6.transform.SetPositionAndRotation(new Vector3(-0.040002573f, -0.06549633f, -0.03463273f), Quaternion.Euler(19.440311f, 0.011659833f, 0.052958783f));
						}
						Plugin.Logger.LogDebug((object)"Torso attachment complete for player corpse");
					}
				}
				Transform val7 = ((val4 != null) ? val4.Find("spine.002/spine.003") : null);
				bool flag3 = ((Object)val.headCostumeObject).name.StartsWith("PartyHatContainer");
				if ((Object)(object)val.headCostumeObject != (Object)null && (!flag3 || (!flag && (Object)(object)((Renderer)componentInChildren).sharedMaterial != (Object)(object)GlobalReferences.scavengerSuitBurnt)))
				{
					Transform val8 = __instance.detachedHeadObject;
					if (((Object)(object)val8 == (Object)null || flag2) && (Object)(object)val7 != (Object)null)
					{
						val8 = val7.Find("spine.004");
					}
					if ((Object)(object)val8 != (Object)null)
					{
						GameObject val9 = Object.Instantiate<GameObject>(val.headCostumeObject, val8.position, val8.rotation, val8);
						if ((Object)(object)val8 == (Object)(object)__instance.detachedHeadObject)
						{
							val9.transform.SetPositionAndRotation(new Vector3(0.06989373f, 0.0544735f, -0.6852454f), Quaternion.Euler(96.69699f, 0f, 0f));
							val9.transform.localScale = new Vector3(val9.transform.localScale.x / val8.localScale.x, val9.transform.localScale.y / val8.localScale.y, val9.transform.localScale.z / val8.localScale.z);
						}
						if ((!__instance.setMaterialToPlayerSuit || flag) && !flag3)
						{
							Renderer[] componentsInChildren = val9.GetComponentsInChildren<Renderer>();
							for (int i = 0; i < componentsInChildren.Length; i++)
							{
								componentsInChildren[i].sharedMaterial = val2;
							}
						}
						Plugin.Logger.LogDebug((object)"Head attachment complete for player corpse");
					}
				}
				if ((Object)(object)val7 != (Object)null && __instance.setMaterialToPlayerSuit && !flag)
				{
					Transform val10 = Object.Instantiate<Transform>(((Component)__instance.playerScript.playerBadgeMesh).transform, val7);
					Transform val11 = Object.Instantiate<Transform>(((Component)__instance.playerScript.playerBetaBadgeMesh).transform, val7);
					if ((Object)(object)__instance.playerScript == (Object)(object)GameNetworkManager.Instance.localPlayerController)
					{
						((Component)val10).GetComponent<Renderer>().forceRenderingOff = false;
						((Component)val11).GetComponent<Renderer>().forceRenderingOff = false;
					}
					Plugin.Logger.LogDebug((object)"Badges added to player corpse");
				}
			}
			catch (Exception ex)
			{
				Plugin.Logger.LogError((object)"Encountered a non-fatal error while adjusting player corpse appearance");
				Plugin.Logger.LogError((object)ex);
			}
		}

		[HarmonyPatch(typeof(DeadBodyInfo), "ChangeMesh")]
		[HarmonyPostfix]
		private static void DeadBodyInfoPostChangeMesh(DeadBodyInfo __instance)
		{
			if (Compatibility.DISABLE_PLAYERMODEL_PATCHES || dontCheckBadges)
			{
				return;
			}
			Renderer[] componentsInChildren = ((Component)__instance).GetComponentsInChildren<Renderer>();
			foreach (Renderer val in componentsInChildren)
			{
				if (((Component)val).gameObject.layer == 0 && (((Object)val).name.StartsWith("BetaBadge") || ((Object)val).name.StartsWith("LevelSticker")))
				{
					val.forceRenderingOff = true;
					Plugin.Logger.LogDebug((object)("Player corpse transformed; hide badge \"" + ((Object)val).name + "\""));
				}
			}
		}

		[HarmonyPatch(typeof(RagdollGrabbableObject), "Start")]
		[HarmonyPostfix]
		private static void RagdollGrabbableObjectPostStart(RagdollGrabbableObject __instance)
		{
			if ((Object)(object)StartOfRound.Instance != (Object)null && !StartOfRound.Instance.isChallengeFile && ((Object)StartOfRound.Instance.currentLevel).name != "CompanyBuildingLevel")
			{
				((GrabbableObject)__instance).scrapValue = 0;
			}
		}

		[HarmonyPatch(typeof(DeadBodyInfo), "SetRagdollPositionSafely")]
		[HarmonyPostfix]
		private static void PostSetRagdollPositionSafely(DeadBodyInfo __instance, Vector3 newPosition)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			if (!Compatibility.INSTALLED_GENERAL_IMPROVEMENTS && (Object)(object)__instance.grabBodyObject != (Object)null)
			{
				Bounds bounds = StartOfRound.Instance.shipInnerRoomBounds.bounds;
				if (((Bounds)(ref bounds)).Contains(newPosition))
				{
					GameNetworkManager.Instance.localPlayerController.SetItemInElevator(true, true, __instance.grabBodyObject);
				}
			}
		}
	}
	[HarmonyPatch]
	internal class PlayerPatches
	{
		private static List<PlayerControllerB> bunnyhoppingPlayers = new List<PlayerControllerB>(50);

		private static float safeTimer = 0f;

		[HarmonyPatch(typeof(PlayerControllerB), "Update")]
		[HarmonyPostfix]
		private static void PlayerControllerBPostUpdate(PlayerControllerB __instance, bool ___isWalking)
		{
			if (__instance.isClimbingLadder && !Compatibility.DISABLE_LADDER_PATCH)
			{
				__instance.isSprinting = false;
				if (___isWalking)
				{
					__instance.playerBodyAnimator.SetFloat("animationSpeed", 1f);
				}
			}
			if (__instance.isGrabbingObjectAnimation)
			{
				safeTimer += Time.deltaTime;
				if (safeTimer > __instance.grabObjectAnimationTime + 0.3f)
				{
					Plugin.Logger.LogWarning((object)"Player's interactions probably got stuck - resetting");
					__instance.isGrabbingObjectAnimation = false;
				}
			}
			else if (safeTimer > 0f)
			{
				safeTimer = 0f;
			}
		}

		[HarmonyPatch(typeof(PlayerControllerB), "ConnectClientToPlayerObject")]
		[HarmonyPostfix]
		private static void PostConnectClientToPlayerObject(PlayerControllerB __instance)
		{
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_021e: Unknown result type (might be due to invalid IL or missing references)
			//IL_022a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0239: Unknown result type (might be due to invalid IL or missing references)
			if (Configuration.gameResolution.Value != GameResolution.DontChange)
			{
				RenderTexture targetTexture = __instance.gameplayCamera.targetTexture;
				if (Configuration.gameResolution.Value == GameResolution.High)
				{
					((Texture)targetTexture).width = 970;
					((Texture)targetTexture).height = 580;
					Plugin.Logger.LogInfo((object)"High resolution applied");
				}
				else
				{
					((Texture)targetTexture).width = 620;
					((Texture)targetTexture).height = 350;
					Plugin.Logger.LogInfo((object)"Low resolution applied");
				}
				GlobalReferences.patchScanNodes = true;
			}
			else
			{
				if (GlobalReferences.patchScanNodes)
				{
					Plugin.Logger.LogInfo((object)"Resolution changes reverted");
				}
				GlobalReferences.patchScanNodes = false;
			}
			if (!Compatibility.DISABLE_PLAYERMODEL_PATCHES)
			{
				Transform obj = __instance.localVisor.Find("ScavengerHelmet");
				Renderer val = ((obj != null) ? ((Component)obj).GetComponent<Renderer>() : null);
				if ((Object)(object)val != (Object)null)
				{
					val.shadowCastingMode = (ShadowCastingMode)0;
					Plugin.Logger.LogDebug((object)"\"Fake helmet\" no longer casts a shadow");
				}
			}
			try
			{
				((Component)__instance.playerBadgeMesh).GetComponent<Renderer>().forceRenderingOff = true;
				((Renderer)__instance.playerBetaBadgeMesh).forceRenderingOff = true;
				Plugin.Logger.LogDebug((object)"Hide badges on local player");
			}
			catch (Exception ex)
			{
				Plugin.Logger.LogWarning((object)"Ran into error fetching local player's badges");
				Plugin.Logger.LogWarning((object)ex);
			}
			if (!Compatibility.INSTALLED_GENERAL_IMPROVEMENTS && ((TMP_Text)__instance.playersManager.mapScreenPlayerName).text == "MONITORING: Player")
			{
				((TMP_Text)__instance.playersManager.mapScreenPlayerName).SetText("MONITORING: " + __instance.playersManager.mapScreen.radarTargets[__instance.playersManager.mapScreen.targetTransformIndex].name, true);
				Plugin.Logger.LogDebug((object)"Fix \"MONITORING: Player\"");
			}
			GlobalReferences.crashedJetpackAsLocalPlayer = false;
			Light[] allHelmetLights = __instance.allHelmetLights;
			foreach (Light val2 in allHelmetLights)
			{
				if ((int)val2.shadows == 0)
				{
					val2.shadows = (LightShadows)1;
					((Component)val2).GetComponent<HDAdditionalLightData>().shadowNearPlane = 0.66f;
				}
			}
			if (Configuration.restoreShipIcon.Value)
			{
				Transform val3 = __instance.playersManager.mapScreen.shipArrowUI.transform.Find("ShipIcon");
				if ((Object)(object)val3 != (Object)null)
				{
					val3.localPosition = new Vector3(val3.localPosition.x, val3.localPosition.y, 0f);
					Plugin.Logger.LogDebug((object)"Fix ship icon on radar");
				}
			}
			if (__instance.currentSuitID >= 0 && __instance.currentSuitID < __instance.playersManager.unlockablesList.unlockables.Count && ((Object)(object)__instance.playersManager.unlockablesList.unlockables[__instance.currentSuitID].headCostumeObject != (Object)null || (Object)(object)__instance.playersManager.unlockablesList.unlockables[__instance.currentSuitID].lowerTorsoCostumeObject != (Object)null))
			{
				UnlockableSuit.SwitchSuitForPlayer(__instance, __instance.currentSuitID, false);
			}
		}

		[HarmonyPatch(typeof(PlayerControllerB), "PlayJumpAudio")]
		[HarmonyPostfix]
		private static void PostPlayJumpAudio(PlayerControllerB __instance, bool ___isWalking)
		{
			//IL_0099: 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_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			if (!Configuration.fixJumpCheese.Value || !((NetworkBehaviour)__instance).IsServer || StartOfRound.Instance.inShipPhase)
			{
				if (bunnyhoppingPlayers.Count > 0)
				{
					Plugin.Logger.LogWarning((object)"Bunnyhopping player list has some residual entries");
					bunnyhoppingPlayers.Clear();
				}
			}
			else
			{
				if (__instance.isInsideFactory || __instance.isInElevator || __instance.isInHangarShipRoom || !GlobalReferences.allEnemiesList.TryGetValue("MouthDog", out var value) || value.numberSpawned < 1)
				{
					return;
				}
				bool flag = false;
				if (((NetworkBehaviour)__instance).IsOwner)
				{
					flag = ___isWalking;
				}
				else if (__instance.timeSincePlayerMoving < 0.25f)
				{
					Vector3 val = __instance.serverPlayerPosition - __instance.oldPlayerPosition;
					val.y = 0f;
					flag = ((Vector3)(ref val)).magnitude > float.Epsilon;
				}
				if (flag)
				{
					Plugin.Logger.LogDebug((object)("Player \"" + __instance.playerUsername + "\" is bunnyhopping with dogs outside; creating noise"));
					NonPatchFunctions.FakeFootstepAlert(__instance);
					if (!bunnyhoppingPlayers.Contains(__instance))
					{
						bunnyhoppingPlayers.Add(__instance);
					}
				}
			}
		}

		[HarmonyPatch(typeof(PlayerControllerB), "LandFromJumpClientRpc")]
		[HarmonyPostfix]
		private static void PostLandFromJumpClientRpc(PlayerControllerB __instance)
		{
			if (bunnyhoppingPlayers.Contains(__instance))
			{
				Plugin.Logger.LogDebug((object)("Player \"" + __instance.playerUsername + "\" landed from bunnyhop"));
				if (Configuration.fixJumpCheese.Value && ((NetworkBehaviour)__instance).IsServer && GlobalReferences.allEnemiesList.TryGetValue("MouthDog", out var value) && value.numberSpawned > 0)
				{
					NonPatchFunctions.FakeFootstepAlert(__instance);
				}
				bunnyhoppingPlayers.Remove(__instance);
			}
		}

		[HarmonyPatch(typeof(PlayerControllerB), "PlayFootstepSound")]
		[HarmonyPostfix]
		private static void PostPlayFootstepSound(PlayerControllerB __instance)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			if (((NetworkBehaviour)__instance).IsServer && !((NetworkBehaviour)__instance).IsOwner)
			{
				bool[] playerWasLastSprinting = NonPatchFunctions.playerWasLastSprinting;
				nint num = checked((nint)__instance.actualClientId);
				AnimatorStateInfo currentAnimatorStateInfo = __instance.playerBodyAnimator.GetCurrentAnimatorStateInfo(0);
				playerWasLastSprinting[num] = ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).IsTag("Sprinting");
			}
		}

		[HarmonyPatch(typeof(PlayerControllerB), "QEItemInteract_performed")]
		[HarmonyPatch(typeof(PlayerControllerB), "ItemSecondaryUse_performed")]
		[HarmonyPatch(typeof(PlayerControllerB), "ItemTertiaryUse_performed")]
		[HarmonyPrefix]
		private static void PreItem_performed(PlayerControllerB __instance)
		{
			if (__instance.equippedUsableItemQE && (Object)(object)__instance.currentlyHeldObjectServer != (Object)null && (__instance.currentlyHeldObjectServer is FlashlightItem || __instance.currentlyHeldObjectServer is JetpackItem || __instance.currentlyHeldObjectServer is BoomboxItem || ((Object)__instance.currentlyHeldObjectServer.itemProperties).name == "Hairdryer"))
			{
				__instance.equippedUsableItemQE = false;
				Plugin.Logger.LogWarning((object)"Tried to use Q/E controls on an item with no secondary/tertiary use. This shouldn't happen");
			}
		}

		[HarmonyPatch(typeof(PlayerControllerB), "PlaceGrabbableObject")]
		[HarmonyPostfix]
		private static void PostPlaceGrabbableObject(GrabbableObject placeObject)
		{
			if (StartOfRound.Instance.isObjectAttachedToMagnet && (Object)(object)StartOfRound.Instance.attachedVehicle != (Object)null && (Object)(object)((Component)placeObject).transform.parent == (Object)(object)((Component)StartOfRound.Instance.attachedVehicle).transform)
			{
				GameNetworkManager.Instance.localPlayerController.SetItemInElevator(true, true, placeObject);
				Plugin.Logger.LogDebug((object)$"Item \"{placeObject.itemProperties.itemName}\" #{((Object)placeObject).GetInstanceID()} was placed inside a magnetized Cruiser and auto-collected");
			}
		}
	}
	[HarmonyPatch]
	internal class SuitPatches
	{
		private static bool localCostumeChanged;

		[HarmonyPatch(typeof(UnlockableSuit), "ChangePlayerCostumeElement")]
		[HarmonyPrefix]
		private static void PreChangePlayerCostumeElement(ref Transform costumeContainer, GameObject newCostume)
		{
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Expected O, but got Unknown
			if (Compatibility.DISABLE_PLAYERMODEL_PATCHES || (Object)(object)GameNetworkManager.Instance?.localPlayerController == (Object)null)
			{
				return;
			}
			if ((Object)(object)costumeContainer == (Object)(object)GameNetworkManager.Instance.localPlayerController.headCostumeContainerLocal)
			{
				if (costumeContainer.childCount > 0)
				{
					foreach (Transform item in costumeContainer)
					{
						Transform val = item;
						if (!((Component)val).CompareTag("DoNotSet"))
						{
							Object.Destroy((Object)(object)((Component)val).gameObject);
						}
					}
				}
				costumeContainer = GameNetworkManager.Instance.localPlayerController.headCostumeContainer;
				if ((Object)(object)newCostume != (Object)null)
				{
					localCostumeChanged = true;
				}
			}
			else if ((Object)(object)costumeContainer == (Object)(object)GameNetworkManager.Instance.localPlayerController.lowerTorsoCostumeContainer && (Object)(object)newCostume != (Object)null)
			{
				localCostumeChanged = true;
			}
		}

		[HarmonyPatch(typeof(UnlockableSuit), "ChangePlayerCostumeElement")]
		[HarmonyPostfix]
		private static void PostChangePlayerCostumeElement(ref Transform costumeContainer)
		{
			if (localCostumeChanged)
			{
				localCostumeChanged = false;
				Renderer[] componentsInChildren = ((Component)costumeContainer).GetComponentsInChildren<Renderer>();
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					componentsInChildren[i].shadowCastingMode = (ShadowCastingMode)3;
				}
				Plugin.Logger.LogDebug((object)("Local costume part only draws shadow - " + ((Object)costumeContainer).name));
			}
		}

		[HarmonyPatch(typeof(UnlockableSuit), "SwitchSuitForPlayer")]
		[HarmonyPostfix]
		private static void PostSwitchSuitForPlayer(PlayerControllerB player, int suitID)
		{
			if ((Object)(object)GameNetworkManager.Instance.localPlayerController == (Object)(object)player)
			{
				UnlockableSuit.ChangePlayerCostumeElement(player.lowerTorsoCostumeContainer, StartOfRound.Instance.unlockablesList.unlockables[suitID].lowerTorsoCostumeObject);
			}
		}
	}
}
namespace ButteryFixes.Patches.Objects
{
	[HarmonyPatch]
	internal class ApparatusPatches
	{
		[HarmonyPatch(typeof(LungProp), "Start")]
		[HarmonyPostfix]
		[HarmonyPriority(0)]
		private static void LungPropPostStart(LungProp __instance)
		{
			ScanNodeProperties componentInChildren = ((Component)__instance).GetComponentInChildren<ScanNodeProperties>();
			if ((Object)(object)componentInChildren != (Object)null)
			{
				if (componentInChildren.headerText == "Apparatice")
				{
					componentInChildren.headerText = "Apparatus";
				}
				if (Configuration.showApparatusValue.Value)
				{
					componentInChildren.scrapValue = ((GrabbableObject)__instance).scrapValue;
					componentInChildren.subText = $"Value: ${componentInChildren.scrapValue}";
				}
				Plugin.Logger.LogDebug((object)"Scan node: Apparatus");
			}
		}

		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> TransDisconnectFromMachinery(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Expected O, but got Unknown
			List<CodeInstruction> list = instructions.ToList();
			MethodInfo methodInfo = AccessTools.Method(typeof(RoundManager), "SpawnEnemyGameObject", (Type[])null, (Type[])null);
			for (int i = 2; i < list.Count; i++)
			{
				if (list[i].opcode == OpCodes.Callvirt && (MethodInfo)list[i].operand == methodInfo)
				{
					list.Insert(i + 2, new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(NonPatchFunctions), "OldBirdSpawnsFromApparatus", (Type[])null, (Type[])null)));
					Plugin.Logger.LogDebug((object)"Transpiler (Radiation warning): Add Old Bird values after spawning");
					return list;
				}
			}
			Plugin.Logger.LogError((object)"Radiation warning transpiler failed");
			return instructions;
		}
	}
	[HarmonyPatch]
	internal class BreakerBoxPatches
	{
		[HarmonyPatch(typeof(BreakerBox), "SetSwitchesOff")]
		[HarmonyPostfix]
		private static void PostSetSwitchesOff(BreakerBox __instance)
		{
			__instance.breakerBoxHum.Stop();
		}

		[HarmonyPatch(typeof(BreakerBox), "SwitchBreaker")]
		[HarmonyPostfix]
		private static void PostSwitchBreaker(BreakerBox __instance)
		{
			if (__instance.breakerBoxHum.isPlaying && RoundManager.Instance.powerOffPermanently)
			{
				__instance.breakerBoxHum.Stop();
			}
		}
	}
	[HarmonyPatch]
	internal class CruiserPatches
	{
		private static float radioPingTimestamp;

		[HarmonyPatch(typeof(VehicleController), "DestroyCar")]
		[HarmonyPostfix]
		private static void PostDestroyCar(VehicleController __instance)
		{
			__instance.hoodAudio.mute = true;
			((Component)__instance.healthMeter).GetComponentInChildren<Renderer>().forceRenderingOff = true;
			((Component)__instance.turboMeter).GetComponentInChildren<Renderer>().forceRenderingOff = true;
		}

		[HarmonyPatch(typeof(VehicleController), "SetCarEffects")]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> TransSetCarEffects(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Expected O, but got Unknown
			List<CodeInstruction> list = instructions.ToList();
			MethodInfo methodInfo = AccessTools.Method(typeof(RoundManager), "PlayAudibleNoise", (Type[])null, (Type[])null);
			for (int i = 0; i < list.Count; i++)
			{
				if (!(list[i].opcode == OpCodes.Callvirt) || !((MethodInfo)list[i].operand == methodInfo))
				{
					continue;
				}
				for (int j = i + 1; j < list.Count; j++)
				{
					if (list[j].opcode == OpCodes.Br)
					{
						list.Insert(i + 1, new CodeInstruction(OpCodes.Br, list[j].operand));
						Plugin.Logger.LogDebug((object)"Transpiler (Cruiser noise alert): Fix 2 audible noises at once");
						return list;
					}
				}
			}
			Plugin.Logger.LogError((object)"Cruiser noise alert transpiler failed");
			return instructions;
		}

		[HarmonyPatch(typeof(VehicleController), "SetRadioValues")]
		[HarmonyPostfix]
		private static void PostSetRadioValues(VehicleController __instance)
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			if (((NetworkBehaviour)__instance).IsServer && __instance.radioAudio.isPlaying && Time.realtimeSinceStartup > radioPingTimestamp)
			{
				radioPingTimestamp = Time.realtimeSinceStartup + 2f;
				RoundManager.Instance.PlayAudibleNoise(((Component)__instance.radioAudio).transform.position, 16f, Mathf.Min((__instance.radioAudio.volume + __instance.radioInterference.volume) * 0.5f, 0.9f), 0, false, 2692);
			}
		}

		[HarmonyPatch(typeof(VehicleController), "CollectItemsInTruck")]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> TransCollectItemsInTruck(IEnumerable<CodeInstruction> instructions)
		{
			List<CodeInstruction> list = instructions.ToList();
			MethodInfo methodInfo = AccessTools.Method(typeof(Physics), "OverlapSphere", new Type[4]
			{
				typeof(Vector3),
				typeof(float),
				typeof(int),
				typeof(QueryTriggerInteraction)
			}, (Type[])null);
			for (int i = 1; i < list.Count; i++)
			{
				if (list[i].opcode == OpCodes.Call && (MethodInfo)list[i].operand == methodInfo && list[i - 1].opcode == OpCodes.Ldc_I4_1)
				{
					list[i - 1].opcode = OpCodes.Ldc_I4_2;
					Plugin.Logger.LogDebug((object)"Transpiler (Cruiser collect): Auto-collect trigger colliders, for Teeth");
					return list;
				}
			}
			Plugin.Logger.LogWarning((object)"Cruiser collect transpiler failed");
			return instructions;
		}
	}
	[HarmonyPatch]
	internal class DramaticMaskPatches
	{
		[HarmonyPatch(typeof(HauntedMaskItem), "MaskClampToHeadAnimationEvent")]
		[HarmonyPostfix]
		private static void PostMaskClampToHeadAnimationEvent(HauntedMaskItem __instance)
		{
			if (__instance.maskTypeId == 5)
			{
				Plugin.Logger.LogDebug((object)"Player is being converted by a Tragedy mask; about to replace mask prefab appearance");
				NonPatchFunctions.ConvertMaskToTragedy(((Component)__instance.currentHeadMask).transform);
			}
		}
	}
	[HarmonyPatch]
	internal class ElevatorPatches
	{
		[HarmonyPatch(typeof(MineshaftElevatorController), "OnEnable")]
		[HarmonyPostfix]
		private static void MineshaftElevatorControllerPostOnEnable(MineshaftElevatorController __instance)
		{
			__instance.elevatorJingleMusic.dopplerLevel = 0.58f * GlobalReferences.dopplerLevelMult;
			Plugin.Logger.LogDebug((object)"Doppler level: Mineshaft elevator");
		}
	}
	[HarmonyPatch]
	internal class ExtensionLadderPatches
	{
		[HarmonyPatch(typeof(ExtensionLadderItem), "StartLadderAnimation")]
		[HarmonyPostfix]
		private static void PostStartLadderAnimation(ref bool ___ladderBlinkWarning)
		{
			if (___ladderBlinkWarning)
			{
				___ladderBlinkWarning = false;
				Plugin.Logger.LogDebug((object)"Fixed broken extension ladder warning");
			}
		}

		[HarmonyPatch(typeof(ExtensionLadderItem), "Update")]
		[HarmonyPostfix]
		private static void ExtensionLadderItemPostUpdate(ExtensionLadderItem __instance)
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)StartOfRound.Instance != (Object)null && StartOfRound.Instance.suckingPlayersOutOfShip && !((GrabbableObject)__instance).itemUsedUp)
			{
				((GrabbableObject)__instance).itemUsedUp = true;
				for (int i = 0; i < ((GrabbableObject)__instance).propColliders.Length; i++)
				{
					((GrabbableObject)__instance).propColliders[i].excludeLayers = LayerMask.op_Implicit(-1);
				}
				Plugin.Logger.LogDebug((object)"Suck players through ladder");
			}
		}
	}
	[HarmonyPatch]
	internal class FlashlightPatches
	{
		[HarmonyPatch(typeof(FlashlightItem), "PocketItem")]
		[HarmonyPatch(typeof(FlashlightItem), "DiscardItem")]
		[HarmonyPatch(typeof(FlashlightItem), "EquipItem")]
		[HarmonyPatch(typeof(FlashlightItem), "SwitchFlashlight")]
		[HarmonyPostfix]
		private static void FlashlightItemPost(PlayerControllerB ___previousPlayerHeldBy)
		{
			if (!Compatibility.INSTALLED_GENERAL_IMPROVEMENTS && !((Object)(object)___previousPlayerHeldBy != (Object)(object)GameNetworkManager.Instance.localPlayerController))
			{
				NonPatchFunctions.ForceRefreshAllHelmetLights(___previousPlayerHeldBy);
			}
		}
	}
	[HarmonyPatch]
	internal class ItemPatches
	{
		[HarmonyPatch(typeof(GrabbableObject), "ChargeBatteries")]
		[HarmonyPostfix]
		private static void PostChargeBatteries(GrabbableObject __instance)
		{
			BoomboxItem val = (BoomboxItem)(object)((__instance is BoomboxItem) ? __instance : null);
			if ((Object)(object)val != (Object)null && val.isPlayingMusic && val.boomboxAudio.pitch < 1f && ((GrabbableObject)val).insertedBattery.charge > 0f)
			{
				val.boomboxAudio.pitch = 1f;
				Plugin.Logger.LogDebug((object)"Boombox was recharged, correcting pitch");
			}
		}

		[HarmonyPatch(typeof(GrabbableObjectPhysicsTrigger), "OnTriggerEnter")]
		[HarmonyPrefix]
		private static bool GrabbableObjectPhysicsTriggerPreOnTriggerEnter(GrabbableObjectPhysicsTrigger __instance, Collider other)
		{
			if (((Component)other).CompareTag("Enemy"))
			{
				EnemyAICollisionDetect val = default(EnemyAICollisionDetect);
				if (!((Component)other).TryGetComponent<EnemyAICollisionDetect>(ref val) || (Object)(object)val.mainScript == (Object)null)
				{
					return false;
				}
				if (val.mainScript.isEnemyDead)
				{
					return false;
				}
				if (__instance.itemScript.isInShipRoom && (StartOfRound.Instance.shipIsLeaving || !val.mainScript.isInsidePlayerShip || val.mainScript is ForestGiantAI || val.mainScript is RadMechAI))
				{
					return false;
				}
			}
			return true;
		}

		[HarmonyPatch(typeof(GrabbableObject), "PocketItem")]
		[HarmonyPostfix]
		private static void GrabbableObjectPostPocketItem(GrabbableObject __instance)
		{
			if ((Object)(object)__instance.playerHeldBy != (Object)null)
			{
				__instance.playerHeldBy.playerBodyAnimator.SetTrigger(__instance.itemProperties.twoHandedAnimation ? "SwitchHoldAnimationTwoHanded" : "SwitchHoldAnimation");
			}
		}
	}
	[HarmonyPatch]
	internal class JetpackPatches
	{
		[HarmonyPatch(typeof(JetpackItem), "ExplodeJetpackClientRpc")]
		[HarmonyPostfix]
		public static void PostExplodeJetpackClientRpc(JetpackItem __instance, PlayerControllerB ___previousPlayerHeldBy)
		{
			if (Compatibility.DISABLE_PLAYERMODEL_PATCHES)
			{
				return;
			}
			DeadBodyInfo val = ___previousPlayerHeldBy.deadBody;
			if ((Object)(object)val == (Object)null)
			{
				DeadBodyInfo[] array = Object.FindObjectsOfType<DeadBodyInfo>();
				foreach (DeadBodyInfo val2 in array)
				{
					if ((Object)(object)val2.playerScript == (Object)(object)___previousPlayerHeldBy)
					{
						val = val2;
					}
				}
			}
			if ((Object)(object)val != (Object)null)
			{
				val.setMaterialToPlayerSuit = false;
				Renderer[] componentsInChildren = ((Component)val).GetComponentsInChildren<Renderer>();
				foreach (Renderer val3 in componentsInChildren)
				{
					if (((Component)val3).gameObject.layer == 0 && (((Object)val3).name.StartsWith("BetaBadge") || ((Object)val3).name.StartsWith("LevelSticker") || ((Object)val3).name.StartsWith("BirthdayHat")))
					{
						val3.forceRenderingOff = true;
					}
					else if (((Component)val3).gameObject.layer == 20 && (val3 is SkinnedMeshRenderer || val3 is MeshRenderer))
					{
						val3.sharedMaterial = GlobalReferences.scavengerSuitBurnt;
					}
				}
				NonPatchFunctions.SmokingHotCorpse(((Component)val).transform);
				Plugin.Logger.LogDebug((object)"Jetpack exploded and burned player corpse");
			}
			else
			{
				Plugin.Logger.LogWarning((object)"Jetpack exploded but the player that crashed it didn't spawn a body");
				if ((Object)(object)___previousPlayerHeldBy == (Object)(object)GameNetworkManager.Instance.localPlayerController)
				{
					GlobalReferences.crashedJetpackAsLocalPlayer = true;
					Plugin.Logger.LogInfo((object)"Local player crashed, try to run other patch when corpse is spawned");
				}
			}
		}
	}
	[HarmonyPatch]
	internal class LandminePatches
	{
		[HarmonyPatch(typeof(Landmine), "Detonate")]
		[HarmonyPostfix]
		private static void LandminePostDetonate(Landmine __instance)
		{
			Transform parent = ((Component)__instance).transform.parent;
			object obj;
			if (parent == null)
			{
				obj = null;
			}
			else
			{
				Transform obj2 = parent.Find("ScanSphere");
				obj = ((obj2 != null) ? ((Component)obj2).GetComponent<Renderer>() : null);
			}
			Renderer val = (Renderer)obj;
			if ((Object)(object)val != (Object)null)
			{
				val.forceRenderingOff = true;
				Plugin.Logger.LogDebug((object)"Landmine: Hide radar dot after detonation");
			}
			if (!Compatibility.INSTALLED_GENERAL_IMPROVEMENTS)
			{
				Transform parent2 = ((Component)__instance).transform.parent;
				ScanNodeProperties val2 = ((parent2 != null) ? ((Component)parent2).GetComponentInChildren<ScanNodeProperties>() : null);
				if ((Object)(object)val2 != (Object)null)
				{
					((Component)val2).GetComponent<Collider>().enabled = false;
					Plugin.Logger.LogDebug((object)"Landmine: Hide scan node after detonation");
				}
				TerminalAccessibleObject val3 = default(TerminalAccessibleObject);
				if (((Component)__instance).TryGetComponent<TerminalAccessibleObject>(ref val3))
				{
					Object.Destroy((Object)(object)val3);
					Plugin.Logger.LogDebug((object)"Landmine: Hide terminal code after detonation");
				}
			}
		}

		[HarmonyPatch(typeof(Landmine), "SetOffMineAnimation")]
		[HarmonyPrefix]
		private static bool PreSetOffMineAnimation(Landmine __instance)
		{
			Renderer component = ((Component)__instance).GetComponent<Renderer>();
			if (__instance.hasExploded && !((Object)(object)component == (Object)null))
			{
				return component.enabled;
			}
			return true;
		}
	}
	[HarmonyPatch]
	internal class ShipLightPatches
	{
		[HarmonyPatch(typeof(CozyLights), "Update")]
		[HarmonyPrefix]
		private static bool CozyLightsPreUpdate(CozyLights __instance, ref bool ___cozyLightsOn)
		{
			if ((Object)(object)StartOfRound.Instance != (Object)null && StartOfRound.Instance.firingPlayersCutsceneRunning && (Object)(object)GlobalReferences.shipAnimator != (Object)null && GlobalReferences.shipAnimator.GetBool("AlarmRinging"))
			{
				if (___cozyLightsOn)
				{
					__instance.cozyLightsAnimator.SetBool("on", false);
					___cozyLightsOn = false;
				}
				if ((Object)(object)__instance.turnOnAudio != (Object)null)
				{
					__instance.SetAudio();
				}
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch]
	internal class ShotgunPatches
	{
		[HarmonyPatch(typeof(ShotgunItem), "ReloadGunEffectsClientRpc")]
		[HarmonyPostfix]
		private static void PostReloadGunEffectsClientRpc(ShotgunItem __instance, bool start)
		{
			if (start && !((NetworkBehaviour)__instance).IsOwner)
			{
				((Renderer)__instance.shotgunShellLeft).enabled = __instance.shellsLoaded > 0;
				((Renderer)__instance.shotgunShellRight).enabled = false;
				((MonoBehaviour)__instance).StartCoroutine(NonPatchFunctions.ShellsAppearAfterDelay(__instance));
				Plugin.Logger.LogDebug((object)"Shotgun was reloaded by another client; animating shells");
			}
		}

		[HarmonyPatch(typeof(ShotgunItem), "Update")]
		[HarmonyPostfix]
		private static void ShotgunItemPostUpdate(ShotgunItem __instance)
		{
			if (__instance.isReloading)
			{
				((Renderer)__instance.shotgunShellLeft).forceRenderingOff = false;
				((Renderer)__instance.shotgunShellRight).forceRenderingOff = false;
			}
		}

		[HarmonyPatch(typeof(ShotgunItem), "Start")]
		[HarmonyPatch(typeof(ShotgunItem), "DiscardItem")]
		[HarmonyPostfix]
		private static void DontRenderShotgunShells(ShotgunItem __instance)
		{
			((Renderer)__instance.shotgunShellLeft).forceRenderingOff = true;
			((Renderer)__instance.shotgunShellRight).forceRenderingOff = true;
		}

		[HarmonyPatch(typeof(ShotgunItem), "ShootGun")]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> ShotgunItemTransShootGun(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
		{
			//IL_01df: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e5: Expected O, but got Unknown
			//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0200: Expected O, but got Unknown
			//IL_0208: Unknown result type (might be due to invalid IL or missing references)
			//IL_020e: Expected O, but got Unknown
			//IL_021a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0220: Expected O, but got Unknown
			//IL_023d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0243: Expected O, but got Unknown
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Expected O, but got Unknown
			List<CodeInstruction> list = instructions.ToList();
			bool flag = false;
			for (int i = 2; i < list.Count; i++)
			{
				if (!flag && list[i].opcode == OpCodes.Bge_Un && list[i - 2].opcode == OpCodes.Ldloc_2)
				{
					for (int j = i + 1; j < list.Count - 1; j++)
					{
						int num = -1;
						if (list[j + 1].opcode == OpCodes.Ldloc_2)
						{
							if (num >= 0 && list[j].opcode == OpCodes.Br)
							{
								list.Insert(num, new CodeInstruction(OpCodes.Br, list[j].operand));
								Plugin.Logger.LogDebug((object)"Transpiler (Shotgun blast): Fix ear-ringing severity in extremely close range");
								flag = true;
								break;
							}
							if (num < 0 && list[j].opcode == OpCodes.Stloc_S)
							{
								num = j + 1;
							}
						}
					}
				}
				else if (list[i].opcode == OpCodes.Newarr && (Type)list[i].operand == typeof(RaycastHit) && list[i - 1].opcode == OpCodes.Ldc_I4_S && (sbyte)list[i - 1].operand == 10)
				{
					list[i - 1].operand = 50;
					Plugin.Logger.LogDebug((object)"Transpiler (Shotgun blast): Resize target colliders array");
				}
				else if (list[i].opcode == OpCodes.Call && list[i].operand.ToString().Contains("SphereCastNonAlloc"))
				{
					list.InsertRange(i + 2, new <>z__ReadOnlyArray<CodeInstruction>((CodeInstruction[])(object)new CodeInstruction[5]
					{
						new CodeInstruction(OpCodes.Ldarg_1, (object)null),
						new CodeInstruction(OpCodes.Ldloca_S, list[i + 1].operand),
						new CodeInstruction(OpCodes.Ldarg_0, (object)null),
						new CodeInstruction(OpCodes.Ldflda, (object)ReflectionCache.ENEMY_COLLIDERS),
						new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(NonPatchFunctions), "ShotgunPreProcess", (Type[])null, (Type[])null))
					}));
					Plugin.Logger.LogDebug((object)"Transpiler (Shotgun blast): Pre-process shotgun targets");
				}
			}
			return list;
		}
	}
	[HarmonyPatch]
	internal class SpikeTrapPatches
	{
		[HarmonyPatch(typeof(SpikeRoofTrap), "StickBodyToSpikes")]
		[HarmonyPostfix]
		private static void PostStickBodyToSpikes(DeadBodyInfo body)
		{
			if (!Compatibility.DISABLE_PLAYERMODEL_PATCHES)
			{
				body.MakeCorpseBloody();
			}
		}
	}
	[HarmonyPatch]
	internal class SprayPaintPatches
	{
		[HarmonyPatch(typeof(SprayPaintItem), "LateUpdate")]
		[HarmonyPrefix]
		private static void SprayPaintItemPreLateUpdate(SprayPaintItem __instance, ref bool ___isSpraying, ref float ___sprayInterval, DecalProjector ___delayedSprayPaintDecal)
		{
			if (___isSpraying)
			{
				if (((GrabbableObject)__instance).itemProperties.canBeInspected && (Object)(object)((GrabbableObject)__instance).playerHeldBy != (Object)null && ((GrabbableObject)__instance).playerHeldBy.IsInspectingItem)
				{
					___isSpraying = false;
					__instance.StopSpraying();
				}
				else if (!Compatibility.DISABLE_SPRAY_PAINT_PATCHES && !__instance.isWeedKillerSprayBottle && ___sprayInterval > 0f && (Object)(object)___delayedSprayPaintDecal != (Object)null && ((Behaviour)___delayedSprayPaintDecal).enabled && ___sprayInterval < __instance.sprayIntervalSpeed - Time.fixedDeltaTime)
				{
					___sprayInterval = 0f;
				}
			}
		}

		[HarmonyPatch(typeof(SprayPaintItem), "ItemActivate")]
		[HarmonyPrefix]
		private static void SprayPaintItemPreItemActivate(SprayPaintItem __instance, ref bool buttonDown, float ___sprayCanTank)
		{
			if (buttonDown && ((GrabbableObject)__instance).itemProperties.canBeInspected && (Object)(object)((GrabbableObject)__instance).playerHeldBy != (Object)null && ((GrabbableObject)__instance).playerHeldBy.IsInspectingItem && ___sprayCanTank > 0f)
			{
				buttonDown = false;
			}
		}

		[HarmonyPatch(typeof(SprayPaintItem), "EquipItem")]
		[HarmonyPostfix]
		private static void SprayPaintItemPostEquipItem(SprayPaintItem __instance)
		{
			if (__instance.isWeedKillerSprayBottle)
			{
				((GrabbableObject)__instance).playerHeldBy.equippedUsableItemQE = false;
			}
		}

		[HarmonyPatch(typeof(SprayPaintItem), "Start")]
		[HarmonyPostfix]
		private static void SprayPaintItemPostStart(SprayPaintItem __instance, ref int ___sprayCanMatsIndex)
		{
			if (!__instance.isWeedKillerSprayBottle)
			{
				if (!Compatibility.DISABLE_SPRAY_PAINT_PATCHES)
				{
					__instance.sprayIntervalSpeed = 0.037f;
					__instance.maxSprayPaintDecals = 2200;
				}
				if (!Compatibility.INSTALLED_GENERAL_IMPROVEMENTS)
				{
					___sprayCanMatsIndex = new Random((int)((NetworkBehaviour)__instance).NetworkObjectId).Next(__instance.particleMats.Length);
					((Renderer)((Component)__instance.sprayParticle).GetComponent<ParticleSystemRenderer>()).material = __instance.particleMats[___sprayCanMatsIndex];
					((Renderer)((Component)__instance.sprayCanNeedsShakingParticle).GetComponent<ParticleSystemRenderer>()).material = __instance.particleMats[___sprayCanMatsIndex];
					Plugin.Logger.LogDebug((object)$"Rerolled spray can #{((NetworkBehaviour)__instance).NetworkObjectId} color");
				}
			}
		}

		[HarmonyPatch(typeof(SprayPaintItem), "AddSprayPaintLocal")]
		[HarmonyPrefix]
		private static void PreAddSprayPaintLocal(SprayPaintItem __instance, ref int ___sprayPaintMask, ref int ___addSprayPaintWithFrameDelay, DecalProjector ___delayedSprayPaintDecal)
		{
			if (!Compatibility.DISABLE_SPRAY_PAINT_PATCHES)
			{
				int num = 67108864;
				if (((GrabbableObject)__instance).isInShipRoom || ((GrabbableObject)__instance).isInElevator || ((Object)(object)((GrabbableObject)__instance).playerHeldBy != (Object)null && (((GrabbableObject)__instance).playerHeldBy.isInHangarShipRoom || ((GrabbableObject)__instance).playerHeldBy.isInElevator)) || StartOfRound.Instance.inShipPhase || (Object)(object)RoundManager.Instance.mapPropsContainer == (Object)null)
				{
					___sprayPaintMask |= num;
				}
				else
				{
					___sprayPaintMask &= ~num;
				}
				if (___addSprayPaintWithFrameDelay > 0)
				{
					___addSprayPaintWithFrameDelay = 0;
					((Behaviour)___delayedSprayPaintDecal).enabled = true;
				}
			}
		}

		[HarmonyPatch(typeof(SprayPaintItem), "AddSprayPaintLocal")]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> TransAddSprayPaintLocal(IEnumerable<CodeInstruction> instructions)
		{
			if (Compatibility.DISABLE_SPRAY_PAINT_PATCHES)
			{
				return instructions;
			}
			List<CodeInstruction> list = instructions.ToList();
			for (int i = 1; i