Decompiled source of Test Crew ModPack v0.1.0

plugins/FacelessStalker/SlendermanMod.dll

Decompiled 2 years ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using LethalLib.Modules;
using Microsoft.CodeAnalysis;
using SlendermanMod.Behaviours;
using SlendermanMod.NetcodePatcher;
using Unity.Collections;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.AI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("")]
[assembly: AssemblyCompany("SlendermanMod")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("A Lethal Company plugin that adds the famous stalking Slenderman entity to the game.")]
[assembly: AssemblyFileVersion("1.1.5.0")]
[assembly: AssemblyInformationalVersion("1.1.5")]
[assembly: AssemblyProduct("SlendermanMod")]
[assembly: AssemblyTitle("SlendermanMod")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.5.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
[module: NetcodePatchedAssembly]
internal class <Module>
{
	static <Module>()
	{
	}
}
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 SlendermanMod
{
	[BepInPlugin("sparble.slendermanmod", "SlendermanMod", "1.1.5")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		private const string GUID = "sparble.slendermanmod";

		private const string NAME = "SlendermanMod";

		private const string VERSION = "1.1.5";

		public static Harmony _harmony;

		public static EnemyType SlendermanEnemy;

		public static Item page1Item;

		public static Item page2Item;

		public static Item page3Item;

		public static Item page4Item;

		internal static ManualLogSource Logger;

		public static AssetBundle SlendermanAssets;

		public static float slendermanHauntCooldown;

		public static float slendermanHauntIntervalLength;

		public static float slendermanStalkingIntervalLength;

		public static float slendermanChaseDuration;

		public static bool slendermanFlipsLightBreaker;

		public static bool slendermanPlaysSpawningSound;

		public static bool slendermanPlaysApproachingSound;

		public static float slendermanApproachingSoundChance;

		public static float slendermanSpotFoundSoundChance;

		public static bool slendermanClosedDoorsTargetSwitch;

		public static float slendermanVolume;

		public static SlendermanConfig SlendermanConfig { get; internal set; }

		private static void NetcodePatcher()
		{
			Type[] types = Assembly.GetExecutingAssembly().GetTypes();
			for (int i = 0; i < types.Length; i++)
			{
				MethodInfo[] methods = types[i].GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic);
				foreach (MethodInfo methodInfo in methods)
				{
					if (methodInfo.GetCustomAttributes(typeof(RuntimeInitializeOnLoadMethodAttribute), inherit: false).Length != 0)
					{
						methodInfo.Invoke(null, null);
					}
				}
			}
		}

		private void Awake()
		{
			Logger = ((BaseUnityPlugin)this).Logger;
			Assets.PopulateAssets();
			SlendermanConfig = new SlendermanConfig(((BaseUnityPlugin)this).Config);
			NetcodePatcher();
			SlendermanEnemy = Assets.SlendermanAssets.LoadAsset<EnemyType>("SlendermanEnemy");
			TerminalNode val = Assets.SlendermanAssets.LoadAsset<TerminalNode>("SlendermanEnemyTN");
			NetworkPrefabs.RegisterNetworkPrefab(SlendermanEnemy.enemyPrefab);
			Enemies.RegisterEnemy(SlendermanEnemy, SyncedInstance<SlendermanConfig>.Instance.configSlendermanSpawnChances.Value, (LevelTypes)(-1), (SpawnType)0, val, (TerminalKeyword)null);
			string value = SlendermanConfig.configPageMoons.Value;
			(Dictionary<LevelTypes, int> spawnRateByLevelType, Dictionary<string, int> spawnRateByCustomLevelType) tuple = ConfigParsing(value);
			Dictionary<LevelTypes, int> item = tuple.spawnRateByLevelType;
			Dictionary<string, int> item2 = tuple.spawnRateByCustomLevelType;
			Item val2 = Assets.SlendermanAssets.LoadAsset<Item>("Assets/Items/page1Item.asset");
			SpawnSlendermanEnemyItem spawnSlendermanEnemyItem = val2.spawnPrefab.AddComponent<SpawnSlendermanEnemyItem>();
			((GrabbableObject)spawnSlendermanEnemyItem).grabbable = true;
			((GrabbableObject)spawnSlendermanEnemyItem).grabbableToEnemies = true;
			((GrabbableObject)spawnSlendermanEnemyItem).itemProperties = val2;
			Utilities.FixMixerGroups(val2.spawnPrefab);
			NetworkPrefabs.RegisterNetworkPrefab(val2.spawnPrefab);
			Items.RegisterScrap(val2, item, item2);
			Item val3 = Assets.SlendermanAssets.LoadAsset<Item>("Assets/Items/page2Item.asset");
			SpawnSlendermanEnemyItem spawnSlendermanEnemyItem2 = val3.spawnPrefab.AddComponent<SpawnSlendermanEnemyItem>();
			((GrabbableObject)spawnSlendermanEnemyItem2).grabbable = true;
			((GrabbableObject)spawnSlendermanEnemyItem2).grabbableToEnemies = true;
			((GrabbableObject)spawnSlendermanEnemyItem2).itemProperties = val3;
			Utilities.FixMixerGroups(val3.spawnPrefab);
			NetworkPrefabs.RegisterNetworkPrefab(val3.spawnPrefab);
			Items.RegisterScrap(val3, item, item2);
			Item val4 = Assets.SlendermanAssets.LoadAsset<Item>("Assets/Items/page3Item.asset");
			SpawnSlendermanEnemyItem spawnSlendermanEnemyItem3 = val4.spawnPrefab.AddComponent<SpawnSlendermanEnemyItem>();
			((GrabbableObject)spawnSlendermanEnemyItem3).grabbable = true;
			((GrabbableObject)spawnSlendermanEnemyItem3).grabbableToEnemies = true;
			((GrabbableObject)spawnSlendermanEnemyItem3).itemProperties = val4;
			Utilities.FixMixerGroups(val4.spawnPrefab);
			NetworkPrefabs.RegisterNetworkPrefab(val4.spawnPrefab);
			Items.RegisterScrap(val4, item, item2);
			Item val5 = Assets.SlendermanAssets.LoadAsset<Item>("Assets/Items/page4Item.asset");
			SpawnSlendermanEnemyItem spawnSlendermanEnemyItem4 = val5.spawnPrefab.AddComponent<SpawnSlendermanEnemyItem>();
			((GrabbableObject)spawnSlendermanEnemyItem4).grabbable = true;
			((GrabbableObject)spawnSlendermanEnemyItem4).grabbableToEnemies = true;
			((GrabbableObject)spawnSlendermanEnemyItem4).itemProperties = val5;
			Utilities.FixMixerGroups(val5.spawnPrefab);
			NetworkPrefabs.RegisterNetworkPrefab(val5.spawnPrefab);
			Items.RegisterScrap(val5, item, item2);
			slendermanHauntCooldown = SyncedInstance<SlendermanConfig>.Instance.configSlendermanHauntCooldown.Value;
			slendermanHauntIntervalLength = SyncedInstance<SlendermanConfig>.Instance.configSlendermanAbsentIntervalRate.Value;
			slendermanStalkingIntervalLength = SyncedInstance<SlendermanConfig>.Instance.configSlendermanStalkingIntervalRate.Value;
			slendermanChaseDuration = SyncedInstance<SlendermanConfig>.Instance.configSlendermanChaseDuration.Value;
			slendermanFlipsLightBreaker = SyncedInstance<SlendermanConfig>.Instance.configSlendermanLightBreaker.Value;
			slendermanVolume = SyncedInstance<SlendermanConfig>.Instance.configSlendermanVolume.Value;
			slendermanPlaysSpawningSound = SyncedInstance<SlendermanConfig>.Instance.configSlendermanPlaysSpawnSound.Value;
			slendermanPlaysApproachingSound = SyncedInstance<SlendermanConfig>.Instance.configSlendermanPlaysApproachingSound.Value;
			slendermanApproachingSoundChance = SyncedInstance<SlendermanConfig>.Instance.configSlendermanApproachingSoundChance.Value;
			slendermanSpotFoundSoundChance = SyncedInstance<SlendermanConfig>.Instance.configSlendermanSpotFoundSoundChance.Value;
			slendermanClosedDoorsTargetSwitch = SyncedInstance<SlendermanConfig>.Instance.configSlendermanDoorsClosedTargetSwitch.Value;
			Logger.LogInfo((object)"Plugin SlendermanMod is loaded!");
		}

		private (Dictionary<LevelTypes, int> spawnRateByLevelType, Dictionary<string, int> spawnRateByCustomLevelType) ConfigParsing(string configMoonRarity)
		{
			//IL_0077: 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)
			Dictionary<LevelTypes, int> dictionary = new Dictionary<LevelTypes, int>();
			Dictionary<string, int> dictionary2 = new Dictionary<string, int>();
			foreach (string item in from s in configMoonRarity.Split(',')
				select s.Trim())
			{
				string[] array = item.Split('@');
				if (array.Length != 2)
				{
					continue;
				}
				string text = array[0];
				if (int.TryParse(array[1], out var result))
				{
					if (Enum.TryParse<LevelTypes>(text, ignoreCase: true, out LevelTypes result2))
					{
						dictionary[result2] = result;
						Logger.LogInfo((object)$"Registered spawn rate for level type {result2} to {result}");
					}
					else
					{
						dictionary2[text] = result;
						Logger.LogInfo((object)$"Registered spawn rate for custom level type {text} to {result}");
					}
				}
			}
			return (dictionary, dictionary2);
		}
	}
	public static class Assets
	{
		public static AssetBundle SlendermanAssets;

		public static void PopulateAssets()
		{
			SlendermanAssets = AssetBundle.LoadFromFile(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "slendermanbundle"));
			if ((Object)(object)SlendermanAssets == (Object)null)
			{
				Plugin.Logger.LogError((object)"Failed to load slendermanbundle assets.");
			}
		}
	}
	[Serializable]
	public class SlendermanConfig : SyncedInstance<SlendermanConfig>
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static HandleNamedMessageDelegate <0>__OnRequestSync;

			public static HandleNamedMessageDelegate <1>__OnReceiveSync;
		}

		public readonly ConfigEntry<string> configPageMoons;

		public readonly ConfigEntry<int> configSlendermanSpawnChances;

		public readonly ConfigEntry<float> configSlendermanHauntCooldown;

		public readonly ConfigEntry<float> configSlendermanAbsentIntervalRate;

		public readonly ConfigEntry<float> configSlendermanStalkingIntervalRate;

		public readonly ConfigEntry<float> configSlendermanChaseDuration;

		public readonly ConfigEntry<float> configSlendermanVolume;

		public readonly ConfigEntry<bool> configSlendermanLightBreaker;

		public readonly ConfigEntry<bool> configSlendermanPlaysSpawnSound;

		public readonly ConfigEntry<bool> configSlendermanPlaysApproachingSound;

		public readonly ConfigEntry<float> configSlendermanApproachingSoundChance;

		public readonly ConfigEntry<float> configSlendermanSpotFoundSoundChance;

		public readonly ConfigEntry<bool> configSlendermanDoorsClosedTargetSwitch;

		public SlendermanConfig(ConfigFile cfg)
		{
			InitInstance(this);
			configPageMoons = cfg.Bind<string>("PageItem.Values", "Page Spawning", "AssuranceLevel@5,VowLevel@20,MarchLevel@20,DineLevel@15,RendLevel@15,TitanLevel@10", "The LevelTypes/Moons that the page items can spawn on. \nUses the format 'Moon@Rarity,Moon2@Rarity2,' etc, also supports custom moons.");
			configSlendermanSpawnChances = cfg.Bind<int>("Slenderman", "Natural Spawn Chances", 0, "The chances of spawning Slenderman, independent from any pages. \nDefault value is 0, which will cause him to never spawn naturally and only spawn him when a page is picked up.");
			configSlendermanHauntCooldown = cfg.Bind<float>("Slenderman.Behavior", "Absent State Cooldown", 35f, "The duration of the cooldown after first picking up a page, looking at slenderman and after a chase before Slenderman tries to spawn again (in seconds). \nThe higher the value, the more time the player has before Slenderman spawns in.");
			configSlendermanAbsentIntervalRate = cfg.Bind<float>("Slenderman.Behavior", "Absent State Interval Length", 15f, "The duration of intervals of the Slenderman trying to find a haunting spot during his Absent state (in seconds). If he fails to find a spot, he will wait x seconds again before trying to find a spot again. \nThe higher the value, the longer the intervals are and the longer it will take for him to try to re-spawn. \nHigh numbers may result in him almost never spawning at all on small moons without many outside objects. (0 = Very frequent spawn intervals, 60 = Wait 60 seconds before trying to find a spawning spot again).");
			configSlendermanStalkingIntervalRate = cfg.Bind<float>("Slenderman.Behavior", "Stalking State Interval Length", 20f, "The duration of intervals (in seconds) of the Slenderman stalking the player before creeping closer - The value MUST be higher than 4.0 and it is recommended to not set this number too high or low. \nThe higher the value, the longer the intervals are and the longer it takes him to creep closer to the haunted player. \nHigh numbers mean the player has much time to spot Slenderman, while very low numbers mean they will have to constantly check their surroundings. (4.5 = Pretty much immediate chase, 60 = Wait 60 seconds before creeping closer).");
			configSlendermanChaseDuration = cfg.Bind<float>("Slenderman.Behavior", "Chase Duration", 20f, "The duration of a chase (in seconds).");
			configSlendermanLightBreaker = cfg.Bind<bool>("Slenderman.Behavior", "Light Breaker Flip", false, "Whether Slenderman should shut off the facility lights after being seen the first time.");
			configSlendermanPlaysSpawnSound = cfg.Bind<bool>("Slenderman.Behavior", "Play Spawning Sound", true, "Whether the global spawning sound should be played after Slenderman spawned in the round (both naturally and through picking up a page).");
			configSlendermanPlaysApproachingSound = cfg.Bind<bool>("Slenderman.Behavior", "Play Approaching Sound", true, "Whether the approaching sound should be enabled for the haunted player.");
			configSlendermanApproachingSoundChance = cfg.Bind<float>("Slenderman.Behavior", "Approaching Sound Chance", 25f, "(Requires the 'Play Approaching Sound' option to be set to 'true') - The chance of Slenderman playing a static noise for the haunted player when creeping closer in % (must be between 0 and 100) - 0 means no sound will be played at all, 100 means for every interval he will play the sound 100%.");
			configSlendermanSpotFoundSoundChance = cfg.Bind<float>("Slenderman.Behavior", "Play Spot Found-Sound", 50f, "Chance for the bass sound playing after Slenderman found a spot to spawn in. Value in %, must be between 0 and 100 (0 = Never play the sound, 100 = always play the sound).");
			configSlendermanDoorsClosedTargetSwitch = cfg.Bind<bool>("Slenderman.Behavior", "Closed Doors Target Switch", true, "Whether Slenderman should change targets when the haunted player is inside the ship and the doors are closed during a chase.");
			configSlendermanVolume = cfg.Bind<float>("Slenderman.Volume", "Slenderman Volume", 1f, "The volume of the Slenderman enemy voice. 1.0 means 100% (default value), 0.8 means 80% etc.");
		}

		public static void RequestSync()
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			if (!SyncedInstance<SlendermanConfig>.IsClient)
			{
				return;
			}
			FastBufferWriter val = default(FastBufferWriter);
			((FastBufferWriter)(ref val))..ctor(SyncedInstance<SlendermanConfig>.IntSize, (Allocator)2, -1);
			try
			{
				SyncedInstance<SlendermanConfig>.MessageManager.SendNamedMessage("ModName_OnRequestConfigSync", 0uL, val, (NetworkDelivery)3);
			}
			finally
			{
				((IDisposable)(FastBufferWriter)(ref val)).Dispose();
			}
		}

		public static void OnRequestSync(ulong clientId, FastBufferReader _)
		{
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			if (!SyncedInstance<SlendermanConfig>.IsHost)
			{
				return;
			}
			Plugin.Logger.LogInfo((object)$"Config sync request received from client: {clientId}");
			byte[] array = SyncedInstance<SlendermanConfig>.SerializeToBytes(SyncedInstance<SlendermanConfig>.Instance);
			int num = array.Length;
			FastBufferWriter val = default(FastBufferWriter);
			((FastBufferWriter)(ref val))..ctor(num + SyncedInstance<SlendermanConfig>.IntSize, (Allocator)2, -1);
			try
			{
				((FastBufferWriter)(ref val)).WriteValueSafe<int>(ref num, default(ForPrimitives));
				((FastBufferWriter)(ref val)).WriteBytesSafe(array, -1, 0);
				SyncedInstance<SlendermanConfig>.MessageManager.SendNamedMessage("ModName_OnReceiveConfigSync", clientId, val, (NetworkDelivery)3);
			}
			catch (Exception arg)
			{
				Plugin.Logger.LogInfo((object)$"Error occurred syncing config with client: {clientId}\n{arg}");
			}
			finally
			{
				((IDisposable)(FastBufferWriter)(ref val)).Dispose();
			}
		}

		public static void OnReceiveSync(ulong _, FastBufferReader reader)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			if (!((FastBufferReader)(ref reader)).TryBeginRead(SyncedInstance<SlendermanConfig>.IntSize))
			{
				Plugin.Logger.LogError((object)"Config sync error: Could not begin reading buffer.");
				return;
			}
			int num = default(int);
			((FastBufferReader)(ref reader)).ReadValueSafe<int>(ref num, default(ForPrimitives));
			if (!((FastBufferReader)(ref reader)).TryBeginRead(num))
			{
				Plugin.Logger.LogError((object)"Config sync error: Host could not sync.");
				return;
			}
			byte[] data = new byte[num];
			((FastBufferReader)(ref reader)).ReadBytesSafe(ref data, num, 0);
			SyncedInstance<SlendermanConfig>.SyncInstance(data);
			Plugin.Logger.LogInfo((object)"Successfully synced config with host.");
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(PlayerControllerB), "ConnectClientToPlayerObject")]
		public static void InitializeLocalPlayer()
		{
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Expected O, but got Unknown
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			if (SyncedInstance<SlendermanConfig>.IsHost)
			{
				CustomMessagingManager messageManager = SyncedInstance<SlendermanConfig>.MessageManager;
				object obj = <>O.<0>__OnRequestSync;
				if (obj == null)
				{
					HandleNamedMessageDelegate val = OnRequestSync;
					<>O.<0>__OnRequestSync = val;
					obj = (object)val;
				}
				messageManager.RegisterNamedMessageHandler("SlendermanMod_OnRequestConfigSync", (HandleNamedMessageDelegate)obj);
				SyncedInstance<SlendermanConfig>.Synced = true;
				return;
			}
			SyncedInstance<SlendermanConfig>.Synced = false;
			CustomMessagingManager messageManager2 = SyncedInstance<SlendermanConfig>.MessageManager;
			object obj2 = <>O.<1>__OnReceiveSync;
			if (obj2 == null)
			{
				HandleNamedMessageDelegate val2 = OnReceiveSync;
				<>O.<1>__OnReceiveSync = val2;
				obj2 = (object)val2;
			}
			messageManager2.RegisterNamedMessageHandler("SlendermanMod_OnReceiveConfigSync", (HandleNamedMessageDelegate)obj2);
			RequestSync();
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(GameNetworkManager), "StartDisconnect")]
		public static void PlayerLeave()
		{
			SyncedInstance<SlendermanConfig>.RevertSync();
		}
	}
	internal class SlendermanEnemyAI : EnemyAI
	{
		private enum States
		{
			Absent,
			Stalking,
			Vanishing,
			Chasing
		}

		public PlayerControllerB hauntingPlayer;

		public Renderer enemyMeshRenderer;

		public float timer;

		private float stalkingTimer;

		private float chaseTimer;

		private bool couldNotStareLastAttempt;

		private bool seenByPlayerThisTime;

		private bool disappearWithDelay;

		private bool enemyMeshEnabled;

		private bool vanishWithSound;

		private bool vanishWithJumpscare;

		private bool switchedHauntingPlayer;

		private bool toggleLights;

		private int timesSeenByPlayer;

		private float hauntingIntervalTime;

		private float stalkingIntervalTime;

		private float chaseDuration;

		private float hauntCooldown;

		private bool canFlipLightsBreaker;

		private float slendermanVoiceVolume;

		private bool spawningSoundEnabled;

		private bool approachingSoundEnabled;

		private float approachingSoundChance;

		private float spotFoundSoundChance;

		private bool switchTargetWhenDoorsClosed;

		public static int numSlendermanEnemiesInLevel;

		private int doorsTimesSwitched;

		private bool creepingCloser;

		private float creepingCloserTimer = 4f;

		public GameObject[] outsideNodes;

		public NavMeshHit navHit;

		private Coroutine disappearOnDelayCoroutine;

		public Transform turnCompass;

		public AudioClip chaseSFX;

		public AudioClip ambienceSFX;

		public AudioClip disappearSFX;

		public AudioClip jumpscareSFX;

		public AudioClip approachingSFX;

		public AudioClip spawnFirstTimeSFX;

		public override void Start()
		{
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			((EnemyAI)this).Start();
			if (((NetworkBehaviour)this).IsServer)
			{
				base.agent = ((Component)this).GetComponent<NavMeshAgent>();
				if ((Object)(object)base.agent == (Object)null)
				{
					Debug.LogError((object)("NavMeshAgent component not found on " + ((Object)this).name));
				}
				((Behaviour)base.agent).enabled = true;
				DisableMesh();
				outsideNodes = GameObject.FindGameObjectsWithTag("OutsideAINode");
				ChoosePlayerToHaunt();
				navHit = default(NavMeshHit);
				hauntCooldown = Plugin.slendermanHauntCooldown;
				_ = hauntCooldown;
				hauntingIntervalTime = Plugin.slendermanHauntIntervalLength;
				_ = hauntingIntervalTime;
				stalkingIntervalTime = Plugin.slendermanStalkingIntervalLength;
				_ = stalkingIntervalTime;
				chaseDuration = Plugin.slendermanChaseDuration;
				_ = chaseDuration;
				canFlipLightsBreaker = Plugin.slendermanFlipsLightBreaker;
				_ = canFlipLightsBreaker;
				spawningSoundEnabled = Plugin.slendermanPlaysSpawningSound;
				_ = spawningSoundEnabled;
				approachingSoundEnabled = Plugin.slendermanPlaysApproachingSound;
				_ = approachingSoundEnabled;
				approachingSoundChance = Plugin.slendermanApproachingSoundChance;
				_ = approachingSoundChance;
				spotFoundSoundChance = Plugin.slendermanSpotFoundSoundChance;
				_ = spotFoundSoundChance;
				switchTargetWhenDoorsClosed = Plugin.slendermanClosedDoorsTargetSwitch;
				_ = switchTargetWhenDoorsClosed;
				Debug.Log((object)"Slenderman spawned in Level.");
				SyncNumSlendermanEnemiesInLevelClientRpc(1);
				slendermanVoiceVolume = Plugin.slendermanVolume;
				SetCreatureVoiceVolumeClientRpc(slendermanVoiceVolume);
				AnimStalkingBaseClientRpc();
				TeleportAway();
				if (spawningSoundEnabled)
				{
					PlaySfxClientRpc("spawnFirstTimeSFX");
				}
			}
		}

		public override void OnDestroy()
		{
			numSlendermanEnemiesInLevel = 0;
			((EnemyAI)this).OnDestroy();
		}

		private void ChoosePlayerToHaunt()
		{
			if (!((NetworkBehaviour)this).IsServer)
			{
				return;
			}
			SyncTimesSeenByPlayerClientRpc(0);
			float num = 0f;
			float num2 = 0f;
			int num3 = 0;
			int num4 = 0;
			for (int i = 0; i < 4; i++)
			{
				if (StartOfRound.Instance.gameStats.allPlayerStats[i].turnAmount > num3)
				{
					num3 = StartOfRound.Instance.gameStats.allPlayerStats[i].turnAmount;
					num4 = i;
				}
				if (StartOfRound.Instance.allPlayerScripts[i].insanityLevel > num)
				{
					num = StartOfRound.Instance.allPlayerScripts[i].insanityLevel;
					num2 = i;
				}
			}
			int[] array = new int[4];
			for (int j = 0; j < 4; j++)
			{
				if (!StartOfRound.Instance.allPlayerScripts[j].isPlayerControlled)
				{
					array[j] = 0;
					continue;
				}
				array[j] += 80;
				if (num2 == (float)j && num > 1f)
				{
					array[j] += 50;
				}
				if (num4 == j)
				{
					array[j] += 30;
				}
				if (!StartOfRound.Instance.allPlayerScripts[j].hasBeenCriticallyInjured)
				{
					array[j] += 10;
				}
				if ((Object)(object)StartOfRound.Instance.allPlayerScripts[j].currentlyHeldObjectServer != (Object)null && StartOfRound.Instance.allPlayerScripts[j].currentlyHeldObjectServer.scrapValue > 100)
				{
					array[j] += 30;
				}
			}
			hauntingPlayer = StartOfRound.Instance.allPlayerScripts[RoundManager.Instance.GetRandomWeightedIndex(array, (Random)null)];
			if (hauntingPlayer.isPlayerDead)
			{
				for (int k = 0; k < StartOfRound.Instance.allPlayerScripts.Length; k++)
				{
					if (!StartOfRound.Instance.allPlayerScripts[k].isPlayerDead)
					{
						hauntingPlayer = StartOfRound.Instance.allPlayerScripts[k];
						break;
					}
				}
			}
			switchedHauntingPlayer = false;
			HandleChangeHauntingPlayerClientRpc((int)hauntingPlayer.playerClientId);
		}

		private Vector3 TryFindingHauntPosition(bool mustBeInLOS = true)
		{
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			if (hauntingPlayer.isInsideFactory)
			{
				for (int i = 0; i < base.allAINodes.Length; i++)
				{
					if ((!mustBeInLOS || !Physics.Linecast(((Component)hauntingPlayer.gameplayCamera).transform.position, base.allAINodes[i].transform.position, StartOfRound.Instance.collidersAndRoomMaskAndDefault)) && !hauntingPlayer.HasLineOfSightToPosition(base.allAINodes[i].transform.position, 60f, 40, 25f))
					{
						SetStalkingPosition(base.allAINodes[i].transform.position);
						return base.allAINodes[i].transform.position;
					}
				}
			}
			else if (!hauntingPlayer.isInsideFactory)
			{
				for (int j = 0; j < outsideNodes.Length; j++)
				{
					if ((!mustBeInLOS || !Physics.Linecast(((Component)hauntingPlayer.gameplayCamera).transform.position, outsideNodes[j].transform.position, StartOfRound.Instance.collidersAndRoomMaskAndDefault)) && !hauntingPlayer.HasLineOfSightToPosition(outsideNodes[j].transform.position, 70f, 100, 60f))
					{
						SetStalkingPosition(base.allAINodes[j].transform.position);
						return outsideNodes[j].transform.position;
					}
				}
			}
			couldNotStareLastAttempt = true;
			return Vector3.zero;
		}

		private void SetStalkingPosition(Vector3 newPosition)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: 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)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			if (((NetworkBehaviour)this).IsServer && base.currentBehaviourStateIndex != 1)
			{
				((EnemyAI)this).SwitchToBehaviourStateOnLocalClient(1);
				couldNotStareLastAttempt = false;
				Vector3 randomNavMeshPositionInRadiusSpherical = RoundManager.Instance.GetRandomNavMeshPositionInRadiusSpherical(newPosition, 1f, navHit);
				base.agent.Warp(randomNavMeshPositionInRadiusSpherical);
				base.moveTowardsDestination = false;
				base.destination = ((Component)this).transform.position;
				base.agent.SetDestination(base.destination);
				base.agent.speed = 0f;
				stalkingTimer = stalkingIntervalTime;
				seenByPlayerThisTime = false;
				if ((float)Random.Range(0, 100) < spotFoundSoundChance)
				{
					PlaySfxHauntedPlayerClientRpc("ambienceSFX");
				}
			}
		}

		private IEnumerator disappearOnDelay()
		{
			if (vanishWithJumpscare)
			{
				PlaySfxHauntedPlayerClientRpc("jumpscareSFX");
				vanishWithJumpscare = false;
			}
			yield return (object)new WaitForSeconds(1.5f);
			Disappear();
			disappearOnDelayCoroutine = null;
			if (toggleLights)
			{
				FlipLightsBreaker();
				toggleLights = false;
				canFlipLightsBreaker = false;
			}
			if (vanishWithSound)
			{
				PlaySfxHauntedPlayerClientRpc("disappearSFX");
				vanishWithSound = false;
			}
		}

		private void Disappear()
		{
			if (((NetworkBehaviour)this).IsServer)
			{
				timer = 0f;
				DisableMesh();
				disappearWithDelay = false;
				TeleportAway();
				((EnemyAI)this).SwitchToBehaviourStateOnLocalClient(0);
			}
		}

		private void StartCreepingTowardsPlayer(float movementSpeed = 10f)
		{
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			if (!((NetworkBehaviour)this).IsServer)
			{
				return;
			}
			if (!creepingCloser)
			{
				DisableMesh();
				creepingCloser = true;
				base.agent.speed = movementSpeed;
				base.agent.acceleration = 24f;
				((EnemyAI)this).SetDestinationToPosition(((Component)hauntingPlayer).transform.position, false);
				base.moveTowardsDestination = true;
				creepingCloserTimer = 4f;
				timer = 0f;
				if (approachingSoundEnabled && (float)Random.Range(0, 100) <= approachingSoundChance)
				{
					PlaySfxHauntedPlayerClientRpc("approachingSFX", toggleSpatialBlend: false);
				}
			}
			else
			{
				Debug.Log((object)"Slenderman already creeping closer, abort.");
			}
		}

		private void StopCreepingTowardsPlayer()
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			if (((NetworkBehaviour)this).IsServer)
			{
				creepingCloser = false;
				base.agent.speed = 0f;
				base.moveTowardsDestination = false;
				float num = Vector3.Distance(((Component)hauntingPlayer.gameplayCamera).transform.position, ((Component)this).transform.position);
				if (num >= 60f)
				{
					AnimStalkingBaseClientRpc();
				}
				else if (num < 60f && num >= 30f)
				{
					AnimStalking1ClientRpc();
				}
				else
				{
					AnimStalking2ClientRpc();
				}
				if (!enemyMeshEnabled)
				{
					EnableMesh();
				}
			}
		}

		private void SwitchHauntingPlayerTo(PlayerControllerB newHauntingTarget)
		{
			if (!((NetworkBehaviour)this).IsServer)
			{
				return;
			}
			if ((Object)(object)newHauntingTarget != (Object)null)
			{
				hauntingPlayer = null;
				hauntingPlayer = newHauntingTarget;
				SyncTimesSeenByPlayerClientRpc(0);
				if (hauntingPlayer.isPlayerDead)
				{
					for (int i = 0; i < StartOfRound.Instance.allPlayerScripts.Length; i++)
					{
						if (!StartOfRound.Instance.allPlayerScripts[i].isPlayerDead)
						{
							hauntingPlayer = StartOfRound.Instance.allPlayerScripts[i];
							break;
						}
					}
				}
				HandleChangeHauntingPlayerClientRpc((int)hauntingPlayer.playerClientId);
			}
			else
			{
				Debug.LogWarning((object)"Error: Could not set new hauntingPlayer as assigned newHauntingTarget == null!");
			}
			switchedHauntingPlayer = false;
		}

		private void StartChasing()
		{
			if (((NetworkBehaviour)this).IsServer && base.currentBehaviourStateIndex != 3)
			{
				((EnemyAI)this).SwitchToBehaviourStateOnLocalClient(3);
				disappearWithDelay = false;
				StartChaseAnimClientRpc();
				chaseTimer = chaseDuration;
				timer = 0f;
				base.agent.speed = 13f;
				base.agent.acceleration = 26f;
				base.moveTowardsDestination = true;
				PlaySfxClientRpc("chaseSFX", toggleSpatialBlend: false);
				MessWithLights();
				EnableMesh(visibleToEveryone: true);
			}
		}

		private void StopChasing()
		{
			if (((NetworkBehaviour)this).IsServer)
			{
				base.agent.speed = 0f;
				base.moveTowardsDestination = false;
				StopChaseAnimClientRpc();
				base.creatureVoice.Stop();
				base.creatureSFX.Stop();
				seenByPlayerThisTime = false;
				doorsTimesSwitched = 0;
				((EnemyAI)this).SwitchToBehaviourStateOnLocalClient(2);
			}
		}

		private void TeleportAway()
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			if (((NetworkBehaviour)this).IsServer)
			{
				int num = Random.Range(25, 200);
				Vector3 val = ((Component)hauntingPlayer).transform.position + Vector3.Scale(new Vector3((float)(-num), 0f, (float)(-num)), ((Component)GameNetworkManager.Instance.localPlayerController).transform.forward);
				base.agent.Warp(val);
			}
		}

		private void HandleChangeHauntingPlayer(int hauntingPlayerId)
		{
			if (hauntingPlayerId == -69420)
			{
				hauntingPlayer = null;
				return;
			}
			PlayerControllerB val = StartOfRound.Instance.allPlayerScripts[hauntingPlayerId];
			hauntingPlayer = val;
		}

		[ClientRpc]
		private void HandleChangeHauntingPlayerClientRpc(int hauntingPlayerId)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
				{
					ClientRpcParams val = default(ClientRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(198283396u, val, (RpcDelivery)0);
					BytePacker.WriteValueBitPacked(val2, hauntingPlayerId);
					((NetworkBehaviour)this).__endSendClientRpc(ref val2, 198283396u, val, (RpcDelivery)0);
				}
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
				{
					HandleChangeHauntingPlayer(hauntingPlayerId);
				}
			}
		}

		[ClientRpc]
		private void SyncTimesSeenByPlayerClientRpc(int timesSeen)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
			{
				ClientRpcParams val = default(ClientRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(2385237018u, val, (RpcDelivery)0);
				BytePacker.WriteValueBitPacked(val2, timesSeen);
				((NetworkBehaviour)this).__endSendClientRpc(ref val2, 2385237018u, val, (RpcDelivery)0);
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost) && !((Object)(object)GameNetworkManager.Instance.localPlayerController == (Object)null))
			{
				switch (timesSeen)
				{
				case 0:
					timesSeenByPlayer = 0;
					break;
				case 1:
					timesSeenByPlayer++;
					break;
				case -1:
					timesSeenByPlayer--;
					break;
				default:
					Debug.LogWarning((object)"Slenderman: Synchronization of timesSeenByPlayer - invalid number!");
					break;
				}
			}
		}

		[ClientRpc]
		private void SyncNumSlendermanEnemiesInLevelClientRpc(int numSlendermanEnemies)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
			{
				ClientRpcParams val = default(ClientRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(2082126723u, val, (RpcDelivery)0);
				BytePacker.WriteValueBitPacked(val2, numSlendermanEnemies);
				((NetworkBehaviour)this).__endSendClientRpc(ref val2, 2082126723u, val, (RpcDelivery)0);
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost) && !((Object)(object)GameNetworkManager.Instance.localPlayerController == (Object)null))
			{
				switch (numSlendermanEnemies)
				{
				case 0:
					numSlendermanEnemiesInLevel = 0;
					break;
				case 1:
					numSlendermanEnemiesInLevel++;
					break;
				case -1:
					numSlendermanEnemiesInLevel--;
					break;
				default:
					Debug.LogWarning((object)"Slenderman: Synchronization of numSlendermanEnemiesInLevel - invalid number!");
					break;
				}
			}
		}

		[ClientRpc]
		private void StartChaseAnimClientRpc()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
				{
					ClientRpcParams val = default(ClientRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(556991154u, val, (RpcDelivery)0);
					((NetworkBehaviour)this).__endSendClientRpc(ref val2, 556991154u, val, (RpcDelivery)0);
				}
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
				{
					base.creatureAnimator.SetBool("StalkingBase", false);
					base.creatureAnimator.SetBool("Stalking1", false);
					base.creatureAnimator.SetBool("Stalking2", false);
					base.creatureAnimator.SetBool("Chase", true);
				}
			}
		}

		[ClientRpc]
		private void StopChaseAnimClientRpc()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
				{
					ClientRpcParams val = default(ClientRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(4108450410u, val, (RpcDelivery)0);
					((NetworkBehaviour)this).__endSendClientRpc(ref val2, 4108450410u, val, (RpcDelivery)0);
				}
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
				{
					base.creatureAnimator.SetBool("Chase", false);
					base.creatureAnimator.SetBool("StalkingBase", true);
				}
			}
		}

		[ClientRpc]
		private void AnimStalkingBaseClientRpc()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
				{
					ClientRpcParams val = default(ClientRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(916132259u, val, (RpcDelivery)0);
					((NetworkBehaviour)this).__endSendClientRpc(ref val2, 916132259u, val, (RpcDelivery)0);
				}
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
				{
					base.creatureAnimator.SetBool("StalkingBase", true);
					base.creatureAnimator.SetBool("Stalking1", false);
					base.creatureAnimator.SetBool("Stalking2", false);
					base.creatureAnimator.SetBool("Chase", false);
				}
			}
		}

		[ClientRpc]
		private void AnimStalking1ClientRpc()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
				{
					ClientRpcParams val = default(ClientRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(2420316138u, val, (RpcDelivery)0);
					((NetworkBehaviour)this).__endSendClientRpc(ref val2, 2420316138u, val, (RpcDelivery)0);
				}
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
				{
					base.creatureAnimator.SetBool("StalkingBase", false);
					base.creatureAnimator.SetBool("Stalking1", true);
					base.creatureAnimator.SetBool("Stalking2", false);
					base.creatureAnimator.SetBool("Chase", false);
				}
			}
		}

		[ClientRpc]
		private void AnimStalking2ClientRpc()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
				{
					ClientRpcParams val = default(ClientRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(2779633377u, val, (RpcDelivery)0);
					((NetworkBehaviour)this).__endSendClientRpc(ref val2, 2779633377u, val, (RpcDelivery)0);
				}
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
				{
					base.creatureAnimator.SetBool("StalkingBase", false);
					base.creatureAnimator.SetBool("Stalking1", false);
					base.creatureAnimator.SetBool("Stalking2", true);
					base.creatureAnimator.SetBool("Chase", false);
				}
			}
		}

		[ClientRpc]
		private void SetCreatureVoiceVolumeClientRpc(float creatureVoiceVolume)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
				{
					ClientRpcParams val = default(ClientRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(3175837790u, val, (RpcDelivery)0);
					((FastBufferWriter)(ref val2)).WriteValueSafe<float>(ref creatureVoiceVolume, default(ForPrimitives));
					((NetworkBehaviour)this).__endSendClientRpc(ref val2, 3175837790u, val, (RpcDelivery)0);
				}
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
				{
					base.creatureVoice.volume = creatureVoiceVolume;
				}
			}
		}

		[ClientRpc]
		private void PlaySfxHauntedPlayerClientRpc(string sfxClipName, bool toggleSpatialBlend = true)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
			{
				ClientRpcParams val = default(ClientRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(1031461232u, val, (RpcDelivery)0);
				bool flag = sfxClipName != null;
				((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref flag, default(ForPrimitives));
				if (flag)
				{
					((FastBufferWriter)(ref val2)).WriteValueSafe(sfxClipName, false);
				}
				((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref toggleSpatialBlend, default(ForPrimitives));
				((NetworkBehaviour)this).__endSendClientRpc(ref val2, 1031461232u, val, (RpcDelivery)0);
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost) && !((Object)(object)hauntingPlayer != (Object)(object)GameNetworkManager.Instance.localPlayerController))
			{
				if (toggleSpatialBlend)
				{
					base.creatureVoice.spatialBlend = 0f;
					base.creatureSFX.spatialBlend = 0f;
				}
				switch (sfxClipName)
				{
				case "ambienceSFX":
					base.creatureVoice.clip = ambienceSFX;
					base.creatureVoice.Play();
					break;
				case "disappearSFX":
					base.creatureSFX.clip = disappearSFX;
					base.creatureSFX.Play();
					break;
				case "chaseSFX":
					base.creatureSFX.clip = chaseSFX;
					base.creatureSFX.Play();
					break;
				case "jumpscareSFX":
					base.creatureVoice.clip = jumpscareSFX;
					base.creatureVoice.Play();
					break;
				case "spawnFirstTimeSFX":
					base.creatureVoice.clip = spawnFirstTimeSFX;
					base.creatureVoice.Play();
					break;
				case "approachingSFX":
					base.creatureVoice.clip = approachingSFX;
					base.creatureVoice.Play();
					break;
				default:
					Debug.LogWarning((object)"Slenderman: Couldn't find assigned SFX sound!");
					return;
				}
				if (toggleSpatialBlend)
				{
					base.creatureVoice.spatialBlend = 1f;
					base.creatureSFX.spatialBlend = 1f;
				}
			}
		}

		[ClientRpc]
		private void PlaySfxClientRpc(string sfxClipName, bool toggleSpatialBlend = true)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
			{
				ClientRpcParams val = default(ClientRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(1861453801u, val, (RpcDelivery)0);
				bool flag = sfxClipName != null;
				((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref flag, default(ForPrimitives));
				if (flag)
				{
					((FastBufferWriter)(ref val2)).WriteValueSafe(sfxClipName, false);
				}
				((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref toggleSpatialBlend, default(ForPrimitives));
				((NetworkBehaviour)this).__endSendClientRpc(ref val2, 1861453801u, val, (RpcDelivery)0);
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
			{
				if (toggleSpatialBlend)
				{
					base.creatureVoice.spatialBlend = 0f;
					base.creatureSFX.spatialBlend = 0f;
				}
				switch (sfxClipName)
				{
				case "ambienceSFX":
					base.creatureVoice.clip = ambienceSFX;
					base.creatureVoice.Play();
					break;
				case "disappearSFX":
					base.creatureSFX.clip = disappearSFX;
					base.creatureSFX.Play();
					break;
				case "chaseSFX":
					base.creatureSFX.clip = chaseSFX;
					base.creatureSFX.Play();
					break;
				case "jumpscareSFX":
					base.creatureVoice.clip = jumpscareSFX;
					base.creatureVoice.Play();
					break;
				case "spawnFirstTimeSFX":
					base.creatureVoice.clip = spawnFirstTimeSFX;
					base.creatureVoice.Play();
					break;
				case "approachingSFX":
					base.creatureVoice.clip = approachingSFX;
					base.creatureVoice.Play();
					break;
				default:
					Debug.LogWarning((object)"Slenderman: Couldn't find assigned SFX sound!");
					return;
				}
				if (toggleSpatialBlend)
				{
					base.creatureVoice.spatialBlend = 1f;
					base.creatureSFX.spatialBlend = 1f;
				}
			}
		}

		private void DisableMesh()
		{
			if (((NetworkBehaviour)this).IsServer)
			{
				enemyMeshEnabled = false;
				DisableEnemyMeshClientRpc();
			}
		}

		[ClientRpc]
		private void DisableEnemyMeshClientRpc()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
			{
				ClientRpcParams val = default(ClientRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(2930548839u, val, (RpcDelivery)0);
				((NetworkBehaviour)this).__endSendClientRpc(ref val2, 2930548839u, val, (RpcDelivery)0);
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
			{
				if ((Object)(object)enemyMeshRenderer != (Object)null)
				{
					enemyMeshRenderer.enabled = false;
				}
				else
				{
					Debug.LogError((object)"Slenderman Renderer not found on this GameObject!");
				}
			}
		}

		private void EnableMesh(bool visibleToEveryone = false)
		{
			if (((NetworkBehaviour)this).IsServer)
			{
				enemyMeshEnabled = true;
				if (visibleToEveryone)
				{
					EnableEnemyMeshEveryoneClientRpc();
				}
				else
				{
					EnableEnemyMeshClientRpc();
				}
			}
		}

		[ClientRpc]
		private void EnableEnemyMeshEveryoneClientRpc()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
			{
				ClientRpcParams val = default(ClientRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(795220426u, val, (RpcDelivery)0);
				((NetworkBehaviour)this).__endSendClientRpc(ref val2, 795220426u, val, (RpcDelivery)0);
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
			{
				if ((Object)(object)enemyMeshRenderer != (Object)null)
				{
					enemyMeshRenderer.enabled = true;
				}
				else
				{
					Debug.LogError((object)"Slenderman Renderer not found on this GameObject!");
				}
			}
		}

		[ClientRpc]
		private void EnableEnemyMeshClientRpc()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
			{
				ClientRpcParams val = default(ClientRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(1983075969u, val, (RpcDelivery)0);
				((NetworkBehaviour)this).__endSendClientRpc(ref val2, 1983075969u, val, (RpcDelivery)0);
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost) && !((Object)(object)hauntingPlayer != (Object)(object)GameNetworkManager.Instance.localPlayerController))
			{
				if ((Object)(object)enemyMeshRenderer != (Object)null)
				{
					enemyMeshRenderer.enabled = true;
				}
				else
				{
					Debug.LogError((object)"Couldn't enable Slenderman Renderer for hauntingPlayer only!");
				}
			}
		}

		[ClientRpc]
		private void MessWithLightsClientRpc()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
			{
				ClientRpcParams val = default(ClientRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(3661018855u, val, (RpcDelivery)0);
				((NetworkBehaviour)this).__endSendClientRpc(ref val2, 3661018855u, val, (RpcDelivery)0);
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 2 || (!networkManager.IsClient && !networkManager.IsHost))
			{
				return;
			}
			if ((Object)(object)hauntingPlayer == (Object)null)
			{
				Debug.LogWarning((object)"Error: Could not increase fear level - hauntingPlayer == null!");
			}
			else if (!((Object)(object)hauntingPlayer != (Object)(object)GameNetworkManager.Instance.localPlayerController))
			{
				if (timesSeenByPlayer > 0)
				{
					GameNetworkManager.Instance.localPlayerController.JumpToFearLevel(0.8f, true);
					Debug.Log((object)("Jump to fear level 0.8 for player: " + ((Object)hauntingPlayer).name));
				}
				else
				{
					GameNetworkManager.Instance.localPlayerController.JumpToFearLevel(0.2f, true);
					Debug.Log((object)("Jump to fear level 0.2 for player: " + ((Object)hauntingPlayer).name));
				}
			}
		}

		[ClientRpc]
		private void FlipLightsBreakerClientRpc()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
				{
					ClientRpcParams val = default(ClientRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(803887099u, val, (RpcDelivery)0);
					((NetworkBehaviour)this).__endSendClientRpc(ref val2, 803887099u, val, (RpcDelivery)0);
				}
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
				{
					GameNetworkManager.Instance.localPlayerController.JumpToFearLevel(0.2f, true);
				}
			}
		}

		private void MessWithLights()
		{
			if (((NetworkBehaviour)this).IsServer)
			{
				RoundManager.Instance.FlickerLights(true, true);
				MessWithLightsClientRpc();
				Debug.Log((object)("Flickering flashlights for player: " + ((Object)hauntingPlayer).name));
			}
		}

		private void FlipLightsBreaker()
		{
			if (((NetworkBehaviour)this).IsServer)
			{
				BreakerBox val = Object.FindObjectOfType<BreakerBox>();
				if ((Object)(object)val != (Object)null)
				{
					val.SetSwitchesOff();
					RoundManager.Instance.TurnOnAllLights(false);
					FlipLightsBreakerClientRpc();
				}
			}
		}

		[ClientRpc]
		private void KillHauntedPlayerClientRpc()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
				{
					ClientRpcParams val = default(ClientRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(2890890656u, val, (RpcDelivery)0);
					((NetworkBehaviour)this).__endSendClientRpc(ref val2, 2890890656u, val, (RpcDelivery)0);
				}
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost) && !((Object)(object)hauntingPlayer != (Object)(object)GameNetworkManager.Instance.localPlayerController))
				{
					hauntingPlayer.KillPlayer(Vector3.zero, true, (CauseOfDeath)0, 1);
				}
			}
		}

		public override void Update()
		{
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Unknown result type (might be due to invalid IL or missing references)
			//IL_046f: Unknown result type (might be due to invalid IL or missing references)
			//IL_047a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0538: Unknown result type (might be due to invalid IL or missing references)
			//IL_0548: 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_01e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0200: Unknown result type (might be due to invalid IL or missing references)
			//IL_0205: 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_022f: 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)
			//IL_023e: Unknown result type (might be due to invalid IL or missing references)
			//IL_028c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0297: Unknown result type (might be due to invalid IL or missing references)
			((EnemyAI)this).Update();
			if (!((NetworkBehaviour)this).IsServer || StartOfRound.Instance.allPlayersDead)
			{
				return;
			}
			if ((!hauntingPlayer.isPlayerControlled || hauntingPlayer.isPlayerDead || timesSeenByPlayer >= 8) && !switchedHauntingPlayer)
			{
				switchedHauntingPlayer = true;
				ChoosePlayerToHaunt();
			}
			switch (base.currentBehaviourStateIndex)
			{
			case 0:
			{
				if (enemyMeshEnabled)
				{
					DisableMesh();
				}
				float num2 = hauntCooldown;
				if (couldNotStareLastAttempt)
				{
					num2 = hauntingIntervalTime;
				}
				if (timer > num2)
				{
					timer = 0f;
					TryFindingHauntPosition();
				}
				else if (hauntingPlayer.isInsideFactory)
				{
					timer += Time.deltaTime * 2f;
				}
				else
				{
					timer += Time.deltaTime;
				}
				break;
			}
			case 1:
				if (!enemyMeshEnabled && !creepingCloser)
				{
					EnableMesh();
				}
				turnCompass.LookAt(((Component)hauntingPlayer).transform);
				((Component)this).transform.eulerAngles = new Vector3(((Component)this).transform.eulerAngles.x, turnCompass.eulerAngles.y, ((Component)this).transform.eulerAngles.z);
				if (timer > stalkingTimer)
				{
					if (Vector3.Distance(((Component)hauntingPlayer.gameplayCamera).transform.position, ((Component)this).transform.position) > 10f)
					{
						timer = 0f;
						StartCreepingTowardsPlayer();
						break;
					}
					if (creepingCloser)
					{
						StopCreepingTowardsPlayer();
					}
					PlaySfxHauntedPlayerClientRpc("jumpscareSFX");
					StartChasing();
				}
				else if (!creepingCloser && !Physics.Linecast(((Component)hauntingPlayer.gameplayCamera).transform.position, ((Component)this).transform.position + Vector3.up * 0.4f, StartOfRound.Instance.collidersAndRoomMask))
				{
					if (hauntingPlayer.HasLineOfSightToPosition(((Component)this).transform.position + Vector3.up * 0.4f, 50f, 100, 5f))
					{
						if (seenByPlayerThisTime)
						{
							break;
						}
						seenByPlayerThisTime = true;
						SyncTimesSeenByPlayerClientRpc(1);
						float num3 = Random.Range(0, 100);
						float num4 = Vector3.Distance(((Component)hauntingPlayer.gameplayCamera).transform.position, ((Component)this).transform.position);
						if (timesSeenByPlayer != 1)
						{
							if (num4 > 80f && num3 <= 1f + (float)timesSeenByPlayer)
							{
								PlaySfxHauntedPlayerClientRpc("jumpscareSFX");
								StartChasing();
							}
							else if (num4 < 80f && num4 > 60f && num3 < 5f + (float)timesSeenByPlayer)
							{
								PlaySfxHauntedPlayerClientRpc("jumpscareSFX");
								StartChasing();
							}
							else if (num4 < 60f && num4 > 40f && num3 < 15f + (float)timesSeenByPlayer)
							{
								PlaySfxHauntedPlayerClientRpc("jumpscareSFX");
								StartChasing();
							}
							else if (num4 < 40f && num4 > 25f && num3 < 30f + (float)timesSeenByPlayer)
							{
								PlaySfxHauntedPlayerClientRpc("jumpscareSFX");
								StartChasing();
							}
							else if (num4 < 25f && num4 > 11f && num3 < 50f + (float)timesSeenByPlayer)
							{
								PlaySfxHauntedPlayerClientRpc("jumpscareSFX");
								StartChasing();
							}
							else if (num4 <= 11f && num3 < 70f + (float)timesSeenByPlayer)
							{
								PlaySfxHauntedPlayerClientRpc("jumpscareSFX");
								StartChasing();
							}
							else
							{
								seenByPlayerThisTime = false;
								disappearWithDelay = true;
								((EnemyAI)this).SwitchToBehaviourStateOnLocalClient(2);
							}
							break;
						}
						if (timesSeenByPlayer == 1)
						{
							if (canFlipLightsBreaker)
							{
								toggleLights = true;
							}
							PlaySfxHauntedPlayerClientRpc("jumpscareSFX", toggleSpatialBlend: false);
						}
						seenByPlayerThisTime = false;
						disappearWithDelay = true;
						((EnemyAI)this).SwitchToBehaviourStateOnLocalClient(2);
					}
					else
					{
						timer += Time.deltaTime;
					}
				}
				else
				{
					timer += Time.deltaTime * 2.5f;
				}
				break;
			case 2:
				if (disappearWithDelay)
				{
					if (disappearOnDelayCoroutine == null)
					{
						float num = Vector3.Distance(((Component)hauntingPlayer.gameplayCamera).transform.position, ((Component)this).transform.position);
						if (num <= 70f && num > 25f)
						{
							vanishWithSound = true;
							MessWithLights();
						}
						else if (num <= 25f)
						{
							vanishWithJumpscare = true;
							MessWithLights();
						}
						disappearOnDelayCoroutine = ((MonoBehaviour)this).StartCoroutine(disappearOnDelay());
					}
				}
				else
				{
					Disappear();
				}
				break;
			case 3:
				if (switchTargetWhenDoorsClosed && hauntingPlayer.isInHangarShipRoom && StartOfRound.Instance.hangarDoorsClosed && doorsTimesSwitched <= 10 && !switchedHauntingPlayer)
				{
					switchedHauntingPlayer = true;
					doorsTimesSwitched++;
					ChoosePlayerToHaunt();
				}
				if (chaseTimer <= 0f || Vector3.Distance(((Component)this).transform.position, ((Component)hauntingPlayer).transform.position) > 100f)
				{
					StopChasing();
				}
				else
				{
					chaseTimer -= Time.deltaTime;
				}
				break;
			}
		}

		public override void DoAIInterval()
		{
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			((EnemyAI)this).DoAIInterval();
			if (!((NetworkBehaviour)this).IsServer)
			{
				return;
			}
			switch (base.currentBehaviourStateIndex)
			{
			case 1:
				if (creepingCloser && timer > creepingCloserTimer)
				{
					StopCreepingTowardsPlayer();
				}
				break;
			case 3:
				if ((Object)(object)hauntingPlayer != (Object)null && !hauntingPlayer.isPlayerDead)
				{
					((EnemyAI)this).SetDestinationToPosition(((Component)hauntingPlayer).transform.position, false);
				}
				else if (base.moveTowardsDestination)
				{
					base.moveTowardsDestination = false;
					base.destination = ((Component)this).transform.position;
					base.agent.SetDestination(base.destination);
				}
				break;
			}
		}

		private PlayerControllerB PlayerMeetsStandardCollisionConditions(Collider other)
		{
			if (!((NetworkBehaviour)this).IsServer)
			{
				return null;
			}
			if (base.isEnemyDead)
			{
				return null;
			}
			if (!base.ventAnimationFinished)
			{
				return null;
			}
			if (base.stunNormalizedTimer >= 0f)
			{
				return null;
			}
			PlayerControllerB component = ((Component)other).gameObject.GetComponent<PlayerControllerB>();
			if ((Object)(object)component == (Object)null)
			{
				return null;
			}
			if (!component.isPlayerDead && (double)component.sinkingValue < 0.7300000190734863)
			{
				return component;
			}
			return null;
		}

		public override void OnCollideWithPlayer(Collider other)
		{
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			((EnemyAI)this).OnCollideWithPlayer(other);
			if (!((NetworkBehaviour)this).IsServer)
			{
				return;
			}
			PlayerControllerB val = PlayerMeetsStandardCollisionConditions(other);
			if ((Object)(object)val != (Object)null)
			{
				Debug.Log((object)"Slenderman: collided with player");
				if ((Object)(object)val == (Object)(object)hauntingPlayer)
				{
					if (base.currentBehaviourStateIndex == 1)
					{
						if (!creepingCloser)
						{
							Debug.Log((object)"Slenderman: collided with hauntingPlayer during stalking phase!");
							((EnemyAI)this).SwitchToBehaviourStateOnLocalClient(2);
						}
					}
					else if (base.currentBehaviourStateIndex == 3)
					{
						hauntingPlayer.KillPlayer(Vector3.zero, true, (CauseOfDeath)0, 1);
						KillHauntedPlayerClientRpc();
						Debug.Log((object)"Slenderman: killed player");
						base.moveTowardsDestination = false;
						disappearWithDelay = false;
						StopChasing();
					}
				}
				else if (base.currentBehaviourStateIndex == 1 && creepingCloser)
				{
					switchedHauntingPlayer = true;
					SwitchHauntingPlayerTo(val);
					StopChasing();
				}
				else if (base.currentBehaviourStateIndex == 3)
				{
					switchedHauntingPlayer = true;
					SwitchHauntingPlayerTo(val);
					StopChasing();
				}
				else
				{
					Debug.Log((object)"Slenderman: collided with non-haunted player outside of a chase.");
					((EnemyAI)this).SwitchToBehaviourStateOnLocalClient(2);
				}
			}
			else
			{
				Debug.LogWarning((object)"ERROR: Slenderman player collision: playerControllerB == null!!!!!!!!!!!!!!!!!!!");
			}
		}

		protected override void __initializeVariables()
		{
			((EnemyAI)this).__initializeVariables();
		}

		[RuntimeInitializeOnLoadMethod]
		internal static void InitializeRPCS_SlendermanEnemyAI()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Expected O, but got Unknown
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Expected O, but got Unknown
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Expected O, but got Unknown
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Expected O, but got Unknown
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Expected O, but got Unknown
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Expected O, but got Unknown
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Expected O, but got Unknown
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Expected O, but got Unknown
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Expected O, but got Unknown
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Expected O, but got Unknown
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Expected O, but got Unknown
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Expected O, but got Unknown
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Expected O, but got Unknown
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Expected O, but got Unknown
			//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Expected O, but got Unknown
			NetworkManager.__rpc_func_table.Add(198283396u, new RpcReceiveHandler(__rpc_handler_198283396));
			NetworkManager.__rpc_func_table.Add(2385237018u, new RpcReceiveHandler(__rpc_handler_2385237018));
			NetworkManager.__rpc_func_table.Add(2082126723u, new RpcReceiveHandler(__rpc_handler_2082126723));
			NetworkManager.__rpc_func_table.Add(556991154u, new RpcReceiveHandler(__rpc_handler_556991154));
			NetworkManager.__rpc_func_table.Add(4108450410u, new RpcReceiveHandler(__rpc_handler_4108450410));
			NetworkManager.__rpc_func_table.Add(916132259u, new RpcReceiveHandler(__rpc_handler_916132259));
			NetworkManager.__rpc_func_table.Add(2420316138u, new RpcReceiveHandler(__rpc_handler_2420316138));
			NetworkManager.__rpc_func_table.Add(2779633377u, new RpcReceiveHandler(__rpc_handler_2779633377));
			NetworkManager.__rpc_func_table.Add(3175837790u, new RpcReceiveHandler(__rpc_handler_3175837790));
			NetworkManager.__rpc_func_table.Add(1031461232u, new RpcReceiveHandler(__rpc_handler_1031461232));
			NetworkManager.__rpc_func_table.Add(1861453801u, new RpcReceiveHandler(__rpc_handler_1861453801));
			NetworkManager.__rpc_func_table.Add(2930548839u, new RpcReceiveHandler(__rpc_handler_2930548839));
			NetworkManager.__rpc_func_table.Add(795220426u, new RpcReceiveHandler(__rpc_handler_795220426));
			NetworkManager.__rpc_func_table.Add(1983075969u, new RpcReceiveHandler(__rpc_handler_1983075969));
			NetworkManager.__rpc_func_table.Add(3661018855u, new RpcReceiveHandler(__rpc_handler_3661018855));
			NetworkManager.__rpc_func_table.Add(803887099u, new RpcReceiveHandler(__rpc_handler_803887099));
			NetworkManager.__rpc_func_table.Add(2890890656u, new RpcReceiveHandler(__rpc_handler_2890890656));
		}

		private static void __rpc_handler_198283396(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				int hauntingPlayerId = default(int);
				ByteUnpacker.ReadValueBitPacked(reader, ref hauntingPlayerId);
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((SlendermanEnemyAI)(object)target).HandleChangeHauntingPlayerClientRpc(hauntingPlayerId);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_2385237018(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				int timesSeen = default(int);
				ByteUnpacker.ReadValueBitPacked(reader, ref timesSeen);
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((SlendermanEnemyAI)(object)target).SyncTimesSeenByPlayerClientRpc(timesSeen);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_2082126723(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				int numSlendermanEnemies = default(int);
				ByteUnpacker.ReadValueBitPacked(reader, ref numSlendermanEnemies);
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((SlendermanEnemyAI)(object)target).SyncNumSlendermanEnemiesInLevelClientRpc(numSlendermanEnemies);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_556991154(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((SlendermanEnemyAI)(object)target).StartChaseAnimClientRpc();
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_4108450410(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((SlendermanEnemyAI)(object)target).StopChaseAnimClientRpc();
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_916132259(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((SlendermanEnemyAI)(object)target).AnimStalkingBaseClientRpc();
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_2420316138(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((SlendermanEnemyAI)(object)target).AnimStalking1ClientRpc();
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_2779633377(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((SlendermanEnemyAI)(object)target).AnimStalking2ClientRpc();
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_3175837790(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				float creatureVoiceVolumeClientRpc = default(float);
				((FastBufferReader)(ref reader)).ReadValueSafe<float>(ref creatureVoiceVolumeClientRpc, default(ForPrimitives));
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((SlendermanEnemyAI)(object)target).SetCreatureVoiceVolumeClientRpc(creatureVoiceVolumeClientRpc);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_1031461232(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				bool flag = default(bool);
				((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref flag, default(ForPrimitives));
				string sfxClipName = null;
				if (flag)
				{
					((FastBufferReader)(ref reader)).ReadValueSafe(ref sfxClipName, false);
				}
				bool toggleSpatialBlend = default(bool);
				((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref toggleSpatialBlend, default(ForPrimitives));
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((SlendermanEnemyAI)(object)target).PlaySfxHauntedPlayerClientRpc(sfxClipName, toggleSpatialBlend);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_1861453801(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				bool flag = default(bool);
				((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref flag, default(ForPrimitives));
				string sfxClipName = null;
				if (flag)
				{
					((FastBufferReader)(ref reader)).ReadValueSafe(ref sfxClipName, false);
				}
				bool toggleSpatialBlend = default(bool);
				((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref toggleSpatialBlend, default(ForPrimitives));
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((SlendermanEnemyAI)(object)target).PlaySfxClientRpc(sfxClipName, toggleSpatialBlend);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_2930548839(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((SlendermanEnemyAI)(object)target).DisableEnemyMeshClientRpc();
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_795220426(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((SlendermanEnemyAI)(object)target).EnableEnemyMeshEveryoneClientRpc();
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_1983075969(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((SlendermanEnemyAI)(object)target).EnableEnemyMeshClientRpc();
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_3661018855(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((SlendermanEnemyAI)(object)target).MessWithLightsClientRpc();
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_803887099(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((SlendermanEnemyAI)(object)target).FlipLightsBreakerClientRpc();
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_2890890656(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((SlendermanEnemyAI)(object)target).KillHauntedPlayerClientRpc();
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		protected internal override string __getTypeName()
		{
			return "SlendermanEnemyAI";
		}
	}
	public class SlendermanNetworkHandler : NetworkBehaviour
	{
		public static SlendermanNetworkHandler Instance { get; private set; }

		public static event Action<string> LevelEvent;

		public override void OnNetworkSpawn()
		{
			SlendermanNetworkHandler.LevelEvent = null;
			if (NetworkManager.Singleton.IsHost || NetworkManager.Singleton.IsServer)
			{
				SlendermanNetworkHandler instance = Instance;
				if (instance != null)
				{
					((Component)instance).gameObject.GetComponent<NetworkObject>().Despawn(true);
				}
			}
			Instance = this;
			((NetworkBehaviour)this).OnNetworkSpawn();
		}

		[ClientRpc]
		public void EventClientRpc(string eventName)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)base.__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
			{
				ClientRpcParams val = default(ClientRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(196005081u, val, (RpcDelivery)0);
				bool flag = eventName != null;
				((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref flag, default(ForPrimitives));
				if (flag)
				{
					((FastBufferWriter)(ref val2)).WriteValueSafe(eventName, false);
				}
				((NetworkBehaviour)this).__endSendClientRpc(ref val2, 196005081u, val, (RpcDelivery)0);
			}
			if ((int)base.__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
			{
				SlendermanNetworkHandler.LevelEvent?.Invoke(eventName);
			}
		}

		protected override void __initializeVariables()
		{
			((NetworkBehaviour)this).__initializeVariables();
		}

		[RuntimeInitializeOnLoadMethod]
		internal static void InitializeRPCS_SlendermanNetworkHandler()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			NetworkManager.__rpc_func_table.Add(196005081u, new RpcReceiveHandler(__rpc_handler_196005081));
		}

		private static void __rpc_handler_196005081(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				bool flag = default(bool);
				((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref flag, default(ForPrimitives));
				string eventName = null;
				if (flag)
				{
					((FastBufferReader)(ref reader)).ReadValueSafe(ref eventName, false);
				}
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((SlendermanNetworkHandler)(object)target).EventClientRpc(eventName);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		protected internal override string __getTypeName()
		{
			return "SlendermanNetworkHandler";
		}
	}
	[Serializable]
	public class SyncedInstance<T>
	{
		[NonSerialized]
		protected static int IntSize = 4;

		internal static CustomMessagingManager MessageManager => NetworkManager.Singleton.CustomMessagingManager;

		internal static bool IsClient => NetworkManager.Singleton.IsClient;

		internal static bool IsHost => NetworkManager.Singleton.IsHost;

		public static T Default { get; private set; }

		public static T Instance { get; private set; }

		public static bool Synced { get; internal set; }

		protected void InitInstance(T instance)
		{
			Default = instance;
			Instance = instance;
			IntSize = 4;
		}

		internal static void SyncInstance(byte[] data)
		{
			Instance = DeserializeFromBytes(data);
			Synced = true;
		}

		internal static void RevertSync()
		{
			Instance = Default;
			Synced = false;
		}

		public static byte[] SerializeToBytes(T val)
		{
			BinaryFormatter binaryFormatter = new BinaryFormatter();
			using MemoryStream memoryStream = new MemoryStream();
			try
			{
				binaryFormatter.Serialize(memoryStream, val);
				return memoryStream.ToArray();
			}
			catch (Exception arg)
			{
				Plugin.Logger.LogError((object)$"Error serializing instance: {arg}");
				return null;
			}
		}

		public static T DeserializeFromBytes(byte[] data)
		{
			BinaryFormatter binaryFormatter = new BinaryFormatter();
			using MemoryStream serializationStream = new MemoryStream(data);
			try
			{
				return (T)binaryFormatter.Deserialize(serializationStream);
			}
			catch (Exception arg)
			{
				Plugin.Logger.LogError((object)$"Error deserializing instance: {arg}");
				return default(T);
			}
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "SlendermanMod";

		public const string PLUGIN_NAME = "SlendermanMod";

		public const string PLUGIN_VERSION = "1.1.5";
	}
}
namespace SlendermanMod.Patches
{
	[HarmonyPatch]
	public class NetworkObjectManager
	{
		private static GameObject networkPrefab;

		[HarmonyPostfix]
		[HarmonyPatch(typeof(GameNetworkManager), "Start")]
		public static void Init()
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Expected O, but got Unknown
			if (!((Object)(object)networkPrefab != (Object)null))
			{
				networkPrefab = (GameObject)Plugin.SlendermanAssets.LoadAsset("SlendermanNetworkHandler");
				networkPrefab.AddComponent<SlendermanNetworkHandler>();
				NetworkManager.Singleton.AddNetworkPrefab(networkPrefab);
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(StartOfRound), "Awake")]
		private static void SpawnNetworkHandler()
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			if (NetworkManager.Singleton.IsHost || NetworkManager.Singleton.IsServer)
			{
				Object.Instantiate<GameObject>(networkPrefab, Vector3.zero, Quaternion.identity).GetComponent<NetworkObject>().Spawn(false);
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(RoundManager), "GenerateNewFloor")]
		private static void SubscribeToHandler()
		{
			SlendermanNetworkHandler.LevelEvent += ReceivedEventFromServer;
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(RoundManager), "DespawnPropsAtEndOfRound")]
		private static void UnsubscribeFromHandler()
		{
			SlendermanNetworkHandler.LevelEvent -= ReceivedEventFromServer;
		}

		private static void ReceivedEventFromServer(string eventName)
		{
		}

		private static void SendEventToClients(string eventName)
		{
			if (NetworkManager.Singleton.IsHost || NetworkManager.Singleton.IsServer)
			{
				SlendermanNetworkHandler.Instance.EventClientRpc(eventName);
			}
		}
	}
}
namespace SlendermanMod.Behaviours
{
	internal class SpawnSlendermanEnemyItem : PhysicsProp
	{
		private EnemyType slendermanEnemy = Plugin.SlendermanEnemy;

		private bool isSpawned;

		public override void EquipItem()
		{
			((PhysicsProp)this).EquipItem();
			if ((Object)(object)((GrabbableObject)this).playerHeldBy != (Object)null)
			{
				if (!StartOfRound.Instance.inShipPhase && RoundManager.Instance.currentLevel.spawnEnemiesAndScrap)
				{
					if (SlendermanEnemyAI.numSlendermanEnemiesInLevel <= 0 && !isSpawned)
					{
						SpawnSlenderman();
						isSpawned = true;
					}
					else
					{
						Debug.Log((object)"Slenderman not spawning as there's a

plugins/FacilityMeltdown/FacilityMeltdown.dll

Decompiled 2 years ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using Biodiversity.Util.Assetloading;
using FacilityMeltdown.API;
using FacilityMeltdown.Behaviours;
using FacilityMeltdown.Config;
using FacilityMeltdown.Equipment;
using FacilityMeltdown.Integrations;
using FacilityMeltdown.Lang;
using FacilityMeltdown.MeltdownSequence.Behaviours;
using FacilityMeltdown.NetcodePatcher;
using FacilityMeltdown.Patches;
using FacilityMeltdown.Util;
using FacilityMeltdown.Util.Attributes;
using FacilityMeltdown.Util.Config;
using GameNetcodeStuff;
using HarmonyLib;
using LethalConfig;
using LethalConfig.ConfigItems;
using LethalConfig.ConfigItems.Options;
using LethalLib.Modules;
using LethalSettings.UI;
using LethalSettings.UI.Components;
using LobbyCompatibility.Enums;
using LobbyCompatibility.Features;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Serialization;
using Unity.Collections;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.Events;
using UnityEngine.Rendering.HighDefinition;

[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("FacilityMeltdown")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+e314fbd4d665ed732df843d6558ab18ccb9ca601")]
[assembly: AssemblyProduct("FacilityMeltdown")]
[assembly: AssemblyTitle("FacilityMeltdown")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
[module: NetcodePatchedAssembly]
internal class <Module>
{
	static <Module>()
	{
	}
}
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[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 Biodiversity.Util.Assetloading
{
	[AttributeUsage(AttributeTargets.Property)]
	internal class LoadFromBundleAttribute : Attribute
	{
		public string BundleFile { get; private set; }

		public LoadFromBundleAttribute(string bundleFile)
		{
			BundleFile = bundleFile;
			base..ctor();
		}
	}
}
namespace FacilityMeltdown
{
	[BepInPlugin("me.loaforc.facilitymeltdown", "FacilityMeltdown", "2.6.7")]
	[CompatibleDependency("ainavt.lc.lethalconfig", typeof(LethalConfigIntergration))]
	[CompatibleDependency("com.willis.lc.lethalsettings", typeof(LethalSettingsIntegration))]
	[CompatibleDependency("BMX.LobbyCompatibility", typeof(LobbyCompatibilityIntegration))]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class MeltdownPlugin : BaseUnityPlugin
	{
		internal const string modGUID = "me.loaforc.facilitymeltdown";

		internal const string modName = "FacilityMeltdown";

		internal const string modVersion = "2.6.7";

		internal static MeltdownPlugin instance;

		internal static ManualLogSource logger;

		internal static MeltdownAssets assets { get; private set; }

		public static bool loadedFully { get; private set; }

		internal static MeltdownConfig config { get; set; }

		internal static MeltdownClientConfig clientConfig { get; private set; }

		private void Awake()
		{
			if (!((Object)(object)instance == (Object)null))
			{
				return;
			}
			instance = this;
			logger = Logger.CreateLogSource("me.loaforc.facilitymeltdown");
			if (RunLoadStep("Assets.Init", "Getting assets", delegate
			{
				assets = new MeltdownAssets();
			}) && RunLoadStep("LangParser.Init", "Getting possible languages", LangParser.Init) && RunLoadStep("new MeltdownConfig()", "Setting up config", delegate
			{
				//IL_0032: Unknown result type (might be due to invalid IL or missing references)
				//IL_003c: Expected O, but got Unknown
				config = new MeltdownConfig(((BaseUnityPlugin)this).Config);
				clientConfig = new MeltdownClientConfig(new ConfigFile(Utility.CombinePaths(new string[2]
				{
					Paths.ConfigPath,
					"me.loaforc.facilitymeltdown.Client.cfg"
				}), false, MetadataHelper.GetMetadata((object)this)));
				logger.LogDebug((object)$"Test Config Value: {config.ApparatusValue}");
				((BaseUnityPlugin)this).Config.ClearOrphans();
				clientConfig.configFile.ClearOrphans();
			}) && RunLoadStep("LangParser.SetLanguage", "Setting language", delegate
			{
				LangParser.SetLanguage(clientConfig.Language);
			}) && RunLoadStep("RegisterPatches", "Integrating into LethalCompany", RegisterPatches) && RunLoadStep("RegisterNetworking", "Making sure everything is networked", RegisterNetworking))
			{
				if (!RunLoadStep("RegisterItems", "Adding the Geiger Counter", RegisterItems))
				{
					logger.LogWarning((object)"Failed to register the geiger counter.");
				}
				if (!RunLoadStep("CompatibleDependency.Init", "Checking for any soft dependencies", delegate
				{
					CompatibleDependencyAttribute.Init((BaseUnityPlugin)(object)this);
				}))
				{
					logger.LogWarning((object)"Doing something with soft dependencies broke, meltdown itself should be fine.");
				}
				loadedFully = true;
				logger.LogInfo((object)"FacilityMeltdown:2.6.7 by loaforc has loaded! have fun :3");
				logger.LogInfo((object)"         .-_; ;_-.          ");
				logger.LogInfo((object)"        / /     \\ \\        ");
				logger.LogInfo((object)"       | |       | |      ");
				logger.LogInfo((object)"        \\ \\.---./ /       ");
				logger.LogInfo((object)"  .-\\\"\"~   .---.   ~\"\"-.");
				logger.LogInfo((object)" ,`.-~// .'`---`'. \\\\~-.`,");
				logger.LogInfo((object)" ' `   | | \\(_)/ | |   `' ");
				logger.LogInfo((object)"  ,    \\  \\ | | /  /    , ");
				logger.LogInfo((object)"  ;`'.,_\\  `-'-'  /_,.'`; ");
				logger.LogInfo((object)"   '-._  _.-'^'-._  _.-'    ");
			}
		}

		private bool RunLoadStep(string stepName, string descrption, Action callback)
		{
			try
			{
				callback();
			}
			catch (Exception ex)
			{
				logger.LogError((object)("`" + stepName + "` caused an exception to be thrown, meltdown may or may not work, look for more errors."));
				logger.LogError((object)ex);
				return false;
			}
			logger.LogInfo((object)(stepName.PadRight(25) + " == " + descrption));
			return true;
		}

		private void RegisterItems()
		{
			logger.LogInfo((object)"Registering Items");
			Items.RegisterShopItem(assets.geigerCounterItemDef, (TerminalNode)null, (TerminalNode)null, assets.geigerCounterNode, 90);
		}

		private void OnDisable()
		{
			if (!loadedFully)
			{
				Harmony.UnpatchID("me.loaforc.facilitymeltdown");
				logger.LogInfo((object)"Unpatching as something failed while loading.");
			}
			else if (Chainloader.PluginInfos.ContainsKey("den.meltdownchance") || Chainloader.PluginInfos.ContainsKey("PizzaProbability"))
			{
				logger.LogInfo((object)"You are using a mod that makes meltdown have a random chance of occuring.");
				logger.LogInfo((object)"Keep in mind this goes against meltdown's core design, but your choice.");
				logger.LogWarning((object)"However; BY DESIGN these mods need to mess with the internals of meltdown");
				logger.LogWarning((object)"so I personally will be offering low to no support with these mods installed.");
			}
		}

		private void RegisterNetworking()
		{
			Type[] array = new Type[2]
			{
				typeof(MeltdownHandler),
				typeof(GeigerCounterItem)
			};
			Type[] array2 = array;
			foreach (Type type in array2)
			{
				try
				{
					MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic);
					MethodInfo[] array3 = methods;
					foreach (MethodInfo methodInfo in array3)
					{
						object[] customAttributes = methodInfo.GetCustomAttributes(typeof(RuntimeInitializeOnLoadMethodAttribute), inherit: false);
						if (customAttributes.Length != 0)
						{
							methodInfo.Invoke(null, null);
						}
					}
				}
				catch (Exception)
				{
					logger.LogWarning((object)"supressed an error from netcode patcher, probably fine but should still log that something happened.");
				}
			}
		}

		private void RegisterPatches()
		{
			Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "me.loaforc.facilitymeltdown");
		}
	}
	internal static class ExtensionMethods
	{
		private static Random rng = new Random();

		public static void Shuffle<T>(this IList<T> list)
		{
			int num = list.Count;
			while (num > 1)
			{
				num--;
				int index = rng.Next(num + 1);
				T value = list[index];
				list[index] = list[num];
				list[num] = value;
			}
		}

		public static float Remap(this float value, float from1, float to1, float from2, float to2)
		{
			return (value - from1) / (to1 - from1) * (to2 - from2) + from2;
		}

		public static List<PlayerControllerB> GetConnectedPlayers(this StartOfRound startOfRound)
		{
			return startOfRound.allPlayerScripts.Where((PlayerControllerB player) => player.isPlayerControlled).ToList();
		}

		public static void SpawnEnemy(this EnemyVent vent, SpawnableEnemyWithRarity enemy)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			Vector3 position = vent.floorNode.position;
			float y = vent.floorNode.eulerAngles.y;
			RoundManager.Instance.SpawnEnemyOnServer(position, y, RoundManager.Instance.currentLevel.Enemies.IndexOf(enemy));
			vent.OpenVentClientRpc();
			vent.occupied = false;
		}

		internal static string Translate(this string text)
		{
			return LangParser.GetTranslation(text);
		}

		internal static void ClearOrphans(this ConfigFile config)
		{
			PropertyInfo property = ((object)config).GetType().GetProperty("OrphanedEntries", BindingFlags.Instance | BindingFlags.NonPublic);
			Dictionary<ConfigDefinition, string> dictionary = (Dictionary<ConfigDefinition, string>)property.GetValue(config, null);
			dictionary.Clear();
			config.Save();
		}
	}
	internal class MeltdownAssets : AssetBundleLoader<MeltdownAssets>
	{
		[LoadFromBundle("meltdownmusic.mp3")]
		public AudioClip defaultMusic { get; private set; }

		[LoadFromBundle("shockwave.mp3")]
		public AudioClip shockwave { get; private set; }

		[LoadFromBundle("FacilityExplosion.prefab")]
		public GameObject facilityExplosionPrefab { get; private set; }

		[LoadFromBundle("MeltdownHandler.prefab")]
		public GameObject meltdownHandlerPrefab { get; private set; }

		[LoadFromBundle("Shockwave.prefab")]
		public GameObject shockwavePrefab { get; private set; }

		[LoadFromBundle("GeigerCounterItemDef.asset")]
		public Item geigerCounterItemDef { get; private set; }

		[LoadFromBundle("GeigerCounterNode.asset")]
		public TerminalNode geigerCounterNode { get; private set; }

		[LoadFromBundle("HealthKeyword.asset")]
		public TerminalKeyword healthKeyword { get; private set; }

		[LoadFromBundle("ReactorKeyword.asset")]
		public TerminalKeyword reactorKeyword { get; private set; }

		[LoadFromBundle("ReactorHealthReport.asset")]
		public TerminalNode reactorHealthNode { get; private set; }

		public GameObject[] facilityEffects { get; private set; }

		public AudioClip[] warnings { get; private set; }

		public MeltdownAssets()
			: base("facilitymeltdown")
		{
		}

		protected override void FinishLoadingAssets(AssetBundle bundle)
		{
			warnings = (AudioClip[])(object)new AudioClip[4]
			{
				LoadAsset<AudioClip>(bundle, "warning1.mp3"),
				LoadAsset<AudioClip>(bundle, "warning2.mp3"),
				LoadAsset<AudioClip>(bundle, "warning3.mp3"),
				LoadAsset<AudioClip>(bundle, "warning4.mp3")
			};
			facilityEffects = (GameObject[])(object)new GameObject[2]
			{
				LoadAsset<GameObject>(bundle, "Dust.prefab"),
				LoadAsset<GameObject>(bundle, "Waterstream.prefab")
			};
			TerminalPatch.terminalKeywordsToRegister.Add(healthKeyword);
			TerminalPatch.terminalKeywordsToRegister.Add(reactorKeyword);
			TerminalPatch.terminalNodesToRegister.Add(reactorHealthNode);
		}
	}
}
namespace FacilityMeltdown.Util
{
	internal abstract class AssetBundleLoader<T> where T : AssetBundleLoader<T>
	{
		public AssetBundleLoader(string filePath)
		{
			AssetBundle val = AssetBundle.LoadFromFile(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), filePath));
			MeltdownPlugin.logger.LogDebug((object)("[Assets] AssetBundle `" + filePath + "` contains these objects: \n" + string.Join("\n", val.GetAllAssetNames())));
			Type typeFromHandle = typeof(T);
			PropertyInfo[] properties = typeFromHandle.GetProperties();
			foreach (PropertyInfo propertyInfo in properties)
			{
				LoadFromBundleAttribute loadFromBundleAttribute = (LoadFromBundleAttribute)propertyInfo.GetCustomAttribute(typeof(LoadFromBundleAttribute));
				if (loadFromBundleAttribute != null)
				{
					MeltdownPlugin.logger.LogDebug((object)("[Assets] Got LoadFromBundle attribute on `" + propertyInfo.Name + "`. Loading asset: `" + loadFromBundleAttribute.BundleFile + "` into the [roperty."));
					propertyInfo.SetValue(this, LoadAsset<Object>(val, loadFromBundleAttribute.BundleFile.ToLower(CultureInfo.GetCultureInfo("en-GB"))));
				}
			}
			GameObject[] array = val.LoadAllAssets<GameObject>();
			foreach (GameObject val2 in array)
			{
				if (!((Object)(object)val2.GetComponent<NetworkObject>() == (Object)null) && !GameNetworkManagerPatch.networkPrefabsToRegister.Contains(val2))
				{
					GameNetworkManagerPatch.networkPrefabsToRegister.Add(val2);
				}
			}
			FinishLoadingAssets(val);
		}

		protected virtual void FinishLoadingAssets(AssetBundle bundle)
		{
		}

		protected AssetType LoadAsset<AssetType>(AssetBundle bundle, string path) where AssetType : Object
		{
			AssetType val = bundle.LoadAsset<AssetType>(path);
			if ((Object)(object)val == (Object)null)
			{
				throw new ArgumentException(path + " is not valid in the assetbundle!");
			}
			return val;
		}
	}
}
namespace FacilityMeltdown.Util.Config
{
	[AttributeUsage(AttributeTargets.Property)]
	internal class ConfigDescAttribute : Attribute
	{
		public string Description { get; private set; }

		public ConfigDescAttribute(string desc)
		{
			Description = desc;
			base..ctor();
		}
	}
	[AttributeUsage(AttributeTargets.Property)]
	internal class ConfigGroupAttribute : Attribute
	{
		public string Group { get; private set; }

		public ConfigGroupAttribute(string Group)
		{
			this.Group = Group;
			base..ctor();
		}
	}
	[AttributeUsage(AttributeTargets.Property)]
	internal class ConfigIgnoreAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Property)]
	internal class ConfigRangeAttribute : Attribute
	{
		internal float Min { get; private set; }

		internal float Max { get; private set; }

		internal ConfigRangeAttribute(float min, float max)
		{
			Min = min;
			Max = max;
		}
	}
	[Serializable]
	internal abstract class LoafConfig<T> where T : LoafConfig<T>
	{
		internal List<(PropertyInfo, object)> configEntries = new List<(PropertyInfo, object)>();

		internal ConfigFile configFile { get; private set; }

		public LoafConfig(ConfigFile configFile)
		{
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Expected O, but got Unknown
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Expected O, but got Unknown
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Expected O, but got Unknown
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Expected O, but got Unknown
			if (configFile == null)
			{
				return;
			}
			this.configFile = configFile;
			string header = "Misc";
			Type typeFromHandle = typeof(T);
			PropertyInfo[] properties = typeFromHandle.GetProperties();
			foreach (PropertyInfo propertyInfo in properties)
			{
				if (propertyInfo.GetCustomAttribute(typeof(ConfigIgnoreAttribute)) == null)
				{
					ConfigGroupAttribute configGroupAttribute = (ConfigGroupAttribute)propertyInfo.GetCustomAttribute(typeof(ConfigGroupAttribute));
					if (configGroupAttribute != null)
					{
						header = configGroupAttribute.Group.Replace(" ", "");
					}
					string text = "no description here :pensive:";
					ConfigDescAttribute configDescAttribute = (ConfigDescAttribute)propertyInfo.GetCustomAttribute(typeof(ConfigDescAttribute));
					if (configDescAttribute != null)
					{
						text = configDescAttribute.Description;
					}
					ConfigDescription val = new ConfigDescription(text, (AcceptableValueBase)null, Array.Empty<object>());
					ConfigRangeAttribute configRangeAttribute = (ConfigRangeAttribute)propertyInfo.GetCustomAttribute(typeof(ConfigRangeAttribute));
					val = ((configRangeAttribute == null) ? new ConfigDescription(text, (AcceptableValueBase)null, Array.Empty<object>()) : ((!(propertyInfo.PropertyType == typeof(int))) ? new ConfigDescription(text, (AcceptableValueBase)(object)new AcceptableValueRange<float>(configRangeAttribute.Min, configRangeAttribute.Max), Array.Empty<object>()) : new ConfigDescription(text, (AcceptableValueBase)(object)new AcceptableValueRange<int>((int)configRangeAttribute.Min, (int)configRangeAttribute.Max), Array.Empty<object>())));
					if (propertyInfo.PropertyType == typeof(float))
					{
						BindProperty<float>(propertyInfo, header, val);
					}
					if (propertyInfo.PropertyType == typeof(int))
					{
						BindProperty<int>(propertyInfo, header, val);
					}
					if (propertyInfo.PropertyType == typeof(string))
					{
						BindProperty<string>(propertyInfo, header, val);
					}
					if (propertyInfo.PropertyType == typeof(bool))
					{
						BindProperty<bool>(propertyInfo, header, val);
					}
				}
			}
		}

		protected void BindProperty<V>(PropertyInfo property, string header, ConfigDescription description)
		{
			ConfigEntry<V> val = configFile.Bind<V>(header, property.Name, (V)property.GetValue(this), description);
			configEntries.Add((property, val));
			property.SetValue(this, val.Value);
		}
	}
	internal abstract class LoafSyncedConfig<T> : LoafConfig<T> where T : LoafSyncedConfig<T>
	{
		internal static T Default { get; private set; }

		internal LoafSyncedConfig(ConfigFile file)
			: base(file)
		{
			if (Default == null)
			{
				Default = (T)this;
			}
		}
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property)]
	internal class RequiresRestartAttribute : Attribute
	{
		public bool RequiresRestart { get; private set; }

		public RequiresRestartAttribute(bool requiresRestart = true)
		{
			RequiresRestart = requiresRestart;
			base..ctor();
		}
	}
}
namespace FacilityMeltdown.Util.Attributes
{
	internal class CompatibleDependencyAttribute : BepInDependency
	{
		public Type Handler;

		public CompatibleDependencyAttribute(string guid, Type handlerType)
			: base(guid, (DependencyFlags)2)
		{
			Handler = handlerType;
		}

		public static void Init(BaseUnityPlugin source)
		{
			IEnumerable<CompatibleDependencyAttribute> customAttributes = ((MemberInfo)((object)source).GetType()).GetCustomAttributes<CompatibleDependencyAttribute>();
			foreach (CompatibleDependencyAttribute item in customAttributes)
			{
				if (Chainloader.PluginInfos.ContainsKey(((BepInDependency)item).DependencyGUID))
				{
					item.Handler.GetMethod("Initialize", BindingFlags.Static | BindingFlags.NonPublic)?.Invoke(null, null);
					item.Handler = null;
				}
			}
		}
	}
}
namespace FacilityMeltdown.Patches
{
	[HarmonyPatch(typeof(LungProp))]
	internal class ApparaticePatch
	{
		[HarmonyPrefix]
		[HarmonyPatch("EquipItem")]
		internal static void BeginMeltdownSequence(LungProp __instance, ref bool ___isLungDocked)
		{
			if (!((NetworkBehaviour)__instance).IsHost || !___isLungDocked || MeltdownAPI.MeltdownStarted)
			{
				return;
			}
			try
			{
				if (MeltdownPlugin.config.OverrideApparatusValue)
				{
					((GrabbableObject)__instance).scrapValue = MeltdownPlugin.config.ApparatusValue;
				}
				GameObject val = Object.Instantiate<GameObject>(MeltdownPlugin.assets.meltdownHandlerPrefab);
				val.GetComponent<NetworkObject>().Spawn(false);
			}
			catch (Exception ex)
			{
				MeltdownPlugin.logger.LogError((object)ex);
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch("Start")]
		internal static void AddRadiationSource(LungProp __instance)
		{
			try
			{
				RadiationSource radiationSource = ((Component)__instance).gameObject.AddComponent<RadiationSource>();
				radiationSource.radiationAmount = 80f;
				radiationSource.radiationDistance = 60f;
				MeltdownMoonMapper.EnsureMeltdownMoonMapper();
				if (MeltdownPlugin.config.OverrideApparatusValue)
				{
					((GrabbableObject)__instance).scrapValue = MeltdownPlugin.config.ApparatusValue;
				}
				MeltdownPlugin.logger.LogDebug((object)((GrabbableObject)__instance).scrapValue);
			}
			catch (Exception ex)
			{
				MeltdownPlugin.logger.LogError((object)ex);
			}
		}
	}
	[HarmonyPatch(typeof(BlobAI))]
	internal class BlobAIPatch
	{
		[HarmonyPrefix]
		[HarmonyPatch("Start")]
		internal static void AddRadiationSource(BlobAI __instance)
		{
			RadiationSource radiationSource = ((Component)__instance).gameObject.AddComponent<RadiationSource>();
			radiationSource.radiationAmount = 30f;
			radiationSource.radiationDistance = 25f;
		}
	}
	[HarmonyPatch(typeof(EntranceTeleport))]
	internal static class EntranceTeleportPatch
	{
		[HarmonyPrefix]
		[HarmonyPatch("FindExitPoint")]
		private static bool dontAllowReneter(ref bool __result)
		{
			if ((Object)(object)MeltdownHandler.Instance != (Object)null && MeltdownHandler.Instance.HasExplosionOccured())
			{
				__result = false;
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(GameNetworkManager))]
	internal class GameNetworkManagerPatch
	{
		internal static List<GameObject> networkPrefabsToRegister = new List<GameObject>();

		[HarmonyPatch("Start")]
		[HarmonyPrefix]
		private static void AddNetworkPrefabs()
		{
			foreach (GameObject item in networkPrefabsToRegister)
			{
				NetworkManager.Singleton.AddNetworkPrefab(item);
				MeltdownPlugin.logger.LogDebug((object)("Registered " + ((Object)item).name + " as a network prefab."));
			}
			MeltdownPlugin.logger.LogInfo((object)$"Succesfully registered {networkPrefabsToRegister.Count} network prefabs.");
		}

		[HarmonyPostfix]
		[HarmonyPatch("StartDisconnect")]
		public static void PlayerLeave()
		{
			MeltdownPlugin.config = LoafSyncedConfig<MeltdownConfig>.Default;
		}
	}
	[HarmonyPatch(typeof(GrabbableObject))]
	public class GrabbableObjectPatch
	{
		[HarmonyPrefix]
		[HarmonyPatch("Update")]
		internal static void ApplyMinPeople(GrabbableObject __instance)
		{
			LungProp apparatus = (LungProp)(object)((__instance is LungProp) ? __instance : null);
			if (apparatus == null)
			{
				return;
			}
			if (!apparatus.isLungDocked)
			{
				if (!((GrabbableObject)apparatus).grabbable)
				{
					((GrabbableObject)apparatus).customGrabTooltip = "";
					((GrabbableObject)apparatus).grabbable = true;
				}
				return;
			}
			int num = StartOfRound.Instance.GetConnectedPlayers().Count((PlayerControllerB player) => Vector3.Distance(((Component)player).transform.position, ((Component)apparatus).transform.position) < 15f);
			int num2 = Mathf.Min(MeltdownPlugin.config.MinPeopleToPullApparatus, StartOfRound.Instance.livingPlayers);
			if (num < num2)
			{
				((GrabbableObject)apparatus).customGrabTooltip = $"[ NEEDS {num2} PEOPLE ]";
				((GrabbableObject)apparatus).grabbable = false;
			}
			else
			{
				((GrabbableObject)apparatus).customGrabTooltip = "";
				((GrabbableObject)apparatus).grabbable = true;
			}
		}
	}
	[HarmonyPatch(typeof(PlayerControllerB))]
	internal static class PlayerControllerPatch
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static HandleNamedMessageDelegate <0>__OnRequestSync;

			public static HandleNamedMessageDelegate <1>__OnReceiveSync;
		}

		private const string MESSAGE_REQUEST = "meltdown_OnRequestConfigSync";

		private const string MESSAGE_RECIEVE = "meltdown_OnRecieveConfigSync";

		private const int IntSize = 4;

		[HarmonyPostfix]
		[HarmonyPatch("ConnectClientToPlayerObject")]
		private static void SyncConfig()
		{
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Expected O, but got Unknown
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			if (NetworkManager.Singleton.IsHost)
			{
				CustomMessagingManager customMessagingManager = NetworkManager.Singleton.CustomMessagingManager;
				object obj = <>O.<0>__OnRequestSync;
				if (obj == null)
				{
					HandleNamedMessageDelegate val = OnRequestSync;
					<>O.<0>__OnRequestSync = val;
					obj = (object)val;
				}
				customMessagingManager.RegisterNamedMessageHandler("meltdown_OnRequestConfigSync", (HandleNamedMessageDelegate)obj);
				return;
			}
			CustomMessagingManager customMessagingManager2 = NetworkManager.Singleton.CustomMessagingManager;
			object obj2 = <>O.<1>__OnReceiveSync;
			if (obj2 == null)
			{
				HandleNamedMessageDelegate val2 = OnReceiveSync;
				<>O.<1>__OnReceiveSync = val2;
				obj2 = (object)val2;
			}
			customMessagingManager2.RegisterNamedMessageHandler("meltdown_OnRecieveConfigSync", (HandleNamedMessageDelegate)obj2);
			RequestSync();
		}

		public static void RequestSync()
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			if (NetworkManager.Singleton.IsHost)
			{
				return;
			}
			FastBufferWriter val = default(FastBufferWriter);
			((FastBufferWriter)(ref val))..ctor(4, (Allocator)2, -1);
			try
			{
				NetworkManager.Singleton.CustomMessagingManager.SendNamedMessage("meltdown_OnRequestConfigSync", 0uL, val, (NetworkDelivery)3);
			}
			finally
			{
				((IDisposable)(FastBufferWriter)(ref val)).Dispose();
			}
		}

		public static void OnRequestSync(ulong clientId, FastBufferReader _)
		{
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			if (!NetworkManager.Singleton.IsHost)
			{
				return;
			}
			MeltdownPlugin.logger.LogInfo((object)$"Config sync request received from client: {clientId}");
			byte[] bytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject((object)MeltdownPlugin.config));
			int num = bytes.Length;
			FastBufferWriter val = default(FastBufferWriter);
			((FastBufferWriter)(ref val))..ctor(num + 4, (Allocator)2, -1);
			try
			{
				((FastBufferWriter)(ref val)).WriteValueSafe<int>(ref num, default(ForPrimitives));
				((FastBufferWriter)(ref val)).WriteBytesSafe(bytes, -1, 0);
				NetworkManager.Singleton.CustomMessagingManager.SendNamedMessage("meltdown_OnRecieveConfigSync", clientId, val, (NetworkDelivery)3);
			}
			catch (Exception arg)
			{
				MeltdownPlugin.logger.LogInfo((object)$"Error occurred syncing config with client: {clientId}\n{arg}");
			}
			finally
			{
				((IDisposable)(FastBufferWriter)(ref val)).Dispose();
			}
		}

		private static void OnReceiveSync(ulong _, FastBufferReader reader)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Expected O, but got Unknown
			if (!((FastBufferReader)(ref reader)).TryBeginRead(4))
			{
				MeltdownPlugin.logger.LogError((object)"Config sync error: Could not begin reading buffer.");
				return;
			}
			int num = default(int);
			((FastBufferReader)(ref reader)).ReadValueSafe<int>(ref num, default(ForPrimitives));
			if (!((FastBufferReader)(ref reader)).TryBeginRead(num))
			{
				MeltdownPlugin.logger.LogError((object)"Config sync error: Host could not sync.");
				return;
			}
			byte[] bytes = new byte[num];
			((FastBufferReader)(ref reader)).ReadBytesSafe(ref bytes, num, 0);
			MeltdownPlugin.logger.LogDebug((object)Encoding.UTF8.GetString(bytes));
			MeltdownPlugin.config = JsonConvert.DeserializeObject<MeltdownConfig>(Encoding.UTF8.GetString(bytes), new JsonSerializerSettings
			{
				ContractResolver = (IContractResolver)(object)new IncludePrivateSetterContractResolver()
			});
			MeltdownPlugin.logger.LogDebug((object)"Deserialized values are: ");
			PropertyInfo[] properties = MeltdownPlugin.config.GetType().GetProperties();
			foreach (PropertyInfo propertyInfo in properties)
			{
				MeltdownPlugin.logger.LogDebug((object)$"{propertyInfo.Name} => {propertyInfo.GetValue(MeltdownPlugin.config)}");
			}
			MeltdownPlugin.logger.LogInfo((object)"Successfully synced config with host.");
		}
	}
	internal class IncludePrivateSetterContractResolver : DefaultContractResolver
	{
		protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			JsonProperty val = ((DefaultContractResolver)this).CreateProperty(member, memberSerialization);
			if (!val.Writable && member is PropertyInfo propertyInfo)
			{
				val.Writable = propertyInfo.GetSetMethod(nonPublic: true) != null;
			}
			return val;
		}
	}
	[HarmonyPatch(typeof(StartOfRound))]
	internal static class StartOfRoundPatches
	{
		[HarmonyPrefix]
		[HarmonyPatch("EndOfGame")]
		internal static void UnloadMeltdownHandler()
		{
			if (Object.op_Implicit((Object)(object)MeltdownHandler.Instance))
			{
				Object.Destroy((Object)(object)((Component)MeltdownHandler.Instance).gameObject);
			}
			if (Object.op_Implicit((Object)(object)MeltdownMoonMapper.Instance))
			{
				Object.Destroy((Object)(object)((Component)MeltdownMoonMapper.Instance).gameObject);
			}
			if (Object.op_Implicit((Object)(object)MeltdownInteriorMapper.Instance))
			{
				Object.Destroy((Object)(object)((Component)MeltdownInteriorMapper.Instance).gameObject);
			}
		}
	}
	[HarmonyPatch(typeof(Terminal))]
	internal class TerminalPatch
	{
		internal class ReactorHealthReport
		{
			public float reactorInstability;

			public float timeRemaining;

			public float generatedAt = Time.time;

			public string GetFlavourText()
			{
				if (timeRemaining / (float)MeltdownPlugin.config.MeltdownTime > 0.75f)
				{
					return "reactorscan.result.flavour.start";
				}
				if (timeRemaining / (float)MeltdownPlugin.config.MeltdownTime > 0.5f)
				{
					return "reactorscan.result.flavour.low";
				}
				if (timeRemaining / (float)MeltdownPlugin.config.MeltdownTime > 0.33f)
				{
					return "reactorscan.result.flavour.medium";
				}
				if (timeRemaining / (float)MeltdownPlugin.config.MeltdownTime > 0.15f)
				{
					return "reactorscan.result.flavour.high";
				}
				return "";
			}

			public string GetTeminalOutput()
			{
				string text = "reactorscan.result.unstable".Translate();
				text = SubstituteVariables(text);
				return text + "\n\n" + SubstituteVariables(GetFlavourText().Translate()) + "\n\n";
			}
		}

		internal static float lastHealthCheck = 0f;

		internal static ReactorHealthReport lastReport = null;

		internal static List<TerminalKeyword> terminalKeywordsToRegister = new List<TerminalKeyword>();

		internal static List<TerminalNode> terminalNodesToRegister = new List<TerminalNode>();

		internal static string SubstituteVariables(string text)
		{
			StringBuilder stringBuilder = new StringBuilder(text);
			stringBuilder.Replace("<cooldown>", MeltdownPlugin.config.ShipScanCooldown.ToString());
			stringBuilder.Replace("<instability>", lastReport.reactorInstability.ToString());
			stringBuilder.Replace("<time_left>", lastReport.timeRemaining.ToString());
			return stringBuilder.ToString();
		}

		internal static string GetTextForNode()
		{
			if (Object.op_Implicit((Object)(object)MeltdownHandler.Instance))
			{
				string text = "reactorscan.error.overheat";
				if (ReactorHealthCheckReady())
				{
					lastHealthCheck = Time.time;
					lastReport = GetNewReactorHealthReport();
					text = "reactorscan.success";
				}
				return SubstituteVariables(text.Translate()) + lastReport.GetTeminalOutput();
			}
			return "reactorscan.result.stable".Translate();
		}

		internal static bool ReactorHealthCheckReady()
		{
			return Time.time >= lastHealthCheck + MeltdownPlugin.config.ShipScanCooldown;
		}

		internal static ReactorHealthReport GetNewReactorHealthReport()
		{
			float num = ((float)MeltdownPlugin.config.MeltdownTime - MeltdownHandler.Instance.meltdownTimer) / (float)MeltdownPlugin.config.MeltdownTime * 100f;
			num = Mathf.Round(num / MeltdownPlugin.config.ShipScanAccuracy) * MeltdownPlugin.config.ShipScanAccuracy;
			float timeRemaining = (1f - num / 100f) * (float)MeltdownPlugin.config.MeltdownTime;
			return new ReactorHealthReport
			{
				reactorInstability = num,
				timeRemaining = timeRemaining
			};
		}

		[HarmonyPostfix]
		[HarmonyPatch("Awake")]
		internal static void RegisterNodes(Terminal __instance)
		{
			__instance.terminalNodes.allKeywords = CollectionExtensions.AddRangeToArray<TerminalKeyword>(__instance.terminalNodes.allKeywords, terminalKeywordsToRegister.ToArray());
			__instance.terminalNodes.terminalNodes.AddRange(terminalNodesToRegister);
		}

		[HarmonyPostfix]
		[HarmonyPatch("TextPostProcess")]
		internal static void ProcessReactorText(TerminalNode node, ref string __result)
		{
			if ((Object)(object)node == (Object)(object)MeltdownPlugin.assets.reactorHealthNode)
			{
				__result = "\n\n\n" + GetTextForNode();
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(StormyWeather), "GetMetalObjectsAfterDelay")]
		internal static void CancelCoroutine(StormyWeather __instance, ref IEnumerator __result)
		{
			((MonoBehaviour)__instance).StopCoroutine(__result);
		}
	}
}
namespace FacilityMeltdown.MeltdownSequence
{
	public static class MeltdownEffects
	{
		public static List<(Light light, Color originalColour)> SetupEmergencyLights()
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i < RoundManager.Instance.allPoweredLights.Count; i++)
			{
				RoundManager.Instance.allPoweredLights[i].color = MeltdownInteriorMapper.Instance.outsideEmergencyLightColour;
			}
			List<(Light, Color)> list = new List<(Light, Color)>();
			for (int j = 0; j < MeltdownMoonMapper.Instance.outsideEmergencyLights.Count; j++)
			{
				list.Add((MeltdownMoonMapper.Instance.outsideEmergencyLights[j], MeltdownMoonMapper.Instance.outsideEmergencyLights[j].color));
			}
			return list;
		}

		public static IEnumerator RepeatUntilEndOfMeltdown(Func<IEnumerator> enumerator)
		{
			while (true)
			{
				MeltdownPlugin.logger.LogDebug((object)"looping effect");
				yield return enumerator();
			}
		}

		public static IEnumerator WithDelay(IEnumerator enumerator, float delay)
		{
			yield return (object)new WaitForSeconds(delay);
			yield return enumerator;
		}

		public static IEnumerator WithDelay(Action callback, float delay)
		{
			yield return (object)new WaitForSeconds(delay);
			callback();
		}

		public static IEnumerator WithRandomDelay(IEnumerator enumerator, float min, float max)
		{
			yield return WithDelay(enumerator, Random.Range(min, max));
		}

		public static IEnumerator WithRandomDelay(Action callback, float min, float max)
		{
			yield return WithDelay(callback, Random.Range(min, max));
		}

		public static IEnumerator AtProgress(IEnumerator enumerator, float progress)
		{
			while (MeltdownAPI.MeltdownStarted && MeltdownHandler.Instance.Progress > progress)
			{
				yield return null;
			}
			yield return enumerator;
		}

		public static IEnumerator AtProgress(Action callback, float progress)
		{
			while (MeltdownAPI.MeltdownStarted && MeltdownHandler.Instance.Progress > progress)
			{
				yield return null;
			}
			callback();
		}

		public static IEnumerator WithDynamicRandomDelay(IEnumerator enumerator)
		{
			yield return enumerator;
			float progress = MeltdownHandler.Instance.Progress;
			if (!(progress > 0.75f))
			{
				if (!(progress > 0.5f))
				{
					if (progress > 0.25f)
					{
						yield return (object)new WaitForSeconds(Random.Range(5f, 6.5f));
					}
					else
					{
						yield return (object)new WaitForSeconds(Random.Range(3f, 4f));
					}
				}
				else
				{
					yield return (object)new WaitForSeconds(Random.Range(6f, 10f));
				}
			}
			else
			{
				yield return (object)new WaitForSeconds(Random.Range(10f, 14f));
			}
		}

		public static IEnumerator WithDynamicRandomDelay(Action callback)
		{
			callback();
			float progress = MeltdownHandler.Instance.Progress;
			if (!(progress > 0.75f))
			{
				if (!(progress > 0.5f))
				{
					if (progress > 0.25f)
					{
						yield return (object)new WaitForSeconds(Random.Range(5f, 6.5f));
					}
					else
					{
						yield return (object)new WaitForSeconds(Random.Range(3f, 4f));
					}
				}
				else
				{
					yield return (object)new WaitForSeconds(Random.Range(6f, 10f));
				}
			}
			else
			{
				yield return (object)new WaitForSeconds(Random.Range(10f, 14f));
			}
		}

		public static IEnumerator EmergencyLights(float onTime, float offTime, List<(Light light, Color originalColour)> originalLightColours)
		{
			MeltdownPlugin.logger.LogDebug((object)"Switching lights ON");
			for (int i = 0; i < RoundManager.Instance.allPoweredLightsAnimators.Count; i++)
			{
				RoundManager.Instance.allPoweredLightsAnimators[i].SetBool("on", true);
			}
			for (int j = 0; j < MeltdownMoonMapper.Instance.outsideEmergencyLights.Count; j++)
			{
				MeltdownMoonMapper.Instance.outsideEmergencyLights[j].color = MeltdownMoonMapper.Instance.outsideEmergencyLightColour;
			}
			yield return (object)new WaitForSeconds(onTime);
			MeltdownPlugin.logger.LogDebug((object)"Switching lights OFF");
			for (int k = 0; k < RoundManager.Instance.allPoweredLightsAnimators.Count; k++)
			{
				RoundManager.Instance.allPoweredLightsAnimators[k].SetBool("on", false);
			}
			foreach (var (val, color) in originalLightColours)
			{
				val.color = color;
			}
			yield return (object)new WaitForSeconds(offTime);
		}

		public static void InsideParticleEffects()
		{
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: 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)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			if (MeltdownPlugin.clientConfig.ScreenShake)
			{
				RaycastHit val2 = default(RaycastHit);
				for (int i = 0; i < Random.Range(5, 15); i++)
				{
					Vector3 val = GetRandomPositionInsideFacility() + Vector3.up;
					if (Physics.Raycast(new Ray(val, Vector3.up), ref val2, 20f, 256))
					{
						GameObject val3 = MeltdownPlugin.assets.facilityEffects[Random.Range(0, MeltdownPlugin.assets.facilityEffects.Length)];
						GameObject val4 = Object.Instantiate<GameObject>(val3);
						val3.transform.position = ((RaycastHit)(ref val2)).point;
						val4.transform.parent = ((Component)MeltdownHandler.Instance).transform;
					}
				}
			}
			if (GameNetworkManager.Instance.localPlayerController.isInsideFactory)
			{
				Object.Instantiate<GameObject>(StartOfRound.Instance.explosionPrefab, GetRandomPositionNearPlayer(), Quaternion.Euler(-90f, 0f, 0f), RoundManager.Instance.mapPropsContainer.transform);
			}
			if (MeltdownPlugin.clientConfig.ScreenShake)
			{
				if (MeltdownHandler.Instance.Progress > 0.5f)
				{
					HUDManager.Instance.ShakeCamera((ScreenShakeType)1);
				}
				else
				{
					HUDManager.Instance.ShakeCamera((ScreenShakeType)3);
				}
			}
		}

		public static IEnumerator WarningAnnouncer(AudioSource source)
		{
			source.volume = MeltdownPlugin.clientConfig.MusicVolume;
			AudioClip clip = MeltdownPlugin.assets.warnings[Random.Range(0, MeltdownPlugin.assets.warnings.Length)];
			source.clip = clip;
			source.Play();
			yield return (object)new WaitForSeconds(source.clip.length);
		}

		private static Vector3 PlacePositionInsideFacility(Vector3 position, float radius = 10f)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			RoundManager instance = RoundManager.Instance;
			Random random = new Random();
			return instance.GetRandomNavMeshPositionInBoxPredictable(position, 10f, default(NavMeshHit), random, -1);
		}

		private static Vector3 GetRandomPositionNearPlayer(float radius = 15f)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			return PlacePositionInsideFacility(((Component)GameNetworkManager.Instance.localPlayerController).transform.position + Random.insideUnitSphere * radius);
		}

		private static Vector3 GetRandomPositionInsideFacility()
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			return PlacePositionInsideFacility(RoundManager.Instance.insideAINodes[Random.Range(0, RoundManager.Instance.insideAINodes.Length)].transform.position);
		}
	}
}
namespace FacilityMeltdown.MeltdownSequence.Behaviours
{
	internal class FacilityExplosionHandler : MonoBehaviour
	{
		private PlayerControllerB player;

		private float size;

		private float time;

		private LocalVolumetricFog internalFog;

		private void Awake()
		{
			player = GameNetworkManager.Instance.localPlayerController;
			internalFog = ((Component)this).GetComponent<LocalVolumetricFog>();
			if ((Object)(object)internalFog == (Object)null)
			{
				MeltdownPlugin.logger.LogError((object)"Failed to get volumetric fog!");
			}
			if (MeltdownPlugin.clientConfig.ScreenShake)
			{
				HUDManager.Instance.ShakeCamera((ScreenShakeType)0);
				HUDManager.Instance.ShakeCamera((ScreenShakeType)1);
				HUDManager.Instance.ShakeCamera((ScreenShakeType)2);
				HUDManager.Instance.ShakeCamera((ScreenShakeType)3);
			}
			if (!player.isPlayerDead && player.isInsideFactory)
			{
				if (player.isInElevator)
				{
					MeltdownPlugin.logger.LogWarning((object)"Player is inside ship and facility at the same time!! Did you teleport out? Aborting kill");
				}
				else
				{
					KillPlayer();
				}
			}
		}

		private void Update()
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			time += Time.deltaTime * 10f;
			size = TimeToSize(time);
			((Component)this).transform.localScale = Vector3.one * size;
			if ((Object)(object)internalFog != (Object)null)
			{
				internalFog.parameters.size = Vector3.one * size * 1.25f;
			}
			if (!ShouldIgnorePlayer() && PlayerIsInsideFireball())
			{
				player.KillPlayer(Vector3.zero, false, (CauseOfDeath)3, 0);
			}
		}

		private void KillPlayer()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			player.KillPlayer(Vector3.zero, false, (CauseOfDeath)3, 0);
		}

		private bool PlayerIsInsideFireball()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			return Vector3.Distance(((Component)this).transform.position, ((Component)player).transform.position) < size;
		}

		private bool ShouldIgnorePlayer()
		{
			if (!player.isPlayerDead)
			{
				if (player.isInElevator)
				{
					return StartOfRound.Instance.shipIsLeaving;
				}
				return false;
			}
			return true;
		}

		private float TimeToSize(float time)
		{
			return Mathf.Log(time) + 3f + 2f * time;
		}
	}
	public class MeltdownHandler : NetworkBehaviour
	{
		private AudioSource musicSource;

		private AudioSource warningSource;

		internal float meltdownTimer;

		private bool meltdownStarted;

		private GameObject explosion;

		private GameObject shockwave;

		private List<ulong> readyPlayers = new List<ulong>();

		private Vector3 effectOrigin;

		public float TimeLeftUntilMeltdown => meltdownTimer;

		public float Progress => 1f - TimeLeftUntilMeltdown / (float)MeltdownPlugin.config.MeltdownTime;

		private static PlayerControllerB Player => GameNetworkManager.Instance.localPlayerController;

		internal static MeltdownHandler Instance { get; private set; }

		[ClientRpc]
		private void StartMeltdownClientRpc()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_0494: Unknown result type (might be due to invalid IL or missing references)
			//IL_0499: Unknown result type (might be due to invalid IL or missing references)
			//IL_049f: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)base.__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
			{
				ClientRpcParams val = default(ClientRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(3631067672u, val, (RpcDelivery)0);
				((NetworkBehaviour)this).__endSendClientRpc(ref val2, 3631067672u, val, (RpcDelivery)0);
			}
			if ((int)base.__rpc_exec_stage != 2 || (!networkManager.IsClient && !networkManager.IsHost) || (Object)(object)Instance != (Object)null)
			{
				return;
			}
			Instance = this;
			MeltdownPlugin.logger.LogInfo((object)"Beginning Meltdown Sequence! I'd run if I were you!");
			MeltdownMoonMapper.EnsureMeltdownMoonMapper();
			MeltdownInteriorMapper.EnsureMeltdownInteriorMapper();
			if ((Object)(object)MeltdownInteriorMapper.Instance == (Object)null)
			{
				MeltdownPlugin.logger.LogError((object)"WHAT. Just ensured that the interior mapper exists and it doesnt?!?");
			}
			if ((Object)(object)MeltdownMoonMapper.Instance == (Object)null)
			{
				MeltdownPlugin.logger.LogError((object)"WHAT. Just ensured that the moon mapper exists and it doesnt?!?");
			}
			meltdownTimer = MeltdownPlugin.config.MeltdownTime;
			musicSource = ((Component)this).gameObject.AddComponent<AudioSource>();
			musicSource.clip = MeltdownPlugin.assets.defaultMusic;
			musicSource.spatialBlend = 0f;
			musicSource.loop = false;
			musicSource.Play();
			warningSource = ((Component)this).gameObject.AddComponent<AudioSource>();
			warningSource.spatialBlend = 0f;
			warningSource.loop = false;
			((MonoBehaviour)this).StartCoroutine(MeltdownEffects.WithDelay(delegate
			{
				HUDManager.Instance.ReadDialogue(GetDialogue("meltdown.dialogue.start"));
			}, 5f));
			((MonoBehaviour)this).StartCoroutine(MeltdownEffects.WithDelay(MeltdownEffects.RepeatUntilEndOfMeltdown(() => MeltdownEffects.WithDynamicRandomDelay(MeltdownEffects.WarningAnnouncer(warningSource))), 10f));
			((MonoBehaviour)this).StartCoroutine(MeltdownEffects.RepeatUntilEndOfMeltdown(() => MeltdownEffects.WithDynamicRandomDelay(MeltdownEffects.InsideParticleEffects)));
			if (MeltdownPlugin.config.EmergencyLights)
			{
				try
				{
					List<(Light, Color)> originalLightColours = MeltdownEffects.SetupEmergencyLights();
					((MonoBehaviour)this).StartCoroutine(MeltdownEffects.RepeatUntilEndOfMeltdown(() => MeltdownEffects.EmergencyLights(2f, 5f, originalLightColours)));
				}
				catch (Exception arg)
				{
					MeltdownPlugin.logger.LogError((object)$"Failed to set the emergency light colour: {arg}");
				}
			}
			((MonoBehaviour)this).StartCoroutine(MeltdownEffects.RepeatUntilEndOfMeltdown(() => MeltdownEffects.WithRandomDelay(delegate
			{
				//IL_003a: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)shockwave != (Object)null)
				{
					Object.Destroy((Object)(object)shockwave);
				}
				shockwave = Object.Instantiate<GameObject>(MeltdownPlugin.assets.shockwavePrefab);
				shockwave.transform.position = effectOrigin;
			}, 25f, 35f)));
			((MonoBehaviour)this).StartCoroutine(MeltdownEffects.AtProgress((Action)HUDManager.Instance.RadiationWarningHUD, 0.5f));
			if (((NetworkBehaviour)GameNetworkManager.Instance.localPlayerController).IsServer)
			{
				List<string> disallowedEnemies = MeltdownPlugin.config.GetDisallowedEnemies();
				List<SpawnableEnemyWithRarity> list = new List<SpawnableEnemyWithRarity>();
				foreach (SpawnableEnemyWithRarity enemy in RoundManager.Instance.currentLevel.Enemies)
				{
					if (!disallowedEnemies.Contains(enemy.enemyType.enemyName))
					{
						list.Add(enemy);
					}
				}
				List<int> list2 = new List<int>();
				foreach (SpawnableEnemyWithRarity item in list)
				{
					if (!EnemyCannotBeSpawned(item.enemyType))
					{
						list2.Add(item.rarity);
					}
				}
				List<EnemyVent> list3 = new List<EnemyVent>();
				for (int i = 0; i < RoundManager.Instance.allEnemyVents.Length; i++)
				{
					if (!RoundManager.Instance.allEnemyVents[i].occupied)
					{
						list3.Add(RoundManager.Instance.allEnemyVents[i]);
					}
				}
				list3.Shuffle();
				for (int j = 0; j < Mathf.Min(MeltdownPlugin.config.MonsterSpawnAmount, list3.Count); j++)
				{
					EnemyVent vent = list3[j];
					int randomWeightedIndex = RoundManager.Instance.GetRandomWeightedIndex(list2.ToArray(), RoundManager.Instance.EnemySpawnRandom);
					if (!EnemyCannotBeSpawned(list[randomWeightedIndex].enemyType))
					{
						RoundManager instance = RoundManager.Instance;
						instance.currentEnemyPower += list[randomWeightedIndex].enemyType.PowerLevel;
						MeltdownPlugin.logger.LogInfo((object)("Spawning a " + list[randomWeightedIndex].enemyType.enemyName + " during the meltdown sequence"));
						vent.SpawnEnemy(list[randomWeightedIndex]);
					}
				}
			}
			effectOrigin = RoundManager.FindMainEntrancePosition(false, true);
			if (effectOrigin == Vector3.zero)
			{
				MeltdownPlugin.logger.LogError((object)"Effect Origin is Vector3.Zero! We couldn't find the effect origin");
				HUDManager.Instance.DisplayGlobalNotification("Failed to find effect origin... Things will look broken.");
			}
			if (MeltdownPlugin.clientConfig.ScreenShake)
			{
				HUDManager.Instance.ShakeCamera((ScreenShakeType)3);
				HUDManager.Instance.ShakeCamera((ScreenShakeType)2);
			}
			MeltdownAPI.OnMeltdownStart();
			meltdownStarted = true;
		}

		[ServerRpc(RequireOwnership = false)]
		private void MeltdownReadyServerRpc(ulong clientId)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
			{
				ServerRpcParams val = default(ServerRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(2863729516u, val, (RpcDelivery)0);
				BytePacker.WriteValueBitPacked(val2, clientId);
				((NetworkBehaviour)this).__endSendServerRpc(ref val2, 2863729516u, val, (RpcDelivery)0);
			}
			if ((int)base.__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost))
			{
				readyPlayers.Add(clientId);
				if (readyPlayers.Count == StartOfRound.Instance.GetConnectedPlayers().Count)
				{
					StartMeltdownClientRpc();
				}
			}
		}

		public override void OnNetworkSpawn()
		{
			if (!MeltdownPlugin.loadedFully)
			{
				MeltdownPlugin.logger.LogError((object)"Meltdown didn't load fully correctly and so this client blocked the Meltdown Sequence");
			}
			else
			{
				MeltdownReadyServerRpc(((NetworkBehaviour)this).NetworkManager.LocalClientId);
			}
		}

		internal bool EnemyCannotBeSpawned(EnemyType type)
		{
			if (!type.spawningDisabled)
			{
				return type.numberSpawned >= type.MaxCount;
			}
			return true;
		}

		internal static DialogueSegment[] GetDialogue(string translation)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Expected O, but got Unknown
			JArray translationSet = LangParser.GetTranslationSet(translation);
			DialogueSegment[] array = (DialogueSegment[])(object)new DialogueSegment[((JContainer)translationSet).Count];
			for (int i = 0; i < ((JContainer)translationSet).Count; i++)
			{
				array[i] = new DialogueSegment
				{
					bodyText = ((string)translationSet[i]).Replace("<meltdown_time>", Math.Round((float)MeltdownPlugin.config.MeltdownTime / 60f).ToString()),
					speakerText = "meltdown.dialogue.speaker".Translate()
				};
			}
			return array;
		}

		private void OnDisable()
		{
			if (!((Object)(object)Instance != (Object)(object)this))
			{
				MeltdownPlugin.logger.LogInfo((object)"Cleaning up MeltdownHandler.");
				Instance = null;
				if ((Object)(object)explosion != (Object)null)
				{
					Object.Destroy((Object)(object)explosion);
				}
				if ((Object)(object)shockwave != (Object)null)
				{
					Object.Destroy((Object)(object)shockwave);
				}
				if (!meltdownStarted)
				{
					MeltdownPlugin.logger.LogError((object)"MeltdownHandler was disabled without starting a meltdown, a client most likely failed the MeltdownReadyCheck. If you are going to report this make sure to provide ALL client logs.");
				}
			}
		}

		private void Update()
		{
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			if (!meltdownStarted || HasExplosionOccured())
			{
				return;
			}
			StartOfRound instance = StartOfRound.Instance;
			musicSource.volume = (float)MeltdownPlugin.clientConfig.MusicVolume / 100f;
			if (!Player.isInsideFactory && !MeltdownPlugin.clientConfig.MusicPlaysOutside)
			{
				musicSource.volume = 0f;
			}
			meltdownTimer -= Time.deltaTime;
			if (meltdownTimer <= 3f && !instance.shipIsLeaving)
			{
				((MonoBehaviour)this).StartCoroutine(ShipTakeOff());
			}
			if (meltdownTimer <= 0f)
			{
				musicSource.Stop();
				GameObject val = MeltdownMoonMapper.Instance.explosionPrefab;
				if ((Object)(object)val == (Object)null)
				{
					val = MeltdownPlugin.assets.facilityExplosionPrefab;
				}
				explosion = Object.Instantiate<GameObject>(val);
				explosion.transform.position = effectOrigin;
				FacilityExplosionHandler facilityExplosionHandler = default(FacilityExplosionHandler);
				if (!explosion.TryGetComponent<FacilityExplosionHandler>(ref facilityExplosionHandler))
				{
					explosion.AddComponent<FacilityExplosionHandler>();
				}
			}
		}

		private IEnumerator ShipTakeOff()
		{
			StartOfRound shipManager = StartOfRound.Instance;
			shipManager.shipLeftAutomatically = true;
			shipManager.shipIsLeaving = true;
			HUDManager.Instance.ReadDialogue(GetDialogue("meltdown.dialogue.shiptakeoff"));
			yield return (object)new WaitForSeconds(3f);
			yield return (object)new WaitForSeconds(3f);
			((Behaviour)HUDManager.Instance.shipLeavingEarlyIcon).enabled = false;
			StartMatchLever val = Object.FindObjectOfType<StartMatchLever>();
			val.triggerScript.animationString = "SA_PushLeverBack";
			val.leverHasBeenPulled = false;
			val.triggerScript.interactable = false;
			val.leverAnimatorObject.SetBool("pullLever", false);
			shipManager.ShipLeave();
			yield return (object)new WaitForSeconds(1.5f);
			shipManager.SetSpectateCameraToGameOverMode(true, (PlayerControllerB)null);
			if (GameNetworkManager.Instance.localPlayerController.isPlayerDead)
			{
				GameNetworkManager.Instance.localPlayerController.SetSpectatedPlayerEffects(true);
			}
			yield return (object)new WaitForSeconds(1f);
			yield return (object)new WaitForSeconds(9.5f);
		}

		public bool HasExplosionOccured()
		{
			return (Object)(object)explosion != (Object)null;
		}

		protected override void __initializeVariables()
		{
			((NetworkBehaviour)this).__initializeVariables();
		}

		[RuntimeInitializeOnLoadMethod]
		internal static void InitializeRPCS_MeltdownHandler()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			NetworkManager.__rpc_func_table.Add(3631067672u, new RpcReceiveHandler(__rpc_handler_3631067672));
			NetworkManager.__rpc_func_table.Add(2863729516u, new RpcReceiveHandler(__rpc_handler_2863729516));
		}

		private static void __rpc_handler_3631067672(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((MeltdownHandler)(object)target).StartMeltdownClientRpc();
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_2863729516(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				ulong clientId = default(ulong);
				ByteUnpacker.ReadValueBitPacked(reader, ref clientId);
				target.__rpc_exec_stage = (__RpcExecStage)1;
				((MeltdownHandler)(object)target).MeltdownReadyServerRpc(clientId);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		protected internal override string __getTypeName()
		{
			return "MeltdownHandler";
		}
	}
	public class Shockwave : MonoBehaviour
	{
		private bool localPlayerCameraShake;

		private float size;

		private AudioSource sound;

		private Renderer renderer;

		private void Awake()
		{
			sound = ((Component)this).gameObject.AddComponent<AudioSource>();
			sound.clip = MeltdownPlugin.assets.shockwave;
			sound.spatialBlend = 0f;
			sound.loop = false;
			renderer = ((Component)this).GetComponent<Renderer>();
		}

		private void Update()
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			PlayerControllerB localPlayerController = GameNetworkManager.Instance.localPlayerController;
			size += Time.deltaTime * 50f;
			((Component)this).transform.localScale = Vector3.one * size;
			if (localPlayerController.isInsideFactory)
			{
				renderer.enabled = false;
				return;
			}
			renderer.enabled = true;
			if (PlayerIsInsideShockwave() && !localPlayerCameraShake && MeltdownPlugin.clientConfig.ScreenShake)
			{
				ScreenShake();
				localPlayerCameraShake = true;
				sound.Play();
			}
		}

		private void ScreenShake()
		{
			HUDManager.Instance.ShakeCamera((ScreenShakeType)1);
		}

		internal bool PlayerIsInsideShockwave()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			return Vector3.Distance(((Component)this).transform.position, ((Component)GameNetworkManager.Instance.localPlayerController).transform.position) <= size;
		}
	}
}
namespace FacilityMeltdown.Lang
{
	internal static class LangParser
	{
		internal static Dictionary<string, string> languages { get; private set; }

		internal static Dictionary<string, object> loadedLanguage { get; private set; }

		internal static Dictionary<string, object> defaultLanguage { get; private set; }

		internal static void Init()
		{
			using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("FacilityMeltdown.Lang.defs.json");
			using StreamReader streamReader = new StreamReader(stream);
			string text = streamReader.ReadToEnd();
			languages = JsonConvert.DeserializeObject<Dictionary<string, string>>(text);
		}

		internal static Dictionary<string, object> LoadLanguage(string id)
		{
			using Stream stream = File.Open(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "lang", id + ".json"), FileMode.Open);
			using StreamReader streamReader = new StreamReader(stream);
			string text = streamReader.ReadToEnd();
			return JsonConvert.DeserializeObject<Dictionary<string, object>>(text);
		}

		internal static void SetLanguage(string id)
		{
			MeltdownPlugin.logger.LogInfo((object)("Loading language: " + languages[id] + " (" + id + ")"));
			loadedLanguage = LoadLanguage(id);
			MeltdownPlugin.logger.LogInfo((object)("Loaded " + languages[id]));
		}

		internal static string GetTranslation(string translation)
		{
			if (loadedLanguage.TryGetValue(translation, out var value))
			{
				return (string)value;
			}
			if (defaultLanguage.TryGetValue(translation, out value))
			{
				MeltdownPlugin.logger.LogError((object)("Falling back to english. for translation: " + translation));
				return (string)value;
			}
			if (translation == "lang.missing")
			{
				MeltdownPlugin.logger.LogError((object)"LANG.MISSING IS MISSING!!!!!  THIS IS BAD!! VERY BAD!!");
				return "lang.missing; <translation_id>";
			}
			return GetTranslation("lang.missing").Replace("<translation_id>", translation);
		}

		internal static JArray GetTranslationSet(string translation)
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Expected O, but got Unknown
			if (loadedLanguage.TryGetValue(translation, out var value))
			{
				MeltdownPlugin.logger.LogInfo((object)value.GetType());
				return (JArray)((value is JArray) ? value : null);
			}
			if (defaultLanguage.TryGetValue(translation, out value))
			{
				MeltdownPlugin.logger.LogError((object)("Falling back to english. for translation (dialogue): " + translation));
				return (JArray)((value is JArray) ? value : null);
			}
			JArray val = new JArray();
			val.Add(JToken.op_Implicit(GetTranslation("lang.missing").Replace("<translation_id>", translation)));
			return val;
		}
	}
}
namespace FacilityMeltdown.Integrations
{
	internal class LethalConfigIntergration
	{
		public static bool Enabled { get; private set; }

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		private static void Initialize()
		{
			Enabled = true;
			LethalConfigManager.SetModDescription("Maybe taking the appartus isn't such a great idea...");
			HandleConfig(MeltdownPlugin.config);
			HandleConfig(MeltdownPlugin.clientConfig);
		}

		private static void HandleConfig<T>(LoafConfig<T> config) where T : LoafConfig<T>
		{
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Expected O, but got Unknown
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Expected O, but got Unknown
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Expected O, but got Unknown
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Expected O, but got Unknown
			//IL_0204: Unknown result type (might be due to invalid IL or missing references)
			//IL_020e: Expected O, but got Unknown
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Expected O, but got Unknown
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: Expected O, but got Unknown
			//IL_018c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Expected O, but got Unknown
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Expected O, but got Unknown
			//IL_0257: Unknown result type (might be due to invalid IL or missing references)
			//IL_0261: Expected O, but got Unknown
			bool flag = true;
			if (config.GetType().GetCustomAttribute<RequiresRestartAttribute>() != null)
			{
				flag = config.GetType().GetCustomAttribute<RequiresRestartAttribute>().RequiresRestart;
			}
			foreach (var configEntry in config.configEntries)
			{
				PropertyInfo property = configEntry.Item1;
				object uncastedEntry = configEntry.Item2;
				bool flag2 = flag;
				RequiresRestartAttribute customAttribute = property.GetCustomAttribute<RequiresRestartAttribute>();
				if (customAttribute != null)
				{
					flag2 = customAttribute.RequiresRestart;
				}
				ConfigRangeAttribute customAttribute2 = property.GetCustomAttribute<ConfigRangeAttribute>();
				if (property.PropertyType == typeof(int))
				{
					if (customAttribute2 == null)
					{
						throw new NotImplementedException(property.Name + ": config entry of type: int, must have a range attribute, because i was too lazy lmao");
					}
					ConfigEntry<int> obj2 = (ConfigEntry<int>)uncastedEntry;
					IntSliderOptions val = new IntSliderOptions();
					((BaseRangeOptions<int>)val).Min = (int)customAttribute2.Min;
					((BaseRangeOptions<int>)val).Max = (int)customAttribute2.Max;
					((BaseOptions)val).RequiresRestart = flag2;
					LethalConfigManager.AddConfigItem((BaseConfigItem)new IntSliderConfigItem(obj2, val));
					if (!flag2)
					{
						((ConfigEntry<int>)uncastedEntry).SettingChanged += delegate
						{
							property.SetValue(config, ((ConfigEntry<int>)uncastedEntry).Value);
						};
					}
				}
				if (property.PropertyType == typeof(float))
				{
					if (customAttribute2 == null)
					{
						throw new NotImplementedException(property.Name + ": config entry of type: float, must have a range attribute, because i was too lazy lmao");
					}
					ConfigEntry<float> obj3 = (ConfigEntry<float>)uncastedEntry;
					FloatSliderOptions val2 = new FloatSliderOptions();
					((BaseRangeOptions<float>)val2).Min = customAttribute2.Min;
					((BaseRangeOptions<float>)val2).Max = customAttribute2.Max;
					((BaseOptions)val2).RequiresRestart = flag2;
					LethalConfigManager.AddConfigItem((BaseConfigItem)new FloatSliderConfigItem(obj3, val2));
					if (!flag2)
					{
						((ConfigEntry<float>)uncastedEntry).SettingChanged += delegate
						{
							property.SetValue(config, ((ConfigEntry<float>)uncastedEntry).Value);
						};
					}
				}
				if (property.PropertyType == typeof(bool))
				{
					LethalConfigManager.AddConfigItem((BaseConfigItem)new BoolCheckBoxConfigItem((ConfigEntry<bool>)uncastedEntry, flag2));
					if (!flag2)
					{
						((ConfigEntry<bool>)uncastedEntry).SettingChanged += delegate
						{
							property.SetValue(config, ((ConfigEntry<bool>)uncastedEntry).Value);
						};
					}
				}
				if (!(property.PropertyType == typeof(string)))
				{
					continue;
				}
				LethalConfigManager.AddConfigItem((BaseConfigItem)new TextInputFieldConfigItem((ConfigEntry<string>)uncastedEntry, flag2));
				if (!flag2)
				{
					((ConfigEntry<string>)uncastedEntry).SettingChanged += delegate
					{
						property.SetValue(config, ((ConfigEntry<string>)uncastedEntry).Value);
					};
				}
			}
		}
	}
	internal class LethalSettingsIntegration
	{
		public static bool Enabled { get; private set; }

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		private static void Initialize()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Expected O, but got Unknown
			Enabled = true;
			VerticalComponent val = BuildConfig(MeltdownPlugin.clientConfig);
			ModSettingsConfig val2 = new ModSettingsConfig();
			val2.Name = "FacilityMeltdown";
			val2.Id = "me.loaforc.facilitymeltdown";
			val2.Version = "2.6.7";
			val2.Description = "Maybe taking the appartus isn't such a great idea...";
			val2.MenuComponents = (MenuComponent[])(object)new MenuComponent[2]
			{
				(MenuComponent)BuildConfig(MeltdownPlugin.config),
				(MenuComponent)val
			};
			ModMenu.RegisterMod(val2);
			val2 = new ModSettingsConfig();
			val2.Name = "FacilityMeltdown";
			val2.Id = "me.loaforc.facilitymeltdown";
			val2.Version = "2.6.7";
			val2.Description = "Maybe taking the appartus isn't such a great idea... (GameSettings are hidden in game)";
			val2.MenuComponents = (MenuComponent[])(object)new MenuComponent[1] { (MenuComponent)val };
			ModMenu.RegisterMod(val2, false, true);
		}

		private static VerticalComponent BuildConfig<T>(LoafConfig<T> config) where T : LoafConfig<T>
		{
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Expected O, but got Unknown
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Expected O, but got Unknown
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0188: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Expected O, but got Unknown
			//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0205: Unknown result type (might be due to invalid IL or missing references)
			//IL_0212: Unknown result type (might be due to invalid IL or missing references)
			//IL_0224: Unknown result type (might be due to invalid IL or missing references)
			//IL_023c: Expected O, but got Unknown
			//IL_025a: Unknown result type (might be due to invalid IL or missing references)
			//IL_025f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0271: Unknown result type (might be due to invalid IL or missing references)
			//IL_0294: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ac: Expected O, but got Unknown
			//IL_02ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0304: Unknown result type (might be due to invalid IL or missing references)
			//IL_031c: Expected O, but got Unknown
			bool flag = true;
			if (config.GetType().GetCustomAttribute<RequiresRestartAttribute>() != null)
			{
				flag = config.GetType().GetCustomAttribute<RequiresRestartAttribute>().RequiresRestart;
			}
			List<MenuComponent> list = new List<MenuComponent>();
			string text = "Misc";
			foreach (var configEntry in config.configEntries)
			{
				PropertyInfo property = configEntry.Item1;
				object uncastedEntry = configEntry.Item2;
				bool requiresRestart = flag;
				RequiresRestartAttribute customAttribute = property.GetCustomAttribute<RequiresRestartAttribute>();
				if (customAttribute != null)
				{
					requiresRestart = customAttribute.RequiresRestart;
				}
				ConfigGroupAttribute configGroupAttribute = (ConfigGroupAttribute)property.GetCustomAttribute(typeof(ConfigGroupAttribute));
				if (configGroupAttribute != null)
				{
					text = configGroupAttribute.Group;
					list.Add((MenuComponent)new LabelComponent
					{
						Text = text
					});
				}
				else if (text == "Misc")
				{
					list.Add((MenuComponent)new LabelComponent
					{
						Text = text
					});
				}
				ConfigRangeAttribute customAttribute2 = property.GetCustomAttribute<ConfigRangeAttribute>();
				if (property.PropertyType == typeof(int))
				{
					list.Add((MenuComponent)new SliderComponent
					{
						Value = (int)property.GetValue(config),
						WholeNumbers = true,
						MinValue = customAttribute2.Min,
						MaxValue = customAttribute2.Max,
						Text = property.Name,
						OnValueChanged = delegate(SliderComponent self, float value)
						{
							((ConfigEntry<int>)uncastedEntry).Value = (int)value;
							if (!requiresRestart)
							{
								property.SetValue(config, value);
							}
						}
					});
				}
				if (property.PropertyType == typeof(float))
				{
					list.Add((MenuComponent)new SliderComponent
					{
						Value = (float)property.GetValue(config),
						MinValue = customAttribute2.Min,
						MaxValue = customAttribute2.Max,
						Text = property.Name,
						OnValueChanged = delegate(SliderComponent self, float value)
						{
							((ConfigEntry<float>)uncastedEntry).Value = value;
							if (!requiresRestart)
							{
								property.SetValue(config, value);
							}
						}
					});
				}
				if (property.PropertyType == typeof(bool))
				{
					list.Add((MenuComponent)new ToggleComponent
					{
						Text = property.Name,
						Value = (bool)property.GetValue(config),
						OnValueChanged = delegate(ToggleComponent self, bool value)
						{
							((ConfigEntry<bool>)uncastedEntry).Value = value;
							if (!requiresRestart)
							{
								property.SetValue(config, value);
							}
						}
					});
				}
				if (!(property.PropertyType == typeof(string)))
				{
					continue;
				}
				list.Add((MenuComponent)new InputComponent
				{
					Placeholder = property.Name,
					Value = (string)property.GetValue(config),
					OnValueChanged = delegate(InputComponent self, string value)
					{
						((ConfigEntry<string>)uncastedEntry).Value = value;
						if (!requiresRestart)
						{
							property.SetValue(config, value);
						}
					}
				});
			}
			return null;
		}
	}
	public class LobbyCompatibilityIntegration
	{
		public static bool Enabled { get; private set; }

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		private static void Initialize()
		{
			Enabled = true;
			PluginHelper.RegisterPlugin("me.loaforc.facilitymeltdown", Version.Parse("2.6.7"), (CompatibilityLevel)2, (VersionStrictness)3);
		}
	}
}
namespace FacilityMeltdown.Equipment
{
	public class GeigerCounterItem : GrabbableObject
	{
		[Space(15f)]
		[Header("Audio")]
		public AudioSource generalAudioSource;

		public AudioSource lowRadiation;

		public AudioSource mediumRadiation;

		public AudioSource highRadiation;

		public AudioClip toggle;

		public AudioClip outOfBattery;

		public GameObject needle;

		public float maxRotation = 25f;

		public float maxDetection = 50f;

		public override void ItemActivate(bool used, bool buttonDown = true)
		{
			((GrabbableObject)this).ItemActivate(used, buttonDown);
			MeltdownPlugin.logger.LogInfo((object)"ACTIVATED GEIGER COUNTER");
			SwitchPoweredState(used);
			generalAudioSource.clip = toggle;
			generalAudioSource.Play();
		}

		public override void UseUpBatteries()
		{
			((GrabbableObject)this).UseUpBatteries();
			SwitchPoweredState(on: false);
			generalAudioSource.clip = outOfBattery;
			generalAudioSource.Play();
		}

		public void SwitchPoweredState(bool on)
		{
			MeltdownPlugin.logger.LogInfo((object)$"me when the on value is {on}. :rofl::rofl::rofl:");
			if (base.isBeingUsed)
			{
				lowRadiation.Play();
				mediumRadiation.Play();
				highRadiation.Play();
			}
			else
			{
				lowRadiation.Stop();
				mediumRadiation.Stop();
				highRadiation.Stop();
			}
		}

		public override void Update()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			((GrabbableObject)this).Update();
			if (base.isBeingUsed)
			{
				float num = RadiationSource.CollectRadiationFromPoint(((Component)this).transform.position);
				lowRadiation.volume = 0f;
				mediumRadiation.volume = 0f;
				highRadiation.volume = 0f;
				if (num > maxDetection)
				{
					highRadiation.volume = 1f;
				}
				else if (num > maxDetection / 2f)
				{
					mediumRadiation.volume = 1f;
				}
				else
				{
					lowRadiation.volume = 1f;
				}
				float num2 = Mathf.Clamp01(num / maxDetection) * (maxRotation * 2f);
				num2 -= maxRotation;
				needle.transform.localEulerAngles = new Vector3(-90f, num2, 0f);
			}
		}

		protected override void __initializeVariables()
		{
			((GrabbableObject)this).__initializeVariables();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		protected internal override string __getTypeName()
		{
			return "GeigerCounterItem";
		}
	}
}
namespace FacilityMeltdown.Config
{
	[RequiresRestart(false)]
	internal class MeltdownClientConfig : LoafConfig<MeltdownClientConfig>
	{
		[ConfigGroup("Audio")]
		[ConfigDesc("What volume the music plays at. Also controls the volume of the random voicelines that play")]
		[ConfigRange(0f, 100f)]
		public int MusicVolume { get; private set; } = 100;


		[ConfigDesc("Does the music play outside the facility?")]
		public bool MusicPlaysOutside { get; private set; } = true;


		[ConfigGroup("Visuals")]
		[ConfigDesc("Whether or not to shake the screen during the meltdown sequence. Doesn't control other places of screen shake in the game.")]
		public bool ScreenShake { get; private set; } = true;


		[ConfigDesc("Should meltdown sequence contain particle effects? Doesn't include particle effects on the fireball.")]
		public bool ParticleEffects { get; private set; } = true;


		[ConfigIgnore]
		[RequiresRestart(true)]
		public string Language { get; private set; } = "en";


		internal MeltdownClientConfig(ConfigFile file)
			: base(file)
		{
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Expected O, but got Unknown
			BindProperty<string>(typeof(MeltdownClientConfig).GetProperty("Language"), "Language", new ConfigDescription("What language should FacilityMeltdown use? NOTE: This only affects facility meltdown and won't change the rest of the games langauge\nSome Languages may also need FontPatcher(https://thunderstore.io/c/lethal-company/p/LeKAKiD/FontPatcher/)\nLanguages Available: " + string.Join(", ", LangParser.languages.Keys), (AcceptableValueBase)null, Array.Empty<object>()));
		}
	}
	internal class MeltdownConfig : LoafSyncedConfig<MeltdownConfig>
	{
		[ConfigGroup("GameBalance")]
		[ConfigDesc("Whether or not FacilityMeltdown should override appartus value. Only disable for compatibility reasons.")]
		public bool OverrideApparatusValue { get; private set; } = true;


		[ConfigDesc("When overriding the apparatus value what should it's base value be?")]
		[ConfigRange(80f, 500f)]
		public int ApparatusValue { get; private set; } = 240;


		[ConfigDesc("How many monsters should spawn during the meltdown sequence? Set to 0 to disable.")]
		[ConfigRange(0f, 10f)]
		public int MonsterSpawnAmount { get; private set; } = 5;


		[ConfigDesc("Should the lights turn on periodically? Disabling this option makes them permanently off. (Matches Vanilla Behaviour)")]
		public bool EmergencyLights { get; private set; } = true;


		[ConfigDesc("How many people need to be nearby to the apparatus for it to be collectable? Will go UP TO the value, e.g. if it's set to 3 and there are only 2 people in the lobby, everyone will need to be there.")]
		[ConfigRange(1f, 10f)]
		public int MinPeopleToPullApparatus { get; private set; } = 2;


		[ConfigDesc("What enemies to exclude from spawning in the meltdown sequence. Comma seperated list. Supports modded entities.")]
		public string DisallowedEnemies { get; private set; } = "Centipede,Hoarding bug";


		[ConfigDesc("How long until the ship's scanner can scan the reactor. (Doesn't affect the vanilla `scan` command)")]
		[ConfigRange(0f, 20f)]
		public float ShipScanCooldown { get; private set; } = 15f;


		[ConfigDesc("How accurate is the ship's scanner when scanning the reactor. Higher values mean it is more uncertain, and lower values is more accurate. (Doesn't affect the vanilla `scan` command)")]
		[ConfigRange(0f, 100f)]
		public float ShipScanAccuracy { get; private set; } = 15f;


		[ConfigGroup("UNSUPPORTED")]
		[ConfigDesc("ABSOLUETLY NOT SUPPORTED OR RECOMMENDED! Change the length of the meltdown sequence. If this breaks I am not fixing it, you have been warned.")]
		[ConfigRange(60f, 300f)]
		public int MeltdownTime { get; private set; } = 120;


		public MeltdownConfig(ConfigFile file)
			: base(file)
		{
		}

		public List<string> GetDisallowedEnemies()
		{
			return DisallowedEnemies.Split(',').ToList();
		}
	}
}
namespace FacilityMeltdown.Behaviours
{
	public class MeltdownEvents : MonoBehaviour
	{
		[Serializable]
		public class Marker
		{
			internal bool Triggered;

			[field: SerializeField]
			public float Progress { get; private set; } = 0.5f;


			[field: SerializeField]
			public UnityEvent OnMarker { get; private set; }
		}

		[SerializeField]
		private UnityEvent OnMeltdownStart;

		[SerializeField]
		private List<Marker> markers = new List<Marker>();

		private void OnEnable()
		{
			MeltdownAPI.OnMeltdownStart = (Action)Delegate.Combine(MeltdownAPI.OnMeltdownStart, new Action(OnMeltdownStart.Invoke));
		}

		private void OnDisable()
		{
			MeltdownAPI.OnMeltdownStart = (Action)Delegate.Remove(MeltdownAPI.OnMeltdownStart, new Action(OnMeltdownStart.Invoke));
		}

		private void Update()
		{
			if (!MeltdownAPI.MeltdownStarted)
			{
				return;
			}
			foreach (Marker marker in markers)
			{
				if (!marker.Triggered && !(marker.Progress > MeltdownHandler.Instance.Progress))
				{
					marker.OnMarker.Invoke();
					marker.Triggered = true;
				}
			}
		}
	}
	public class MeltdownInteriorMapper : MonoBehaviour
	{
		public static MeltdownInteriorMapper Instance { get; private set; }

		[Tooltip("Colour to flash lights with, should probably just leave this at red. Only applies to inside lights.")]
		[field: SerializeField]
		public Color outsideEmergencyLightColour { get; private set; } = Color.red;


		private void Awake()
		{
			Instance = this;
		}

		private void OnDisable()
		{
			if ((Object)(object)Instance != (Object)null)
			{
				Instance = null;
			}
		}

		internal static void EnsureMeltdownInteriorMapper()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)Object.FindObjectOfType<MeltdownInteriorMapper>() != (Object)null))
			{
				Instance = new GameObject("DefaultMeltdownInteriorMappings").AddComponent<MeltdownInteriorMapper>();
			}
		}
	}
	public class MeltdownMoonMapper : MonoBehaviour
	{
		[SerializeField]
		[Tooltip("Lights to flash red during the meltdown sequence. Doesn't include inside lights.")]
		public List<Light> outsideEmergencyLights = new List<Light>();

		public static MeltdownMoonMapper Instance { get; private set; }

		[Tooltip("Colour to flash lights with, should probably just leave this at red. Only applies to outside lights.")]
		[field: SerializeField]
		public Color outsideEmergencyLightColour { get; private set; } = Color.red;


		[field: SerializeField]
		public GameObject shockwavePrefab { get; private set; }

		[field: SerializeField]
		public GameObject explosionPrefab { get; private set; }

		private void Awake()
		{
			Instance = this;
		}

		private void OnDisable()
		{
			if ((Object)(object)Instance != (Object)null)
			{
				Instance = null;
			}
		}

		internal static void EnsureMeltdownMoonMapper()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)Object.FindObjectOfType<MeltdownMoonMapper>() != (Object)null))
			{
				Instance = new GameObject("DefaultMeltdownMappings").AddComponent<MeltdownMoonMapper>();
				Instance.outsideEmergencyLights = (from light in GameObject.Find("Environment").GetComponentsInChildren<Light>()
					where CheckParentForDisallowed(((Component)light).transform)
					select light).ToList();
			}
		}

		private static bool CheckParentForDisallowed(Transform child)
		{
			if (((Object)((Component)child).gameObject).name == "Sun" || ((Object)((Component)child).gameObject).name == "ItemShipAnimContainer" || ((Object)((Component)child).gameObject).name == "MapPropsContainer")
			{
				return false;
			}
			if ((Object)(object)child.parent == (Object)null)
			{
				return true;
			}
			return CheckParentForDisallowed(child.parent);
		}
	}
	public class RadiationSource : MonoBehaviour
	{
		[HideInInspector]
		public static List<RadiationSource> radiators = new List<RadiationSource>();

		[Range(0f, 100f)]
		public float radiationAmount = 70f;

		public bool isGlobal;

		[Range(0f, 100f)]
		public float radiationDistance = 50f;

		[Header("Decay Settings")]
		public bool doesDecay;

		[Range(0f, 120f)]
		public float decayTime = 120f;

		public AnimationCurve radiationOutputVsDecay = new AnimationCurve((Keyframe[])(object)new Keyframe[2]
		{
			new Keyframe(0f, 1f),
			new Keyframe(0f, 1f)
		});

		private float existingTime;

		public static float CollectRadiationFromPoint(Vector3 point)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			float num = 0f;
			foreach (RadiationSource radiator in radiators)
			{
				num += radiator.GetRadiationFromPoint(point);
			}
			return num;
		}

		public float GetRadiationAtDistance(float distance)
		{
			if (distance > radiationDistance)
			{
				return 0f;
			}
			float num = Mathf.Clamp01((radiationDistance - distance) / radiationDistance);
			if (isGlobal)
			{
				num = 1f;
			}
			return num * radiationAmount * GetDecayReduction();
		}

		public float GetDecayProgress()
		{
			if (!doesDecay)
			{
				return 0f;
			}
			return Mathf.Clamp01(existingTime / decayTime);
		}

		public float GetDecayReduction()
		{
			if (!doesDecay)
			{
				return 1f;
			}
			return radiationOutputVsDecay.Evaluate(GetDecayProgress());
		}

		public float GetRadiationFromPoint(Vector3 point)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			return GetRadiationAtDistance(Vector3.Distance(((Component)this).transform.position, point));
		}

		private void OnEnable()
		{
			radiators.Add(this);
			MeltdownPlugin.logger.LogInfo((object)$"A new RadiationSource was created, there is now: {radiators.Count} radiators.");
		}

		private void OnDisable()
		{
			radiators.Remove(this);
		}

		private void Update()
		{
			existingTime += Time.deltaTime;
		}
	}
}
namespace FacilityMeltdown.API
{
	public static class MeltdownAPI
	{
		internal static Action OnMeltdownStart = delegate
		{
		};

		public static bool MeltdownStarted => (Object)(object)MeltdownHandler.Instance != (Object)null;

		public static void StartMeltdown(string modGUID)
		{
			if (!MeltdownStarted)
			{
				MeltdownPlugin.logger.LogInfo((object)("A mod (" + modGUID + ") has begun a meltdown!"));
				if (!((NetworkBehaviour)GameNetworkManager.Instance.localPlayerController).IsHost)
				{
					MeltdownPlugin.logger.LogWarning((object)"Local Player isn't host! Aborting!!");
					return;
				}
				GameObject val = Object.Instantiate<GameObject>(MeltdownPlugin.assets.meltdownHandlerPrefab);
				val.GetComponent<NetworkObject>().Spawn(false);
			}
		}

		public static void RegisterMeltdownListener(Action callback)
		{
			OnMeltdownStart = (Action)Delegate.Combine(OnMeltdownStart, callback);
		}
	}
}
namespace FacilityMeltdown.NetcodePatcher
{
	[AttributeUsage(AttributeTargets.Module)]
	internal class NetcodePatchedAssemblyAttribute : Attribute
	{
	}
}

plugins/FasterItemDropship.dll

Decompiled 2 years ago
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Unity.Netcode;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("FasterItemDropship")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("Mod made by flipf17")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("FasterItemDropship")]
[assembly: AssemblyCopyright("Copyright ©  2023")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("a5a250fd-b706-48b9-9be9-da360fd939dc")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace FasterItemDropship
{
	public static class ConfigSettings
	{
		public static ConfigEntry<int> dropshipDeliveryTime;

		public static ConfigEntry<int> dropshipMaxStayDuration;

		public static ConfigEntry<int> dropshipLeaveAfterSecondsOpenDoors;

		public static void BindConfigSettings()
		{
			Plugin.Log("BindingConfigs");
			dropshipDeliveryTime = ((BaseUnityPlugin)Plugin.instance).Config.Bind<int>("FasterItemDropship", "DeliveryTime", 10, "How long it takes (in seconds) for the item dropship to arrive.");
			dropshipMaxStayDuration = ((BaseUnityPlugin)Plugin.instance).Config.Bind<int>("FasterItemDropship", "MaxLandDuration", 40, "The max duration (in seconds) the item dropship will stay.");
			dropshipLeaveAfterSecondsOpenDoors = ((BaseUnityPlugin)Plugin.instance).Config.Bind<int>("FasterItemDropship", "LeaveAfterSecondsOpenDoors", 3, "How long (in seconds) the item dropship will stay for after opening its doors.");
		}
	}
	[BepInPlugin("FlipMods.FasterItemDropship", "FasterItemDropship", "1.2.1")]
	public class Plugin : BaseUnityPlugin
	{
		private Harmony _harmony;

		public static Plugin instance;

		private void Awake()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			instance = this;
			ConfigSettings.BindConfigSettings();
			_harmony = new Harmony("FasterItemDropship");
			_harmony.PatchAll();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"FasterItemDropship loaded");
		}

		public static void Log(string message)
		{
			((BaseUnityPlugin)instance).Logger.LogInfo((object)message);
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "FlipMods.FasterItemDropship";

		public const string PLUGIN_NAME = "FasterItemDropship";

		public const string PLUGIN_VERSION = "1.2.1";
	}
}
namespace FasterItemDropship.Patches
{
	[HarmonyPatch]
	internal class FasterItemDropshipPatcher
	{
		private static Terminal terminalScript;

		private static StartOfRound playersManager;

		private static List<int> itemsToDeliver;

		private static List<int> orderedItemsFromTerminal;

		[HarmonyPatch(typeof(ItemDropship), "Start")]
		[HarmonyPrefix]
		public static void InitializeDropship(ItemDropship __instance)
		{
			playersManager = Object.FindObjectOfType<StartOfRound>();
			terminalScript = Object.FindObjectOfType<Terminal>();
			itemsToDeliver = (List<int>)Traverse.Create((object)__instance).Field("itemsToDeliver").GetValue();
		}

		[HarmonyPatch(typeof(Terminal), "Start")]
		[HarmonyPrefix]
		public static void InitializeTerminal(Terminal __instance)
		{
			orderedItemsFromTerminal = __instance.orderedItemsFromTerminal;
		}

		[HarmonyPatch(typeof(ItemDropship), "Update")]
		[HarmonyPrefix]
		public static void DropshipUpdate(ItemDropship __instance)
		{
			if (((NetworkBehaviour)__instance).IsServer && !__instance.deliveringOrder && terminalScript.orderedItemsFromTerminal.Count > 0 && !playersManager.shipHasLanded)
			{
				__instance.shipTimer += Time.deltaTime;
			}
		}

		[HarmonyPatch(typeof(ItemDropship), "Update")]
		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			List<CodeInstruction> list = new List<CodeInstruction>(instructions);
			for (int i = 0; i < list.Count; i++)
			{
				if (list[i].opcode == OpCodes.Ldc_R4)
				{
					if ((float)list[i].operand == 20f)
					{
						list[i].operand = (float)ConfigSettings.dropshipMaxStayDuration.Value;
					}
					else if ((float)list[i].operand == 40f)
					{
						list[i].operand = (float)(ConfigSettings.dropshipMaxStayDuration.Value + ConfigSettings.dropshipDeliveryTime.Value);
					}
					else if ((float)list[i].operand == 30f)
					{
						list[i].operand = (float)ConfigSettings.dropshipMaxStayDuration.Value;
						break;
					}
				}
			}
			return list.AsEnumerable();
		}

		[HarmonyPatch(typeof(ItemDropship), "OpenShipDoorsOnServer")]
		[HarmonyPostfix]
		public static void OnOpenShipDoors(ItemDropship __instance)
		{
			if (((NetworkBehaviour)__instance).IsServer)
			{
				__instance.shipTimer = Mathf.Max(__instance.shipTimer, (float)(ConfigSettings.dropshipMaxStayDuration.Value - ConfigSettings.dropshipLeaveAfterSecondsOpenDoors.Value));
			}
		}

		[HarmonyPatch(typeof(ItemDropship), "ShipLandedAnimationEvent")]
		[HarmonyPrefix]
		public static void AddLateItemsServer(ItemDropship __instance)
		{
			if (((NetworkBehaviour)__instance).IsServer && !__instance.shipLanded && !__instance.shipDoorsOpened)
			{
				while (orderedItemsFromTerminal.Count > 0 && itemsToDeliver.Count < 12)
				{
					itemsToDeliver.Add(orderedItemsFromTerminal[0]);
					orderedItemsFromTerminal.RemoveAt(0);
				}
			}
		}
	}
}

plugins/LethalLevelLoader.dll

Decompiled 2 years ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Cryptography;
using System.Security.Permissions;
using System.Text;
using System.Threading.Tasks;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using DunGen;
using DunGen.Graph;
using GameNetcodeStuff;
using HarmonyLib;
using LethalLevelLoader.NetcodePatcher;
using LethalLevelLoader.Tools;
using LethalLib.Modules;
using LethalModDataLib.Base;
using Microsoft.CodeAnalysis;
using Mono.Cecil.Cil;
using MonoMod.Cil;
using MonoMod.RuntimeDetour;
using On;
using TMPro;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.Audio;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using UnityEngine.Video;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp-firstpass")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: AssemblyCompany("LethalLevelLoader")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("A Custom API to support the manual and dynamic integration of custom levels and dungeons in Lethal Company.")]
[assembly: AssemblyFileVersion("1.1.0.0")]
[assembly: AssemblyInformationalVersion("1.1.0+88b43aabe293f3ba795d8202a1b97a7d10e0cd87")]
[assembly: AssemblyProduct("LethalLevelLoader")]
[assembly: AssemblyTitle("LethalLevelLoader")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
[module: NetcodePatchedAssembly]
internal class <Module>
{
	static <Module>()
	{
	}
}
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;
		}
	}
}
public enum ContentType
{
	Vanilla,
	Custom,
	Any
}
internal static class HookHelper
{
	public class DisposableHookCollection
	{
		private List<ILHook> ilHooks = new List<ILHook>();

		private List<Hook> hooks = new List<Hook>();

		public void Clear()
		{
			foreach (Hook hook in hooks)
			{
				hook.Dispose();
			}
			hooks.Clear();
			foreach (ILHook ilHook in ilHooks)
			{
				ilHook.Dispose();
			}
			ilHooks.Clear();
		}

		public void ILHook<T>(string methodName, Manipulator to, Type[] parameters = null)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Expected O, but got Unknown
			ilHooks.Add(new ILHook((MethodBase)EzGetMethod<T>(methodName, parameters), to));
		}

		public void Hook<T>(string methodName, Delegate to, Type[] parameters = null)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Expected O, but got Unknown
			hooks.Add(new Hook((MethodBase)EzGetMethod<T>(methodName, parameters), to));
		}
	}

	public static MethodInfo methodof(Delegate method)
	{
		return method.Method;
	}

	public static MethodInfo EzGetMethod(Type type, string name, Type[] parameters = null)
	{
		BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
		if (parameters == null)
		{
			return type.GetMethod(name, bindingAttr);
		}
		return type.GetMethod(name, bindingAttr, null, parameters, null);
	}

	public static MethodInfo EzGetMethod<T>(string name, Type[] parameters = null)
	{
		return EzGetMethod(typeof(T), name, parameters);
	}
}
public static class NetworkScenePatcher
{
	[CompilerGenerated]
	private static class <>O
	{
		public static Action<Action<NetworkSceneManager>, NetworkSceneManager> <0>__GenerateScenesInBuild_Hook;

		public static Func<Func<NetworkSceneManager, uint, string>, NetworkSceneManager, uint, string> <1>__SceneNameFromHash_Hook;

		public static Func<Func<NetworkSceneManager, int, string, LoadSceneMode, bool>, NetworkSceneManager, int, string, LoadSceneMode, bool> <2>__ValidateSceneBeforeLoading_Hook;

		public static Manipulator <3>__ReplaceBuildIndexByScenePath;

		public static Manipulator <4>__ReplaceScenePathByBuildIndex;

		public static Func<int, string> <5>__GetScenePathByBuildIndex;

		public static Func<string, int> <6>__GetBuildIndexByScenePath;
	}

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

	private static Dictionary<string, int> scenePathToBuildIndex = new Dictionary<string, int>();

	private static Dictionary<int, string> buildIndexToScenePath = new Dictionary<int, string>();

	private static Dictionary<uint, string> sceneHashToScenePath = new Dictionary<uint, string>();

	private static HookHelper.DisposableHookCollection hooks = new HookHelper.DisposableHookCollection();

	internal static bool patched { get; private set; }

	public static void AddScenePath(string scenePath)
	{
		if (!scenePaths.Contains(scenePath))
		{
			scenePaths.Add(scenePath);
		}
	}

	internal static void Patch()
	{
		//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00eb: Expected O, but got Unknown
		//IL_010c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0111: Unknown result type (might be due to invalid IL or missing references)
		//IL_0117: Expected O, but got Unknown
		//IL_0138: Unknown result type (might be due to invalid IL or missing references)
		//IL_013d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0143: Expected O, but got Unknown
		if (!patched)
		{
			patched = true;
			hooks.Hook<NetworkSceneManager>("GenerateScenesInBuild", new Action<Action<NetworkSceneManager>, NetworkSceneManager>(GenerateScenesInBuild_Hook));
			hooks.Hook<NetworkSceneManager>("SceneNameFromHash", new Func<Func<NetworkSceneManager, uint, string>, NetworkSceneManager, uint, string>(SceneNameFromHash_Hook));
			hooks.Hook<NetworkSceneManager>("ValidateSceneBeforeLoading", new Func<Func<NetworkSceneManager, int, string, LoadSceneMode, bool>, NetworkSceneManager, int, string, LoadSceneMode, bool>(ValidateSceneBeforeLoading_Hook), new Type[3]
			{
				typeof(int),
				typeof(string),
				typeof(LoadSceneMode)
			});
			HookHelper.DisposableHookCollection disposableHookCollection = hooks;
			object obj = <>O.<3>__ReplaceBuildIndexByScenePath;
			if (obj == null)
			{
				Manipulator val = ReplaceBuildIndexByScenePath;
				<>O.<3>__ReplaceBuildIndexByScenePath = val;
				obj = (object)val;
			}
			disposableHookCollection.ILHook<NetworkSceneManager>("SceneHashFromNameOrPath", (Manipulator)obj);
			HookHelper.DisposableHookCollection disposableHookCollection2 = hooks;
			object obj2 = <>O.<3>__ReplaceBuildIndexByScenePath;
			if (obj2 == null)
			{
				Manipulator val2 = ReplaceBuildIndexByScenePath;
				<>O.<3>__ReplaceBuildIndexByScenePath = val2;
				obj2 = (object)val2;
			}
			disposableHookCollection2.ILHook<NetworkSceneManager>("ValidateSceneEvent", (Manipulator)obj2);
			HookHelper.DisposableHookCollection disposableHookCollection3 = hooks;
			object obj3 = <>O.<4>__ReplaceScenePathByBuildIndex;
			if (obj3 == null)
			{
				Manipulator val3 = ReplaceScenePathByBuildIndex;
				<>O.<4>__ReplaceScenePathByBuildIndex = val3;
				obj3 = (object)val3;
			}
			disposableHookCollection3.ILHook<NetworkSceneManager>("ScenePathFromHash", (Manipulator)obj3);
		}
	}

	internal static void Unpatch()
	{
		if (patched)
		{
			patched = false;
			hooks.Clear();
		}
	}

	private static void ReplaceScenePathByBuildIndex(ILContext il)
	{
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_0008: Expected O, but got Unknown
		//IL_0034: Unknown result type (might be due to invalid IL or missing references)
		ILCursor val = new ILCursor(il);
		MethodInfo methodInfo = HookHelper.methodof(new Func<int, string>(GetScenePathByBuildIndex));
		while (val.TryGotoNext(new Func<Instruction, bool>[1]
		{
			(Instruction instr) => ILPatternMatchingExt.MatchCall(instr, typeof(SceneUtility), "GetScenePathByBuildIndex")
		}))
		{
			val.Remove();
			val.Emit(OpCodes.Call, (MethodBase)methodInfo);
		}
	}

	private static void ReplaceBuildIndexByScenePath(ILContext il)
	{
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_0008: Expected O, but got Unknown
		//IL_0034: Unknown result type (might be due to invalid IL or missing references)
		ILCursor val = new ILCursor(il);
		MethodInfo methodInfo = HookHelper.methodof(new Func<string, int>(GetBuildIndexByScenePath));
		while (val.TryGotoNext(new Func<Instruction, bool>[1]
		{
			(Instruction instr) => ILPatternMatchingExt.MatchCall(instr, typeof(SceneUtility), "GetBuildIndexByScenePath")
		}))
		{
			val.Remove();
			val.Emit(OpCodes.Call, (MethodBase)methodInfo);
		}
	}

	private static string GetScenePathByBuildIndex(int buildIndex)
	{
		if (buildIndexToScenePath.ContainsKey(buildIndex))
		{
			return buildIndexToScenePath[buildIndex];
		}
		return SceneUtility.GetScenePathByBuildIndex(buildIndex);
	}

	private static int GetBuildIndexByScenePath(string scenePath)
	{
		int num = SceneUtility.GetBuildIndexByScenePath(scenePath);
		if (num == -1 && scenePathToBuildIndex.ContainsKey(scenePath))
		{
			num = scenePathToBuildIndex[scenePath];
		}
		return num;
	}

	private static void GenerateScenesInBuild_Hook(Action<NetworkSceneManager> orig, NetworkSceneManager self)
	{
		scenePathToBuildIndex.Clear();
		buildIndexToScenePath.Clear();
		sceneHashToScenePath.Clear();
		orig(self);
		int sceneCountInBuildSettings = SceneManager.sceneCountInBuildSettings;
		for (int i = 0; i < scenePaths.Count; i++)
		{
			int num = sceneCountInBuildSettings + i;
			string text = scenePaths[i];
			uint num2 = XXHash.Hash32(text);
			self.HashToBuildIndex.Add(num2, num);
			self.BuildIndexToHash.Add(num, num2);
			scenePathToBuildIndex.Add(text, num);
			buildIndexToScenePath.Add(num, text);
			sceneHashToScenePath.Add(num2, text);
		}
	}

	private static string SceneNameFromHash_Hook(Func<NetworkSceneManager, uint, string> orig, NetworkSceneManager self, uint sceneHash)
	{
		if (sceneHash == 0)
		{
			return "No Scene";
		}
		if (sceneHashToScenePath.ContainsKey(sceneHash))
		{
			return sceneHashToScenePath[sceneHash];
		}
		return orig(self, sceneHash);
	}

	private static bool ValidateSceneBeforeLoading_Hook(Func<NetworkSceneManager, int, string, LoadSceneMode, bool> orig, NetworkSceneManager self, int sceneIndex, string sceneName, LoadSceneMode loadSceneMode)
	{
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		bool flag = orig(self, sceneIndex, sceneName, loadSceneMode);
		return true;
	}
}
namespace LethalLevelLoader
{
	public class ExtendedContent : ScriptableObject
	{
		public ExtendedMod ExtendedMod { get; internal set; }

		public ContentType ContentType { get; internal set; } = ContentType.Vanilla;


		public List<string> ContentTagStrings { get; internal set; } = new List<string>();


		[field: SerializeField]
		public List<ContentTag> ContentTags { get; internal set; } = new List<ContentTag>();


		public string ModName => ExtendedMod.ModName;

		public string AuthorName => ExtendedMod.AuthorName;

		internal virtual void TryCreateMatchingProperties()
		{
		}

		public bool TryGetTag(string tag)
		{
			foreach (ContentTag contentTag in ContentTags)
			{
				if (contentTag.contentTagName == tag)
				{
					return true;
				}
			}
			return false;
		}

		public bool TryGetTag(string tag, out ContentTag returnTag)
		{
			returnTag = null;
			foreach (ContentTag contentTag in ContentTags)
			{
				if (contentTag.contentTagName == tag)
				{
					returnTag = contentTag;
					return true;
				}
			}
			return false;
		}

		public bool TryAddTag(string tag)
		{
			if (!TryGetTag(tag))
			{
				ContentTags.Add(ContentTag.Create(tag));
				return true;
			}
			return false;
		}
	}
	[Serializable]
	public class StringWithRarity
	{
		[SerializeField]
		private string _name;

		[SerializeField]
		[Range(0f, 300f)]
		private int _rarity;

		[HideInInspector]
		public string Name
		{
			get
			{
				return _name;
			}
			set
			{
				_name = value;
			}
		}

		[HideInInspector]
		public int Rarity
		{
			get
			{
				return _rarity;
			}
			set
			{
				_rarity = value;
			}
		}

		[HideInInspector]
		public StringWithRarity(string newName, int newRarity)
		{
			_name = newName;
			_rarity = newRarity;
		}
	}
	[Serializable]
	public class Vector2WithRarity
	{
		[SerializeField]
		private Vector2 _minMax;

		[SerializeField]
		private int _rarity;

		[HideInInspector]
		public float Min
		{
			get
			{
				return _minMax.x;
			}
			set
			{
				_minMax.x = value;
			}
		}

		[HideInInspector]
		public float Max
		{
			get
			{
				return _minMax.y;
			}
			set
			{
				_minMax.y = value;
			}
		}

		[HideInInspector]
		public int Rarity
		{
			get
			{
				return _rarity;
			}
			set
			{
				_rarity = value;
			}
		}

		public Vector2WithRarity(Vector2 vector2, int newRarity)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			_minMax.x = vector2.x;
			_minMax.y = vector2.y;
			_rarity = newRarity;
		}

		public Vector2WithRarity(float newMin, float newMax, int newRarity)
		{
			_minMax.x = newMin;
			_minMax.y = newMax;
			_rarity = newRarity;
		}
	}
	[CreateAssetMenu(fileName = "ExtendedDungeonFlow", menuName = "Lethal Level Loader/Extended Content/ExtendedDungeonFlow", order = 21)]
	public class ExtendedDungeonFlow : ExtendedContent
	{
		[Space(25f)]
		[Header("Obsolete (Legacy Fields, Will Be Removed In The Future)")]
		[Obsolete]
		public bool generateAutomaticConfigurationOptions = true;

		[Obsolete]
		public bool enableDynamicDungeonSizeRestriction = false;

		[Obsolete]
		public float dungeonSizeMin = 1f;

		[Obsolete]
		public float dungeonSizeMax = 1f;

		[Obsolete]
		[Range(0f, 1f)]
		public float dungeonSizeLerpPercentage = 1f;

		[Obsolete]
		public AudioClip dungeonFirstTimeAudio;

		[Obsolete]
		public DungeonFlow dungeonFlow;

		[Obsolete]
		public string dungeonDisplayName = string.Empty;

		[Obsolete]
		public string contentSourceName = string.Empty;

		[Obsolete]
		public List<StringWithRarity> dynamicLevelTagsList = new List<StringWithRarity>();

		[Obsolete]
		public List<Vector2WithRarity> dynamicRoutePricesList = new List<Vector2WithRarity>();

		[Obsolete]
		public List<StringWithRarity> dynamicCurrentWeatherList = new List<StringWithRarity>();

		[Obsolete]
		public List<StringWithRarity> manualPlanetNameReferenceList = new List<StringWithRarity>();

		[Obsolete]
		public List<StringWithRarity> manualContentSourceNameReferenceList = new List<StringWithRarity>();

		[Obsolete]
		[HideInInspector]
		public int dungeonDefaultRarity;

		[HideInInspector]
		public DungeonEvents dungeonEvents = new DungeonEvents();

		[field: Header("General Settings")]
		[field: SerializeField]
		public DungeonFlow DungeonFlow { get; set; }

		[field: SerializeField]
		public string DungeonName { get; set; } = string.Empty;


		[field: SerializeField]
		public float MapTileSize { get; set; } = 1f;


		[field: SerializeField]
		public AudioClip FirstTimeDungeonAudio { get; set; }

		[field: Space(5f)]
		[field: Header("Dynamic Injection Matching Settings")]
		[field: SerializeField]
		public LevelMatchingProperties LevelMatchingProperties { get; set; }

		[field: Space(5f)]
		[field: Header("Extended Feature Settings")]
		[field: SerializeField]
		public GameObject OverrideKeyPrefab { get; set; }

		[field: SerializeField]
		public List<SpawnableMapObject> SpawnableMapObjects { get; set; } = new List<SpawnableMapObject>();


		[field: SerializeField]
		public List<GlobalPropCountOverride> GlobalPropCountOverridesList { get; set; } = new List<GlobalPropCountOverride>();


		[field: Space(5f)]
		[field: SerializeField]
		public bool IsDynamicDungeonSizeRestrictionEnabled { get; set; }

		[field: SerializeField]
		public Vector2 DynamicDungeonSizeMinMax { get; set; } = new Vector2(1f, 1f);


		[field: SerializeField]
		[field: Range(0f, 1f)]
		public float DynamicDungeonSizeLerpRate { get; set; } = 1f;


		[field: Space(10f)]
		[field: Header("Misc. Settings")]
		[field: SerializeField]
		public bool GenerateAutomaticConfigurationOptions { get; set; } = true;


		public int DungeonID { get; internal set; }

		public bool IsCurrentDungeon => (Object)(object)DungeonManager.CurrentExtendedDungeonFlow == (Object)(object)this;

		internal static ExtendedDungeonFlow Create(DungeonFlow newDungeonFlow, AudioClip newFirstTimeDungeonAudio)
		{
			ExtendedDungeonFlow extendedDungeonFlow = ScriptableObject.CreateInstance<ExtendedDungeonFlow>();
			extendedDungeonFlow.DungeonFlow = newDungeonFlow;
			extendedDungeonFlow.FirstTimeDungeonAudio = newFirstTimeDungeonAudio;
			if ((Object)(object)extendedDungeonFlow.LevelMatchingProperties == (Object)null)
			{
				extendedDungeonFlow.LevelMatchingProperties = LevelMatchingProperties.Create(extendedDungeonFlow);
			}
			return extendedDungeonFlow;
		}

		internal void Initialize()
		{
			if ((Object)(object)LevelMatchingProperties == (Object)null)
			{
				LevelMatchingProperties = LevelMatchingProperties.Create(this);
			}
			GetDungeonFlowID();
			if (DungeonName == null || DungeonName == string.Empty)
			{
				DungeonName = ((Object)DungeonFlow).name;
			}
			((Object)this).name = ((Object)DungeonFlow).name.Replace("Flow", "") + "ExtendedDungeonFlow";
			if ((Object)(object)FirstTimeDungeonAudio == (Object)null)
			{
				DebugHelper.LogWarning("Custom Dungeon: " + DungeonName + " Is Missing A DungeonFirstTimeAudio Reference! Assigning Facility Audio To Prevent Errors.", DebugType.Developer);
				FirstTimeDungeonAudio = Patches.RoundManager.firstTimeDungeonAudios[0];
			}
			if ((Object)(object)OverrideKeyPrefab == (Object)null)
			{
				OverrideKeyPrefab = DungeonLoader.defaultKeyPrefab;
			}
		}

		private void GetDungeonFlowID()
		{
			if (base.ContentType == ContentType.Custom)
			{
				DungeonID = PatchedContent.ExtendedDungeonFlows.Count;
			}
			if (base.ContentType != 0)
			{
				return;
			}
			IndoorMapType[] dungeonFlowTypes = Patches.RoundManager.dungeonFlowTypes;
			foreach (IndoorMapType val in dungeonFlowTypes)
			{
				if ((Object)(object)val.dungeonFlow == (Object)(object)DungeonFlow)
				{
					DungeonID = Patches.RoundManager.dungeonFlowTypes.ToList().IndexOf(val);
				}
			}
		}

		internal override void TryCreateMatchingProperties()
		{
			if ((Object)(object)LevelMatchingProperties == (Object)null)
			{
				LevelMatchingProperties = LevelMatchingProperties.Create(this);
			}
			LevelMatchingProperties.ApplyValues(null, manualContentSourceNameReferenceList, newPlanetNames: manualPlanetNameReferenceList, newLevelTags: dynamicLevelTagsList, newRoutePrices: dynamicRoutePricesList, newCurrentWeathers: dynamicCurrentWeatherList);
		}

		internal void ConvertObsoleteValues()
		{
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)DungeonFlow == (Object)null && (Object)(object)dungeonFlow != (Object)null)
			{
				DebugHelper.LogWarning("ExtendedDungeonFlow.dungeonFlow is Obsolete and will be removed in following releases, Please use ExtendedDungeonFlow.DungeonFlow instead.", DebugType.Developer);
				DungeonFlow = dungeonFlow;
				dungeonFlow = null;
			}
			if (string.IsNullOrEmpty(DungeonName) && !string.IsNullOrEmpty(dungeonDisplayName))
			{
				DebugHelper.LogWarning("ExtendedDungeonFlow.dungeonDisplayName is Obsolete and will be removed in following releases, Please use ExtendedDungeonFlow.DungeonName instead.", DebugType.Developer);
				DungeonName = dungeonDisplayName;
				dungeonDisplayName = string.Empty;
			}
			if ((Object)(object)FirstTimeDungeonAudio == (Object)null && (Object)(object)dungeonFirstTimeAudio != (Object)null)
			{
				DebugHelper.LogWarning("ExtendedDungeonFlow.dungeonFirstTimeAudio is Obsolete and will be removed in following releases, Please use ExtendedDungeonFlow.FirstTimeDungeonAudio instead.", DebugType.Developer);
				FirstTimeDungeonAudio = dungeonFirstTimeAudio;
				dungeonFirstTimeAudio = null;
			}
			if (dungeonSizeLerpPercentage != 1f)
			{
				DebugHelper.LogWarning("ExtendedDungeonFlow.dungeonSizeLerpPercentage is Obsolete and will be removed in following releases, Please use ExtendedDungeonFlow.DynamicDungeonSizeLerpRate instead.", DebugType.Developer);
			}
			if (dungeonSizeMax != 1f || dungeonSizeMin != 1f)
			{
				DebugHelper.LogWarning("ExtendedDungeonFlow.dungeonSizeMin and ExtendedDungeonFlow.dungeonSizeMax are Obsolete and will be removed in following releases, Please use ExtendedDungeonFlow.DynamicSungeonSizeMinMax instead.", DebugType.Developer);
				DynamicDungeonSizeMinMax = new Vector2(dungeonSizeMin, dungeonSizeMax);
			}
			if (!string.IsNullOrEmpty(contentSourceName))
			{
				DebugHelper.LogWarning("ExtendedDungeonFlow.contentSourceName is Obsolete and will be removed in following releases, Please use ExtendedMod.AuthorName instead.", DebugType.Developer);
			}
			if ((Object)(object)LevelMatchingProperties == (Object)null && (dynamicLevelTagsList.Count > 0 || dynamicRoutePricesList.Count > 0 || dynamicCurrentWeatherList.Count > 0 || manualContentSourceNameReferenceList.Count > 0 || manualContentSourceNameReferenceList.Count > 0))
			{
				DebugHelper.LogWarning("ExtendedDungeonFlow dynamic and manual match reference lists are Obsolete and will be removed in following releases, Please use ExtendedDungeonFlow.LevelMatchingProperties instead.", DebugType.Developer);
				TryCreateMatchingProperties();
			}
			if (enableDynamicDungeonSizeRestriction || IsDynamicDungeonSizeRestrictionEnabled != enableDynamicDungeonSizeRestriction)
			{
				DebugHelper.LogWarning("ExtendedDungeonFlow.enableDynamicDungeonSizeRestriction Is Obsolete and will be removed in following releases, Please use ExtendedDungeonFlow.IsDynamicDungeonRestrictionEnabled instead.", DebugType.Developer);
				IsDynamicDungeonSizeRestrictionEnabled = enableDynamicDungeonSizeRestriction;
			}
			if (!generateAutomaticConfigurationOptions || GenerateAutomaticConfigurationOptions != generateAutomaticConfigurationOptions)
			{
				DebugHelper.LogWarning("ExtendedDungeonFlow.generateAutomaticConfigurationOptions Is Obsolete and will be removed in following releases, Please use ExtendedDungeonFlow.GenerateAutomaticConfigurationOptions instead.", DebugType.Developer);
				GenerateAutomaticConfigurationOptions = generateAutomaticConfigurationOptions;
			}
		}
	}
	[Serializable]
	public class GlobalPropCountOverride
	{
		public int globalPropID;

		[Range(0f, 1f)]
		public float globalPropCountScaleRate = 0f;
	}
	[Serializable]
	public class DungeonEvents
	{
		public ExtendedEvent<RoundManager> onBeforeDungeonGenerate = new ExtendedEvent<RoundManager>();

		public ExtendedEvent<List<GameObject>> onSpawnedSyncedObjects = new ExtendedEvent<List<GameObject>>();

		public ExtendedEvent<List<GameObject>> onSpawnedMapObjects = new ExtendedEvent<List<GameObject>>();

		public ExtendedEvent<List<GrabbableObject>> onSpawnedScrapObjects = new ExtendedEvent<List<GrabbableObject>>();

		public ExtendedEvent<(EnemyVent, EnemyAI)> onEnemySpawnedFromVent = new ExtendedEvent<(EnemyVent, EnemyAI)>();

		public ExtendedEvent<(EntranceTeleport, PlayerControllerB)> onPlayerEnterDungeon = new ExtendedEvent<(EntranceTeleport, PlayerControllerB)>();

		public ExtendedEvent<(EntranceTeleport, PlayerControllerB)> onPlayerExitDungeon = new ExtendedEvent<(EntranceTeleport, PlayerControllerB)>();

		public ExtendedEvent<bool> onPowerSwitchToggle = new ExtendedEvent<bool>();

		public ExtendedEvent<LungProp> onApparatusTaken = new ExtendedEvent<LungProp>();
	}
	[CreateAssetMenu(fileName = "ExtendedEnemyType", menuName = "Lethal Level Loader/Extended Content/ExtendedEnemyType", order = 24)]
	public class ExtendedEnemyType : ExtendedContent
	{
		[field: Header("General Settings")]
		[field: SerializeField]
		public EnemyType EnemyType { get; set; }

		[field: SerializeField]
		public string EnemyDisplayName { get; set; }

		[field: Space(5f)]
		[field: Header("Dynamic Injection Matching Settings")]
		[field: SerializeField]
		public LevelMatchingProperties OutsideLevelMatchingProperties { get; set; }

		[field: SerializeField]
		public LevelMatchingProperties DaytimeLevelMatchingProperties { get; set; }

		[field: SerializeField]
		public LevelMatchingProperties InsideLevelMatchingProperties { get; set; }

		[field: SerializeField]
		public DungeonMatchingProperties InsideDungeonMatchingProperties { get; set; }

		[field: Space(5f)]
		[field: Header("Terminal Bestiary Override Settings")]
		[field: SerializeField]
		[field: TextArea(2, 20)]
		public string InfoNodeDescription { get; set; } = string.Empty;


		[field: SerializeField]
		public VideoClip InfoNodeVideoClip { get; set; }

		public ScanNodeProperties ScanNodeProperties { get; internal set; }

		public int EnemyID { get; internal set; }

		public TerminalNode EnemyInfoNode { get; internal set; }

		public static ExtendedEnemyType Create(EnemyType enemyType, ExtendedMod extendedMod, ContentType contentType)
		{
			ExtendedEnemyType extendedEnemyType = ScriptableObject.CreateInstance<ExtendedEnemyType>();
			extendedEnemyType.EnemyType = enemyType;
			((Object)extendedEnemyType).name = enemyType.enemyName.SkipToLetters().RemoveWhitespace() + "ExtendedEnemyType";
			extendedEnemyType.ContentType = contentType;
			extendedMod.RegisterExtendedContent(extendedEnemyType);
			extendedEnemyType.TryCreateMatchingProperties();
			return extendedEnemyType;
		}

		public void Initalize()
		{
			DebugHelper.Log("Initializing Custom Enemy: " + EnemyType.enemyName, DebugType.Developer);
			TryCreateMatchingProperties();
		}

		internal override void TryCreateMatchingProperties()
		{
			if ((Object)(object)InsideLevelMatchingProperties == (Object)null)
			{
				InsideLevelMatchingProperties = LevelMatchingProperties.Create(this);
			}
			if ((Object)(object)InsideDungeonMatchingProperties == (Object)null)
			{
				InsideDungeonMatchingProperties = DungeonMatchingProperties.Create(this);
			}
			if ((Object)(object)OutsideLevelMatchingProperties == (Object)null)
			{
				OutsideLevelMatchingProperties = LevelMatchingProperties.Create(this);
			}
			if ((Object)(object)DaytimeLevelMatchingProperties == (Object)null)
			{
				DaytimeLevelMatchingProperties = LevelMatchingProperties.Create(this);
			}
		}
	}
	[CreateAssetMenu(fileName = "ExtendedFootstepSurface", menuName = "Lethal Level Loader/Extended Content/ExtendedFootstepSurface", order = 27)]
	public class ExtendedFootstepSurface : ExtendedContent
	{
		public FootstepSurface footstepSurface;

		public List<Material> associatedMaterials;

		public List<GameObject> associatedGameObjects;

		internal int arrayIndex;
	}
	[CreateAssetMenu(fileName = "ExtendedItem", menuName = "Lethal Level Loader/Extended Content/ExtendedItem", order = 23)]
	public class ExtendedItem : ExtendedContent
	{
		[field: Header("General Settings")]
		[field: SerializeField]
		public Item Item { get; set; }

		[field: SerializeField]
		public string PluralisedItemName { get; set; } = string.Empty;


		[field: SerializeField]
		public bool IsBuyableItem { get; set; }

		[field: Space(5f)]
		[field: Header("Dynamic Injection Matching Settings")]
		[field: SerializeField]
		public LevelMatchingProperties LevelMatchingProperties { get; set; }

		[field: SerializeField]
		public DungeonMatchingProperties DungeonMatchingProperties { get; set; }

		[field: Space(5f)]
		[field: Header("Terminal Store & Info Override Settings")]
		[field: SerializeField]
		public string OverrideInfoNodeDescription { get; set; } = string.Empty;


		[field: SerializeField]
		public string OverrideBuyNodeDescription { get; set; } = string.Empty;


		[field: SerializeField]
		public string OverrideBuyConfirmNodeDescription { get; set; } = string.Empty;


		public TerminalNode BuyNode { get; internal set; }

		public TerminalNode BuyConfirmNode { get; internal set; }

		public TerminalNode BuyInfoNode { get; internal set; }

		public int CreditsWorth
		{
			get
			{
				if ((Object)(object)BuyNode != (Object)null && (Object)(object)BuyConfirmNode != (Object)null)
				{
					BuyNode.itemCost = Item.creditsWorth;
					BuyConfirmNode.itemCost = Item.creditsWorth;
				}
				else
				{
					Debug.LogWarning((object)"BuyNode And/Or BuyConfirm Node Missing!");
				}
				return Item.creditsWorth;
			}
			set
			{
				if (value >= 0)
				{
					if ((Object)(object)BuyNode != (Object)null && (Object)(object)BuyConfirmNode != (Object)null)
					{
						BuyNode.itemCost = value;
						BuyConfirmNode.itemCost = value;
					}
					else
					{
						Debug.LogWarning((object)"BuyNode And/Or BuyConfirm Node Missing!");
					}
					Item.creditsWorth = value;
				}
			}
		}

		public static ExtendedItem Create(Item newItem, ExtendedMod extendedMod, ContentType contentType)
		{
			ExtendedItem extendedItem = ScriptableObject.CreateInstance<ExtendedItem>();
			extendedItem.Item = newItem;
			((Object)extendedItem).name = newItem.itemName.SkipToLetters().RemoveWhitespace() + "ExtendedItem";
			extendedItem.ContentType = contentType;
			extendedMod.RegisterExtendedContent(extendedItem);
			extendedItem.TryCreateMatchingProperties();
			return extendedItem;
		}

		public void Initialize()
		{
			DebugHelper.Log("Initializing Custom Item: " + Item.itemName + ". Is Buyable: " + IsBuyableItem + ". Is Scrap: " + Item.isScrap, DebugType.Developer);
			TryCreateMatchingProperties();
			Patches.StartOfRound.allItemsList.itemsList.Add(Item);
			if (IsBuyableItem)
			{
				TerminalManager.CreateItemTerminalData(this);
			}
		}

		internal override void TryCreateMatchingProperties()
		{
			if ((Object)(object)LevelMatchingProperties == (Object)null)
			{
				LevelMatchingProperties = LevelMatchingProperties.Create(this);
			}
			if ((Object)(object)DungeonMatchingProperties == (Object)null)
			{
				DungeonMatchingProperties = DungeonMatchingProperties.Create(this);
			}
		}

		public void SetLevelMatchingProperties(LevelMatchingProperties newLevelMatchingProperties)
		{
			if ((Object)(object)Plugin.Instance != (Object)null)
			{
				Debug.LogError((object)"SetLevelMatchingProperties() Should Only Be Used In Editor!");
			}
			LevelMatchingProperties = newLevelMatchingProperties;
		}
	}
	[CreateAssetMenu(fileName = "ExtendedLevel", menuName = "Lethal Level Loader/Extended Content/ExtendedLevel", order = 20)]
	public class ExtendedLevel : ExtendedContent
	{
		[Space(5f)]
		[SerializeField]
		private int routePrice = 0;

		[Space(25f)]
		[Header("Obsolete (Legacy Fields, Will Be Removed In The Future)")]
		[Obsolete]
		public SelectableLevel selectableLevel;

		[Obsolete]
		[Space(5f)]
		public string contentSourceName = string.Empty;

		[Obsolete]
		[Space(5f)]
		public List<string> levelTags = new List<string>();

		[field: Header("General Settings")]
		[field: SerializeField]
		public SelectableLevel SelectableLevel { get; set; }

		[field: Header("Extended Feature Settings")]
		[field: SerializeField]
		public bool OverrideDynamicRiskLevelAssignment { get; set; } = false;


		[field: Space(5f)]
		[field: SerializeField]
		public GameObject OverrideQuicksandPrefab { get; set; }

		[field: Space(5f)]
		[field: SerializeField]
		public bool IsRouteHidden { get; set; } = false;


		[field: SerializeField]
		public bool IsRouteLocked { get; set; } = false;


		[field: SerializeField]
		public string LockedRouteNodeText { get; set; } = string.Empty;


		[field: Space(5f)]
		[field: SerializeField]
		public AnimationClip ShipFlyToMoonClip { get; set; }

		[field: SerializeField]
		public AnimationClip ShipFlyFromMoonClip { get; set; }

		[field: Space(5f)]
		[field: SerializeField]
		public List<StringWithRarity> SceneSelections { get; set; } = new List<StringWithRarity>();


		[field: Space(5f)]
		[field: Header("Terminal Route Override Settings")]
		[field: SerializeField]
		[field: TextArea(2, 20)]
		public string OverrideInfoNodeDescription { get; set; } = string.Empty;


		[field: SerializeField]
		[field: TextArea(2, 20)]
		public string OverrideRouteNodeDescription { get; set; } = string.Empty;


		[field: SerializeField]
		[field: TextArea(2, 20)]
		public string OverrideRouteConfirmNodeDescription { get; set; } = string.Empty;


		[field: Space(10f)]
		[field: Header("Misc. Settings")]
		[field: Space(5f)]
		[field: SerializeField]
		public bool GenerateAutomaticConfigurationOptions { get; set; } = true;


		public int RoutePrice
		{
			get
			{
				if ((Object)(object)RouteNode != (Object)null)
				{
					routePrice = RouteNode.itemCost;
					RouteConfirmNode.itemCost = routePrice;
					return RouteNode.itemCost;
				}
				DebugHelper.LogWarning("routeNode Is Missing! Using internal value!", DebugType.Developer);
				return routePrice;
			}
			set
			{
				if ((Object)(object)RouteNode != (Object)null && (Object)(object)RouteConfirmNode != (Object)null)
				{
					RouteNode.itemCost = value;
					RouteConfirmNode.itemCost = value;
				}
				else
				{
					DebugHelper.LogWarning("routeNode Is Missing! Only setting internal value!", DebugType.Developer);
				}
				routePrice = value;
			}
		}

		public string NumberlessPlanetName => GetNumberlessPlanetName(SelectableLevel);

		public int CalculatedDifficultyRating => LevelManager.CalculateExtendedLevelDifficultyRating(this);

		public bool IsCurrentLevel => (Object)(object)LevelManager.CurrentExtendedLevel == (Object)(object)this;

		public bool IsLevelLoaded
		{
			get
			{
				//IL_000b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0010: Unknown result type (might be due to invalid IL or missing references)
				Scene sceneByName = SceneManager.GetSceneByName(SelectableLevel.sceneName);
				return ((Scene)(ref sceneByName)).isLoaded;
			}
		}

		[HideInInspector]
		public LevelEvents LevelEvents { get; internal set; } = new LevelEvents();


		public TerminalNode RouteNode { get; internal set; }

		public TerminalNode RouteConfirmNode { get; internal set; }

		public TerminalNode InfoNode { get; internal set; }

		public List<ExtendedWeatherEffect> EnabledExtendedWeatherEffects { get; set; } = new List<ExtendedWeatherEffect>();


		public ExtendedWeatherEffect CurrentExtendedWeatherEffect { get; set; }

		internal static ExtendedLevel Create(SelectableLevel newSelectableLevel)
		{
			ExtendedLevel extendedLevel = ScriptableObject.CreateInstance<ExtendedLevel>();
			extendedLevel.SelectableLevel = newSelectableLevel;
			return extendedLevel;
		}

		internal void Initialize(string newContentSourceName, bool generateTerminalAssets)
		{
			bool flag = false;
			foreach (StringWithRarity sceneSelection in SceneSelections)
			{
				if (sceneSelection.Name == SelectableLevel.sceneName)
				{
					flag = true;
				}
			}
			if (!flag)
			{
				StringWithRarity item = new StringWithRarity(SelectableLevel.sceneName, 300);
				SceneSelections.Add(item);
			}
			foreach (StringWithRarity item2 in new List<StringWithRarity>(SceneSelections))
			{
				if (!PatchedContent.AllLevelSceneNames.Contains(item2.Name))
				{
					DebugHelper.LogWarning("Removing SceneSelection From: " + SelectableLevel.PlanetName + " As SceneName: " + item2.Name + " Is Not Loaded!", DebugType.Developer);
					SceneSelections.Remove(item2);
				}
			}
			if ((Object)(object)ShipFlyToMoonClip == (Object)null)
			{
				ShipFlyToMoonClip = LevelLoader.defaultShipFlyToMoonClip;
			}
			if ((Object)(object)ShipFlyFromMoonClip == (Object)null)
			{
				ShipFlyFromMoonClip = LevelLoader.defaultShipFlyFromMoonClip;
			}
			if ((Object)(object)OverrideQuicksandPrefab == (Object)null)
			{
				OverrideQuicksandPrefab = LevelLoader.defaultQuicksandPrefab;
			}
			if (base.ContentType == ContentType.Custom)
			{
				((Object)this).name = NumberlessPlanetName.StripSpecialCharacters() + "ExtendedLevel";
				((Object)SelectableLevel).name = NumberlessPlanetName.StripSpecialCharacters() + "Level";
				if (generateTerminalAssets)
				{
					TerminalManager.CreateLevelTerminalData(this, routePrice);
				}
			}
			if (base.ContentType == ContentType.Vanilla)
			{
				GetVanillaInfoNode();
			}
			SetExtendedDungeonFlowMatches();
		}

		internal void ConvertObsoleteValues()
		{
			if (levelTags.Count > 0 && base.ContentTags.Count == 0)
			{
				DebugHelper.LogWarning("ExtendedLevel.levelTags Is Obsolete and will be removed in following releases, Please use .ContentTags instead.", DebugType.Developer);
				foreach (ContentTag item in ContentTagManager.CreateNewContentTags(levelTags))
				{
					base.ContentTags.Add(item);
				}
			}
			levelTags.Clear();
			if ((Object)(object)SelectableLevel == (Object)null && (Object)(object)selectableLevel != (Object)null)
			{
				DebugHelper.LogWarning("ExtendedLevel.selectableLevel Is Obsolete and will be removed in following releases, Please use .SelectableLevel instead.", DebugType.Developer);
				SelectableLevel = selectableLevel;
			}
			if (!string.IsNullOrEmpty(contentSourceName))
			{
				DebugHelper.LogWarning("ExtendedLevel.contentSourceName is Obsolete and will be removed in following releases, Please use ExtendedMod.AuthorName instead.", DebugType.Developer);
			}
		}

		internal static string GetNumberlessPlanetName(SelectableLevel selectableLevel)
		{
			if ((Object)(object)selectableLevel != (Object)null)
			{
				return new string(selectableLevel.PlanetName.SkipWhile((char c) => !char.IsLetter(c)).ToArray());
			}
			return string.Empty;
		}

		internal void SetLevelID()
		{
			if (base.ContentType == ContentType.Custom)
			{
				SelectableLevel.levelID = PatchedContent.ExtendedLevels.IndexOf(this);
				if ((Object)(object)RouteNode != (Object)null)
				{
					RouteNode.displayPlanetInfo = SelectableLevel.levelID;
				}
				if ((Object)(object)RouteConfirmNode != (Object)null)
				{
					RouteConfirmNode.buyRerouteToMoon = SelectableLevel.levelID;
				}
			}
		}

		internal void SetExtendedDungeonFlowMatches()
		{
			IntWithRarity[] dungeonFlowTypes = SelectableLevel.dungeonFlowTypes;
			foreach (IntWithRarity val in dungeonFlowTypes)
			{
				if (DungeonManager.TryGetExtendedDungeonFlow(Patches.RoundManager.dungeonFlowTypes[val.id].dungeonFlow, out var returnExtendedDungeonFlow))
				{
					returnExtendedDungeonFlow.LevelMatchingProperties.planetNames.Add(new StringWithRarity(NumberlessPlanetName, val.rarity));
				}
			}
			if (!(SelectableLevel.sceneName == "Level4March"))
			{
				return;
			}
			IndoorMapType[] dungeonFlowTypes2 = Patches.RoundManager.dungeonFlowTypes;
			foreach (IndoorMapType val2 in dungeonFlowTypes2)
			{
				if (((Object)val2.dungeonFlow).name == "Level1Flow3Exits" && DungeonManager.TryGetExtendedDungeonFlow(val2.dungeonFlow, out var returnExtendedDungeonFlow2))
				{
					returnExtendedDungeonFlow2.LevelMatchingProperties.planetNames.Add(new StringWithRarity(NumberlessPlanetName, 300));
				}
			}
		}

		internal void GetVanillaInfoNode()
		{
			CompatibleNoun[] compatibleNouns = TerminalManager.routeInfoKeyword.compatibleNouns;
			foreach (CompatibleNoun val in compatibleNouns)
			{
				if (val.noun.word == NumberlessPlanetName.ToLower())
				{
					InfoNode = val.result;
					break;
				}
			}
		}

		public void ForceSetRoutePrice(int newValue)
		{
			if ((Object)(object)Plugin.Instance != (Object)null)
			{
				Debug.LogWarning((object)"ForceSetRoutePrice Should Only Be Used In Editor! Consider Using RoutePrice Property To Sync TerminalNode's With New Value.");
			}
			routePrice = newValue;
		}
	}
	[Serializable]
	public class LevelEvents
	{
		public ExtendedEvent onLevelLoaded = new ExtendedEvent();

		public ExtendedEvent<EnemyAI> onDaytimeEnemySpawn = new ExtendedEvent<EnemyAI>();

		public ExtendedEvent<EnemyAI> onNighttimeEnemySpawn = new ExtendedEvent<EnemyAI>();

		public ExtendedEvent<StoryLog> onStoryLogCollected = new ExtendedEvent<StoryLog>();

		public ExtendedEvent<LungProp> onApparatusTaken = new ExtendedEvent<LungProp>();

		public ExtendedEvent<(EntranceTeleport, PlayerControllerB)> onPlayerEnterDungeon = new ExtendedEvent<(EntranceTeleport, PlayerControllerB)>();

		public ExtendedEvent<(EntranceTeleport, PlayerControllerB)> onPlayerExitDungeon = new ExtendedEvent<(EntranceTeleport, PlayerControllerB)>();

		public ExtendedEvent<bool> onPowerSwitchToggle = new ExtendedEvent<bool>();

		public ExtendedEvent<DayMode> onDayModeToggle = new ExtendedEvent<DayMode>();
	}
	public enum ModMergeSetting
	{
		MatchingAuthorName,
		MatchingModName,
		Disabled
	}
	[CreateAssetMenu(fileName = "ExtendedMod", menuName = "Lethal Level Loader/ExtendedMod", order = 30)]
	public class ExtendedMod : ScriptableObject
	{
		[field: SerializeField]
		public string ModName { get; internal set; } = "Unspecified";


		[field: SerializeField]
		public string AuthorName { get; internal set; } = "Unknown";


		public List<string> ModNameAliases { get; internal set; } = new List<string>();


		[field: SerializeField]
		public ModMergeSetting ModMergeSetting { get; internal set; } = ModMergeSetting.MatchingAuthorName;


		[field: SerializeField]
		public List<ExtendedLevel> ExtendedLevels { get; private set; } = new List<ExtendedLevel>();


		[field: SerializeField]
		public List<ExtendedDungeonFlow> ExtendedDungeonFlows { get; private set; } = new List<ExtendedDungeonFlow>();


		[field: SerializeField]
		public List<ExtendedItem> ExtendedItems { get; private set; } = new List<ExtendedItem>();


		[field: SerializeField]
		public List<ExtendedEnemyType> ExtendedEnemyTypes { get; private set; } = new List<ExtendedEnemyType>();


		[field: SerializeField]
		public List<ExtendedWeatherEffect> ExtendedWeatherEffects { get; private set; } = new List<ExtendedWeatherEffect>();


		[field: SerializeField]
		public List<ExtendedFootstepSurface> ExtendedFootstepSurfaces { get; private set; } = new List<ExtendedFootstepSurface>();


		[field: SerializeField]
		public List<ExtendedStoryLog> ExtendedStoryLogs { get; private set; } = new List<ExtendedStoryLog>();


		public List<ExtendedContent> ExtendedContents
		{
			get
			{
				List<ExtendedContent> list = new List<ExtendedContent>();
				foreach (ExtendedLevel extendedLevel in ExtendedLevels)
				{
					list.Add(extendedLevel);
				}
				foreach (ExtendedDungeonFlow extendedDungeonFlow in ExtendedDungeonFlows)
				{
					list.Add(extendedDungeonFlow);
				}
				foreach (ExtendedItem extendedItem in ExtendedItems)
				{
					list.Add(extendedItem);
				}
				foreach (ExtendedEnemyType extendedEnemyType in ExtendedEnemyTypes)
				{
					list.Add(extendedEnemyType);
				}
				foreach (ExtendedWeatherEffect extendedWeatherEffect in ExtendedWeatherEffects)
				{
					list.Add(extendedWeatherEffect);
				}
				foreach (ExtendedFootstepSurface extendedFootstepSurface in ExtendedFootstepSurfaces)
				{
					list.Add(extendedFootstepSurface);
				}
				return list;
			}
		}

		internal static ExtendedMod Create(string modName)
		{
			ExtendedMod extendedMod = ScriptableObject.CreateInstance<ExtendedMod>();
			extendedMod.ModName = modName;
			((Object)extendedMod).name = modName.Sanitized() + "Mod";
			DebugHelper.Log("Created New ExtendedMod: " + extendedMod.ModName, DebugType.Developer);
			return extendedMod;
		}

		public static ExtendedMod Create(string modName, string authorName)
		{
			ExtendedMod extendedMod = ScriptableObject.CreateInstance<ExtendedMod>();
			extendedMod.ModName = modName;
			((Object)extendedMod).name = modName.SkipToLetters().RemoveWhitespace() + "Mod";
			extendedMod.AuthorName = authorName;
			if ((Object)(object)Plugin.Instance != (Object)null)
			{
				DebugHelper.Log("Created New ExtendedMod: " + extendedMod.ModName + " by " + authorName, DebugType.Developer);
			}
			return extendedMod;
		}

		public static ExtendedMod Create(string modName, string authorName, ExtendedContent[] extendedContents)
		{
			ExtendedMod extendedMod = ScriptableObject.CreateInstance<ExtendedMod>();
			extendedMod.ModName = modName;
			((Object)extendedMod).name = modName.SkipToLetters().RemoveWhitespace() + "Mod";
			extendedMod.AuthorName = authorName;
			foreach (ExtendedContent newExtendedContent in extendedContents)
			{
				extendedMod.RegisterExtendedContent(newExtendedContent);
			}
			if ((Object)(object)Plugin.Instance != (Object)null)
			{
				DebugHelper.Log("Created New ExtendedMod: " + extendedMod.ModName + " by " + authorName, DebugType.Developer);
			}
			return extendedMod;
		}

		internal void RegisterExtendedContent(ExtendedContent newExtendedContent)
		{
			if ((Object)(object)newExtendedContent != (Object)null)
			{
				if (!ExtendedContents.Contains(newExtendedContent))
				{
					if (newExtendedContent is ExtendedLevel extendedLevel)
					{
						RegisterExtendedContent(extendedLevel);
						return;
					}
					if (newExtendedContent is ExtendedDungeonFlow extendedDungeonFlow)
					{
						RegisterExtendedContent(extendedDungeonFlow);
						return;
					}
					if (newExtendedContent is ExtendedItem extendedItem)
					{
						RegisterExtendedContent(extendedItem);
						return;
					}
					if (newExtendedContent is ExtendedEnemyType extendedEnemyType)
					{
						RegisterExtendedContent(extendedEnemyType);
						return;
					}
					if (newExtendedContent is ExtendedWeatherEffect extendedWeatherEffect)
					{
						RegisterExtendedContent(extendedWeatherEffect);
						return;
					}
					if (newExtendedContent is ExtendedFootstepSurface extendedFootstepSurface)
					{
						RegisterExtendedContent(extendedFootstepSurface);
						return;
					}
					if (newExtendedContent is ExtendedStoryLog extendedStoryLog)
					{
						RegisterExtendedContent(extendedStoryLog);
						return;
					}
					throw new ArgumentException("newExtendedContent", ((Object)newExtendedContent).name + " (" + ((object)newExtendedContent).GetType().Name + ")  Could Not Be Registered To ExtendedMod: " + ModName + " Due To Unimplemented Registration Check!");
				}
				throw new ArgumentException("newExtendedContent", ((Object)newExtendedContent).name + " (" + ((object)newExtendedContent).GetType().Name + ")  Could Not Be Registered To ExtendedMod: " + ModName + " Due To Already Being Registered To This Mod!");
			}
			throw new ArgumentNullException("newExtendedContent", "Null ExtendedContent Could Not Be Registered To ExtendedMod: " + ModName + " Due To Failed Validation Check!");
		}

		internal void RegisterExtendedContent(ExtendedLevel extendedLevel)
		{
			extendedLevel.ConvertObsoleteValues();
			TryThrowInvalidContentException(extendedLevel, Validators.ValidateExtendedContent(extendedLevel));
			ExtendedLevels.Add(extendedLevel);
			extendedLevel.ContentTags.Add(ContentTag.Create("Custom"));
			extendedLevel.ExtendedMod = this;
		}

		internal void RegisterExtendedContent(ExtendedDungeonFlow extendedDungeonFlow)
		{
			extendedDungeonFlow.ConvertObsoleteValues();
			TryThrowInvalidContentException(extendedDungeonFlow, Validators.ValidateExtendedContent(extendedDungeonFlow));
			ExtendedDungeonFlows.Add(extendedDungeonFlow);
			extendedDungeonFlow.ContentTags.Add(ContentTag.Create("Custom"));
			extendedDungeonFlow.ExtendedMod = this;
		}

		internal void RegisterExtendedContent(ExtendedItem extendedItem)
		{
			TryThrowInvalidContentException(extendedItem, Validators.ValidateExtendedContent(extendedItem));
			ExtendedItems.Add(extendedItem);
			extendedItem.ContentTags.Add(ContentTag.Create("Custom"));
			extendedItem.ExtendedMod = this;
		}

		internal void RegisterExtendedContent(ExtendedEnemyType extendedEnemyType)
		{
			TryThrowInvalidContentException(extendedEnemyType, Validators.ValidateExtendedContent(extendedEnemyType));
			ExtendedEnemyTypes.Add(extendedEnemyType);
			extendedEnemyType.ContentTags.Add(ContentTag.Create("Custom"));
			extendedEnemyType.ExtendedMod = this;
		}

		internal void RegisterExtendedContent(ExtendedWeatherEffect extendedWeatherEffect)
		{
			TryThrowInvalidContentException(extendedWeatherEffect, Validators.ValidateExtendedContent(extendedWeatherEffect));
			ExtendedWeatherEffects.Add(extendedWeatherEffect);
			extendedWeatherEffect.ContentTags.Add(ContentTag.Create("Custom"));
			extendedWeatherEffect.ExtendedMod = this;
		}

		internal void RegisterExtendedContent(ExtendedFootstepSurface extendedFootstepSurface)
		{
			TryThrowInvalidContentException(extendedFootstepSurface, Validators.ValidateExtendedContent(extendedFootstepSurface));
			ExtendedFootstepSurfaces.Add(extendedFootstepSurface);
			extendedFootstepSurface.ContentTags.Add(ContentTag.Create("Custom"));
			extendedFootstepSurface.ExtendedMod = this;
		}

		internal void RegisterExtendedContent(ExtendedStoryLog extendedStoryLog)
		{
			TryThrowInvalidContentException(extendedStoryLog, Validators.ValidateExtendedContent(extendedStoryLog));
			ExtendedStoryLogs.Add(extendedStoryLog);
			extendedStoryLog.ContentTags.Add(ContentTag.Create("Custom"));
			extendedStoryLog.ExtendedMod = this;
		}

		internal void TryThrowInvalidContentException(ExtendedContent extendedContent, (bool, string) result)
		{
			if (!result.Item1)
			{
				if ((Object)(object)extendedContent == (Object)null)
				{
					throw new ArgumentNullException("extendedContent", "Null ExtendedContent Could Not Be Registered To ExtendedMod: " + ModName + " Due To Failed Validation Check! " + result.Item2);
				}
				throw new ArgumentException("extendedContent", ((Object)extendedContent).name + " (" + ((object)extendedContent).GetType().Name + ")  Could Not Be Registered To ExtendedMod: " + ModName + " Due To Failed Validation Check! " + result.Item2);
			}
		}

		internal void UnregisterExtendedContent(ExtendedContent currentExtendedContent)
		{
			if (currentExtendedContent is ExtendedLevel item)
			{
				ExtendedLevels.Remove(item);
			}
			else if (currentExtendedContent is ExtendedDungeonFlow item2)
			{
				ExtendedDungeonFlows.Remove(item2);
			}
			else if (currentExtendedContent is ExtendedItem item3)
			{
				ExtendedItems.Remove(item3);
			}
			currentExtendedContent.ExtendedMod = null;
			DebugHelper.LogWarning("Unregistered ExtendedContent: " + ((Object)currentExtendedContent).name + " In ExtendedMod: " + ModName, DebugType.Developer);
		}

		internal void UnregisterAllExtendedContent()
		{
			ExtendedLevels.Clear();
			ExtendedDungeonFlows.Clear();
			ExtendedItems.Clear();
			ExtendedEnemyTypes.Clear();
			ExtendedWeatherEffects.Clear();
			ExtendedFootstepSurfaces.Clear();
		}

		internal void SortRegisteredContent()
		{
			ExtendedDungeonFlows.Sort((ExtendedDungeonFlow s1, ExtendedDungeonFlow s2) => ((Object)s1).name.CompareTo(((Object)s2).name));
			ExtendedItems.Sort((ExtendedItem s1, ExtendedItem s2) => ((Object)s1).name.CompareTo(((Object)s2).name));
			ExtendedEnemyTypes.Sort((ExtendedEnemyType s1, ExtendedEnemyType s2) => ((Object)s1).name.CompareTo(((Object)s2).name));
			ExtendedWeatherEffects.Sort((ExtendedWeatherEffect s1, ExtendedWeatherEffect s2) => ((Object)s1).name.CompareTo(((Object)s2).name));
			ExtendedFootstepSurfaces.Sort((ExtendedFootstepSurface s1, ExtendedFootstepSurface s2) => ((Object)s1).name.CompareTo(((Object)s2).name));
		}

		internal void Example()
		{
			AssetBundle val = null;
			ExtendedDungeonFlow extendedDungeonFlow = val.LoadAsset<ExtendedDungeonFlow>("Assets/CoolDungeonFlow");
			ExtendedEnemyType extendedEnemyType = val.LoadAsset<ExtendedEnemyType>("Assets/Ghost");
			ExtendedMod extendedMod = Create("BatbysMod", "IAmBatby", new ExtendedContent[2] { extendedDungeonFlow, extendedEnemyType });
			PatchedContent.RegisterExtendedMod(extendedMod);
		}
	}
	[CreateAssetMenu(fileName = "ExtendedStoryLog", menuName = "Lethal Level Loader/Extended Content/ExtendedStoryLog", order = 26)]
	public class ExtendedStoryLog : ExtendedContent
	{
		public string sceneName = string.Empty;

		public int storyLogID;

		[Space(5f)]
		public string terminalKeywordNoun = string.Empty;

		[Space(5f)]
		public string storyLogTitle = string.Empty;

		[TextArea]
		public string storyLogDescription = string.Empty;

		[HideInInspector]
		internal int newStoryLogID;
	}
	[CreateAssetMenu(fileName = "ExtendedWeatherEffect", menuName = "Lethal Level Loader/Extended Content/ExtendedWeatherEffect", order = 25)]
	public class ExtendedWeatherEffect : ExtendedContent
	{
		public ContentType contentType;

		[field: Header("General Settings")]
		[field: SerializeField]
		public LevelWeatherType BaseWeatherType { get; set; } = (LevelWeatherType)(-1);


		[field: SerializeField]
		public string WeatherDisplayName { get; set; } = string.Empty;


		[field: SerializeField]
		public GameObject WorldObject { get; set; }

		[field: SerializeField]
		public GameObject GlobalObject { get; set; }

		internal static ExtendedWeatherEffect Create(LevelWeatherType levelWeatherType, WeatherEffect weatherEffect, string weatherDisplayName, ContentType newContentType)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			return Create(levelWeatherType, weatherEffect.effectObject, weatherEffect.effectPermanentObject, weatherDisplayName, newContentType);
		}

		internal static ExtendedWeatherEffect Create(LevelWeatherType levelWeatherType, GameObject worldObject, GameObject globalObject, string newWeatherDisplayName, ContentType newContentType)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			ExtendedWeatherEffect extendedWeatherEffect = ScriptableObject.CreateInstance<ExtendedWeatherEffect>();
			extendedWeatherEffect.WeatherDisplayName = newWeatherDisplayName;
			((Object)extendedWeatherEffect).name = extendedWeatherEffect.WeatherDisplayName + "ExtendedWeatherEffect";
			extendedWeatherEffect.BaseWeatherType = levelWeatherType;
			extendedWeatherEffect.WorldObject = worldObject;
			extendedWeatherEffect.GlobalObject = globalObject;
			return extendedWeatherEffect;
		}
	}
	public class LLLSaveFile : ModDataContainer
	{
		public Dictionary<string, string> customItemDictionary = new Dictionary<string, string>();

		public List<string> allItemsList = new List<string>();

		public List<AllItemsListItemData> itemSaveDataList = new List<AllItemsListItemData>();

		public Dictionary<int, AllItemsListItemData> itemSaveData = new Dictionary<int, AllItemsListItemData>();

		public string CurrentLevelName { get; internal set; } = string.Empty;


		public LLLSaveFile(string name)
		{
			((ModDataContainer)this).OptionalPrefixSuffix = name;
		}
	}
	public struct AllItemsListItemData
	{
		public string itemName;

		public string itemDisplayName;

		public string modName;

		public int allItemsListIndex;

		public AllItemsListItemData(string newItemName, string newItemDisplayName, string newModName, int newAllItemsListIndex)
		{
			itemName = newItemName;
			itemDisplayName = newItemDisplayName;
			modName = newModName;
			allItemsListIndex = newAllItemsListIndex;
		}
	}
	[CreateAssetMenu(fileName = "ContentTag", menuName = "Lethal Level Loader/Utility/ContentTag", order = 11)]
	public class ContentTag : ScriptableObject
	{
		public string contentTagName;

		public Color contentTagColor;

		public static ContentTag Create(string tag, Color color)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			ContentTag contentTag = ScriptableObject.CreateInstance<ContentTag>();
			contentTag.contentTagName = tag;
			contentTag.contentTagColor = color;
			((Object)contentTag).name = tag + "ContentTag";
			return contentTag;
		}

		public static ContentTag Create(string tag)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			return Create(tag, Color.white);
		}
	}
	[CreateAssetMenu(fileName = "DungeonMatchingProperties", menuName = "Lethal Level Loader/Utility/DungeonMatchingProperties", order = 13)]
	public class DungeonMatchingProperties : MatchingProperties
	{
		[Space(5f)]
		public List<StringWithRarity> dungeonTags = new List<StringWithRarity>();

		[Space(5f)]
		public List<StringWithRarity> dungeonNames = new List<StringWithRarity>();

		public new static DungeonMatchingProperties Create(ExtendedContent extendedContent)
		{
			DungeonMatchingProperties dungeonMatchingProperties = ScriptableObject.CreateInstance<DungeonMatchingProperties>();
			((Object)dungeonMatchingProperties).name = ((Object)extendedContent).name + "DungeonMatchingProperties";
			return dungeonMatchingProperties;
		}

		public int GetDynamicRarity(ExtendedDungeonFlow extendedDungeonFlow)
		{
			int currentValue = 0;
			MatchingProperties.UpdateRarity(ref currentValue, MatchingProperties.GetHighestRarityViaMatchingNormalizedTags(extendedDungeonFlow.ContentTags, dungeonNames), ((Object)extendedDungeonFlow).name, "Content Tags");
			MatchingProperties.UpdateRarity(ref currentValue, MatchingProperties.GetHighestRarityViaMatchingNormalizedString(extendedDungeonFlow.AuthorName, authorNames), ((Object)extendedDungeonFlow).name, "Author Name");
			MatchingProperties.UpdateRarity(ref currentValue, MatchingProperties.GetHighestRarityViaMatchingNormalizedStrings(extendedDungeonFlow.ExtendedMod.ModNameAliases, modNames), ((Object)extendedDungeonFlow).name, "Mod Name Name");
			MatchingProperties.UpdateRarity(ref currentValue, MatchingProperties.GetHighestRarityViaMatchingNormalizedString(((Object)extendedDungeonFlow.DungeonFlow).name, dungeonNames), ((Object)extendedDungeonFlow).name, "Dungeon Name");
			return currentValue;
		}

		public void ApplyValues(List<StringWithRarity> newModNames = null, List<StringWithRarity> newAuthorNames = null, List<StringWithRarity> newDungeonTags = null, List<StringWithRarity> newDungeonNames = null)
		{
			if (newModNames != null && newModNames.Count != 0)
			{
				modNames = new List<StringWithRarity>(newModNames);
			}
			if (newAuthorNames != null && newAuthorNames.Count != 0)
			{
				authorNames = new List<StringWithRarity>(newAuthorNames);
			}
			if (newDungeonTags != null && newDungeonTags.Count != 0)
			{
				dungeonTags = new List<StringWithRarity>(newDungeonTags);
			}
			if (newDungeonNames != null && newDungeonNames.Count != 0)
			{
				dungeonNames = new List<StringWithRarity>(newDungeonNames);
			}
		}
	}
	[CreateAssetMenu(fileName = "LevelMatchingProperties", menuName = "Lethal Level Loader/Utility/LevelMatchingProperties", order = 12)]
	public class LevelMatchingProperties : MatchingProperties
	{
		[Space(5f)]
		public List<StringWithRarity> levelTags = new List<StringWithRarity>();

		[Space(5f)]
		public List<Vector2WithRarity> currentRoutePrice = new List<Vector2WithRarity>();

		[Space(5f)]
		public List<StringWithRarity> currentWeather = new List<StringWithRarity>();

		[Space(5f)]
		public List<StringWithRarity> planetNames = new List<StringWithRarity>();

		public new static LevelMatchingProperties Create(ExtendedContent extendedContent)
		{
			LevelMatchingProperties levelMatchingProperties = ScriptableObject.CreateInstance<LevelMatchingProperties>();
			((Object)levelMatchingProperties).name = ((Object)extendedContent).name + "LevelMatchingProperties";
			return levelMatchingProperties;
		}

		public int GetDynamicRarity(ExtendedLevel extendedLevel)
		{
			int currentValue = 0;
			MatchingProperties.UpdateRarity(ref currentValue, MatchingProperties.GetHighestRarityViaMatchingNormalizedTags(extendedLevel.ContentTags, levelTags), ((Object)extendedLevel).name, "Content Tags");
			MatchingProperties.UpdateRarity(ref currentValue, MatchingProperties.GetHighestRarityViaMatchingNormalizedString(extendedLevel.AuthorName, authorNames), ((Object)extendedLevel).name, "Author Name");
			MatchingProperties.UpdateRarity(ref currentValue, MatchingProperties.GetHighestRarityViaMatchingNormalizedStrings(extendedLevel.ExtendedMod.ModNameAliases, modNames), ((Object)extendedLevel).name, "Mod Name");
			MatchingProperties.UpdateRarity(ref currentValue, MatchingProperties.GetHighestRarityViaMatchingWithinRanges(extendedLevel.RoutePrice, currentRoutePrice), ((Object)extendedLevel).name, "Route Price");
			MatchingProperties.UpdateRarity(ref currentValue, MatchingProperties.GetHighestRarityViaMatchingNormalizedString(extendedLevel.NumberlessPlanetName, planetNames), ((Object)extendedLevel).name, "Planet Name");
			MatchingProperties.UpdateRarity(ref currentValue, MatchingProperties.GetHighestRarityViaMatchingNormalizedString(((object)(LevelWeatherType)(ref extendedLevel.SelectableLevel.currentWeather)).ToString(), currentWeather), ((Object)extendedLevel).name, "Current Weather");
			return currentValue;
		}

		public void ApplyValues(List<StringWithRarity> newModNames = null, List<StringWithRarity> newAuthorNames = null, List<StringWithRarity> newLevelTags = null, List<Vector2WithRarity> newRoutePrices = null, List<StringWithRarity> newCurrentWeathers = null, List<StringWithRarity> newPlanetNames = null)
		{
			if (newModNames != null && newModNames.Count != 0)
			{
				modNames = new List<StringWithRarity>(newModNames);
			}
			if (newAuthorNames != null && newAuthorNames.Count != 0)
			{
				authorNames = new List<StringWithRarity>(newAuthorNames);
			}
			if (newLevelTags != null && newLevelTags.Count != 0)
			{
				levelTags = new List<StringWithRarity>(newLevelTags);
			}
			if (newRoutePrices != null && newRoutePrices.Count != 0)
			{
				currentRoutePrice = new List<Vector2WithRarity>(newRoutePrices);
			}
			if (newCurrentWeathers != null && newCurrentWeathers.Count != 0)
			{
				currentWeather = new List<StringWithRarity>(newCurrentWeathers);
			}
			if (newPlanetNames != null && newPlanetNames.Count != 0)
			{
				planetNames = new List<StringWithRarity>(newPlanetNames);
			}
		}
	}
	public class MatchingProperties : ScriptableObject
	{
		[Space(5f)]
		public List<StringWithRarity> modNames = new List<StringWithRarity>();

		[Space(5f)]
		public List<StringWithRarity> authorNames = new List<StringWithRarity>();

		public static MatchingProperties Create(ExtendedContent extendedContent)
		{
			MatchingProperties matchingProperties = ScriptableObject.CreateInstance<MatchingProperties>();
			((Object)matchingProperties).name = ((Object)extendedContent).name + "MatchingProperties";
			return matchingProperties;
		}

		internal static bool UpdateRarity(ref int currentValue, int newValue, string debugActionObject = null, string debugActionReason = null)
		{
			if (newValue > currentValue)
			{
				if (!string.IsNullOrEmpty(debugActionReason))
				{
					if (!string.IsNullOrEmpty(debugActionObject))
					{
						DebugHelper.Log("Raised Rarity Of: " + debugActionObject + " From (" + currentValue + ") To (" + newValue + ") Due To Matching " + debugActionReason, DebugType.Developer);
					}
					else
					{
						DebugHelper.Log("Raised Rarity From (" + currentValue + ") To (" + newValue + ") Due To Matching " + debugActionReason, DebugType.Developer);
					}
				}
				currentValue = newValue;
				return true;
			}
			return false;
		}

		internal static int GetHighestRarityViaMatchingWithinRanges(int comparingValue, List<Vector2WithRarity> matchingVectors)
		{
			int num = 0;
			foreach (Vector2WithRarity matchingVector in matchingVectors)
			{
				if (matchingVector.Rarity >= num && (float)comparingValue >= matchingVector.Min && (float)comparingValue <= matchingVector.Max)
				{
					num = matchingVector.Rarity;
				}
			}
			return num;
		}

		internal static int GetHighestRarityViaMatchingNormalizedString(string comparingString, List<StringWithRarity> matchingStrings)
		{
			return GetHighestRarityViaMatchingNormalizedStrings(new List<string> { comparingString }, matchingStrings);
		}

		internal static int GetHighestRarityViaMatchingNormalizedTags(List<ContentTag> comparingTags, List<StringWithRarity> matchingStrings)
		{
			List<string> comparingStrings = comparingTags.Select((ContentTag t) => t.contentTagName).ToList();
			return GetHighestRarityViaMatchingNormalizedStrings(comparingStrings, matchingStrings);
		}

		internal static int GetHighestRarityViaMatchingNormalizedStrings(List<string> comparingStrings, List<StringWithRarity> matchingStrings)
		{
			int num = 0;
			foreach (StringWithRarity matchingString in matchingStrings)
			{
				foreach (string item in new List<string>(comparingStrings))
				{
					if (matchingString.Rarity >= num && (matchingString.Name.Sanitized().Contains(item.Sanitized()) || item.Sanitized().Contains(matchingString.Name.Sanitized())))
					{
						num = matchingString.Rarity;
					}
				}
			}
			return num;
		}
	}
	public class MoonsCataloguePage
	{
		private List<ExtendedLevelGroup> extendedLevelGroups;

		public List<ExtendedLevelGroup> ExtendedLevelGroups => extendedLevelGroups;

		public List<ExtendedLevel> ExtendedLevels
		{
			get
			{
				List<ExtendedLevel> list = new List<ExtendedLevel>();
				foreach (ExtendedLevelGroup extendedLevelGroup in extendedLevelGroups)
				{
					foreach (ExtendedLevel extendedLevels in extendedLevelGroup.extendedLevelsList)
					{
						list.Add(extendedLevels);
					}
				}
				return list;
			}
		}

		public MoonsCataloguePage(List<ExtendedLevelGroup> newExtendedLevelGroupList)
		{
			extendedLevelGroups = new List<ExtendedLevelGroup>();
			extendedLevelGroups.Clear();
			foreach (ExtendedLevelGroup newExtendedLevelGroup in newExtendedLevelGroupList)
			{
				extendedLevelGroups.Add(new ExtendedLevelGroup(newExtendedLevelGroup.extendedLevelsList));
			}
		}

		public void RebuildLevelGroups(List<ExtendedLevelGroup> newExtendedLevelGroups, int splitCount)
		{
			List<ExtendedLevel> list = new List<ExtendedLevel>();
			foreach (ExtendedLevelGroup extendedLevelGroup in extendedLevelGroups)
			{
				foreach (ExtendedLevel extendedLevels in extendedLevelGroup.extendedLevelsList)
				{
					list.Add(extendedLevels);
				}
			}
			RebuildLevelGroups(list.ToArray(), splitCount);
		}

		public void RebuildLevelGroups(List<ExtendedLevel> newExtendedLevels, int splitCount)
		{
			RebuildLevelGroups(newExtendedLevels.ToArray(), splitCount);
		}

		public void RebuildLevelGroups(IOrderedEnumerable<ExtendedLevel> orderedExtendedLevels, int splitCount)
		{
			RebuildLevelGroups(orderedExtendedLevels.ToArray(), splitCount);
		}

		public void RebuildLevelGroups(ExtendedLevel[] newExtendedLevels, int splitCount)
		{
			extendedLevelGroups = TerminalManager.GetExtendedLevelGroups(newExtendedLevels, splitCount);
		}

		public void RefreshLevelGroups(List<ExtendedLevelGroup> newLevelGroups)
		{
			extendedLevelGroups.Clear();
			foreach (ExtendedLevelGroup newLevelGroup in newLevelGroups)
			{
				if (newLevelGroup.extendedLevelsList.Count != 0)
				{
					extendedLevelGroups.Add(new ExtendedLevelGroup(newLevelGroup.extendedLevelsList));
				}
			}
		}
	}
	[Serializable]
	public class ExtendedLevelGroup
	{
		public List<ExtendedLevel> extendedLevelsList;

		public int AverageCalculatedDifficulty => GetAverageCalculatedDifficulty();

		public ExtendedLevelGroup(List<ExtendedLevel> newExtendedLevelsList)
		{
			extendedLevelsList = new List<ExtendedLevel>(newExtendedLevelsList);
		}

		public ExtendedLevelGroup(List<SelectableLevel> newSelectableLevelsList)
		{
			extendedLevelsList = new List<ExtendedLevel>();
			foreach (SelectableLevel newSelectableLevels in newSelectableLevelsList)
			{
				extendedLevelsList.Add(LevelManager.GetExtendedLevel(newSelectableLevels));
			}
		}

		public int GetAverageCalculatedDifficulty()
		{
			List<int> list = new List<int>();
			foreach (ExtendedLevel extendedLevels in extendedLevelsList)
			{
				list.Add(extendedLevels.CalculatedDifficultyRating);
			}
			return (int)list.Average();
		}
	}
	public static class PatchedContent
	{
		public static ExtendedMod VanillaMod { get; internal set; }

		public static List<string> AllLevelSceneNames { get; internal set; } = new List<string>();


		public static List<ExtendedMod> ExtendedMods { get; internal set; } = new List<ExtendedMod>();


		public static List<ExtendedLevel> ExtendedLevels { get; internal set; } = new List<ExtendedLevel>();


		public static List<ExtendedLevel> VanillaExtendedLevels
		{
			get
			{
				List<ExtendedLevel> list = new List<ExtendedLevel>();
				foreach (ExtendedLevel extendedLevel in ExtendedLevels)
				{
					if (extendedLevel.ContentType == ContentType.Vanilla)
					{
						list.Add(extendedLevel);
					}
				}
				return list;
			}
		}

		public static List<ExtendedLevel> CustomExtendedLevels
		{
			get
			{
				List<ExtendedLevel> list = new List<ExtendedLevel>();
				foreach (ExtendedLevel extendedLevel in ExtendedLevels)
				{
					if (extendedLevel.ContentType == ContentType.Custom)
					{
						list.Add(extendedLevel);
					}
				}
				return list;
			}
		}

		public static List<SelectableLevel> SeletectableLevels
		{
			get
			{
				List<SelectableLevel> list = new List<SelectableLevel>();
				foreach (ExtendedLevel extendedLevel in ExtendedLevels)
				{
					list.Add(extendedLevel.SelectableLevel);
				}
				return list;
			}
		}

		public static List<SelectableLevel> MoonsCatalogue
		{
			get
			{
				List<SelectableLevel> list = new List<SelectableLevel>();
				foreach (SelectableLevel item in OriginalContent.MoonsCatalogue)
				{
					list.Add(item);
				}
				foreach (ExtendedLevel extendedLevel in ExtendedLevels)
				{
					if (extendedLevel.ContentType == ContentType.Custom)
					{
						list.Add(extendedLevel.SelectableLevel);
					}
				}
				return list;
			}
		}

		public static List<ExtendedDungeonFlow> ExtendedDungeonFlows { get; internal set; } = new List<ExtendedDungeonFlow>();


		public static List<ExtendedDungeonFlow> VanillaExtendedDungeonFlows
		{
			get
			{
				List<ExtendedDungeonFlow> list = new List<ExtendedDungeonFlow>();
				foreach (ExtendedDungeonFlow extendedDungeonFlow in ExtendedDungeonFlows)
				{
					if (extendedDungeonFlow.ContentType == ContentType.Vanilla)
					{
						list.Add(extendedDungeonFlow);
					}
				}
				return list;
			}
		}

		public static List<ExtendedDungeonFlow> CustomExtendedDungeonFlows
		{
			get
			{
				List<ExtendedDungeonFlow> list = new List<ExtendedDungeonFlow>();
				foreach (ExtendedDungeonFlow extendedDungeonFlow in ExtendedDungeonFlows)
				{
					if (extendedDungeonFlow.ContentType == ContentType.Custom)
					{
						list.Add(extendedDungeonFlow);
					}
				}
				return list;
			}
		}

		public static List<ExtendedWeatherEffect> ExtendedWeatherEffects { get; internal set; } = new List<ExtendedWeatherEffect>();


		public static List<ExtendedWeatherEffect> VanillaExtendedWeatherEffects
		{
			get
			{
				List<ExtendedWeatherEffect> list = new List<ExtendedWeatherEffect>();
				foreach (ExtendedWeatherEffect extendedWeatherEffect in ExtendedWeatherEffects)
				{
					if (extendedWeatherEffect.contentType == ContentType.Vanilla)
					{
						list.Add(extendedWeatherEffect);
					}
				}
				return list;
			}
		}

		public static List<ExtendedWeatherEffect> CustomExtendedWeatherEffects
		{
			get
			{
				List<ExtendedWeatherEffect> list = new List<ExtendedWeatherEffect>();
				foreach (ExtendedWeatherEffect extendedWeatherEffect in ExtendedWeatherEffects)
				{
					if (extendedWeatherEffect.contentType == ContentType.Custom)
					{
						list.Add(extendedWeatherEffect);
					}
				}
				return list;
			}
		}

		public static List<ExtendedItem> ExtendedItems { get; internal set; } = new List<ExtendedItem>();


		public static List<ExtendedItem> CustomExtendedItems
		{
			get
			{
				List<ExtendedItem> list = new List<ExtendedItem>();
				foreach (ExtendedItem extendedItem in ExtendedItems)
				{
					if (extendedItem.ContentType == ContentType.Custom)
					{
						list.Add(extendedItem);
					}
				}
				return list;
			}
		}

		public static List<ExtendedEnemyType> ExtendedEnemyTypes { get; internal set; } = new List<ExtendedEnemyType>();


		public static List<ExtendedEnemyType> CustomExtendedEnemyTypes
		{
			get
			{
				List<ExtendedEnemyType> list = new List<ExtendedEnemyType>();
				foreach (ExtendedEnemyType extendedEnemyType in ExtendedEnemyTypes)
				{
					if (extendedEnemyType.ContentType == ContentType.Custom)
					{
						list.Add(extendedEnemyType);
					}
				}
				return list;
			}
		}

		public static List<ExtendedEnemyType> VanillaExtendedEnemyTypes
		{
			get
			{
				List<ExtendedEnemyType> list = new List<ExtendedEnemyType>();
				foreach (ExtendedEnemyType extendedEnemyType in ExtendedEnemyTypes)
				{
					if (extendedEnemyType.ContentType == ContentType.Vanilla)
					{
						list.Add(extendedEnemyType);
					}
				}
				return list;
			}
		}

		public static List<AudioMixer> AudioMixers { get; internal set; } = new List<AudioMixer>();


		public static List<AudioMixerGroup> AudioMixerGroups { get; internal set; } = new List<AudioMixerGroup>();


		public static List<AudioMixerSnapshot> AudioMixerSnapshots { get; internal set; } = new List<AudioMixerSnapshot>();


		public static List<Item> Items { get; internal set; } = new List<Item>();


		public static List<EnemyType> Enemies { get; internal set; } = new List<EnemyType>();


		public static void RegisterExtendedDungeonFlow(ExtendedDungeonFlow extendedDungeonFlow)
		{
			extendedDungeonFlow.ConvertObsoleteValues();
			if (string.IsNullOrEmpty(((Object)extendedDungeonFlow).name))
			{
				DebugHelper.LogWarning("Tried to register ExtendedDungeonFlow with missing name! Setting to DungeonFlow name for safety!", DebugType.Developer);
				((Object)extendedDungeonFlow).name = ((Object)extendedDungeonFlow.DungeonFlow).name;
			}
			AssetBundleLoader.RegisterNewExtendedContent(extendedDungeonFlow, ((Object)extendedDungeonFlow).name);
		}

		public static void RegisterExtendedLevel(ExtendedLevel extendedLevel)
		{
			AssetBundleLoader.RegisterNewExtendedContent(extendedLevel, ((Object)extendedLevel).name);
		}

		public static void RegisterExtendedMod(ExtendedMod extendedMod)
		{
			DebugHelper.Log("Registering ExtendedMod: " + extendedMod.ModName + " Manually.", DebugType.Developer);
			AssetBundleLoader.RegisterExtendedMod(extendedMod);
		}

		internal static void SortExtendedMods()
		{
			ExtendedMods = new List<ExtendedMod>(ExtendedMods.OrderBy((ExtendedMod o) => o.ModName).ToList());
			foreach (ExtendedMod extendedMod in ExtendedMods)
			{
				extendedMod.SortRegisteredContent();
			}
		}
	}
	public static class OriginalContent
	{
		public static List<SelectableLevel> SelectableLevels { get; internal set; } = new List<SelectableLevel>();


		public static List<SelectableLevel> MoonsCatalogue { get; internal set; } = new List<SelectableLevel>();


		public static List<DungeonFlow> DungeonFlows { get; internal set; } = new List<DungeonFlow>();


		public static List<Item> Items { get; internal set; } = new List<Item>();


		public static List<ItemGroup> ItemGroups { get; internal set; } = new List<ItemGroup>();


		public static List<EnemyType> Enemies { get; internal set; } = new List<EnemyType>();


		public static List<SpawnableOutsideObject> SpawnableOutsideObjects { get; internal set; } = new List<SpawnableOutsideObject>();


		public static List<GameObject> SpawnableMapObjects { get; internal set; } = new List<GameObject>();


		public static List<AudioMixer> AudioMixers { get; internal set; } = new List<AudioMixer>();


		public static List<AudioMixerGroup> AudioMixerGroups { get; internal set; } = new List<AudioMixerGroup>();


		public static List<AudioMixerSnapshot> AudioMixerSnapshots { get; internal set; } = new List<AudioMixerSnapshot>();


		public static List<LevelAmbienceLibrary> LevelAmbienceLibraries { get; internal set; } = new List<LevelAmbienceLibrary>();


		public static List<ReverbPreset> ReverbPresets { get; internal set; } = new List<ReverbPreset>();


		public static List<TerminalKeyword> TerminalKeywords { get; internal set; } = new List<TerminalKeyword>();


		public static List<TerminalNode> TerminalNodes { get; internal set; } = new List<TerminalNode>();

	}
	internal class EventPatches
	{
		internal static DayMode previousDayMode = (DayMode)(-1);

		internal static bool firedDawnEvent = false;

		private static EnemyVent cachedSelectedVent;

		internal static void InvokeExtendedEvent<T>(ExtendedEvent<T> extendedEvent, T eventParameter)
		{
			extendedEvent.Invoke(eventParameter);
		}

		internal static void OnSceneLoaded(Scene scene, LoadSceneMode loadSceneMode)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)LevelManager.CurrentExtendedLevel != (Object)null && LevelManager.CurrentExtendedLevel.IsLevelLoaded)
			{
				previousDayMode = (DayMode)(-1);
				LevelManager.CurrentExtendedLevel.LevelEvents.onLevelLoaded.Invoke();
				LevelManager.GlobalLevelEvents.onLevelLoaded.Invoke();
			}
		}

		[HarmonyPriority(200)]
		[HarmonyPatch(typeof(StoryLog), "CollectLog")]
		[HarmonyPrefix]
		internal static void StoryLogCollectLog_Prefix(StoryLog __instance)
		{
			if ((Object)(object)LevelManager.CurrentExtendedLevel != (Object)null && ((NetworkBehaviour)__instance).IsServer)
			{
				LevelManager.CurrentExtendedLevel.LevelEvents.onStoryLogCollected.Invoke(__instance);
				LevelManager.GlobalLevelEvents.onStoryLogCollected.Invoke(__instance);
			}
		}

		[HarmonyPriority(201)]
		[HarmonyPatch(typeof(DungeonGenerator), "Generate")]
		[HarmonyPrefix]
		internal static void DungeonGeneratorGenerate_Prefix()
		{
			if ((Object)(object)DungeonManager.CurrentExtendedDungeonFlow != (Object)null)
			{
				DungeonManager.CurrentExtendedDungeonFlow.dungeonEvents.onBeforeDungeonGenerate.Invoke(Patches.RoundManager);
				DungeonManager.GlobalDungeonEvents.onBeforeDungeonGenerate.Invoke(Patches.RoundManager);
			}
		}

		[HarmonyPriority(200)]
		[HarmonyPatch(typeof(RoundManager), "SwitchPower")]
		[HarmonyPrefix]
		internal static void RoundManagerSwitchPower_Prefix(bool on)
		{
			if ((Object)(object)DungeonManager.CurrentExtendedDungeonFlow != (Object)null)
			{
				DungeonManager.CurrentExtendedDungeonFlow.dungeonEvents.onPowerSwitchToggle.Invoke(on);
				DungeonManager.GlobalDungeonEvents.onPowerSwitchToggle.Invoke(on);
			}
			if ((Object)(object)LevelManager.CurrentExtendedLevel != (Object)null)
			{
				LevelManager.CurrentExtendedLevel.LevelEvents.onPowerSwitchToggle.Invoke(on);
				LevelManager.GlobalLevelEvents.onPowerSwitchToggle.Invoke(on);
			}
		}

		[HarmonyPriority(200)]
		[HarmonyPatch(typeof(RoundManager), "SpawnScrapInLevel")]
		[HarmonyPostfix]
		internal static void RoundManagerSpawnScrapInLevel_Postfix()
		{
			if ((Object)(object)DungeonManager.CurrentExtendedDungeonFlow != (Object)null)
			{
				List<GrabbableObject> param = Object.FindObjectsOfType<GrabbableObject>().ToList();
				DungeonManager.CurrentExtendedDungeonFlow.dungeonEvents.onSpawnedScrapObjects.Invoke(param);
				DungeonManager.GlobalDungeonEvents.onSpawnedScrapObjects.Invoke(param);
			}
		}

		[HarmonyPriority(200)]
		[HarmonyPatch(typeof(RoundManager), "SpawnSyncedProps")]
		[HarmonyPostfix]
		internal static void RoundManagerSpawnSyncedProps_Postfix()
		{
			if ((Object)(object)DungeonManager.CurrentExtendedDungeonFlow != (Object)null)
			{
				DungeonManager.CurrentExtendedDungeonFlow.dungeonEvents.onSpawnedSyncedObjects.Invoke(Patches.RoundManager.spawnedSyncedObjects);
				DungeonManager.GlobalDungeonEvents.onSpawnedSyncedObjects.Invoke(Patches.RoundManager.spawnedSyncedObjects);
			}
		}

		[HarmonyPriority(200)]
		[HarmonyPatch(typeof(RoundManager), "SpawnEnemyFromVent")]
		[HarmonyPrefix]
		internal static void RoundManagerSpawnEventFromVent_Prefix(EnemyVent vent)
		{
			if ((Object)(object)DungeonManager.CurrentExtendedDungeonFlow != (Object)null)
			{
				cachedSelectedVent = vent;
			}
		}

		[HarmonyPriority(200)]
		[HarmonyPatch(typeof(RoundManager), "SpawnEnemyGameObject")]
		[HarmonyPostfix]
		internal static void RoundManagerSpawnEventFromVent_Postfix()
		{
			if ((Object)(object)DungeonManager.CurrentExtendedDungeonFlow != (Object)null && (Object)(object)cachedSelectedVent != (Object)null)
			{
				DungeonManager.CurrentExtendedDungeonFlow.dungeonEvents.onEnemySpawnedFromVent.Invoke((cachedSelectedVent, Patches.RoundManager.SpawnedEnemies.Last()));
				DungeonManager.GlobalDungeonEvents.onEnemySpawnedFromVent.Invoke((cachedSelectedVent, Patches.RoundManager.SpawnedEnemies.Last()));
				cachedSelectedVent = null;
			}
		}

		[HarmonyPriority(200)]
		[HarmonyPatch(typeof(RoundManager), "SpawnMapObjects")]
		[HarmonyPostfix]
		internal static void RoundManagerSpawnMapObjects_Postfix()
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)DungeonManager.CurrentExtendedDungeonFlow != (Object)null))
			{
				return;
			}
			List<GameObject> list = new List<GameObject>();
			Scene sceneByName = SceneManager.GetSceneByName(LevelManager.CurrentExtendedLevel.SelectableLevel.sceneName);
			GameObject[] rootGameObjects = ((Scene)(ref sceneByName)).GetRootGameObjects();
			foreach (GameObject val in rootGameObjects)
			{
				SpawnableMapObject[] spawnableMapObjects = LevelManager.CurrentExtendedLevel.SelectableLevel.spawnableMapObjects;
				foreach (SpawnableMapObject val2 in spawnableMapObjects)
				{
					if (((Object)val).name.Sanitized().Contains(((Object)val2.prefabToSpawn).name.Sanitized()))
					{
						list.Add(val);
					}
				}
			}
			DungeonManager.CurrentExtendedDungeonFlow.dungeonEvents.onSpawnedMapObjects.Invoke(list);
			DungeonManager.GlobalDungeonEvents.onSpawnedMapObjects.Invoke(list);
		}

		[HarmonyPriority(200)]
		[HarmonyPatch(typeof(EntranceTeleport), "TeleportPlayerServerRpc")]
		[HarmonyPrefix]
		internal static void EntranceTeleportTeleportPlayerServerRpc_Prefix(EntranceTeleport __instance, int playerObj)
		{
			if (!((NetworkBehaviour)__instance).IsHost)
			{
				return;
			}
			if ((Object)(object)DungeonManager.CurrentExtendedDungeonFlow != (Object)null)
			{
				PlayerControllerB item = Patches.StartOfRound.allPlayerScripts[playerObj];
				if (__instance.isEntranceToBuilding)
				{
					DungeonManager.CurrentExtendedDungeonFlow.dungeonEvents.onPlayerEnterDungeon.Invoke((__instance, item));
					DungeonManager.GlobalDungeonEvents.onPlayerEnterDungeon.Invoke((__instance, item));
				}
				else
				{
					DungeonManager.CurrentExtendedDungeonFlow.dungeonEvents.onPlayerExitDungeon.Invoke((__instance, item));
					DungeonManager.GlobalDungeonEvents.onPlayerExitDungeon.Invoke((__instance, item));
				}
			}
			if ((Object)(object)LevelManager.CurrentExtendedLevel != (Object)null)
			{
				PlayerControllerB item2 = Patches.StartOfRound.allPlayerScripts[playerObj];
				if (__instance.isEntranceToBuilding)
				{
					LevelManager.CurrentExtendedLevel.LevelEvents.onPlayerEnterDungeon.Invoke((__instance, item2));
					LevelManager.GlobalLevelEvents.onPlayerEnterDungeon.Invoke((__instance, item2));
				}
				else
				{
					LevelManager.CurrentExtendedLevel.LevelEvents.onPlayerExitDungeon.Invoke((__instance, item2));
					LevelManager.GlobalLevelEvents.onPlayerExitDungeon.Invoke((__instance, item2));
				}
			}
		}

		[HarmonyPriority(200)]
		[HarmonyPatch(typeof(LungProp), "EquipItem")]
		[HarmonyPrefix]
		internal static void LungPropEquipItem_Postfix(LungProp __instance)
		{
			if (((NetworkBehaviour)__instance).IsServer)
			{
				if ((Object)(object)DungeonManager.CurrentExtendedDungeonFlow != (Object)null)
				{
					DungeonManager.CurrentExtendedDungeonFlow.dungeonEvents.onApparatusTaken.Invoke(__instance);
					DungeonManager.GlobalDungeonEvents.onApparatusTaken.Invoke(__instance);
				}
				if ((Object)(object)LevelManager.CurrentExtendedLevel != (Object)null)
				{
					LevelManager.CurrentExtendedLevel.LevelEvents.onApparatusTaken.Invoke(__instance);
					LevelManager.GlobalLevelEvents.onApparatusTaken.Invoke(__instance);
				}
			}
		}

		[HarmonyPriority(200)]
		[HarmonyPatch(typeof(TimeOfDay), "GetDayPhase")]
		[HarmonyPostfix]
		internal static void TimeOfDayGetDayPhase_Postfix(DayMode __result)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			if ((int)previousDayMode == -1 || previousDayMode != __result)
			{
				LevelManager.CurrentExtendedLevel.LevelEvents.onDayModeToggle.Invoke(__result);
				LevelManager.GlobalLevelEvents.onDayModeToggle.Invoke(__result);
			}
			previousDayMode = __result;
		}
	}
	public class ExtendedEvent<T>
	{
		public delegate void ParameterEvent(T param);

		public bool HasListeners => Listeners != 0;

		public int Listeners { get; internal set; }

		private event ParameterEvent onParameterEvent;

		public void Invoke(T param)
		{
			this.onParameterEvent?.Invoke(param);
		}

		public void AddListener(ParameterEvent listener)
		{
			onParameterEvent += listener;
			Listeners++;
		}

		public void RemoveListener(ParameterEvent listener)
		{
			onParameterEvent -= listener;
			Listeners--;
		}
	}
	public class ExtendedEvent
	{
		public delegate void Event();

		public bool HasListeners => Listeners != 0;

		public int Listeners { get; internal set; }

		private event Event onEvent;

		public void Invoke()
		{
			this.onEvent?.Invoke();
		}

		public void AddListener(Event listener)
		{
			onEvent += listener;
			Listeners++;
		}

		public void RemoveListener(Event listener)
		{
			onEvent -= listener;
			Listeners--;
		}
	}
	public static class Extensions
	{
		public static List<Tile> GetTiles(this DungeonFlow dungeonFlow)
		{
			List<Tile> list = new List<Tile>();
			foreach (GraphNode node in dungeonFlow.Nodes)
			{
				foreach (TileSet tileSet in node.TileSets)
				{
					list.AddRange(GetTilesInTileSet(tileSet));
				}
			}
			foreach (GraphLine line in dungeonFlow.Lines)
			{
				foreach (DungeonArchetype dungeonArchetype in line.DungeonArchetypes)
				{
					foreach (TileSet branchCapTileSet in dungeonArchetype.BranchCapTileSets)
					{
						list.AddRange(GetTilesInTileSet(branchCapTileSet));
					}
					foreach (TileSet tileSet2 in dungeonArchetype.TileSets)
					{
						list.AddRange(GetTilesInTileSet(tileSet2));
					}
				}
			}
			foreach (Tile item in new List<Tile>(list))
			{
				if ((Object)(object)item == (Object)null)
				{
					list.Remove(item);
				}
			}
			return list;
		}

		public static List<Tile> GetTilesInTileSet(TileSet tileSet)
		{
			List<Tile> list = new List<Tile>();
			if (tileSet.TileWeights != null && tileSet.TileWeights.Weights != null)
			{
				foreach (GameObjectChance weight in tileSet.TileWeights.Weights)
				{
					Tile[] componentsInChildren = weight.Value.GetComponentsInChildren<Tile>();
					foreach (Tile item in componentsInChildren)
					{
						list.Add(item);
					}
				}
			}
			return list;
		}

		public static List<RandomMapObject> GetRandomMapObjects(this DungeonFlow dungeonFlow)
		{
			List<RandomMapObject> list = new List<RandomMapObject>();
			foreach (Tile tile in dungeonFlow.GetTiles())
			{
				RandomMapObject[] componentsInChildren = ((Component)tile).gameObject.GetComponentsInChildren<RandomMapObject>();
				foreach (RandomMapObject item in componentsInChildren)
				{
					list.Add(item);
				}
			}
			return list;
		}

		public static List<SpawnSyncedObject> GetSpawnSyncedObjects(this DungeonFlow dungeonFlow)
		{
			List<SpawnSyncedObject> list = new List<SpawnSyncedObject>();
			foreach (Tile tile in dungeonFlow.GetTiles())
			{
				Doorway[] componentsInChildren = ((Component)tile).gameObject.GetComponentsInChildren<Doorway>();
				foreach (Doorway val in componentsInChildren)
				{
					foreach (GameObjectWeight connectorPrefabWeight in val.ConnectorPrefabWeights)
					{
						SpawnSyncedObject[] componentsInChildren2 = connectorPrefabWeight.GameObject.GetComponentsInChildren<SpawnSyncedObject>();
						foreach (SpawnSyncedObject item in componentsInChildren2)
						{
							list.Add(item);
						}
					}
					foreach (GameObjectWeight blockerPrefabWeight in val.BlockerPrefabWeights)
					{
						SpawnSyncedObject[] componentsInChildren3 = blockerPrefabWeight.GameObject.GetComponentsInChildren<SpawnSyncedObject>();
						foreach (SpawnSyncedObject item2 in componentsInChildren3)
						{
							list.Add(item2);
						}
					}
				}
				SpawnSyncedObject[] componentsInChildren4 = ((Component)tile).gameObject.GetComponentsInChildren<SpawnSyncedObject>();
				foreach (SpawnSyncedObject item3 in componentsInChildren4)
				{
					list.Add(item3);
				}
			}
			return list;
		}

		public static void AddReferences(this CompatibleNoun compatibleNoun, TerminalKeyword firstNoun, TerminalNode firstResult)
		{
			compatibleNoun.noun = firstNoun;
			compatibleNoun.result = firstResult;
		}

		public static void AddCompatibleNoun(this TerminalKeyword terminalKeyword, TerminalKeyword newNoun, TerminalNode newResult)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			if (terminalKeyword.compatibleNouns == null)
			{
				terminalKeyword.compatibleNouns = (CompatibleNoun[])(object)new CompatibleNoun[0];
			}
			CompatibleNoun val = new CompatibleNoun();
			val.noun = newNoun;
			val.result = newResult;
			terminalKeyword.compatibleNouns = CollectionExtensions.AddItem<CompatibleNoun>((IEnumerable<CompatibleNoun>)terminalKeyword.compatibleNouns, val).ToArray();
		}

		public static void AddCompatibleNoun(this TerminalNode terminalNode, TerminalKeyword newNoun, TerminalNode newResult)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			if (terminalNode.terminalOptions == null)
			{
				terminalNode.terminalOptions = (CompatibleNoun[])(object)new CompatibleNoun[0];
			}
			CompatibleNoun val = new CompatibleNoun();
			val.noun = newNoun;
			val.result = newResult;
			terminalNode.terminalOptions = CollectionExtensions.AddItem<CompatibleNoun>((IEnumerable<CompatibleNoun>)terminalNode.terminalOptions, val).ToArray();
		}

		public static void Add(this IntWithRarity intWithRarity, int id, int rarity)
		{
			intWithRarity.id = id;
			intWithRarity.rarity = rarity;
		}

		public static string Sanitized(this string currentString)
		{
			return new string(currentString.SkipToLetters().RemoveWhitespace().ToLowerInvariant());
		}

		public static string RemoveWhitespace(this string input)
		{
			return new string((from c in input.ToCharArray()
				where !char.IsWhiteSpace(c)
				select c).ToArray());
		}

		public static string SkipToLetters(this string input)
		{
			return new string(input.SkipWhile((char c) => !char.IsLetter(c)).ToArray());
		}

		public static string StripSpecialCharacters(this string input)
		{
			string text = string.Empty;
			for (int i = 0; i < input.Length; i++)
			{
				char c = input[i];
				if ((!".,?!@#$%^&*()_+-=';:'\"".ToCharArray().Contains(c) && char.IsLetterOrDigit(c)) || c.ToString() == " ")
				{
					text += c;
				}
			}
			return text;
		}

		public static List<DungeonFlow> GetDungeonFlows(this RoundManager roundManager)
		{
			return roundManager.dungeonFlowTypes.Select((IndoorMapType i) => i.dungeonFlow).ToList();
		}
	}
	internal static class Patches
	{
		private class DoorwayPairComparer : IComparer<DoorwayPair>
		{
			public int Compare(DoorwayPair x, DoorwayPair y)
			{
				int num = ((DoorwayPair)(ref y)).TileWeight.CompareTo(((DoorwayPair)(ref x)).TileWeight);
				if (num == 0)
				{
					return ((DoorwayPair)(ref y)).DoorwayWeight.CompareTo(((DoorwayPair)(ref x)).DoorwayWeight);
				}
				return num;
			}
		}

		internal const int harmonyPriority = 200;

		internal static string delayedSceneLoadingName = string.Empty;

		internal static List<string> allSceneNamesCalledToLoad = new List<string>();

		public static bool hasInitiallyChangedLevel;

		internal static bool ranLethalLevelLoaderTerminalEvent;

		private static List<SpawnableMapObject> tempoarySpawnableMapObjectList = new List<SpawnableMapObject>();

		internal static GameObject previousHit;

		internal static FootstepSurface previouslyAssignedFootstepSurface;

		public static StartOfRound StartOfRound { get; internal set; }

		public static RoundManager RoundManager { get; internal set; }

		public static Terminal Terminal { get; internal set; }

		public static TimeOfDay TimeOfDay { get; internal set; }

		[HarmonyPriority(200)]
		[HarmonyPatch(typeof(PreInitSceneScript), "Awake")]
		[HarmonyPrefix]
		internal static void PreInitSceneScriptAwake_Prefix(PreInitSceneScript __instance)
		{
			if (!Plugin.IsSetupComplete)
			{
				AudioSource val = default(AudioSource);
				if (((Component)__instance).TryGetComponent<AudioSource>(ref val))
				{
					OriginalContent.AudioMixers.Add(val.outputAudioMixerGroup.audioMixer);
				}
				if (AssetBundleLoader.noBundlesFound)
				{
					AssetBundleLoader.CurrentLoadingStatus = AssetBundleLoader.LoadingStatus.Complete;
					AssetBundleLoader.OnBundlesFinishedLoadingInvoke();
				}
				ContentTagParser.ImportVanillaContentTags();
			}
		}

		[HarmonyPriority(200)]
		[HarmonyPatch(typeof(PreInitSceneScript), "ChooseLaunchOption")]
		[HarmonyPrefix]
		internal static bool PreInitSceneScriptChooseLaunchOption_Prefix()
		{
			return true;
		}

		[HarmonyPriority(200)]
		[HarmonyPatch(typeof(SceneManager), "LoadScene", new Type[] { typeof(string) })]
		[HarmonyPrefix]
		internal static bool SceneManagerLoadScene(string sceneName)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			if (allSceneNamesCalledToLoad.Count == 0)
			{
				List<string> list = allSceneNamesCalledToLoad;
				Scene activeScene = SceneManager.GetActiveScene();
				list.Add(((Scene)(ref activeScene)).name);
			}
			SceneManager.GetSceneByName(sceneName);
			if (true)
			{
				allSceneNamesCalledToLoad.Add(sceneName);
			}
			if (sceneName == "MainMenu" && !allSceneNamesCalledToLoad.Contains("InitSceneLaunchOptions"))
			{
				DebugHelper.LogError("SceneManager has been told to load Main Menu without ever loading InitSceneLaunchOptions. This will break LethalLevelLoader. This is likely due to a \"Skip to Main Menu\" mod.", DebugType.User);
				return false;
			}
			if (AssetBundleLoader.CurrentLoadingStatus == AssetBundleLoader.LoadingStatus.Loading)
			{
				DebugHelper.LogWarning("SceneManager has attempted to load " + sceneName + " Scene before AssetBundles have finished loading. Pausing request until LethalLeveLoader is ready to proceed.", DebugType.User);
				delayedSceneLoadingName = sceneName;
				AssetBundleLoader.onBundlesFinishedLoading -= LoadMainMenu;
				AssetBundleLoader.onBundlesFinishedLoading += LoadMainMenu;
				return false;
			}
			return true;
		}

		internal static void LoadMainMenu()
		{
			DebugHelper.LogWarning("Proceeding with the loading of " + delayedSceneLoadingName + " Scene as LethalLevelLoader has finished loading AssetBundles.", DebugType.User);
			if (delayedSceneLoadingName != string.Empty)
			{
				SceneManager.LoadScene(delayedSceneLoadingName);
			}
			delayedSceneLoadingName = string.Empty;
		}

		[HarmonyPriority(200)]
		[HarmonyPatch(typeof(GameNetworkManager), "Start")]
		[HarmonyPrefix]
		internal static void GameNetworkManagerStart_Prefix(GameNetworkManager __instance)
		{
			if (Plugin.IsSetupComplete)
			{
				return;
			}
			LethalLevelLoaderNetworkManager.networkManager = ((Component)__instance).GetComponent<NetworkManager>();
			foreach (NetworkPrefab prefab in ((Component)__instance).GetComponent<NetworkManager>().NetworkConfig.Prefabs.m_Prefabs)
			{
				if (((Object)prefab.Prefab).name.Contains("EntranceTeleport") && (Object)(object)prefab.Prefab.GetComponent<AudioSource>() != (Object)null)
				{
					OriginalContent.AudioMixers.Add(prefab.Prefab.GetComponent<AudioSource>().outputAudioMixerGroup.audioMixer);
				}
			}
			GameObject val = PrefabHelper.CreateNetworkPrefab("LethalLevelLoaderNetworkManagerTest");
			val.AddComponent<LethalLevelLoaderNetworkManager>();
			val.GetComponent<NetworkObject>().DontDestroyWithOwner = true;
			val.GetComponent<NetworkObject>().SceneMigrationSynchronization = true;
			val.GetComponent<NetworkObject>().DestroyWithScene = false;
			Object.DontDestroyOnLoad((Object)(object)val);
			LethalLevelLoaderNetworkManager.networkingManagerPrefab = val;
			LethalLevelLoaderNetworkManager.RegisterNetworkPrefab(val);
			AssetBundleLoader.NetworkRegisterCustomContent(((Component)__instance).GetComponent<NetworkManager>());
			LethalLevelLoaderNetworkManager.RegisterPrefabs(((Component)__instance).GetComponent<NetworkManager>());
		}

		[HarmonyPriority(200)]
		[HarmonyPatch(typeof(StartOfRound), "Awake")]
		[HarmonyPrefix]
		internal static void StartOfRoundAwake_Prefix(StartOfRound __instance)
		{
			Plugin.OnBeforeSetupInvoke();
			StartOfRound = __instance;
			RoundManager = Object.FindFirstObjectByType<RoundManager>();
			Terminal = Object.FindFirstObjectByType<Terminal>();
			TimeOfDay = Object.FindFirstObjectByType<TimeOfDay>();
			SceneManager.sceneLoaded += OnSceneLoaded;
			SceneManager.sceneLoaded += EventPatches.OnSceneLoaded;
			if (!Plugin.IsSetupComplete)
			{
				StartOfRound.allItemsList.itemsList.RemoveAt(2);
				SaveManager.defaultCachedItemsList = new List<Item>(StartOfRound.allItemsList.itemsList);
				DebugStopwatch.StartStopWatch("Scrape Vanilla Content");
				ContentExtractor.TryScrapeVanillaItems(StartOfRound);
				ContentExtractor.TryScrapeVanillaContent(StartOfRound, RoundManager);
				ContentExtractor.ObtainSpecialItemReferences();
			}
			if (((Component)GameNetworkManager.Instance).GetComponent<NetworkManager>().IsServer)
			{
				Object.Instantiate<GameObject>(LethalLevelLoaderNetworkManager.networkingManagerPrefab).GetComponent<NetworkObject>().Spawn(false);
			}
			RoundManager.firstTimeDungeonAudios = CollectionExtensions.AddItem<AudioClip>((IEnumerable<AudioClip>)RoundManager.firstTimeDungeonAudios.ToList(), RoundManager.firstTimeDungeonAudios[0]).ToArray();
			DebugStopwatch.StartStopWatch("Fix AudioSource Settings");
			AudioSource[] array = Resources.FindObjectsOfTypeAll<AudioSource>();
			foreach (AudioSource val in array)
			{
				val.spatialize = false;
			}
			if (!Plugin.IsSetupComplete)
			{
				TerminalManager.CacheTerminalReferences();
				LevelManager.InitalizeShipAnimatorOverrideController();
				DungeonLoader.defaultKeyPrefab = RoundManager.keyPrefab;
				LevelLoader.defaultQuicksandPrefab = RoundManager.quicksandPrefab;
				DebugStopwatch.StartStopWatch("Create Vanilla ExtendedContent");
				AssetBundleLoader.CreateVanillaExtendedDungeonFlows();
				AssetBundleLoader.CreateVanillaExtendedLevels(StartOfRound);
				AssetBundleLoader.CreateVanillaExtendedItems();
				AssetBundleLoader.CreateVanillaExtendedEnemyTypes();
				DebugStopwatch.StartStopWatch("Initalize Custom ExtendedContent");
				AssetBundleLoader.InitializeBundles();
				foreach (ExtendedLevel customExtendedLevel in PatchedContent.CustomExtendedLevels)
				{
					customExtendedLevel.SetLevelID();
				}
				string text = "LethalLevelLoader Loaded The Following ExtendedLevels:\n";
				foreach (ExtendedLevel extendedLevel in PatchedContent.ExtendedLevels)
				{
					text = text + (PatchedContent.ExtendedLevels.IndexOf(extendedLevel) + 1) + ". " + extendedLevel.SelectableLevel.PlanetName + " (" + extendedLevel.ContentType.ToString() + ")\n";
				}
				DebugHelper.Log(text, DebugType.User);
				text = "LethalLevelLoader Loaded The Following ExtendedDungeonFlows:\n";
				foreach (ExtendedDungeonFlow extendedDungeonFlow in PatchedContent.ExtendedDungeonFlows)
				{
					text = text + (PatchedContent.ExtendedDungeonFlows.IndexOf(extendedDungeonFlow) + 1) + ". " + extendedDungeonFlow.DungeonName + " (" + ((Object)extendedDungeonFlow.DungeonFlow).name + ") (" + extendedDungeonFlow.ContentType.ToString() + ")\n";
				}
				DebugHelper.Log(text, DebugType.User);
				DebugStopwatch.StartStopWatch("Restore Content");
				foreach (ExtendedLevel customExtendedLevel2 in PatchedContent.CustomExtendedLevels)
				{
					ContentRestorer.RestoreVanillaLevelAssetReferences(customExtendedLevel2);
				}
				foreach (ExtendedDungeonFlow customExtendedDungeonFlow in PatchedContent.CustomExtendedDungeonFlows)
				{
					ContentRestorer.RestoreVanillaDungeonAssetReferences(customExtendedDungeonFlow);
				}
				ContentRestorer.DestroyRestoredAssets();
				DebugStopwatch.StartStopWatch("Dynamic Risk Level");
				LevelManager.PopulateDynamicRiskLevelDictionary();
				LevelManager.AssignCalculatedRiskLevels();
				DebugStopwatch.StartStopWatch("Apply, Merge & Populate Content Tags");
				ContentTagParser.ApplyVanillaContentTags();
				ContentTagManager.MergeAllExtendedModTags();
				ContentTagManager.PopulateContentTagData();
				DebugHelper.DebugAllContentTags();
				ItemMa

plugins/LethalLevelLoaderCompanyFixer.dll

Decompiled 2 years ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using MonoMod.Utils;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("AmazingAssets.TerrainToMesh")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp-firstpass")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: IgnoresAccessChecksTo("ClientNetworkTransform")]
[assembly: IgnoresAccessChecksTo("DissonanceVoip")]
[assembly: IgnoresAccessChecksTo("Facepunch Transport for Netcode for GameObjects")]
[assembly: IgnoresAccessChecksTo("Facepunch.Steamworks.Win64")]
[assembly: IgnoresAccessChecksTo("Unity.AI.Navigation")]
[assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging")]
[assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging.DocCodeExamples")]
[assembly: IgnoresAccessChecksTo("Unity.Burst")]
[assembly: IgnoresAccessChecksTo("Unity.Burst.Unsafe")]
[assembly: IgnoresAccessChecksTo("Unity.Collections")]
[assembly: IgnoresAccessChecksTo("Unity.Collections.LowLevel.ILSupport")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem.ForUI")]
[assembly: IgnoresAccessChecksTo("Unity.Jobs")]
[assembly: IgnoresAccessChecksTo("Unity.Mathematics")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.Common")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.MetricTypes")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStats")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Component")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Configuration")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Implementation")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsReporting")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkProfiler.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkSolutionInterface")]
[assembly: IgnoresAccessChecksTo("Unity.Netcode.Components")]
[assembly: IgnoresAccessChecksTo("Unity.Netcode.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.Networking.Transport")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Csg")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.KdTree")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Poly2Tri")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Stl")]
[assembly: IgnoresAccessChecksTo("Unity.Profiling.Core")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.ShaderLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Config.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Authentication")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Analytics")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Configuration")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Device")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments.Internal")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Internal")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Networking")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Registration")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Scheduler")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Telemetry")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Threading")]
[assembly: IgnoresAccessChecksTo("Unity.Services.QoS")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Relay")]
[assembly: IgnoresAccessChecksTo("Unity.TextMeshPro")]
[assembly: IgnoresAccessChecksTo("Unity.Timeline")]
[assembly: IgnoresAccessChecksTo("Unity.VisualEffectGraph.Runtime")]
[assembly: IgnoresAccessChecksTo("UnityEngine.ARModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.NVIDIAModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UI")]
[assembly: AssemblyCompany("TestAccount666.LethalLevelLoaderCompanyFixer")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Fixes the 1.2.2 LethalLevelLoader bug")]
[assembly: AssemblyFileVersion("1.0.1.0")]
[assembly: AssemblyInformationalVersion("1.0.1")]
[assembly: AssemblyProduct("LethalLevelLoaderCompanyFixer")]
[assembly: AssemblyTitle("TestAccount666.LethalLevelLoaderCompanyFixer")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.1.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.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[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 LethalLevelLoaderCompanyFixer
{
	[BepInPlugin("TestAccount666.LethalLevelLoaderCompanyFixer", "LethalLevelLoaderCompanyFixer", "1.0.1")]
	public class LethalLevelLoaderCompanyFixer : BaseUnityPlugin
	{
		public static LethalLevelLoaderCompanyFixer Instance { get; private set; }

		internal static ManualLogSource Logger { get; private set; }

		internal static Harmony? Harmony { get; set; }

		private void Awake()
		{
			Logger = ((BaseUnityPlugin)this).Logger;
			Instance = this;
			Patch();
			Logger.LogInfo((object)"TestAccount666.LethalLevelLoaderCompanyFixer v1.0.1 has loaded!");
		}

		internal static void Patch()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			if (Harmony == null)
			{
				Harmony = new Harmony("TestAccount666.LethalLevelLoaderCompanyFixer");
			}
			Logger.LogDebug((object)"Patching...");
			Harmony.PatchAll();
			Logger.LogDebug((object)"Finished patching!");
		}

		internal static void Unpatch()
		{
			Logger.LogDebug((object)"Unpatching...");
			Harmony? harmony = Harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
			Logger.LogDebug((object)"Finished unpatching!");
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "TestAccount666.LethalLevelLoaderCompanyFixer";

		public const string PLUGIN_NAME = "LethalLevelLoaderCompanyFixer";

		public const string PLUGIN_VERSION = "1.0.1";
	}
}
namespace LethalLevelLoaderCompanyFixer.Patches
{
	[HarmonyPatch(typeof(Terminal))]
	public static class TerminalPatch
	{
		[HarmonyPatch("LoadNewNode")]
		[HarmonyPrefix]
		private static void LoadNewNodePrefix(Terminal __instance, TerminalNode node)
		{
			if ((Object)(object)node == (Object)null)
			{
				return;
			}
			string text = ((object)node).ToString();
			if (text.Contains("CompanyMoonroute"))
			{
				__instance.modifyingText = true;
				try
				{
					__instance.RunTerminalEvents(node);
				}
				catch (Exception ex)
				{
					Extensions.LogDetailed(ex, (string)null);
				}
				((Selectable)__instance.screenText).interactable = true;
				string text2;
				if (node.clearPreviousText)
				{
					text2 = "\n\n\n" + node.displayText;
				}
				else
				{
					string text3 = "\n\n" + __instance.screenText.text + "\n\n" + node.displayText;
					int num = text3.Length - 250;
					string text4 = text3;
					int num2 = Mathf.Clamp(num, 0, text3.Length);
					text2 = text4.Substring(num2, text4.Length - num2);
				}
				try
				{
					text2 = __instance.TextPostProcess(text2, node);
				}
				catch (Exception arg)
				{
					Debug.LogError((object)$"An error occured while post processing terminal text: {arg}");
				}
				__instance.screenText.text = text2;
				__instance.currentText = __instance.screenText.text;
				__instance.textAdded = 0;
				if (node.playSyncedClip != -1)
				{
					__instance.PlayTerminalAudioServerRpc(node.playSyncedClip);
				}
				else if ((Object)(object)node.playClip != (Object)null)
				{
					__instance.terminalAudio.PlayOneShot(node.playClip);
				}
				__instance.LoadTerminalImage(node);
				__instance.currentNode = node;
			}
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}

plugins/LethalLib/LethalLib.dll

Decompiled 2 years ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Cryptography;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using DunGen;
using DunGen.Graph;
using LethalLib.Extras;
using LethalLib.Modules;
using LethalLib.NetcodePatcher;
using Microsoft.CodeAnalysis;
using Mono.Cecil.Cil;
using MonoMod.Cil;
using MonoMod.RuntimeDetour;
using On;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.Audio;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("AmazingAssets.TerrainToMesh")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp-firstpass")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: IgnoresAccessChecksTo("ClientNetworkTransform")]
[assembly: IgnoresAccessChecksTo("DissonanceVoip")]
[assembly: IgnoresAccessChecksTo("Facepunch Transport for Netcode for GameObjects")]
[assembly: IgnoresAccessChecksTo("Facepunch.Steamworks.Win64")]
[assembly: IgnoresAccessChecksTo("Unity.AI.Navigation")]
[assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging")]
[assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging.DocCodeExamples")]
[assembly: IgnoresAccessChecksTo("Unity.Burst")]
[assembly: IgnoresAccessChecksTo("Unity.Burst.Unsafe")]
[assembly: IgnoresAccessChecksTo("Unity.Collections")]
[assembly: IgnoresAccessChecksTo("Unity.Collections.LowLevel.ILSupport")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem.ForUI")]
[assembly: IgnoresAccessChecksTo("Unity.Jobs")]
[assembly: IgnoresAccessChecksTo("Unity.Mathematics")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.Common")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.MetricTypes")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStats")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Component")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Configuration")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Implementation")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsReporting")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkProfiler.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkSolutionInterface")]
[assembly: IgnoresAccessChecksTo("Unity.Netcode.Components")]
[assembly: IgnoresAccessChecksTo("Unity.Netcode.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.Networking.Transport")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Csg")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.KdTree")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Poly2Tri")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Stl")]
[assembly: IgnoresAccessChecksTo("Unity.Profiling.Core")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.ShaderLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Config.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Authentication")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Analytics")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Configuration")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Device")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments.Internal")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Internal")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Networking")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Registration")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Scheduler")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Telemetry")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Threading")]
[assembly: IgnoresAccessChecksTo("Unity.Services.QoS")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Relay")]
[assembly: IgnoresAccessChecksTo("Unity.TextMeshPro")]
[assembly: IgnoresAccessChecksTo("Unity.Timeline")]
[assembly: IgnoresAccessChecksTo("Unity.VisualEffectGraph.Runtime")]
[assembly: IgnoresAccessChecksTo("UnityEngine.ARModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.NVIDIAModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UI")]
[assembly: AssemblyCompany("Evaisa")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Content-addition API for Lethal Company")]
[assembly: AssemblyFileVersion("0.15.1.0")]
[assembly: AssemblyInformationalVersion("0.15.1+f1b4929131592316f522453804d5586da787e9db")]
[assembly: AssemblyProduct("LethalLib")]
[assembly: AssemblyTitle("LethalLib")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/EvaisaDev/LethalLib")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
[module: NetcodePatchedAssembly]
internal class <Module>
{
	static <Module>()
	{
	}
}
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[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 LethalLib
{
	[BepInPlugin("evaisa.lethallib", "LethalLib", "0.15.1")]
	public class Plugin : BaseUnityPlugin
	{
		public const string ModGUID = "evaisa.lethallib";

		public const string ModName = "LethalLib";

		public const string ModVersion = "0.15.1";

		public static AssetBundle MainAssets;

		public static ManualLogSource logger;

		public static ConfigFile config;

		public static Plugin Instance;

		public static ConfigEntry<bool> extendedLogging;

		private void Awake()
		{
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Expected O, but got Unknown
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			Instance = this;
			config = ((BaseUnityPlugin)this).Config;
			logger = ((BaseUnityPlugin)this).Logger;
			((BaseUnityPlugin)this).Logger.LogInfo((object)"LethalLib loaded!!");
			extendedLogging = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ExtendedLogging", false, "Enable extended logging");
			MainAssets = AssetBundle.LoadFromFile(Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), "lethallib"));
			new ILHook((MethodBase)typeof(StackTrace).GetMethod("AddFrames", BindingFlags.Instance | BindingFlags.NonPublic), new Manipulator(IlHook));
			Enemies.Init();
			Items.Init();
			Unlockables.Init();
			MapObjects.Init();
			Dungeon.Init();
			Weathers.Init();
			Player.Init();
			Utilities.Init();
			NetworkPrefabs.Init();
		}

		private void IlHook(ILContext il)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			ILCursor val = new ILCursor(il);
			val.GotoNext(new Func<Instruction, bool>[1]
			{
				(Instruction x) => ILPatternMatchingExt.MatchCallvirt(x, (MethodBase)typeof(StackFrame).GetMethod("GetFileLineNumber", BindingFlags.Instance | BindingFlags.Public))
			});
			val.RemoveRange(2);
			val.EmitDelegate<Func<StackFrame, string>>((Func<StackFrame, string>)GetLineOrIL);
		}

		private static string GetLineOrIL(StackFrame instance)
		{
			int fileLineNumber = instance.GetFileLineNumber();
			if (fileLineNumber == -1 || fileLineNumber == 0)
			{
				return "IL_" + instance.GetILOffset().ToString("X4");
			}
			return fileLineNumber.ToString();
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "LethalLib";

		public const string PLUGIN_NAME = "LethalLib";

		public const string PLUGIN_VERSION = "0.15.1";
	}
}
namespace LethalLib.Modules
{
	public class ContentLoader
	{
		public class CustomContent
		{
			private string id = "";

			public string ID => id;

			public CustomContent(string id)
			{
				this.id = id;
			}
		}

		public class CustomItem : CustomContent
		{
			public Action<Item> registryCallback = delegate
			{
			};

			public string contentPath = "";

			internal Item item;

			public Item Item => item;

			public CustomItem(string id, string contentPath, Action<Item> registryCallback = null)
				: base(id)
			{
				this.contentPath = contentPath;
				if (registryCallback != null)
				{
					this.registryCallback = registryCallback;
				}
			}
		}

		public class ShopItem : CustomItem
		{
			public int initPrice;

			public string buyNode1Path;

			public string buyNode2Path;

			public string itemInfoPath;

			public void RemoveFromShop()
			{
				Items.RemoveShopItem(base.Item);
			}

			public void SetPrice(int price)
			{
				Items.UpdateShopItemPrice(base.Item, price);
			}

			public ShopItem(string id, string contentPath, int price = 0, string buyNode1Path = null, string buyNode2Path = null, string itemInfoPath = null, Action<Item> registryCallback = null)
				: base(id, contentPath, registryCallback)
			{
				initPrice = price;
				this.buyNode1Path = buyNode1Path;
				this.buyNode2Path = buyNode2Path;
				this.itemInfoPath = itemInfoPath;
			}
		}

		public class ScrapItem : CustomItem
		{
			public Dictionary<Levels.LevelTypes, int> levelRarities = new Dictionary<Levels.LevelTypes, int>();

			public Dictionary<string, int> customLevelRarities = new Dictionary<string, int>();

			public int Rarity => 0;

			public void RemoveFromLevels(Levels.LevelTypes levelFlags)
			{
				Items.RemoveScrapFromLevels(base.Item, levelFlags);
			}

			public ScrapItem(string id, string contentPath, int rarity, Levels.LevelTypes levelFlags = Levels.LevelTypes.None, string[] levelOverrides = null, Action<Item> registryCallback = null)
				: base(id, contentPath, registryCallback)
			{
				if (levelFlags != Levels.LevelTypes.None)
				{
					levelRarities.Add(levelFlags, rarity);
				}
				else if (levelOverrides != null)
				{
					foreach (string key in levelOverrides)
					{
						customLevelRarities.Add(key, rarity);
					}
				}
			}

			public ScrapItem(string id, string contentPath, Dictionary<Levels.LevelTypes, int>? levelRarities = null, Dictionary<string, int>? customLevelRarities = null, Action<Item> registryCallback = null)
				: base(id, contentPath, registryCallback)
			{
				if (levelRarities != null)
				{
					this.levelRarities = levelRarities;
				}
				if (customLevelRarities != null)
				{
					this.customLevelRarities = customLevelRarities;
				}
			}
		}

		public class Unlockable : CustomContent
		{
			public Action<UnlockableItem> registryCallback = delegate
			{
			};

			internal UnlockableItem unlockable;

			public string contentPath = "";

			public int initPrice;

			public string buyNode1Path;

			public string buyNode2Path;

			public string itemInfoPath;

			public StoreType storeType;

			public UnlockableItem UnlockableItem => unlockable;

			public void RemoveFromShop()
			{
				Unlockables.DisableUnlockable(UnlockableItem);
			}

			public void SetPrice(int price)
			{
				Unlockables.UpdateUnlockablePrice(UnlockableItem, price);
			}

			public Unlockable(string id, string contentPath, int price = 0, string buyNode1Path = null, string buyNode2Path = null, string itemInfoPath = null, StoreType storeType = StoreType.None, Action<UnlockableItem> registryCallback = null)
				: base(id)
			{
				this.contentPath = contentPath;
				if (registryCallback != null)
				{
					this.registryCallback = registryCallback;
				}
				initPrice = price;
				this.buyNode1Path = buyNode1Path;
				this.buyNode2Path = buyNode2Path;
				this.itemInfoPath = itemInfoPath;
				this.storeType = storeType;
			}
		}

		public class CustomEnemy : CustomContent
		{
			public Action<EnemyType> registryCallback = delegate
			{
			};

			public string contentPath = "";

			internal EnemyType enemy;

			public string infoNodePath;

			public string infoKeywordPath;

			public int rarity;

			public Levels.LevelTypes LevelTypes = Levels.LevelTypes.None;

			public string[] levelOverrides;

			public Enemies.SpawnType spawnType = (Enemies.SpawnType)(-1);

			public EnemyType Enemy => enemy;

			public void RemoveFromLevels(Levels.LevelTypes levelFlags)
			{
				Enemies.RemoveEnemyFromLevels(Enemy, levelFlags);
			}

			public CustomEnemy(string id, string contentPath, int rarity = 0, Levels.LevelTypes levelFlags = Levels.LevelTypes.None, Enemies.SpawnType spawnType = (Enemies.SpawnType)(-1), string[] levelOverrides = null, string infoNodePath = null, string infoKeywordPath = null, Action<EnemyType> registryCallback = null)
				: base(id)
			{
				this.contentPath = contentPath;
				if (registryCallback != null)
				{
					this.registryCallback = registryCallback;
				}
				this.infoNodePath = infoNodePath;
				this.infoKeywordPath = infoKeywordPath;
				this.rarity = rarity;
				LevelTypes = levelFlags;
				this.levelOverrides = levelOverrides;
				this.spawnType = spawnType;
			}
		}

		public class MapHazard : CustomContent
		{
			public Action<SpawnableMapObjectDef> registryCallback = delegate
			{
			};

			public string contentPath = "";

			internal SpawnableMapObjectDef hazard;

			public Func<SelectableLevel, AnimationCurve> spawnRateFunction;

			public Levels.LevelTypes LevelTypes = Levels.LevelTypes.None;

			public string[] levelOverrides;

			public SpawnableMapObjectDef Hazard => hazard;

			public void RemoveFromLevels(Levels.LevelTypes levelFlags = Levels.LevelTypes.None, string[] levelOverrides = null)
			{
				MapObjects.RemoveMapObject(Hazard, levelFlags, levelOverrides);
			}

			public MapHazard(string id, string contentPath, Levels.LevelTypes levelFlags = Levels.LevelTypes.None, string[] levelOverrides = null, Func<SelectableLevel, AnimationCurve> spawnRateFunction = null, Action<SpawnableMapObjectDef> registryCallback = null)
				: base(id)
			{
				this.contentPath = contentPath;
				if (registryCallback != null)
				{
					this.registryCallback = registryCallback;
				}
				LevelTypes = levelFlags;
				this.levelOverrides = levelOverrides;
				this.spawnRateFunction = spawnRateFunction;
			}
		}

		public class OutsideObject : CustomContent
		{
			public Action<SpawnableOutsideObjectDef> registryCallback = delegate
			{
			};

			public string contentPath = "";

			internal SpawnableOutsideObjectDef mapObject;

			public Func<SelectableLevel, AnimationCurve> spawnRateFunction;

			public Levels.LevelTypes LevelTypes = Levels.LevelTypes.None;

			public string[] levelOverrides;

			public SpawnableOutsideObjectDef MapObject => mapObject;

			public void RemoveFromLevels(Levels.LevelTypes levelFlags = Levels.LevelTypes.None, string[] levelOverrides = null)
			{
				MapObjects.RemoveOutsideObject(MapObject, levelFlags, levelOverrides);
			}

			public OutsideObject(string id, string contentPath, Levels.LevelTypes levelFlags = Levels.LevelTypes.None, string[] levelOverrides = null, Func<SelectableLevel, AnimationCurve> spawnRateFunction = null, Action<SpawnableOutsideObjectDef> registryCallback = null)
				: base(id)
			{
				this.contentPath = contentPath;
				if (registryCallback != null)
				{
					this.registryCallback = registryCallback;
				}
				LevelTypes = levelFlags;
				this.levelOverrides = levelOverrides;
				this.spawnRateFunction = spawnRateFunction;
			}
		}

		public PluginInfo modInfo;

		private AssetBundle modBundle;

		public Action<CustomContent, GameObject> prefabCallback = delegate
		{
		};

		public Dictionary<string, CustomContent> LoadedContent { get; } = new Dictionary<string, CustomContent>();


		public string modName => modInfo.Metadata.Name;

		public string modVersion => modInfo.Metadata.Version.ToString();

		public string modGUID => modInfo.Metadata.GUID;

		public ContentLoader(PluginInfo modInfo, AssetBundle modBundle, Action<CustomContent, GameObject> prefabCallback = null)
		{
			this.modInfo = modInfo;
			this.modBundle = modBundle;
			if (prefabCallback != null)
			{
				this.prefabCallback = prefabCallback;
			}
		}

		public ContentLoader Create(PluginInfo modInfo, AssetBundle modBundle, Action<CustomContent, GameObject> prefabCallback = null)
		{
			return new ContentLoader(modInfo, modBundle, prefabCallback);
		}

		public void Register(CustomContent content)
		{
			if (LoadedContent.ContainsKey(content.ID))
			{
				Debug.LogError((object)("[LethalLib] " + modName + " tried to register content with ID " + content.ID + " but it already exists!"));
				return;
			}
			if (content is CustomItem customItem)
			{
				Item val = (customItem.item = modBundle.LoadAsset<Item>(customItem.contentPath));
				NetworkPrefabs.RegisterNetworkPrefab(val.spawnPrefab);
				Utilities.FixMixerGroups(val.spawnPrefab);
				prefabCallback(customItem, val.spawnPrefab);
				customItem.registryCallback(val);
				if (content is ShopItem shopItem)
				{
					TerminalNode buyNode = null;
					TerminalNode buyNode2 = null;
					TerminalNode itemInfo = null;
					if (shopItem.buyNode1Path != null)
					{
						buyNode = modBundle.LoadAsset<TerminalNode>(shopItem.buyNode1Path);
					}
					if (shopItem.buyNode2Path != null)
					{
						buyNode2 = modBundle.LoadAsset<TerminalNode>(shopItem.buyNode2Path);
					}
					if (shopItem.itemInfoPath != null)
					{
						itemInfo = modBundle.LoadAsset<TerminalNode>(shopItem.itemInfoPath);
					}
					Items.RegisterShopItem(val, buyNode, buyNode2, itemInfo, shopItem.initPrice);
				}
				else if (content is ScrapItem scrapItem)
				{
					Items.RegisterScrap(val, scrapItem.levelRarities, scrapItem.customLevelRarities);
				}
				else
				{
					Items.RegisterItem(val);
				}
			}
			else if (content is Unlockable unlockable)
			{
				UnlockableItemDef unlockableItemDef = modBundle.LoadAsset<UnlockableItemDef>(unlockable.contentPath);
				if ((Object)(object)unlockableItemDef.unlockable.prefabObject != (Object)null)
				{
					NetworkPrefabs.RegisterNetworkPrefab(unlockableItemDef.unlockable.prefabObject);
					prefabCallback(content, unlockableItemDef.unlockable.prefabObject);
					Utilities.FixMixerGroups(unlockableItemDef.unlockable.prefabObject);
				}
				unlockable.unlockable = unlockableItemDef.unlockable;
				unlockable.registryCallback(unlockableItemDef.unlockable);
				TerminalNode buyNode3 = null;
				TerminalNode buyNode4 = null;
				TerminalNode itemInfo2 = null;
				if (unlockable.buyNode1Path != null)
				{
					buyNode3 = modBundle.LoadAsset<TerminalNode>(unlockable.buyNode1Path);
				}
				if (unlockable.buyNode2Path != null)
				{
					buyNode4 = modBundle.LoadAsset<TerminalNode>(unlockable.buyNode2Path);
				}
				if (unlockable.itemInfoPath != null)
				{
					itemInfo2 = modBundle.LoadAsset<TerminalNode>(unlockable.itemInfoPath);
				}
				Unlockables.RegisterUnlockable(unlockableItemDef, unlockable.storeType, buyNode3, buyNode4, itemInfo2, unlockable.initPrice);
			}
			else if (content is CustomEnemy customEnemy)
			{
				EnemyType val2 = modBundle.LoadAsset<EnemyType>(customEnemy.contentPath);
				NetworkPrefabs.RegisterNetworkPrefab(val2.enemyPrefab);
				Utilities.FixMixerGroups(val2.enemyPrefab);
				customEnemy.enemy = val2;
				prefabCallback(content, val2.enemyPrefab);
				customEnemy.registryCallback(val2);
				TerminalNode infoNode = null;
				TerminalKeyword infoKeyword = null;
				if (customEnemy.infoNodePath != null)
				{
					infoNode = modBundle.LoadAsset<TerminalNode>(customEnemy.infoNodePath);
				}
				if (customEnemy.infoKeywordPath != null)
				{
					infoKeyword = modBundle.LoadAsset<TerminalKeyword>(customEnemy.infoKeywordPath);
				}
				if (customEnemy.spawnType == (Enemies.SpawnType)(-1))
				{
					Enemies.RegisterEnemy(val2, customEnemy.rarity, customEnemy.LevelTypes, customEnemy.levelOverrides, infoNode, infoKeyword);
				}
				else
				{
					Enemies.RegisterEnemy(val2, customEnemy.rarity, customEnemy.LevelTypes, customEnemy.spawnType, customEnemy.levelOverrides, infoNode, infoKeyword);
				}
			}
			else if (content is MapHazard mapHazard)
			{
				SpawnableMapObjectDef spawnableMapObjectDef = (mapHazard.hazard = modBundle.LoadAsset<SpawnableMapObjectDef>(mapHazard.contentPath));
				NetworkPrefabs.RegisterNetworkPrefab(spawnableMapObjectDef.spawnableMapObject.prefabToSpawn);
				Utilities.FixMixerGroups(spawnableMapObjectDef.spawnableMapObject.prefabToSpawn);
				prefabCallback(content, spawnableMapObjectDef.spawnableMapObject.prefabToSpawn);
				mapHazard.registryCallback(spawnableMapObjectDef);
				MapObjects.RegisterMapObject(spawnableMapObjectDef, mapHazard.LevelTypes, mapHazard.levelOverrides, mapHazard.spawnRateFunction);
			}
			else if (content is OutsideObject outsideObject)
			{
				SpawnableOutsideObjectDef spawnableOutsideObjectDef = (outsideObject.mapObject = modBundle.LoadAsset<SpawnableOutsideObjectDef>(outsideObject.contentPath));
				NetworkPrefabs.RegisterNetworkPrefab(spawnableOutsideObjectDef.spawnableMapObject.spawnableObject.prefabToSpawn);
				Utilities.FixMixerGroups(spawnableOutsideObjectDef.spawnableMapObject.spawnableObject.prefabToSpawn);
				prefabCallback(content, spawnableOutsideObjectDef.spawnableMapObject.spawnableObject.prefabToSpawn);
				outsideObject.registryCallback(spawnableOutsideObjectDef);
				MapObjects.RegisterOutsideObject(spawnableOutsideObjectDef, outsideObject.LevelTypes, outsideObject.levelOverrides, outsideObject.spawnRateFunction);
			}
			LoadedContent.Add(content.ID, content);
		}

		public void RegisterAll(CustomContent[] content)
		{
			Plugin.logger.LogInfo((object)$"[LethalLib] {modName} is registering {content.Length} content items!");
			foreach (CustomContent content2 in content)
			{
				Register(content2);
			}
		}

		public void RegisterAll(List<CustomContent> content)
		{
			Plugin.logger.LogInfo((object)$"[LethalLib] {modName} is registering {content.Count} content items!");
			foreach (CustomContent item in content)
			{
				Register(item);
			}
		}
	}
	public class Dungeon
	{
		public class CustomDungeonArchetype
		{
			public DungeonArchetype archeType;

			public Levels.LevelTypes LevelTypes;

			public int lineIndex = -1;
		}

		public class CustomGraphLine
		{
			public GraphLine graphLine;

			public Levels.LevelTypes LevelTypes;
		}

		public class CustomDungeon
		{
			public int rarity;

			public DungeonFlow dungeonFlow;

			public Levels.LevelTypes LevelTypes;

			public string[] levelOverrides;

			public int dungeonIndex = -1;

			public AudioClip firstTimeDungeonAudio;
		}

		[CompilerGenerated]
		private static class <>O
		{
			public static hook_GenerateNewFloor <0>__RoundManager_GenerateNewFloor;

			public static hook_Start <1>__RoundManager_Start;
		}

		public static List<CustomDungeonArchetype> customDungeonArchetypes = new List<CustomDungeonArchetype>();

		public static List<CustomGraphLine> customGraphLines = new List<CustomGraphLine>();

		public static Dictionary<string, TileSet> extraTileSets = new Dictionary<string, TileSet>();

		public static Dictionary<string, GameObjectChance> extraRooms = new Dictionary<string, GameObjectChance>();

		public static List<CustomDungeon> customDungeons = new List<CustomDungeon>();

		public static void Init()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Expected O, but got Unknown
			object obj = <>O.<0>__RoundManager_GenerateNewFloor;
			if (obj == null)
			{
				hook_GenerateNewFloor val = RoundManager_GenerateNewFloor;
				<>O.<0>__RoundManager_GenerateNewFloor = val;
				obj = (object)val;
			}
			RoundManager.GenerateNewFloor += (hook_GenerateNewFloor)obj;
			object obj2 = <>O.<1>__RoundManager_Start;
			if (obj2 == null)
			{
				hook_Start val2 = RoundManager_Start;
				<>O.<1>__RoundManager_Start = val2;
				obj2 = (object)val2;
			}
			RoundManager.Start += (hook_Start)obj2;
		}

		private static void RoundManager_Start(orig_Start orig, RoundManager self)
		{
			orig.Invoke(self);
		}

		private static void RoundManager_GenerateNewFloor(orig_GenerateNewFloor orig, RoundManager self)
		{
			string name = ((Object)self.currentLevel).name;
			if (Enum.IsDefined(typeof(Levels.LevelTypes), name))
			{
				Levels.LevelTypes levelEnum = (Levels.LevelTypes)Enum.Parse(typeof(Levels.LevelTypes), name);
				int index = 0;
				self.dungeonGenerator.Generator.DungeonFlow.Lines.ForEach(delegate(GraphLine line)
				{
					foreach (CustomDungeonArchetype customDungeonArchetype in customDungeonArchetypes)
					{
						if (customDungeonArchetype.LevelTypes.HasFlag(levelEnum) && !line.DungeonArchetypes.Contains(customDungeonArchetype.archeType) && (customDungeonArchetype.lineIndex == -1 || customDungeonArchetype.lineIndex == index))
						{
							line.DungeonArchetypes.Add(customDungeonArchetype.archeType);
							if (Plugin.extendedLogging.Value)
							{
								Plugin.logger.LogInfo((object)("Added " + ((Object)customDungeonArchetype.archeType).name + " to " + name));
							}
						}
					}
					foreach (DungeonArchetype dungeonArchetype in line.DungeonArchetypes)
					{
						string name2 = ((Object)dungeonArchetype).name;
						if (extraTileSets.ContainsKey(name2))
						{
							TileSet val4 = extraTileSets[name2];
							if (!dungeonArchetype.TileSets.Contains(val4))
							{
								dungeonArchetype.TileSets.Add(val4);
								if (Plugin.extendedLogging.Value)
								{
									Plugin.logger.LogInfo((object)("Added " + ((Object)val4).name + " to " + name));
								}
							}
						}
						foreach (TileSet tileSet in dungeonArchetype.TileSets)
						{
							string name3 = ((Object)tileSet).name;
							if (extraRooms.ContainsKey(name3))
							{
								GameObjectChance item = extraRooms[name3];
								if (!tileSet.TileWeights.Weights.Contains(item))
								{
									tileSet.TileWeights.Weights.Add(item);
								}
							}
						}
					}
					index++;
				});
				foreach (CustomGraphLine customGraphLine in customGraphLines)
				{
					if (customGraphLine.LevelTypes.HasFlag(levelEnum) && !self.dungeonGenerator.Generator.DungeonFlow.Lines.Contains(customGraphLine.graphLine))
					{
						self.dungeonGenerator.Generator.DungeonFlow.Lines.Add(customGraphLine.graphLine);
					}
				}
			}
			orig.Invoke(self);
			NetworkManager val = Object.FindObjectOfType<NetworkManager>();
			RandomMapObject[] array = Object.FindObjectsOfType<RandomMapObject>();
			foreach (RandomMapObject val2 in array)
			{
				for (int j = 0; j < val2.spawnablePrefabs.Count; j++)
				{
					string prefabName = ((Object)val2.spawnablePrefabs[j]).name;
					NetworkPrefab val3 = ((IEnumerable<NetworkPrefab>)val.NetworkConfig.Prefabs.m_Prefabs).FirstOrDefault((Func<NetworkPrefab, bool>)((NetworkPrefab x) => ((Object)x.Prefab).name == prefabName));
					if (val3 != null && (Object)(object)val3.Prefab != (Object)(object)val2.spawnablePrefabs[j])
					{
						val2.spawnablePrefabs[j] = val3.Prefab;
					}
					else if (val3 == null)
					{
						Plugin.logger.LogError((object)("DungeonGeneration - Could not find network prefab (" + prefabName + ")! Make sure your assigned prefab is registered with the network manager, or named identically to the vanilla prefab you are referencing."));
					}
				}
			}
		}

		public static void AddArchetype(DungeonArchetype archetype, Levels.LevelTypes levelFlags, int lineIndex = -1)
		{
			CustomDungeonArchetype customDungeonArchetype = new CustomDungeonArchetype();
			customDungeonArchetype.archeType = archetype;
			customDungeonArchetype.LevelTypes = levelFlags;
			customDungeonArchetype.lineIndex = lineIndex;
			customDungeonArchetypes.Add(customDungeonArchetype);
		}

		public static void AddLine(GraphLine line, Levels.LevelTypes levelFlags)
		{
			CustomGraphLine customGraphLine = new CustomGraphLine();
			customGraphLine.graphLine = line;
			customGraphLine.LevelTypes = levelFlags;
			customGraphLines.Add(customGraphLine);
		}

		public static void AddLine(DungeonGraphLineDef line, Levels.LevelTypes levelFlags)
		{
			AddLine(line.graphLine, levelFlags);
		}

		public static void AddTileSet(TileSet set, string archetypeName)
		{
			extraTileSets.Add(archetypeName, set);
		}

		public static void AddRoom(GameObjectChance room, string tileSetName)
		{
			extraRooms.Add(tileSetName, room);
		}

		public static void AddRoom(GameObjectChanceDef room, string tileSetName)
		{
			AddRoom(room.gameObjectChance, tileSetName);
		}

		public static void AddDungeon(DungeonDef dungeon, Levels.LevelTypes levelFlags)
		{
			AddDungeon(dungeon.dungeonFlow, dungeon.rarity, levelFlags, dungeon.firstTimeDungeonAudio);
		}

		public static void AddDungeon(DungeonDef dungeon, Levels.LevelTypes levelFlags, string[] levelOverrides)
		{
			AddDungeon(dungeon.dungeonFlow, dungeon.rarity, levelFlags, levelOverrides, dungeon.firstTimeDungeonAudio);
		}

		public static void AddDungeon(DungeonFlow dungeon, int rarity, Levels.LevelTypes levelFlags, AudioClip firstTimeDungeonAudio = null)
		{
			customDungeons.Add(new CustomDungeon
			{
				dungeonFlow = dungeon,
				rarity = rarity,
				LevelTypes = levelFlags,
				firstTimeDungeonAudio = firstTimeDungeonAudio
			});
		}

		public static void AddDungeon(DungeonFlow dungeon, int rarity, Levels.LevelTypes levelFlags, string[] levelOverrides = null, AudioClip firstTimeDungeonAudio = null)
		{
			customDungeons.Add(new CustomDungeon
			{
				dungeonFlow = dungeon,
				rarity = rarity,
				LevelTypes = levelFlags,
				firstTimeDungeonAudio = firstTimeDungeonAudio,
				levelOverrides = levelOverrides
			});
		}
	}
	public class Enemies
	{
		public struct EnemyAssetInfo
		{
			public EnemyType EnemyAsset;

			public TerminalKeyword keyword;
		}

		public enum SpawnType
		{
			Default,
			Daytime,
			Outside
		}

		public class SpawnableEnemy
		{
			public EnemyType enemy;

			public SpawnType spawnType;

			public TerminalNode terminalNode;

			public TerminalKeyword infoKeyword;

			public string modName;

			public int rarity;

			public Levels.LevelTypes spawnLevels;

			public string[] spawnLevelOverrides;

			public Dictionary<string, int> customLevelRarities = new Dictionary<string, int>();

			public Dictionary<Levels.LevelTypes, int> levelRarities = new Dictionary<Levels.LevelTypes, int>();

			public SpawnableEnemy(EnemyType enemy, int rarity, Levels.LevelTypes spawnLevels, SpawnType spawnType, string[] spawnLevelOverrides = null)
			{
				this.enemy = enemy;
				this.spawnLevels = spawnLevels;
				this.spawnType = spawnType;
				if (spawnLevelOverrides != null)
				{
					foreach (string levelName in spawnLevelOverrides)
					{
						customLevelRarities.Add(Levels.Compatibility.GetLLLNameOfLevel(levelName), rarity);
					}
				}
				if (spawnLevels == Levels.LevelTypes.None)
				{
					return;
				}
				foreach (Levels.LevelTypes value in Enum.GetValues(typeof(Levels.LevelTypes)))
				{
					if (spawnLevels.HasFlag(value))
					{
						levelRarities.Add(value, rarity);
					}
				}
			}

			public SpawnableEnemy(EnemyType enemy, SpawnType spawnType, Dictionary<Levels.LevelTypes, int>? levelRarities = null, Dictionary<string, int>? customLevelRarities = null)
			{
				this.enemy = enemy;
				this.spawnType = spawnType;
				if (levelRarities != null)
				{
					this.levelRarities = levelRarities;
				}
				if (customLevelRarities != null)
				{
					this.customLevelRarities = Levels.Compatibility.LLLifyLevelRarityDictionary(customLevelRarities);
				}
			}
		}

		[CompilerGenerated]
		private static class <>O
		{
			public static hook_Awake <0>__RegisterLevelEnemies;

			public static hook_Start <1>__Terminal_Start;

			public static hook_Start <2>__QuickMenuManager_Start;

			public static hook_Start <3>__RegisterLevelEnemiesforLLL_RoundManager_Start;

			public static hook_Start <4>__RegisterLevelEnemiesforLE_Terminal_Start;
		}

		private static List<SelectableLevel> levelsAlreadyAddedTo = new List<SelectableLevel>();

		private static bool addedToDebug = false;

		public static Terminal terminal;

		public static List<EnemyAssetInfo> enemyAssetInfos = new List<EnemyAssetInfo>();

		public static List<SpawnableEnemy> spawnableEnemies = new List<SpawnableEnemy>();

		public static void Init()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Expected O, but got Unknown
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Expected O, but got Unknown
			object obj = <>O.<0>__RegisterLevelEnemies;
			if (obj == null)
			{
				hook_Awake val = RegisterLevelEnemies;
				<>O.<0>__RegisterLevelEnemies = val;
				obj = (object)val;
			}
			StartOfRound.Awake += (hook_Awake)obj;
			object obj2 = <>O.<1>__Terminal_Start;
			if (obj2 == null)
			{
				hook_Start val2 = Terminal_Start;
				<>O.<1>__Terminal_Start = val2;
				obj2 = (object)val2;
			}
			Terminal.Start += (hook_Start)obj2;
			object obj3 = <>O.<2>__QuickMenuManager_Start;
			if (obj3 == null)
			{
				hook_Start val3 = QuickMenuManager_Start;
				<>O.<2>__QuickMenuManager_Start = val3;
				obj3 = (object)val3;
			}
			QuickMenuManager.Start += (hook_Start)obj3;
		}

		private static void QuickMenuManager_Start(orig_Start orig, QuickMenuManager self)
		{
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Expected O, but got Unknown
			if (addedToDebug)
			{
				orig.Invoke(self);
				return;
			}
			SelectableLevel testAllEnemiesLevel = self.testAllEnemiesLevel;
			List<SpawnableEnemyWithRarity> enemies = testAllEnemiesLevel.Enemies;
			List<SpawnableEnemyWithRarity> daytimeEnemies = testAllEnemiesLevel.DaytimeEnemies;
			List<SpawnableEnemyWithRarity> outsideEnemies = testAllEnemiesLevel.OutsideEnemies;
			foreach (SpawnableEnemy spawnableEnemy in spawnableEnemies)
			{
				if (enemies.All((SpawnableEnemyWithRarity x) => (Object)(object)x.enemyType == (Object)(object)spawnableEnemy.enemy))
				{
					continue;
				}
				SpawnableEnemyWithRarity item = new SpawnableEnemyWithRarity
				{
					enemyType = spawnableEnemy.enemy,
					rarity = spawnableEnemy.rarity
				};
				switch (spawnableEnemy.spawnType)
				{
				case SpawnType.Default:
					if (!enemies.Any((SpawnableEnemyWithRarity x) => (Object)(object)x.enemyType == (Object)(object)spawnableEnemy.enemy))
					{
						enemies.Add(item);
					}
					break;
				case SpawnType.Daytime:
					if (!daytimeEnemies.Any((SpawnableEnemyWithRarity x) => (Object)(object)x.enemyType == (Object)(object)spawnableEnemy.enemy))
					{
						daytimeEnemies.Add(item);
					}
					break;
				case SpawnType.Outside:
					if (!outsideEnemies.Any((SpawnableEnemyWithRarity x) => (Object)(object)x.enemyType == (Object)(object)spawnableEnemy.enemy))
					{
						outsideEnemies.Add(item);
					}
					break;
				}
				if (Plugin.extendedLogging.Value)
				{
					Plugin.logger.LogInfo((object)$"Added {spawnableEnemy.enemy.enemyName} to DebugList [{spawnableEnemy.spawnType}]");
				}
			}
			addedToDebug = true;
			orig.Invoke(self);
		}

		private static void Terminal_Start(orig_Start orig, Terminal self)
		{
			//IL_0252: Unknown result type (might be due to invalid IL or missing references)
			//IL_0257: Unknown result type (might be due to invalid IL or missing references)
			//IL_0264: Unknown result type (might be due to invalid IL or missing references)
			//IL_027a: Expected O, but got Unknown
			terminal = self;
			TerminalKeyword val = self.terminalNodes.allKeywords.First((TerminalKeyword keyword) => keyword.word == "info");
			List<string> list = new List<string>();
			foreach (SpawnableEnemy spawnableEnemy in spawnableEnemies)
			{
				if (list.Contains(spawnableEnemy.enemy.enemyName))
				{
					Plugin.logger.LogInfo((object)("Skipping " + spawnableEnemy.enemy.enemyName + " because it was already added"));
					continue;
				}
				if ((Object)(object)spawnableEnemy.terminalNode == (Object)null)
				{
					spawnableEnemy.terminalNode = ScriptableObject.CreateInstance<TerminalNode>();
					spawnableEnemy.terminalNode.displayText = spawnableEnemy.enemy.enemyName + "\n\nDanger level: Unknown\n\n[No information about this creature was found.]\n\n";
					spawnableEnemy.terminalNode.clearPreviousText = true;
					spawnableEnemy.terminalNode.maxCharactersToType = 35;
					spawnableEnemy.terminalNode.creatureName = spawnableEnemy.enemy.enemyName;
				}
				if (self.enemyFiles.Any((TerminalNode x) => x.creatureName == spawnableEnemy.terminalNode.creatureName))
				{
					Plugin.logger.LogInfo((object)("Skipping " + spawnableEnemy.enemy.enemyName + " because it was already added"));
					continue;
				}
				TerminalKeyword keyword2 = (((Object)(object)spawnableEnemy.infoKeyword != (Object)null) ? spawnableEnemy.infoKeyword : TerminalUtils.CreateTerminalKeyword(spawnableEnemy.terminalNode.creatureName.ToLowerInvariant().Replace(" ", "-"), isVerb: false, null, null, val));
				keyword2.defaultVerb = val;
				List<TerminalKeyword> list2 = self.terminalNodes.allKeywords.ToList();
				if (!list2.Any((TerminalKeyword x) => x.word == keyword2.word))
				{
					list2.Add(keyword2);
					self.terminalNodes.allKeywords = list2.ToArray();
				}
				List<CompatibleNoun> list3 = val.compatibleNouns.ToList();
				if (!list3.Any((CompatibleNoun x) => x.noun.word == keyword2.word))
				{
					list3.Add(new CompatibleNoun
					{
						noun = keyword2,
						result = spawnableEnemy.terminalNode
					});
				}
				val.compatibleNouns = list3.ToArray();
				spawnableEnemy.terminalNode.creatureFileID = self.enemyFiles.Count;
				self.enemyFiles.Add(spawnableEnemy.terminalNode);
				ScanNodeProperties[] componentsInChildren = spawnableEnemy.enemy.enemyPrefab.GetComponentsInChildren<ScanNodeProperties>();
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					componentsInChildren[i].creatureScanID = spawnableEnemy.terminalNode.creatureFileID;
				}
				EnemyAssetInfo enemyAssetInfo = default(EnemyAssetInfo);
				enemyAssetInfo.EnemyAsset = spawnableEnemy.enemy;
				enemyAssetInfo.keyword = keyword2;
				EnemyAssetInfo item = enemyAssetInfo;
				enemyAssetInfos.Add(item);
			}
			orig.Invoke(self);
		}

		private static void RegisterLevelEnemies(orig_Awake orig, StartOfRound self)
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Expected O, but got Unknown
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Expected O, but got Unknown
			orig.Invoke(self);
			RegisterLethalLibEnemiesForAllLevels();
			if (Chainloader.PluginInfos.ContainsKey("imabatby.lethallevelloader") || Chainloader.PluginInfos.ContainsKey("iambatby.lethallevelloader"))
			{
				object obj = <>O.<3>__RegisterLevelEnemiesforLLL_RoundManager_Start;
				if (obj == null)
				{
					hook_Start val = RegisterLevelEnemiesforLLL_RoundManager_Start;
					<>O.<3>__RegisterLevelEnemiesforLLL_RoundManager_Start = val;
					obj = (object)val;
				}
				RoundManager.Start += (hook_Start)obj;
			}
			if (Chainloader.PluginInfos.ContainsKey("LethalExpansion"))
			{
				object obj2 = <>O.<4>__RegisterLevelEnemiesforLE_Terminal_Start;
				if (obj2 == null)
				{
					hook_Start val2 = RegisterLevelEnemiesforLE_Terminal_Start;
					<>O.<4>__RegisterLevelEnemiesforLE_Terminal_Start = val2;
					obj2 = (object)val2;
				}
				Terminal.Start += (hook_Start)obj2;
			}
		}

		private static void RegisterLevelEnemiesforLLL_RoundManager_Start(orig_Start orig, RoundManager self)
		{
			orig.Invoke(self);
			RegisterLethalLibEnemiesForAllLevels();
		}

		private static void RegisterLevelEnemiesforLE_Terminal_Start(orig_Start orig, Terminal self)
		{
			orig.Invoke(self);
			RegisterLethalLibEnemiesForAllLevels();
		}

		private static void RegisterLethalLibEnemiesForAllLevels()
		{
			SelectableLevel[] levels = StartOfRound.Instance.levels;
			foreach (SelectableLevel val in levels)
			{
				if (levelsAlreadyAddedTo.Contains(val))
				{
					continue;
				}
				foreach (SpawnableEnemy spawnableEnemy in spawnableEnemies)
				{
					AddEnemyToLevel(spawnableEnemy, val);
				}
				levelsAlreadyAddedTo.Add(val);
			}
		}

		private static void AddEnemyToLevel(SpawnableEnemy spawnableEnemy, SelectableLevel level)
		{
			//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: Expected O, but got Unknown
			SpawnableEnemy spawnableEnemy2 = spawnableEnemy;
			string text = ((Object)level).name;
			bool flag = spawnableEnemy2.levelRarities.ContainsKey(Levels.LevelTypes.All) || (spawnableEnemy2.customLevelRarities != null && spawnableEnemy2.customLevelRarities.ContainsKey(text));
			if (spawnableEnemy2.levelRarities.ContainsKey(Levels.LevelTypes.Modded) && !Enum.IsDefined(typeof(Levels.LevelTypes), text))
			{
				flag = true;
			}
			Levels.LevelTypes levelTypes = Levels.LevelTypes.None;
			bool flag2 = false;
			if (Enum.IsDefined(typeof(Levels.LevelTypes), text))
			{
				levelTypes = (Levels.LevelTypes)Enum.Parse(typeof(Levels.LevelTypes), text);
				flag2 = true;
			}
			else
			{
				text = Levels.Compatibility.GetLLLNameOfLevel(text);
			}
			if (!(flag2 || flag))
			{
				return;
			}
			Levels.LevelTypes key = (flag ? Levels.LevelTypes.All : levelTypes);
			if (!flag && !spawnableEnemy2.levelRarities.ContainsKey(key))
			{
				return;
			}
			int num = 0;
			if (flag2 && spawnableEnemy2.levelRarities.ContainsKey(levelTypes))
			{
				num = spawnableEnemy2.levelRarities[levelTypes];
			}
			else if (!flag2 && spawnableEnemy2.customLevelRarities != null && spawnableEnemy2.customLevelRarities.ContainsKey(text))
			{
				num = spawnableEnemy2.customLevelRarities[text];
			}
			else if (!flag2 && spawnableEnemy2.levelRarities.ContainsKey(Levels.LevelTypes.Modded))
			{
				num = spawnableEnemy2.levelRarities[Levels.LevelTypes.Modded];
			}
			else if (spawnableEnemy2.levelRarities.ContainsKey(Levels.LevelTypes.All))
			{
				num = spawnableEnemy2.levelRarities[Levels.LevelTypes.All];
			}
			SpawnableEnemyWithRarity item = new SpawnableEnemyWithRarity
			{
				enemyType = spawnableEnemy2.enemy,
				rarity = num
			};
			switch (spawnableEnemy2.spawnType)
			{
			case SpawnType.Default:
				if (!level.Enemies.Any((SpawnableEnemyWithRarity x) => (Object)(object)x.enemyType == (Object)(object)spawnableEnemy2.enemy))
				{
					level.Enemies.Add(item);
					if (Plugin.extendedLogging.Value)
					{
						Plugin.logger.LogInfo((object)$"To {text} added {((Object)spawnableEnemy2.enemy).name} with weight {num} and SpawnType [Default]");
					}
				}
				break;
			case SpawnType.Daytime:
				if (!level.DaytimeEnemies.Any((SpawnableEnemyWithRarity x) => (Object)(object)x.enemyType == (Object)(object)spawnableEnemy2.enemy))
				{
					level.DaytimeEnemies.Add(item);
					if (Plugin.extendedLogging.Value)
					{
						Plugin.logger.LogInfo((object)$"To {text} added {((Object)spawnableEnemy2.enemy).name} with weight {num} andSpawnType [Daytime]");
					}
				}
				break;
			case SpawnType.Outside:
				if (!level.OutsideEnemies.Any((SpawnableEnemyWithRarity x) => (Object)(object)x.enemyType == (Object)(object)spawnableEnemy2.enemy))
				{
					level.OutsideEnemies.Add(item);
					if (Plugin.extendedLogging.Value)
					{
						Plugin.logger.LogInfo((object)$"To {text} added {((Object)spawnableEnemy2.enemy).name} with weight {num} and SpawnType [Outside]");
					}
				}
				break;
			}
		}

		public static void RegisterEnemy(EnemyType enemy, int rarity, Levels.LevelTypes levelFlags, SpawnType spawnType, TerminalNode infoNode = null, TerminalKeyword infoKeyword = null)
		{
			RegisterEnemy(enemy, rarity, levelFlags, spawnType, null, infoNode, infoKeyword);
		}

		public static void RegisterEnemy(EnemyType enemy, int rarity, Levels.LevelTypes levelFlags, SpawnType spawnType, string[] spawnLevelOverrides = null, TerminalNode infoNode = null, TerminalKeyword infoKeyword = null)
		{
			EnemyType enemy2 = enemy;
			EnemyNullCheck(enemy2);
			SpawnableEnemy spawnableEnemy = spawnableEnemies.FirstOrDefault((SpawnableEnemy x) => (Object)(object)x.enemy == (Object)(object)enemy2 && x.spawnType == spawnType);
			if (spawnableEnemy != null)
			{
				if (levelFlags != Levels.LevelTypes.None)
				{
					spawnableEnemy.levelRarities.Add(levelFlags, rarity);
				}
				if (spawnLevelOverrides != null)
				{
					foreach (string levelName in spawnLevelOverrides)
					{
						spawnableEnemy.customLevelRarities.Add(Levels.Compatibility.GetLLLNameOfLevel(levelName), rarity);
					}
				}
			}
			else
			{
				spawnableEnemy = new SpawnableEnemy(enemy2, rarity, levelFlags, spawnType, spawnLevelOverrides);
				spawnableEnemy.terminalNode = infoNode;
				spawnableEnemy.infoKeyword = infoKeyword;
				FinalizeRegisterEnemy(spawnableEnemy);
			}
		}

		public static void RegisterEnemy(EnemyType enemy, SpawnType spawnType, Dictionary<Levels.LevelTypes, int>? levelRarities = null, Dictionary<string, int>? customLevelRarities = null, TerminalNode infoNode = null, TerminalKeyword infoKeyword = null)
		{
			EnemyType enemy2 = enemy;
			EnemyNullCheck(enemy2);
			SpawnableEnemy spawnableEnemy = spawnableEnemies.FirstOrDefault((SpawnableEnemy x) => (Object)(object)x.enemy == (Object)(object)enemy2 && x.spawnType == spawnType);
			if (spawnableEnemy != null)
			{
				if (levelRarities != null)
				{
					foreach (KeyValuePair<Levels.LevelTypes, int> levelRarity in levelRarities)
					{
						spawnableEnemy.levelRarities.Add(levelRarity.Key, levelRarity.Value);
					}
				}
				if (customLevelRarities == null)
				{
					return;
				}
				{
					foreach (KeyValuePair<string, int> customLevelRarity in customLevelRarities)
					{
						spawnableEnemy.customLevelRarities.Add(Levels.Compatibility.GetLLLNameOfLevel(customLevelRarity.Key), customLevelRarity.Value);
					}
					return;
				}
			}
			spawnableEnemy = new SpawnableEnemy(enemy2, spawnType, levelRarities, customLevelRarities);
			spawnableEnemy.terminalNode = infoNode;
			spawnableEnemy.infoKeyword = infoKeyword;
			FinalizeRegisterEnemy(spawnableEnemy);
		}

		private static void FinalizeRegisterEnemy(SpawnableEnemy spawnableEnemy)
		{
			string name = Assembly.GetCallingAssembly().GetName().Name;
			spawnableEnemy.modName = name;
			if (spawnableEnemy.enemy.enemyPrefab == null)
			{
				throw new NullReferenceException("Cannot register enemy '" + spawnableEnemy.enemy.enemyName + "', because enemy.enemyPrefab is null!");
			}
			EnemyAICollisionDetect[] componentsInChildren = spawnableEnemy.enemy.enemyPrefab.GetComponentsInChildren<EnemyAICollisionDetect>();
			foreach (EnemyAICollisionDetect val in componentsInChildren)
			{
				if (val.mainScript == null)
				{
					Plugin.logger.LogWarning((object)("An Enemy AI Collision Detect Script on GameObject '" + ((Object)((Component)val).gameObject).name + "' of enemy '" + spawnableEnemy.enemy.enemyName + "' does not reference a 'Main Script', and could cause Null Reference Exceptions."));
				}
			}
			spawnableEnemies.Add(spawnableEnemy);
		}

		private static void EnemyNullCheck(EnemyType enemy)
		{
			if (enemy == null)
			{
				throw new ArgumentNullException("enemy", "The first argument of RegisterEnemy was null!");
			}
		}

		public static void RegisterEnemy(EnemyType enemy, int rarity, Levels.LevelTypes levelFlags, TerminalNode infoNode = null, TerminalKeyword infoKeyword = null)
		{
			EnemyNullCheck(enemy);
			SpawnType spawnType = (enemy.isDaytimeEnemy ? SpawnType.Daytime : (enemy.isOutsideEnemy ? SpawnType.Outside : SpawnType.Default));
			RegisterEnemy(enemy, rarity, levelFlags, spawnType, null, infoNode, infoKeyword);
		}

		public static void RegisterEnemy(EnemyType enemy, int rarity, Levels.LevelTypes levelFlags, string[] spawnLevelOverrides = null, TerminalNode infoNode = null, TerminalKeyword infoKeyword = null)
		{
			EnemyNullCheck(enemy);
			SpawnType spawnType = (enemy.isDaytimeEnemy ? SpawnType.Daytime : (enemy.isOutsideEnemy ? SpawnType.Outside : SpawnType.Default));
			RegisterEnemy(enemy, rarity, levelFlags, spawnType, spawnLevelOverrides, infoNode, infoKeyword);
		}

		public static void RegisterEnemy(EnemyType enemy, Dictionary<Levels.LevelTypes, int>? levelRarities = null, Dictionary<string, int>? customLevelRarities = null, TerminalNode infoNode = null, TerminalKeyword infoKeyword = null)
		{
			EnemyNullCheck(enemy);
			SpawnType spawnType = (enemy.isDaytimeEnemy ? SpawnType.Daytime : (enemy.isOutsideEnemy ? SpawnType.Outside : SpawnType.Default));
			RegisterEnemy(enemy, spawnType, levelRarities, customLevelRarities, infoNode, infoKeyword);
		}

		public static void RemoveEnemyFromLevels(EnemyType enemyType, Levels.LevelTypes levelFlags = Levels.LevelTypes.None, string[] levelOverrides = null)
		{
			EnemyType enemyType2 = enemyType;
			if (!((Object)(object)StartOfRound.Instance != (Object)null))
			{
				return;
			}
			SelectableLevel[] levels = StartOfRound.Instance.levels;
			foreach (SelectableLevel val in levels)
			{
				string name = ((Object)val).name;
				if (!Enum.IsDefined(typeof(Levels.LevelTypes), name))
				{
					name = Levels.Compatibility.GetLLLNameOfLevel(name);
				}
				bool flag = levelFlags.HasFlag(Levels.LevelTypes.All) || (levelOverrides?.Any((string item) => Levels.Compatibility.GetLLLNameOfLevel(item).ToLowerInvariant() == name.ToLowerInvariant()) ?? false);
				if (levelFlags.HasFlag(Levels.LevelTypes.Modded) && !Enum.IsDefined(typeof(Levels.LevelTypes), name))
				{
					flag = true;
				}
				if (!(Enum.IsDefined(typeof(Levels.LevelTypes), name) || flag))
				{
					continue;
				}
				Levels.LevelTypes levelTypes = (flag ? Levels.LevelTypes.All : ((Levels.LevelTypes)Enum.Parse(typeof(Levels.LevelTypes), name)));
				if (flag || levelFlags.HasFlag(levelTypes))
				{
					List<SpawnableEnemyWithRarity> enemies = val.Enemies;
					List<SpawnableEnemyWithRarity> daytimeEnemies = val.DaytimeEnemies;
					List<SpawnableEnemyWithRarity> outsideEnemies = val.OutsideEnemies;
					enemies.RemoveAll((SpawnableEnemyWithRarity x) => (Object)(object)x.enemyType == (Object)(object)enemyType2);
					daytimeEnemies.RemoveAll((SpawnableEnemyWithRarity x) => (Object)(object)x.enemyType == (Object)(object)enemyType2);
					outsideEnemies.RemoveAll((SpawnableEnemyWithRarity x) => (Object)(object)x.enemyType == (Object)(object)enemyType2);
					if (Plugin.extendedLogging.Value)
					{
						Plugin.logger.LogInfo((object)("Removed Enemy " + ((Object)enemyType2).name + " from Level " + name));
					}
				}
			}
		}
	}
	public class Items
	{
		public struct ItemSaveOrderData
		{
			public int itemId;

			public string itemName;

			public string assetName;
		}

		public struct BuyableItemAssetInfo
		{
			public Item itemAsset;

			public TerminalKeyword keyword;
		}

		public class ScrapItem
		{
			public Item item;

			public Item origItem;

			public int rarity;

			public Levels.LevelTypes spawnLevels;

			public string[] spawnLevelOverrides;

			public string modName = "Unknown";

			public Dictionary<string, int> customLevelRarities = new Dictionary<string, int>();

			public Dictionary<Levels.LevelTypes, int> levelRarities = new Dictionary<Levels.LevelTypes, int>();

			public ScrapItem(Item item, int rarity, Levels.LevelTypes spawnLevels = Levels.LevelTypes.None, string[] spawnLevelOverrides = null)
			{
				//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
				origItem = item;
				if (!item.isScrap)
				{
					item = item.Clone<Item>();
					item.isScrap = true;
					if (item.maxValue == 0 && item.minValue == 0)
					{
						item.minValue = 40;
						item.maxValue = 100;
					}
					else if (item.maxValue == 0)
					{
						item.maxValue = item.minValue * 2;
					}
					else if (item.minValue == 0)
					{
						item.minValue = item.maxValue / 2;
					}
					GameObject val = NetworkPrefabs.CloneNetworkPrefab(item.spawnPrefab);
					if ((Object)(object)val.GetComponent<GrabbableObject>() != (Object)null)
					{
						val.GetComponent<GrabbableObject>().itemProperties = item;
					}
					if ((Object)(object)val.GetComponentInChildren<ScanNodeProperties>() == (Object)null)
					{
						GameObject obj = Object.Instantiate<GameObject>(scanNodePrefab, val.transform);
						((Object)obj).name = "ScanNode";
						obj.transform.localPosition = new Vector3(0f, 0f, 0f);
						obj.GetComponent<ScanNodeProperties>().headerText = item.itemName;
					}
					item.spawnPrefab = val;
				}
				this.item = item;
				if (spawnLevelOverrides != null)
				{
					foreach (string levelName in spawnLevelOverrides)
					{
						customLevelRarities.Add(Levels.Compatibility.GetLLLNameOfLevel(levelName), rarity);
					}
				}
				if (spawnLevels == Levels.LevelTypes.None)
				{
					return;
				}
				foreach (Levels.LevelTypes value in Enum.GetValues(typeof(Levels.LevelTypes)))
				{
					if (spawnLevels.HasFlag(value))
					{
						levelRarities.Add(value, rarity);
					}
				}
			}

			public ScrapItem(Item item, Dictionary<Levels.LevelTypes, int>? levelRarities = null, Dictionary<string, int>? customLevelRarities = null)
			{
				//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
				origItem = item;
				if (!item.isScrap)
				{
					item = item.Clone<Item>();
					item.isScrap = true;
					if (item.maxValue == 0 && item.minValue == 0)
					{
						item.minValue = 40;
						item.maxValue = 100;
					}
					else if (item.maxValue == 0)
					{
						item.maxValue = item.minValue * 2;
					}
					else if (item.minValue == 0)
					{
						item.minValue = item.maxValue / 2;
					}
					GameObject val = NetworkPrefabs.CloneNetworkPrefab(item.spawnPrefab);
					if ((Object)(object)val.GetComponent<GrabbableObject>() != (Object)null)
					{
						val.GetComponent<GrabbableObject>().itemProperties = item;
					}
					if ((Object)(object)val.GetComponentInChildren<ScanNodeProperties>() == (Object)null)
					{
						GameObject obj = Object.Instantiate<GameObject>(scanNodePrefab, val.transform);
						((Object)obj).name = "ScanNode";
						obj.transform.localPosition = new Vector3(0f, 0f, 0f);
						obj.GetComponent<ScanNodeProperties>().headerText = item.itemName;
					}
					item.spawnPrefab = val;
				}
				this.item = item;
				if (customLevelRarities != null)
				{
					this.customLevelRarities = Levels.Compatibility.LLLifyLevelRarityDictionary(customLevelRarities);
				}
				if (levelRarities != null)
				{
					this.levelRarities = levelRarities;
				}
			}
		}

		public class PlainItem
		{
			public Item item;

			public string modName;

			public PlainItem(Item item)
			{
				this.item = item;
			}
		}

		public class ShopItem
		{
			public Item item;

			public Item origItem;

			public TerminalNode buyNode1;

			public TerminalNode buyNode2;

			public TerminalNode itemInfo;

			public bool wasRemoved;

			public int price;

			public string modName;

			public ShopItem(Item item, TerminalNode buyNode1 = null, TerminalNode buyNode2 = null, TerminalNode itemInfo = null, int price = 0)
			{
				origItem = item;
				this.item = item;
				this.price = price;
				if ((Object)(object)buyNode1 != (Object)null)
				{
					this.buyNode1 = buyNode1;
				}
				if ((Object)(object)buyNode2 != (Object)null)
				{
					this.buyNode2 = buyNode2;
				}
				if ((Object)(object)itemInfo != (Object)null)
				{
					this.itemInfo = itemInfo;
				}
			}
		}

		[CompilerGenerated]
		private static class <>O
		{
			public static hook_Start <0>__StartOfRound_Start;

			public static hook_Awake <1>__Terminal_Awake;

			public static hook_TextPostProcess <2>__Terminal_TextPostProcess;

			public static hook_Start <3>__RegisterLevelScrapforLLL_RoundManager_Start;

			public static hook_Start <4>__RegisterLevelScrapforLE_Terminal_Start;
		}

		public static ConfigEntry<bool> useSavedataFix;

		public static GameObject scanNodePrefab;

		private static List<SelectableLevel> levelsAlreadyAddedTo = new List<SelectableLevel>();

		public static List<Item> LethalLibItemList = new List<Item>();

		public static List<BuyableItemAssetInfo> buyableItemAssetInfos = new List<BuyableItemAssetInfo>();

		public static Terminal terminal;

		public static List<ScrapItem> scrapItems = new List<ScrapItem>();

		public static List<ShopItem> shopItems = new List<ShopItem>();

		public static List<PlainItem> plainItems = new List<PlainItem>();

		public static void Init()
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Expected O, but got Unknown
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Expected O, but got Unknown
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Expected O, but got Unknown
			useSavedataFix = Plugin.config.Bind<bool>("Items", "EnableItemSaveFix", false, "Allow for LethalLib to store/reorder the item list, which should fix issues where items get reshuffled when loading an old save. This is experimental and may cause save corruptions occasionally.");
			scanNodePrefab = Plugin.MainAssets.LoadAsset<GameObject>("Assets/Custom/ItemScanNode.prefab");
			object obj = <>O.<0>__StartOfRound_Start;
			if (obj == null)
			{
				hook_Start val = StartOfRound_Start;
				<>O.<0>__StartOfRound_Start = val;
				obj = (object)val;
			}
			StartOfRound.Start += (hook_Start)obj;
			object obj2 = <>O.<1>__Terminal_Awake;
			if (obj2 == null)
			{
				hook_Awake val2 = Terminal_Awake;
				<>O.<1>__Terminal_Awake = val2;
				obj2 = (object)val2;
			}
			Terminal.Awake += (hook_Awake)obj2;
			object obj3 = <>O.<2>__Terminal_TextPostProcess;
			if (obj3 == null)
			{
				hook_TextPostProcess val3 = Terminal_TextPostProcess;
				<>O.<2>__Terminal_TextPostProcess = val3;
				obj3 = (object)val3;
			}
			Terminal.TextPostProcess += (hook_TextPostProcess)obj3;
		}

		private static string Terminal_TextPostProcess(orig_TextPostProcess orig, Terminal self, string modifiedDisplayText, TerminalNode node)
		{
			List<Item> list = self.buyableItemsList.ToList();
			List<Item> list2 = self.buyableItemsList.ToList();
			list2.RemoveAll((Item x) => shopItems.FirstOrDefault((ShopItem item) => (Object)(object)item.origItem == (Object)(object)x || (Object)(object)item.item == (Object)(object)x)?.wasRemoved ?? false);
			self.buyableItemsList = list2.ToArray();
			string result = orig.Invoke(self, modifiedDisplayText, node);
			self.buyableItemsList = list.ToArray();
			return result;
		}

		private static void StartOfRound_Start(orig_Start orig, StartOfRound self)
		{
			if (useSavedataFix.Value && ((NetworkBehaviour)self).IsHost)
			{
				Plugin.logger.LogInfo((object)"Fixing Item savedata!!");
				List<ItemSaveOrderData> itemList = new List<ItemSaveOrderData>();
				StartOfRound.Instance.allItemsList.itemsList.ForEach(delegate(Item item)
				{
					itemList.Add(new ItemSaveOrderData
					{
						itemId = item.itemId,
						itemName = item.itemName,
						assetName = ((Object)item).name
					});
				});
				if (ES3.KeyExists("LethalLibAllItemsList", GameNetworkManager.Instance.currentSaveFileName))
				{
					itemList = ES3.Load<List<ItemSaveOrderData>>("LethalLibAllItemsList", GameNetworkManager.Instance.currentSaveFileName);
				}
				List<Item> itemsList = StartOfRound.Instance.allItemsList.itemsList;
				List<Item> list = new List<Item>();
				foreach (ItemSaveOrderData item2 in itemList)
				{
					Item val = ((IEnumerable<Item>)itemsList).FirstOrDefault((Func<Item, bool>)((Item x) => x.itemId == item2.itemId && x.itemName == item2.itemName && item2.assetName == ((Object)x).name));
					if ((Object)(object)val != (Object)null)
					{
						list.Add(val);
					}
					else
					{
						list.Add(ScriptableObject.CreateInstance<Item>());
					}
				}
				foreach (Item item3 in itemsList)
				{
					if (!list.Contains(item3))
					{
						list.Add(item3);
					}
				}
				StartOfRound.Instance.allItemsList.itemsList = list;
				ES3.Save<List<ItemSaveOrderData>>("LethalLibAllItemsList", itemList, GameNetworkManager.Instance.currentSaveFileName);
			}
			orig.Invoke(self);
		}

		private static void RegisterLevelScrapforLLL_RoundManager_Start(orig_Start orig, RoundManager self)
		{
			orig.Invoke(self);
			RegisterLethalLibScrapItemsForAllLevels();
		}

		private static void RegisterLevelScrapforLE_Terminal_Start(orig_Start orig, Terminal self)
		{
			orig.Invoke(self);
			RegisterLethalLibScrapItemsForAllLevels();
		}

		private static void RegisterLethalLibScrapItemsForAllLevels()
		{
			SelectableLevel[] levels = StartOfRound.Instance.levels;
			foreach (SelectableLevel val in levels)
			{
				if (levelsAlreadyAddedTo.Contains(val))
				{
					continue;
				}
				foreach (ScrapItem scrapItem in scrapItems)
				{
					AddScrapItemToLevel(scrapItem, val);
				}
				levelsAlreadyAddedTo.Add(val);
			}
		}

		private static void AddScrapItemToLevel(ScrapItem scrapItem, SelectableLevel level)
		{
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01db: Expected O, but got Unknown
			ScrapItem scrapItem2 = scrapItem;
			string text = ((Object)level).name;
			bool flag = scrapItem2.levelRarities.ContainsKey(Levels.LevelTypes.All) || (scrapItem2.customLevelRarities != null && scrapItem2.customLevelRarities.ContainsKey(text));
			if (scrapItem2.levelRarities.ContainsKey(Levels.LevelTypes.Modded) && !Enum.IsDefined(typeof(Levels.LevelTypes), text))
			{
				flag = true;
			}
			Levels.LevelTypes key = Levels.LevelTypes.None;
			bool flag2 = false;
			if (Enum.IsDefined(typeof(Levels.LevelTypes), text))
			{
				key = (Levels.LevelTypes)Enum.Parse(typeof(Levels.LevelTypes), text);
				flag2 = true;
			}
			else
			{
				text = Levels.Compatibility.GetLLLNameOfLevel(text);
			}
			if (!(flag2 || flag))
			{
				return;
			}
			Levels.LevelTypes key2 = (flag ? Levels.LevelTypes.All : ((Levels.LevelTypes)Enum.Parse(typeof(Levels.LevelTypes), text)));
			if (!flag && !scrapItem2.levelRarities.ContainsKey(key2))
			{
				return;
			}
			int rarity = 0;
			if (flag2 && scrapItem2.levelRarities.ContainsKey(key))
			{
				rarity = scrapItem2.levelRarities[key];
			}
			else if (!flag2 && scrapItem2.customLevelRarities != null && scrapItem2.customLevelRarities.ContainsKey(text))
			{
				rarity = scrapItem2.customLevelRarities[text];
			}
			else if (!flag2 && scrapItem2.levelRarities.ContainsKey(Levels.LevelTypes.Modded))
			{
				rarity = scrapItem2.levelRarities[Levels.LevelTypes.Modded];
			}
			else if (scrapItem2.levelRarities.ContainsKey(Levels.LevelTypes.All))
			{
				rarity = scrapItem2.levelRarities[Levels.LevelTypes.All];
			}
			SpawnableItemWithRarity item = new SpawnableItemWithRarity
			{
				spawnableItem = scrapItem2.item,
				rarity = rarity
			};
			if (!level.spawnableScrap.Any((SpawnableItemWithRarity x) => (Object)(object)x.spawnableItem == (Object)(object)scrapItem2.item))
			{
				level.spawnableScrap.Add(item);
				if (Plugin.extendedLogging.Value)
				{
					Plugin.logger.LogInfo((object)("To " + text + " added " + ((Object)scrapItem2.item).name));
				}
			}
		}

		private static void RegisterScrapAsItem(StartOfRound startOfRound)
		{
			foreach (ScrapItem scrapItem in scrapItems)
			{
				if (startOfRound.allItemsList.itemsList.Contains(scrapItem.item))
				{
					continue;
				}
				if (Plugin.extendedLogging.Value)
				{
					if (scrapItem.modName != "LethalLib")
					{
						Plugin.logger.LogInfo((object)(scrapItem.modName + " registered scrap item: " + scrapItem.item.itemName));
					}
					else
					{
						Plugin.logger.LogInfo((object)("Registered scrap item: " + scrapItem.item.itemName));
					}
				}
				LethalLibItemList.Add(scrapItem.item);
				startOfRound.allItemsList.itemsList.Add(scrapItem.item);
			}
		}

		private static void Terminal_Awake(orig_Awake orig, Terminal self)
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Expected O, but got Unknown
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Expected O, but got Unknown
			//IL_0579: Unknown result type (might be due to invalid IL or missing references)
			//IL_057e: Unknown result type (might be due to invalid IL or missing references)
			//IL_05b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_05bc: Expected O, but got Unknown
			//IL_05be: Unknown result type (might be due to invalid IL or missing references)
			//IL_05c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_05f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0600: Expected O, but got Unknown
			//IL_0663: Unknown result type (might be due to invalid IL or missing references)
			//IL_0668: Unknown result type (might be due to invalid IL or missing references)
			//IL_0670: Unknown result type (might be due to invalid IL or missing references)
			//IL_067d: Expected O, but got Unknown
			//IL_070a: Unknown result type (might be due to invalid IL or missing references)
			//IL_070f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0717: Unknown result type (might be due to invalid IL or missing references)
			//IL_0724: Expected O, but got Unknown
			StartOfRound instance = StartOfRound.Instance;
			RegisterLethalLibScrapItemsForAllLevels();
			if (Chainloader.PluginInfos.ContainsKey("imabatby.lethallevelloader") || Chainloader.PluginInfos.ContainsKey("iambatby.lethallevelloader"))
			{
				object obj = <>O.<3>__RegisterLevelScrapforLLL_RoundManager_Start;
				if (obj == null)
				{
					hook_Start val = RegisterLevelScrapforLLL_RoundManager_Start;
					<>O.<3>__RegisterLevelScrapforLLL_RoundManager_Start = val;
					obj = (object)val;
				}
				RoundManager.Start += (hook_Start)obj;
			}
			if (Chainloader.PluginInfos.ContainsKey("LethalExpansion"))
			{
				object obj2 = <>O.<4>__RegisterLevelScrapforLE_Terminal_Start;
				if (obj2 == null)
				{
					hook_Start val2 = RegisterLevelScrapforLE_Terminal_Start;
					<>O.<4>__RegisterLevelScrapforLE_Terminal_Start = val2;
					obj2 = (object)val2;
				}
				Terminal.Start += (hook_Start)obj2;
			}
			RegisterScrapAsItem(instance);
			foreach (ShopItem shopItem in shopItems)
			{
				if (instance.allItemsList.itemsList.Contains(shopItem.item))
				{
					continue;
				}
				if (Plugin.extendedLogging.Value)
				{
					if (shopItem.modName != "LethalLib")
					{
						Plugin.logger.LogInfo((object)(shopItem.modName + " registered shop item: " + shopItem.item.itemName));
					}
					else
					{
						Plugin.logger.LogInfo((object)("Registered shop item: " + shopItem.item.itemName));
					}
				}
				LethalLibItemList.Add(shopItem.item);
				instance.allItemsList.itemsList.Add(shopItem.item);
			}
			foreach (PlainItem plainItem in plainItems)
			{
				if (instance.allItemsList.itemsList.Contains(plainItem.item))
				{
					continue;
				}
				if (Plugin.extendedLogging.Value)
				{
					if (plainItem.modName != "LethalLib")
					{
						Plugin.logger.LogInfo((object)(plainItem.modName + " registered item: " + plainItem.item.itemName));
					}
					else
					{
						Plugin.logger.LogInfo((object)("Registered item: " + plainItem.item.itemName));
					}
				}
				LethalLibItemList.Add(plainItem.item);
				instance.allItemsList.itemsList.Add(plainItem.item);
			}
			terminal = self;
			List<Item> list = self.buyableItemsList.ToList();
			TerminalKeyword val3 = self.terminalNodes.allKeywords.First((TerminalKeyword keyword) => keyword.word == "buy");
			TerminalNode result = val3.compatibleNouns[0].result.terminalOptions[1].result;
			TerminalKeyword val4 = self.terminalNodes.allKeywords.First((TerminalKeyword keyword) => keyword.word == "info");
			Plugin.logger.LogInfo((object)$"Adding {shopItems.Count} items to terminal");
			foreach (ShopItem item in shopItems)
			{
				if (list.Any((Item x) => x.itemName == item.item.itemName) && !item.wasRemoved)
				{
					Plugin.logger.LogInfo((object)("Item " + item.item.itemName + " already exists in terminal, skipping"));
					continue;
				}
				item.wasRemoved = false;
				if (item.price == -1)
				{
					item.price = item.item.creditsWorth;
				}
				else
				{
					item.item.creditsWorth = item.price;
				}
				int num = -1;
				if (!list.Any((Item x) => (Object)(object)x == (Object)(object)item.item))
				{
					list.Add(item.item);
				}
				else
				{
					num = list.IndexOf(item.item);
				}
				int buyItemIndex = ((num == -1) ? (list.Count - 1) : num);
				string itemName = item.item.itemName;
				_ = itemName[itemName.Length - 1];
				string text = itemName;
				TerminalNode val5 = item.buyNode2;
				if ((Object)(object)val5 == (Object)null)
				{
					val5 = ScriptableObject.CreateInstance<TerminalNode>();
					((Object)val5).name = itemName.Replace(" ", "-") + "BuyNode2";
					val5.displayText = "Ordered [variableAmount] " + text + ". Your new balance is [playerCredits].\n\nOur contractors enjoy fast, free shipping while on the job! Any purchased items will arrive hourly at your approximate location.\r\n\r\n";
					val5.clearPreviousText = true;
					val5.maxCharactersToType = 15;
				}
				val5.buyItemIndex = buyItemIndex;
				val5.isConfirmationNode = false;
				val5.itemCost = item.price;
				val5.playSyncedClip = 0;
				TerminalNode val6 = item.buyNode1;
				if ((Object)(object)val6 == (Object)null)
				{
					val6 = ScriptableObject.CreateInstance<TerminalNode>();
					((Object)val6).name = itemName.Replace(" ", "-") + "BuyNode1";
					val6.displayText = "You have requested to order " + text + ". Amount: [variableAmount].\nTotal cost of items: [totalCost].\n\nPlease CONFIRM or DENY.\r\n\r\n";
					val6.clearPreviousText = true;
					val6.maxCharactersToType = 35;
				}
				val6.buyItemIndex = buyItemIndex;
				val6.isConfirmationNode = true;
				val6.overrideOptions = true;
				val6.itemCost = item.price;
				val6.terminalOptions = (CompatibleNoun[])(object)new CompatibleNoun[2]
				{
					new CompatibleNoun
					{
						noun = self.terminalNodes.allKeywords.First((TerminalKeyword keyword2) => keyword2.word == "confirm"),
						result = val5
					},
					new CompatibleNoun
					{
						noun = self.terminalNodes.allKeywords.First((TerminalKeyword keyword2) => keyword2.word == "deny"),
						result = result
					}
				};
				TerminalKeyword val7 = TerminalUtils.CreateTerminalKeyword(itemName.ToLowerInvariant().Replace(" ", "-"), isVerb: false, null, null, val3);
				List<TerminalKeyword> list2 = self.terminalNodes.allKeywords.ToList();
				list2.Add(val7);
				self.terminalNodes.allKeywords = list2.ToArray();
				List<CompatibleNoun> list3 = val3.compatibleNouns.ToList();
				list3.Add(new CompatibleNoun
				{
					noun = val7,
					result = val6
				});
				val3.compatibleNouns = list3.ToArray();
				TerminalNode val8 = item.itemInfo;
				if ((Object)(object)val8 == (Object)null)
				{
					val8 = ScriptableObject.CreateInstance<TerminalNode>();
					((Object)val8).name = itemName.Replace(" ", "-") + "InfoNode";
					val8.displayText = "[No information about this object was found.]\n\n";
					val8.clearPreviousText = true;
					val8.maxCharactersToType = 25;
				}
				self.terminalNodes.allKeywords = list2.ToArray();
				List<CompatibleNoun> list4 = val4.compatibleNouns.ToList();
				list4.Add(new CompatibleNoun
				{
					noun = val7,
					result = val8
				});
				val4.compatibleNouns = list4.ToArray();
				BuyableItemAssetInfo buyableItemAssetInfo = default(BuyableItemAssetInfo);
				buyableItemAssetInfo.itemAsset = item.item;
				buyableItemAssetInfo.keyword = val7;
				BuyableItemAssetInfo item2 = buyableItemAssetInfo;
				buyableItemAssetInfos.Add(item2);
				if (Plugin.extendedLogging.Value)
				{
					Plugin.logger.LogInfo((object)$"Added {itemName} to terminal (Item price: {val6.itemCost}, Item Index: {val6.buyItemIndex}, Terminal keyword: {val7.word})");
				}
			}
			self.buyableItemsList = list.ToArray();
			orig.Invoke(self);
		}

		public static void RegisterScrap(Item spawnableItem, int rarity, Levels.LevelTypes levelFlags)
		{
			Item spawnableItem2 = spawnableItem;
			ScrapItem scrapItem = scrapItems.FirstOrDefault((ScrapItem x) => (Object)(object)x.origItem == (Object)(object)spawnableItem2 || (Object)(object)x.item == (Object)(object)spawnableItem2);
			if (scrapItem != null)
			{
				if (levelFlags != Levels.LevelTypes.None)
				{
					scrapItem.levelRarities.Add(levelFlags, rarity);
				}
			}
			else
			{
				scrapItem = new ScrapItem(spawnableItem2, rarity, levelFlags);
				string name = Assembly.GetCallingAssembly().GetName().Name;
				scrapItem.modName = name;
				scrapItems.Add(scrapItem);
			}
		}

		public static void RegisterScrap(Item spawnableItem, int rarity, Levels.LevelTypes levelFlags = Levels.LevelTypes.None, string[] levelOverrides = null)
		{
			Item spawnableItem2 = spawnableItem;
			ScrapItem scrapItem = scrapItems.FirstOrDefault((ScrapItem x) => (Object)(object)x.origItem == (Object)(object)spawnableItem2 || (Object)(object)x.item == (Object)(object)spawnableItem2);
			if (scrapItem != null)
			{
				if (levelFlags != Levels.LevelTypes.None)
				{
					scrapItem.levelRarities.Add(levelFlags, rarity);
				}
				if (levelOverrides != null)
				{
					foreach (string levelName in levelOverrides)
					{
						scrapItem.customLevelRarities.Add(Levels.Compatibility.GetLLLNameOfLevel(levelName), rarity);
					}
				}
			}
			else
			{
				scrapItem = new ScrapItem(spawnableItem2, rarity, levelFlags, levelOverrides);
				string name = Assembly.GetCallingAssembly().GetName().Name;
				scrapItem.modName = name;
				scrapItems.Add(scrapItem);
			}
		}

		public static void RegisterScrap(Item spawnableItem, Dictionary<Levels.LevelTypes, int>? levelRarities = null, Dictionary<string, int>? customLevelRarities = null)
		{
			Item spawnableItem2 = spawnableItem;
			ScrapItem scrapItem = scrapItems.FirstOrDefault((ScrapItem x) => (Object)(object)x.origItem == (Object)(object)spawnableItem2 || (Object)(object)x.item == (Object)(object)spawnableItem2);
			if (scrapItem != null)
			{
				if (levelRarities != null)
				{
					foreach (KeyValuePair<Levels.LevelTypes, int> levelRarity in levelRarities)
					{
						scrapItem.levelRarities.Add(levelRarity.Key, levelRarity.Value);
					}
				}
				if (customLevelRarities == null)
				{
					return;
				}
				{
					foreach (KeyValuePair<string, int> customLevelRarity in customLevelRarities)
					{
						scrapItem.customLevelRarities.Add(Levels.Compatibility.GetLLLNameOfLevel(customLevelRarity.Key), customLevelRarity.Value);
					}
					return;
				}
			}
			scrapItem = new ScrapItem(spawnableItem2, levelRarities, customLevelRarities);
			string name = Assembly.GetCallingAssembly().GetName().Name;
			scrapItem.modName = name;
			scrapItems.Add(scrapItem);
		}

		public static void RegisterShopItem(Item shopItem, TerminalNode buyNode1 = null, TerminalNode buyNode2 = null, TerminalNode itemInfo = null, int price = -1)
		{
			ShopItem shopItem2 = new ShopItem(shopItem, buyNode1, buyNode2, itemInfo, price);
			string name = Assembly.GetCallingAssembly().GetName().Name;
			shopItem2.modName = name;
			shopItems.Add(shopItem2);
		}

		public static void RegisterShopItem(Item shopItem, int price = -1)
		{
			ShopItem shopItem2 = new ShopItem(shopItem, null, null, null, price);
			string name = Assembly.GetCallingAssembly().GetName().Name;
			shopItem2.modName = name;
			shopItems.Add(shopItem2);
		}

		public static void RegisterItem(Item plainItem)
		{
			PlainItem plainItem2 = new PlainItem(plainItem);
			string name = Assembly.GetCallingAssembly().GetName().Name;
			plainItem2.modName = name;
			plainItems.Add(plainItem2);
		}

		public static void RemoveScrapFromLevels(Item scrapItem, Levels.LevelTypes levelFlags = Levels.LevelTypes.None, string[] levelOverrides = null)
		{
			Item scrapItem2 = scrapItem;
			if (!((Object)(object)StartOfRound.Instance != (Object)null))
			{
				return;
			}
			SelectableLevel[] levels = StartOfRound.Instance.levels;
			foreach (SelectableLevel val in levels)
			{
				string name = ((Object)val).name;
				if (!Enum.IsDefined(typeof(Levels.LevelTypes), name))
				{
					name = Levels.Compatibility.GetLLLNameOfLevel(name);
				}
				bool flag = levelFlags.HasFlag(Levels.LevelTypes.All) || (levelOverrides?.Any((string item) => Levels.Compatibility.GetLLLNameOfLevel(item).ToLowerInvariant() == name.ToLowerInvariant()) ?? false);
				if (levelFlags.HasFlag(Levels.LevelTypes.Modded) && !Enum.IsDefined(typeof(Levels.LevelTypes), name))
				{
					flag = true;
				}
				if (!(Enum.IsDefined(typeof(Levels.LevelTypes), name) || flag))
				{
					continue;
				}
				Levels.LevelTypes levelTypes = (flag ? Levels.LevelTypes.All : ((Levels.LevelTypes)Enum.Parse(typeof(Levels.LevelTypes), name)));
				if (!flag && !levelFlags.HasFlag(levelTypes))
				{
					continue;
				}
				ScrapItem actualItem = scrapItems.FirstOrDefault((ScrapItem x) => (Object)(object)x.origItem == (Object)(object)scrapItem2 || (Object)(object)x.item == (Object)(object)scrapItem2);
				SpawnableItemWithRarity val2 = ((IEnumerable<SpawnableItemWithRarity>)val.spawnableScrap).FirstOrDefault((Func<SpawnableItemWithRarity, bool>)((SpawnableItemWithRarity x) => (Object)(object)x.spawnableItem == (Object)(object)actualItem.item));
				if (val2 != null)
				{
					if (Plugin.extendedLogging.Value)
					{
						Plugin.logger.LogInfo((object)("Removed Item " + ((Object)val2.spawnableItem).name + " from Level " + name));
					}
					val.spawnableScrap.Remove(val2);
				}
			}
		}

		public static void RemoveShopItem(Item shopItem)
		{
			Item shopItem2 = shopItem;
			if (!((Object)(object)StartOfRound.Instance != (Object)null))
			{
				return;
			}
			ShopItem actualItem = shopItems.FirstOrDefault((ShopItem x) => (Object)(object)x.origItem == (Object)(object)shopItem2 || (Object)(object)x.item == (Object)(object)shopItem2);
			actualItem.wasRemoved = true;
			List<TerminalKeyword> list = terminal.terminalNodes.allKeywords.ToList();
			TerminalKeyword obj = terminal.terminalNodes.allKeywords.First((TerminalKeyword keyword) => keyword.word == "info");
			TerminalKeyword val = terminal.terminalNodes.allKeywords.First((TerminalKeyword keyword) => keyword.word == "buy");
			List<CompatibleNoun> list2 = val.compatibleNouns.ToList();
			List<CompatibleNoun> list3 = obj.compatibleNouns.ToList();
			if (buyableItemAssetInfos.Any((BuyableItemAssetInfo x) => (Object)(object)x.itemAsset == (Object)(object)actualItem.item))
			{
				BuyableItemAssetInfo asset = buyableItemAssetInfos.First((BuyableItemAssetInfo x) => (Object)(object)x.itemAsset == (Object)(object)actualItem.item);
				list.Remove(asset.keyword);
				list2.RemoveAll((CompatibleNoun noun) => (Object)(object)noun.noun == (Object)(object)asset.keyword);
				list3.RemoveAll((CompatibleNoun noun) => (Object)(object)noun.noun == (Object)(object)asset.keyword);
			}
			terminal.terminalNodes.allKeywords = list.ToArray();
			val.compatibleNouns = list2.ToArray();
			obj.compatibleNouns = list3.ToArray();
		}

		public static void UpdateShopItemPrice(Item shopItem, int price)
		{
			Item shopItem2 = shopItem;
			if (!((Object)(object)StartOfRound.Instance != (Object)null))
			{
				return;
			}
			ShopItem actualItem = shopItems.FirstOrDefault((ShopItem x) => (Object)(object)x.origItem == (Object)(object)shopItem2 || (Object)(object)x.item == (Object)(object)shopItem2);
			actualItem.item.creditsWorth = price;
			TerminalKeyword obj = terminal.terminalNodes.allKeywords.First((TerminalKeyword keyword) => keyword.word == "buy");
			_ = obj.compatibleNouns[0].result.terminalOptions[1].result;
			List<CompatibleNoun> source = obj.compatibleNouns.ToList();
			if (!buyableItemAssetInfos.Any((BuyableItemAssetInfo x) => (Object)(object)x.itemAsset == (Object)(object)actualItem.item))
			{
				return;
			}
			BuyableItemAssetInfo asset = buyableItemAssetInfos.First((BuyableItemAssetInfo x) => (Object)(object)x.itemAsset == (Object)(object)actualItem.item);
			if (!source.Any((CompatibleNoun noun) => (Object)(object)noun.noun == (Object)(object)asset.keyword))
			{
				return;
			}
			TerminalNode result = source.First((CompatibleNoun noun) => (Object)(object)noun.noun == (Object)(object)asset.keyword).result;
			result.itemCost = price;
			if (result.terminalOptions.Length == 0)
			{
				return;
			}
			CompatibleNoun[] terminalOptions = result.terminalOptions;
			foreach (CompatibleNoun val in terminalOptions)
			{
				if ((Object)(object)val.result != (Object)null && val.result.buyItemIndex != -1)
				{
					val.result.itemCost = price;
				}
			}
		}
	}
	public class Levels
	{
		[Flags]
		public enum LevelTypes
		{
			None = 1,
			ExperimentationLevel = 4,
			AssuranceLevel = 8,
			VowLevel = 0x10,
			OffenseLevel = 0x20,
			MarchLevel = 0x40,
			RendLevel = 0x80,
			DineLevel = 0x100,
			TitanLevel = 0x200,
			Vanilla = 0x3FC,
			Modded = 0x400,
			All = -1
		}

		internal static class Compatibility
		{
			private const string illegalCharacters = ".,?!@#$%^&*()_+-=';:'\"";

			private static string GetNumberlessPlanetName(string planetName)
			{
				if (planetName != null)
				{
					return new string(planetName.SkipWhile((char c) => !char.IsLetter(c)).ToArray());
				}
				return string.Empty;
			}

			private static string StripSpecialCharacters(string input)
			{
				string text = string.Empty;
				for (int i = 0; i < input.Length; i++)
				{
					char c = input[i];
					if ((!".,?!@#$%^&*()_+-=';:'\"".ToCharArray().Contains(c) && char.IsLetterOrDigit(c)) || c.ToString() == " ")
					{
						text += c;
					}
				}
				return text;
			}

			internal static string GetLLLNameOfLevel(string levelName)
			{
				string text = StripSpecialCharacters(GetNumberlessPlanetName(levelName));
				if (!text.EndsWith("Level"))
				{
					text += "Level";
				}
				return text;
			}

			internal static Dictionary<string, int> LLLifyLevelRarityDictionary(Dictionary<string, int> keyValuePairs)
			{
				Dictionary<string, int> dictionary = new Dictionary<string, int>();
				List<string> list = keyValuePairs.Keys.ToList();
				List<int> list2 = keyValuePairs.Values.ToList();
				for (int i = 0; i < keyValuePairs.Count; i++)
				{
					dictionary.Add(GetLLLNameOfLevel(list[i]), list2[i]);
				}
				return dictionary;
			}
		}
	}
	public class MapObjects
	{
		public class RegisteredMapObject
		{
			public SpawnableMapObject mapObject;

			public SpawnableOutsideObjectWithRarity outsideObject;

			public Levels.LevelTypes levels;

			public string[] spawnLevelOverrides;

			public Func<SelectableLevel, AnimationCurve> spawnRateFunction;
		}

		[CompilerGenerated]
		private static class <>O
		{
			public static hook_Awake <0>__StartOfRound_Awake;

			public static hook_SpawnMapObjects <1>__RoundManager_SpawnMapObjects;
		}

		public static List<RegisteredMapObject> mapObjects = new List<RegisteredMapObject>();

		public static void Init()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Expected O, but got Unknown
			object obj = <>O.<0>__StartOfRound_Awake;
			if (obj == null)
			{
				hook_Awake val = StartOfRound_Awake;
				<>O.<0>__StartOfRound_Awake = val;
				obj = (object)val;
			}
			StartOfRound.Awake += (hook_Awake)obj;
			object obj2 = <>O.<1>__RoundManager_SpawnMapObjects;
			if (obj2 == null)
			{
				hook_SpawnMapObjects val2 = RoundManager_SpawnMapObjects;
				<>O.<1>__RoundManager_SpawnMapObjects = val2;
				obj2 = (object)val2;
			}
			RoundManager.SpawnMapObjects += (hook_SpawnMapObjects)obj2;
		}

		private static void RoundManager_SpawnMapObjects(orig_SpawnMapObjects orig, RoundManager self)
		{
			RandomMapObject[] array = Object.FindObjectsOfType<RandomMapObject>();
			foreach (RandomMapObject val in array)
			{
				foreach (RegisteredMapObject mapObject in mapObjects)
				{
					if (mapObject.mapObject != null && !val.spawnablePrefabs.Any((GameObject prefab) => (Object)(object)prefab == (Object)(object)mapObject.mapObject.prefabToSpawn))
					{
						val.spawnablePrefabs.Add(mapObject.mapObject.prefabToSpawn);
					}
				}
			}
			orig.Invoke(self);
		}

		private static void StartOfRound_Awake(orig_Awake orig, StartOfRound self)
		{
			orig.Invoke(self);
			foreach (RegisteredMapObject mapObject in mapObjects)
			{
				SelectableLevel[] levels = self.levels;
				foreach (SelectableLevel val in levels)
				{
					string name = ((Object)val).name;
					bool flag = mapObject.levels.HasFlag(Levels.LevelTypes.All) || (mapObject.spawnLevelOverrides != null && mapObject.spawnLevelOverrides.Any((string item) => item.ToLowerInvariant() == name.ToLowerInvariant()));
					if (mapObject.levels.HasFlag(Levels.LevelTypes.Modded) && !Enum.IsDefined(typeof(Levels.LevelTypes), name))
					{
						flag = true;
					}
					if (!(Enum.IsDefined(typeof(Levels.LevelTypes), name) || flag))
					{
						continue;
					}
					Levels.LevelTypes levelTypes = (flag ? Levels.LevelTypes.All : ((Levels.LevelTypes)Enum.Parse(typeof(Levels.LevelTypes), name)));
					if (!flag && !mapObject.levels.HasFlag(levelTypes))
					{
						continue;
					}
					if (mapObject.mapObject != null)
					{
						if (val.spawnableMapObjects.Any((SpawnableMapObject x) => (Object)(object)x.prefabToSpawn == (Object)(object)mapObject.mapObject.prefabToSpawn))
						{
							List<SpawnableMapObject> list = val.spawnableMapObjects.ToList();
							list.RemoveAll((SpawnableMapObject x) => (Object)(object)x.prefabToSpawn == (Object)(object)mapObject.mapObject.prefabToSpawn);
							val.spawnableMapObjects = list.ToArray();
						}
						SpawnableMapObject mapObject2 = mapObject.mapObject;
						if (mapObject.spawnRateFunction != null)
						{
							mapObject2.numberToSpawn = mapObject.spawnRateFunction(val);
						}
						List<SpawnableMapObject> list2 = val.spawnableMapObjects.ToList();
						list2.Add(mapObject2);
						val.spawnableMapObjects = list2.ToArray();
						if (Plugin.extendedLogging.Value)
						{
							Plugin.logger.LogInfo((object)("Added " + ((Object)mapObject2.prefabToSpawn).name + " to " + name));
						}
					}
					else
					{
						if (mapObject.outsideObject == null)
						{
							continue;
						}
						if (val.spawnableOutsideObjects.Any((SpawnableOutsideObjectWithRarity x) => (Object)(object)x.spawnableObject.prefabToSpawn == (Object)(object)mapObject.outsideObject.spawnableObject.prefabToSpawn))
						{
							List<SpawnableOutsideObjectWithRarity> list3 = val.spawnableOutsideObjects.ToList();
							list3.RemoveAll((SpawnableOutsideObjectWithRarity x) => (Object)(object)x.spawnableObject.prefabToSpawn == (Object)(object)mapObject.outsideObject.spawnableObject.prefabToSpawn);
							val.spawnableOutsideObjects = list3.ToArray();
						}
						SpawnableOutsideObjectWithRarity outsideObject = mapObject.outsideObject;
						if (mapObject.spawnRateFunction != null)
						{
							outsideObject.randomAmount = mapObject.spawnRateFunction(val);
						}
						List<SpawnableOutsideObjectWithRarity> list4 = val.spawnableOutsideObjects.ToList();
						list4.Add(outsideObject);
						val.spawnableOutsideObjects = list4.ToArray();
						if (Plugin.extendedLogging.Value)
						{
							Plugin.logger.LogInfo((object)("Added " + ((Object)outsideObject.spawnableObject.prefabToSpawn).name + " to " + name));
						}
					}
				}
			}
		}

		public static void RegisterMapObject(SpawnableMapObjectDef mapObject, Levels.LevelTypes levels, Func<SelectableLevel, AnimationCurve> spawnRateFunction = null)
		{
			RegisterMapObject(mapObject.spawnableMapObject, levels, spawnRateFunction);
		}

		public static void RegisterMapObject(SpawnableMapObjectDef mapObject, Levels.LevelTypes levels = Levels.LevelTypes.None, string[] levelOverrides = null, Func<SelectableLevel, AnimationCurve> spawnRateFunction = null)
		{
			RegisterMapObject(mapObject.spawnableMapObject, levels, levelOverrides, spawnRateFunction);
		}

		public static void RegisterMapObject(SpawnableMapObject mapObject, Levels.LevelTypes levels, Func<SelectableLevel, AnimationCurve> spawnRateFunction = null)
		{
			mapObjects.Add(new RegisteredMapObject
			{
				mapObject = mapObject,
				levels = levels,
				spawnRateFunction = spawnRateFunction
			});
		}

		public static void RegisterMapObject(SpawnableMapObject mapObject, Levels.LevelTypes levels = Levels.LevelTypes.None, string[] levelOverrides = null, Func<SelectableLevel, AnimationCurve> spawnRateFunction = null)
		{
			mapObjects.Add(new RegisteredMapObject
			{
				mapObject = mapObject,
				levels = levels,
				spawnRateFunction = spawnRateFunction,
				spawnLevelOverrides = levelOverrides
			});
		}

		public static void RegisterOutsideObject(SpawnableOutsideObjectDef mapObject, Levels.LevelTypes levels, Func<SelectableLevel, AnimationCurve> spawnRateFunction = null)
		{
			RegisterOutsideObject(mapObject.spawnableMapObject, levels, spawnRateFunction);
		}

		public static void RegisterOutsideObject(SpawnableOutsideObjectDef mapObject, Levels.LevelTypes levels = Levels.LevelTypes.None, string[] levelOverrides = null, Func<SelectableLevel, AnimationCurve> spawnRateFunction = null)
		{
			RegisterOutsideObject(mapObject.spawnableMapObject, levels, levelOverrides, spawnRateFunction);
		}

		public static void RegisterOutsideObject(SpawnableOutsideObjectWithRarity mapObject, Levels.LevelTypes levels, Func<SelectableLevel, AnimationCurve> spawnRateFunction = null)
		{
			mapObjects.Add(new RegisteredMapObject
			{
				outsideObject = mapObject,
				levels = levels,
				spawnRateFunction = spawnRateFunction
			});
		}

		public static void RegisterOutsideObject(SpawnableOutsideObjectWithRarity mapObject, Levels.LevelTypes levels = Levels.LevelTypes.None, string[] levelOverrides = null, Func<SelectableLevel, AnimationCurve> spawnRateFunction = null)
		{
			mapObjects.Add(new RegisteredMapObject
			{
				outsideObject = mapObject,
				levels = levels,
				spawnRateFunction = spawnRateFunction,
				spawnLevelOverrides = levelOverrides
			});
		}

		public static void RemoveMapObject(SpawnableMapObjectDef mapObject, Levels.LevelTypes levelFlags, string[] levelOverrides = null)
		{
			RemoveMapObject(mapObject.spawnableMapObject, levelFlags, levelOverrides);
		}

		public static void RemoveMapObject(SpawnableMapObject mapObject, Levels.LevelTypes levelFlags, string[] levelOverrides = null)
		{
			SpawnableMapObject mapObject2 = mapObject;
			if (!((Object)(object)StartOfRound.Instance != (Object)null))
			{
				return;
			}
			SelectableLevel[] levels = StartOfRound.Instance.levels;
			foreach (SelectableLevel val in levels)
			{
				string name = ((Object)val).name;
				bool flag = levelFlags.HasFlag(Levels.LevelTypes.All) || (levelOverrides?.Any((string item) => item.ToLowerInvariant() == name.ToLowerInvariant()) ?? false);
				if (levelFlags.HasFlag(Levels.LevelTypes.Modded) && !Enum.IsDefined(typeof(Levels.LevelTypes), name))
				{
					flag = true;
				}
				if (!(Enum.IsDefined(typeof(Levels.LevelTypes), name) || flag))
				{
					continue;
				}
				Levels.LevelTypes levelTypes = (flag ? Levels.LevelTypes.All : ((Levels.LevelTypes)Enum.Parse(typeof(Levels.LevelTypes), name)));
				if (flag || levelFlags.HasFlag(levelTypes))
				{
					val.spawnableMapObjects = val.spawnableMapObjects.Where((SpawnableMapObject x) => (Object)(object)x.prefabToSpawn != (Object)(object)mapObject2.prefabToSpawn).ToArray();
				}
			}
		}

		public static void RemoveOutsideObject(SpawnableOutsideObjectDef mapObject, Levels.LevelTypes levelFlags, string[] levelOverrides = null)
		{
			RemoveOutsideObject(mapObject.spawnableMapObject, levelFlags, levelOverrides);
		}

		public static void RemoveOutsideObject(SpawnableOutsideObjectWithRarity mapObject, Levels.LevelTypes levelFlags, string[] levelOverrides = null)
		{
			SpawnableOutsideObjectWithRarity mapObject2 = mapObject;
			if (!((Object)(object)StartOfRound.Instance != (Object)null))
			{
				return;
			}
			SelectableLevel[] levels = StartOfRound.Instance.levels;
			foreach (SelectableLevel val in levels)
			{
				string name = ((Object)val).name;
				bool flag = levelFlags.HasFlag(Levels.LevelTypes.All) || (levelOverrides?.Any((string item) => item.ToLowerInvariant() == name.ToLowerInvariant()) ?? false);
				if (levelFlags.HasFlag(Levels.LevelTypes.Modded) && !Enum.IsDefined(typeof(Levels.LevelTypes), name))
				{
					flag = true;
				}
				if (!(Enum.IsDefined(typeof(Levels.LevelTypes), name) || flag))
				{
					continue;
				}
				Levels.LevelTypes levelTypes = (flag ? Levels.LevelTypes.All : ((Levels.LevelTypes)Enum.Parse(typeof(Levels.LevelTypes), name)));
				if (flag || levelFlags.HasFlag(levelTypes))
				{
					val.spawnableOutsideObjects = val.spawnableOutsideObjects.Where((SpawnableOutsideObjectWithRarity x) => (Object)(object)x.spawnableObject.prefabToSpawn != (Object)(object)mapObject2.spawnableObject.prefabToSpawn).ToArray();
				}
			}
		}
	}
	public class NetworkPrefabs
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static hook_Start <0>__GameNetworkManager_Start;
		}

		private static List<GameObject> _networkPrefabs = new List<GameObject>();

		internal static void Init()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			object obj = <>O.<0>__GameNetworkManager_Start;
			if (obj == null)
			{
				hook_Start val = GameNetworkManager_Start;
				<>O.<0>__GameNetworkManager_Start = val;
				obj = (object)val;
			}
			GameNetworkManager.Start += (hook_Start)obj;
		}

		public static void RegisterNetworkPrefab(GameObject prefab)
		{
			if (prefab == null)
			{
				throw new ArgumentNullException("prefab", "The given argument for RegisterNetworkPrefab is null!");
			}
			if (!_networkPrefabs.Contains(prefab))
			{
				_networkPrefabs.Add(prefab);
			}
		}

		public static GameObject CreateNetworkPrefab(string name)
		{
			GameObject obj = PrefabUtils.CreatePrefab(name);
			obj.AddComponent<NetworkObject>();
			byte[] value = MD5.Create().ComputeHash(Encoding.UTF8.GetBytes(Assembly.GetCallingAssembly().GetName().Name + name));
			obj.GetComponent<NetworkObject>().GlobalObjectIdHash = BitConverter.ToUInt32(value, 0);
			RegisterNetworkPrefab(obj);
			return obj;
		}

		public static GameObject CloneNetworkPrefab(GameObject prefabToClone, string newName = null)
		{
			GameObject val = PrefabUtils.ClonePrefab(prefabToClone, newName);
			byte[] value = MD5.Create().ComputeHash(Encoding.UTF8.GetBytes(Assembly.GetCallingAssembly().GetName().Name + ((Object)val).name));
			val.GetComponent<NetworkObject>().GlobalObjectIdHash = BitConverter.ToUInt32(value, 0);
			RegisterNetworkPrefab(val);
			return val;
		}

		private static void GameNetworkManager_Start(orig_Start orig, GameNetworkManager self)
		{
			orig.Invoke(self);
			foreach (GameObject networkPrefab in _networkPrefabs)
			{
				if (!NetworkManager.Singleton.NetworkConfig.Prefabs.Contains(networkPrefab))
				{
					NetworkManager.Singleton.AddNetworkPrefab(networkPrefab);
				}
			}
		}
	}
	public class Player
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static hook_Awake <0>__StartOfRound_Awake;
		}

		public static Dictionary<string, GameObject> ragdollRefs = new Dictionary<string, GameObject>();

		public static Dictionary<string, int> ragdollIndexes = new Dictionary<string, int>();

		public static void Init()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			object obj = <>O.<0>__StartOfRound_Awake;
			if (obj == null)
			{
				hook_Awake val = StartOfRound_Awake;
				<>O.<0>__StartOfRound_Awake = val;
				obj = (object)val;
			}
			StartOfRound.Awake += (hook_Awake)obj;
		}

		private static void StartOfRound_Awake(orig_Awake orig, StartOfRound self)
		{
			orig.Invoke(self);
			foreach (KeyValuePair<string, GameObject> ragdollRef in ragdollRefs)
			{
				if (!self.playerRagdolls.Contains(ragdollRef.Value))
				{
					self.playerRagdolls.Add(ragdollRef.Value);
					int value = self.playerRagdolls.Count - 1;
					if (ragdollIndexes.ContainsKey(ragdollRef.Key))
					{
						ragdollIndexes[ragdollRef.Key] = value;
					}
					else
					{
						ragdollIndexes.Add(ragdollRef.Key, value);
					}
				}
			}
		}

		public static int GetRagdollIndex(string id)
		{
			return ragdollIndexes[id];
		}

		public static GameObject GetRagdoll(string id)
		{
			return ragdollRefs[id];
		}

		public static void RegisterPlayerRagdoll(string id, GameObject ragdoll)
		{
			Plugin.logger.LogInfo((object)("Registering player ragdoll " + id));
			ragdollRefs.Add(id, ragdoll);
		}
	}
	public class PrefabUtils
	{
		internal static Lazy<GameObject> _prefabParent;

		internal static GameObject prefabParent => _prefabParent.Value;

		static PrefabUtils()
		{
			_prefabParent = new Lazy<GameObject>((Func<GameObject>)delegate
			{
				//IL_0005: Unknown result type (might be due to invalid IL or missing references)
				//IL_000a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0012: Unknown result type (might be due to invalid IL or missing references)
				//IL_001a: Expected O, but got Unknown
				GameObject val = new GameObject("LethalLibGeneratedPrefabs")
				{
					hideFlags = (HideFlags)61
				};
				val.SetActive(false);
				return val;
			});
		}

		public static GameObject ClonePrefab(GameObject prefabToClone, string newName = null)
		{
			GameObject val = Object.Instantiate<GameObject>(prefabToClone, prefabParent.transform);
			((Object)val).hideFlags = (HideFlags)61;
			if (newName != null)
			{
				((Object)val).name = newName;
			}
			else
			{
				((Object)val).name = ((Object)prefabToClone).name;
			}
			return val;
		}

		public static GameObject CreatePrefab(string name)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Expected O, but got Unknown
			GameObject val = new GameObje

plugins/LethalSirenHead.dll

Decompiled 2 years ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using LethalLib.Modules;
using LethalSirenHead.NetcodePatcher;
using Unity.Netcode;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("LeathalSirenHead")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("LeathalSirenHead")]
[assembly: AssemblyCopyright("Copyright ©  2024")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("22afcc53-9f27-49f9-b82d-3ff7e8026cce")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: NetcodePatchedAssembly]
internal class <Module>
{
	static <Module>()
	{
	}
}
namespace LethalSirenHead
{
	[BepInPlugin("Ccode.SirenHead", "SirenHead", "0.0.1")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		private const string MyGuid = "Ccode.SirenHead";

		private const string PluginName = "SirenHead";

		private const string VersionString = "0.0.1";

		private static readonly Harmony Harmony = new Harmony("Ccode.SirenHead");

		public static ManualLogSource Log;

		public static EnemyType SirenEnemy;

		public static ConfigEntry<string> AIStart;

		public static ConfigEntry<float> walkSpeed;

		public static ConfigEntry<float> runSpeed;

		public static ConfigEntry<string> Levels;

		public static AudioClip[] spotSound;

		public static AudioClip[] stepSound;

		public static AudioClip[] walkieChatter;

		public void Awake()
		{
			AIStart = ((BaseUnityPlugin)this).Config.Bind<string>("General", "AI Start", "random", "The AI option to use. (tree, standard, or random)");
			walkSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Walk Speed", 3.5f, "Walking speed.");
			runSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Run Speed", 7f, "Running speed.");
			Levels = ((BaseUnityPlugin)this).Config.Bind<string>("General", "Levels", "VowLevel:100;MarchLevel:100", "Moons that it will spawn on. Format: \"MoonName:Weight;MoonName2:Weight2\". All will work as a moon name");
			Assets.PopulateAssets();
			SirenEnemy = Assets.MainAssetBundle.LoadAsset<EnemyType>("SirenHead");
			TerminalNode val = Assets.MainAssetBundle.LoadAsset<TerminalNode>("SirenHeadTN");
			TerminalKeyword val2 = Assets.MainAssetBundle.LoadAsset<TerminalKeyword>("SirenHeadKW");
			spotSound = Utils.LoadSounds(Assets.MainAssetBundle, "sirenheadspot");
			stepSound = Utils.LoadSounds(Assets.MainAssetBundle, "sirenfoot");
			walkieChatter = Utils.LoadSounds(Assets.MainAssetBundle, "sirenchatter");
			AudioClip[] array = spotSound;
			foreach (AudioClip val3 in array)
			{
				Debug.Log((object)((object)val3).ToString());
			}
			AudioClip[] array2 = stepSound;
			foreach (AudioClip val4 in array2)
			{
				Debug.Log((object)((object)val4).ToString());
			}
			AudioClip[] array3 = walkieChatter;
			foreach (AudioClip val5 in array3)
			{
				Debug.Log((object)((object)val5).ToString());
			}
			var (dictionary, dictionary2) = SolveLevels(Levels.Value);
			NetworkPrefabs.RegisterNetworkPrefab(SirenEnemy.enemyPrefab);
			Harmony.PatchAll();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"SirenHead 0.0.1 loaded.");
			Enemies.RegisterEnemy(SirenEnemy, dictionary, dictionary2, val, val2);
			Log = ((BaseUnityPlugin)this).Logger;
			Type[] types = Assembly.GetExecutingAssembly().GetTypes();
			Type[] array4 = types;
			foreach (Type type in array4)
			{
				MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic);
				MethodInfo[] array5 = methods;
				foreach (MethodInfo methodInfo in array5)
				{
					object[] customAttributes = methodInfo.GetCustomAttributes(typeof(RuntimeInitializeOnLoadMethodAttribute), inherit: false);
					if (customAttributes.Length != 0)
					{
						methodInfo.Invoke(null, null);
					}
				}
			}
		}

		private (Dictionary<LevelTypes, int> spawnRateByLevelType, Dictionary<string, int> spawnRateByCustomLevelType) SolveLevels(string config)
		{
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			Dictionary<LevelTypes, int> dictionary = new Dictionary<LevelTypes, int>();
			Dictionary<string, int> dictionary2 = new Dictionary<string, int>();
			string[] array = config.Split(new char[1] { ';' });
			string[] array2 = array;
			foreach (string text in array2)
			{
				string[] array3 = text.Trim().Split(new char[1] { ':' });
				if (array3.Length != 2)
				{
					continue;
				}
				int result = 0;
				if (int.TryParse(array3[1], out result))
				{
					if (Enum.TryParse<LevelTypes>(array3[0], ignoreCase: true, out LevelTypes result2))
					{
						dictionary[result2] = result;
						((BaseUnityPlugin)this).Logger.LogInfo((object)$"Registered spawn rate for level type {result2} to {result}");
					}
					else
					{
						dictionary2[array3[0]] = result;
						((BaseUnityPlugin)this).Logger.LogInfo((object)$"Registered spawn rate for custom level type {array3[0]} to {result}");
					}
				}
			}
			return (dictionary, dictionary2);
		}
	}
	public static class Assets
	{
		public static AssetBundle MainAssetBundle;

		public static void PopulateAssets()
		{
			string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
			MainAssetBundle = AssetBundle.LoadFromFile(Path.Combine(directoryName, "sirenheadassets"));
			if ((Object)(object)MainAssetBundle == (Object)null)
			{
				Plugin.Log.LogError((object)"Failed to load custom assets.");
			}
		}
	}
	internal class Utils
	{
		public static AudioClip[] LoadSounds(AssetBundle bundle, string prefix)
		{
			List<AudioClip> list = new List<AudioClip>();
			string[] allAssetNames = bundle.GetAllAssetNames();
			foreach (string text in allAssetNames)
			{
				if (text.Contains(prefix))
				{
					list.Add(bundle.LoadAsset<AudioClip>(text));
				}
			}
			return list.ToArray();
		}
	}
}
namespace LethalSirenHead.Enemy
{
	public class SirenHeadAI : EnemyAI
	{
		public enum State
		{
			WANDERING,
			TREEING,
			CHASING
		}

		private AISearchRoutine wander = new AISearchRoutine();

		private PlayerControllerB[] players;

		private PlayerControllerB[] closePlayers;

		private string AIStart = Plugin.AIStart.Value;

		private float walkSpeed = Plugin.walkSpeed.Value;

		private float runSpeed = Plugin.runSpeed.Value;

		private float walkieTimer = 0f;

		private float walkieInterval = 0f;

		public override void Start()
		{
			((EnemyAI)this).Start();
			int num = Random.Range(0, 2);
			string value = Plugin.AIStart.Value;
			if (value == "random")
			{
				if (num == 0)
				{
					AIStart = "tree";
				}
				else
				{
					AIStart = "standard";
				}
			}
			else if (value == "tree")
			{
				AIStart = "tree";
			}
			if (((NetworkBehaviour)this).IsHost || ((NetworkBehaviour)this).IsServer)
			{
				walkieInterval = Random.Range(60f, 90f);
				ConfigSyncClientRpc(AIStart, walkSpeed, runSpeed);
			}
		}

		public PlayerControllerB[] CheckLineOfSightForPositionCompat(float width = 45f, int range = 60, Transform eyeObject = null, float proximityCheck = -1f, int layerMask = -1)
		{
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Invalid comparison between Unknown and I4
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			if (layerMask == -1)
			{
				layerMask = StartOfRound.Instance.collidersAndRoomMaskAndDefault;
			}
			if ((Object)(object)eyeObject == (Object)null)
			{
				eyeObject = base.eye;
			}
			if (base.isOutside && !base.enemyType.canSeeThroughFog && (int)TimeOfDay.Instance.currentLevelWeather == 3)
			{
				range = Mathf.Clamp(range, 0, 30);
			}
			List<PlayerControllerB> list = new List<PlayerControllerB>(4);
			for (int i = 0; i < StartOfRound.Instance.allPlayerScripts.Length; i++)
			{
				if (!((EnemyAI)this).PlayerIsTargetable(StartOfRound.Instance.allPlayerScripts[i], false, false))
				{
					continue;
				}
				Vector3 position = ((Component)StartOfRound.Instance.allPlayerScripts[i].gameplayCamera).transform.position;
				if (Vector3.Distance(base.eye.position, position) < (float)range && !Physics.Linecast(eyeObject.position, position, StartOfRound.Instance.collidersAndRoomMaskAndDefault, (QueryTriggerInteraction)1))
				{
					Vector3 val = position - eyeObject.position;
					if (Vector3.Angle(eyeObject.forward, val) < width || Vector3.Distance(((Component)this).transform.position, ((Component)StartOfRound.Instance.allPlayerScripts[i]).transform.position) < proximityCheck)
					{
						list.Add(StartOfRound.Instance.allPlayerScripts[i]);
					}
				}
			}
			if (list.Count == 4)
			{
				return StartOfRound.Instance.allPlayerScripts;
			}
			if (list.Count > 0)
			{
				return list.ToArray();
			}
			return null;
		}

		public bool LineOfSightForPositionCompat(Vector3 objectPosition, float width = 45f, int range = 60, float proximityAwareness = -1f, Transform overrideEye = null)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: 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_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			if (!base.isOutside)
			{
				if (objectPosition.y > -80f)
				{
					return false;
				}
			}
			else if (objectPosition.y < -100f)
			{
				return false;
			}
			Transform val = (((Object)(object)overrideEye != (Object)null) ? overrideEye : ((!((Object)(object)base.eye == (Object)null)) ? base.eye : ((Component)this).transform));
			RaycastHit val2 = default(RaycastHit);
			if (Vector3.Distance(val.position, objectPosition) < (float)range && !Physics.Linecast(val.position, objectPosition, ref val2, StartOfRound.Instance.collidersAndRoomMaskAndDefault))
			{
				Vector3 val3 = objectPosition - val.position;
				if (base.debugEnemyAI)
				{
					Debug.DrawRay(val.position, objectPosition - val.position, Color.green, 2f);
				}
				if (Vector3.Angle(val.forward, val3) < width || Vector3.Distance(((Component)this).transform.position, objectPosition) < proximityAwareness)
				{
					return true;
				}
			}
			return false;
		}

		public void PlaySound(AudioClip clip, float volume = 1f)
		{
			base.creatureVoice.PlayOneShot(clip);
			WalkieTalkie.TransmitOneShotAudio(base.creatureVoice, clip, 1f);
		}

		public void BroadcastOnWalkie(AudioClip clip, float volume = 1f)
		{
			for (int i = 0; i < WalkieTalkie.allWalkieTalkies.Count; i++)
			{
				if (((GrabbableObject)WalkieTalkie.allWalkieTalkies[i]).isBeingUsed)
				{
					WalkieTalkie.allWalkieTalkies[i].target.PlayOneShot(clip, volume);
				}
			}
		}

		[ClientRpc]
		public void playSpotOneshotClientRpc(int index)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
				{
					ClientRpcParams val = default(ClientRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(3190762093u, val, (RpcDelivery)0);
					BytePacker.WriteValueBitPacked(val2, index);
					((NetworkBehaviour)this).__endSendClientRpc(ref val2, 3190762093u, val, (RpcDelivery)0);
				}
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
				{
					PlaySound(Plugin.spotSound[index]);
				}
			}
		}

		[ClientRpc]
		public void playWalkOneshotClientRpc(int index)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
				{
					ClientRpcParams val = default(ClientRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(2872467106u, val, (RpcDelivery)0);
					BytePacker.WriteValueBitPacked(val2, index);
					((NetworkBehaviour)this).__endSendClientRpc(ref val2, 2872467106u, val, (RpcDelivery)0);
				}
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
				{
					PlaySound(Plugin.stepSound[index], 0.4f);
				}
			}
		}

		[ClientRpc]
		public void walkieChatterClientRpc(int index)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
				{
					ClientRpcParams val = default(ClientRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(2456587085u, val, (RpcDelivery)0);
					BytePacker.WriteValueBitPacked(val2, index);
					((NetworkBehaviour)this).__endSendClientRpc(ref val2, 2456587085u, val, (RpcDelivery)0);
				}
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
				{
					BroadcastOnWalkie(Plugin.walkieChatter[index], 0.5f);
				}
			}
		}

		[ClientRpc]
		public void maketreeClientRpc()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
				{
					ClientRpcParams val = default(ClientRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(3470109575u, val, (RpcDelivery)0);
					((NetworkBehaviour)this).__endSendClientRpc(ref val2, 3470109575u, val, (RpcDelivery)0);
				}
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost) && (((NetworkBehaviour)this).IsHost || ((NetworkBehaviour)this).IsServer))
				{
					base.creatureAnimator.SetBool("Tree", true);
					base.agent.speed = 0f;
					base.agent.angularSpeed = 0f;
					((EnemyAI)this).SwitchToBehaviourClientRpc(1);
				}
			}
		}

		[ClientRpc]
		public void makewanderClientRpc()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
				{
					ClientRpcParams val = default(ClientRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(2775163830u, val, (RpcDelivery)0);
					((NetworkBehaviour)this).__endSendClientRpc(ref val2, 2775163830u, val, (RpcDelivery)0);
				}
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
				{
					base.agent.speed = walkSpeed;
					((EnemyAI)this).StartSearch(((Component)this).transform.position, wander);
					((EnemyAI)this).SwitchToBehaviourClientRpc(0);
				}
			}
		}

		[ClientRpc]
		public void makechaseClientRpc()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
				{
					ClientRpcParams val = default(ClientRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(1886140381u, val, (RpcDelivery)0);
					((NetworkBehaviour)this).__endSendClientRpc(ref val2, 1886140381u, val, (RpcDelivery)0);
				}
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
				{
					base.agent.speed = runSpeed;
					playSpotOneshotClientRpc(Random.Range(0, Plugin.spotSound.Length));
					((EnemyAI)this).SwitchToBehaviourClientRpc(2);
				}
			}
		}

		public override void DoAIInterval()
		{
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			((EnemyAI)this).DoAIInterval();
			players = CheckLineOfSightForPositionCompat(50f, 70, base.eye, 15f, StartOfRound.Instance.collidersRoomDefaultAndFoliage);
			closePlayers = CheckLineOfSightForPositionCompat(50f, 20, base.eye, 10f, StartOfRound.Instance.collidersRoomDefaultAndFoliage);
			switch (base.currentBehaviourStateIndex)
			{
			case 0:
				if (players != null)
				{
					((EnemyAI)this).StopSearch(wander, true);
					makechaseClientRpc();
				}
				break;
			case 1:
				if (closePlayers != null)
				{
					if (((NetworkBehaviour)this).IsHost || ((NetworkBehaviour)this).IsServer)
					{
						UntreeClientRpc();
					}
					else
					{
						RequestUntreeServerRpc();
					}
				}
				break;
			case 2:
				if (players == null)
				{
					makewanderClientRpc();
				}
				else
				{
					((EnemyAI)this).SetDestinationToPosition(((Component)players[0]).transform.position, false);
				}
				break;
			}
		}

		public override void Update()
		{
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			((EnemyAI)this).Update();
			if (((NetworkBehaviour)this).IsServer || ((NetworkBehaviour)this).IsHost)
			{
				walkieTimer += Time.deltaTime;
				if (walkieTimer >= walkieInterval)
				{
					walkieChatterClientRpc(Random.Range(0, Plugin.walkieChatter.Length));
					walkieTimer -= walkieInterval;
					walkieInterval = Random.Range(60f, 90f);
				}
			}
			if ((Object)(object)GameNetworkManager.Instance.localPlayerController == (Object)null)
			{
				return;
			}
			if (players != null && base.currentBehaviourStateIndex == 2 && (Object)(object)players[0] == (Object)(object)GameNetworkManager.Instance.localPlayerController)
			{
				GameNetworkManager.Instance.localPlayerController.IncreaseFearLevelOverTime(1.4f, 1f);
			}
			else if (LineOfSightForPositionCompat(((Component)GameNetworkManager.Instance.localPlayerController.gameplayCamera).transform.position, 45f, 70))
			{
				if (Vector3.Distance(((Component)this).transform.position, ((Component)GameNetworkManager.Instance.localPlayerController).transform.position) < 15f)
				{
					GameNetworkManager.Instance.localPlayerController.JumpToFearLevel(0.7f, true);
				}
				else
				{
					GameNetworkManager.Instance.localPlayerController.JumpToFearLevel(0.4f, true);
				}
			}
		}

		public void LateUpdate()
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)base.inSpecialAnimationWithPlayer != (Object)null)
			{
				SirenHeadVars component = ((Component)this).gameObject.GetComponent<SirenHeadVars>();
				((Component)base.inSpecialAnimationWithPlayer).transform.position = new Vector3(component.holdPlayerPoint.position.x, component.holdPlayerPoint.position.y - 0.2f, component.holdPlayerPoint.position.z);
				((Component)base.inSpecialAnimationWithPlayer).transform.rotation = Quaternion.Euler(component.holdPlayerPoint.rotation.x, component.holdPlayerPoint.rotation.y + 180f, component.holdPlayerPoint.rotation.z);
			}
		}

		public override void OnCollideWithPlayer(Collider other)
		{
			((EnemyAI)this).OnCollideWithPlayer(other);
			PlayerControllerB val = (base.inSpecialAnimationWithPlayer = ((Component)other).gameObject.GetComponent<PlayerControllerB>());
			base.inSpecialAnimationWithPlayer.inSpecialInteractAnimation = true;
			base.inSpecialAnimationWithPlayer.inAnimationWithEnemy = (EnemyAI)(object)this;
			if ((Object)(object)val != (Object)null && !val.isPlayerDead && val.AllowPlayerDeath())
			{
				if (((NetworkBehaviour)this).IsHost || ((NetworkBehaviour)this).IsServer)
				{
					StartEatingPlayerClientRpc(val.playerClientId);
				}
				else
				{
					RequestStartEatingPlayerServerRpc(val.playerClientId);
				}
			}
		}

		public void PlayFootstep()
		{
			if (((NetworkBehaviour)this).IsHost || ((NetworkBehaviour)this).IsServer)
			{
				playWalkOneshotClientRpc(Random.Range(0, Plugin.stepSound.Length));
			}
		}

		[ClientRpc]
		public void ConfigSyncClientRpc(string AIStart, float walkSpeed, float runSpeed)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
			{
				ClientRpcParams val = default(ClientRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(3822494571u, val, (RpcDelivery)0);
				bool flag = AIStart != null;
				((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref flag, default(ForPrimitives));
				if (flag)
				{
					((FastBufferWriter)(ref val2)).WriteValueSafe(AIStart, false);
				}
				((FastBufferWriter)(ref val2)).WriteValueSafe<float>(ref walkSpeed, default(ForPrimitives));
				((FastBufferWriter)(ref val2)).WriteValueSafe<float>(ref runSpeed, default(ForPrimitives));
				((NetworkBehaviour)this).__endSendClientRpc(ref val2, 3822494571u, val, (RpcDelivery)0);
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
			{
				this.AIStart = AIStart;
				this.walkSpeed = walkSpeed;
				this.runSpeed = runSpeed;
				if (AIStart == "tree")
				{
					maketreeClientRpc();
				}
				else
				{
					makewanderClientRpc();
				}
			}
		}

		[ServerRpc(RequireOwnership = false)]
		public void RequestStartEatingPlayerServerRpc(ulong player)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
				{
					ServerRpcParams val = default(ServerRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(1905488255u, val, (RpcDelivery)0);
					BytePacker.WriteValueBitPacked(val2, player);
					((NetworkBehaviour)this).__endSendServerRpc(ref val2, 1905488255u, val, (RpcDelivery)0);
				}
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost))
				{
					StartEatingPlayerClientRpc(player);
				}
			}
		}

		[ClientRpc]
		public void StartEatingPlayerClientRpc(ulong player)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
				{
					ClientRpcParams val = default(ClientRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(1290495213u, val, (RpcDelivery)0);
					BytePacker.WriteValueBitPacked(val2, player);
					((NetworkBehaviour)this).__endSendClientRpc(ref val2, 1290495213u, val, (RpcDelivery)0);
				}
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
				{
					((MonoBehaviour)this).StartCoroutine(EatPlayer(player));
				}
			}
		}

		[ServerRpc(RequireOwnership = false)]
		public void RequestUntreeServerRpc()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
				{
					ServerRpcParams val = default(ServerRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(2632362978u, val, (RpcDelivery)0);
					((NetworkBehaviour)this).__endSendServerRpc(ref val2, 2632362978u, val, (RpcDelivery)0);
				}
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost))
				{
					UntreeClientRpc();
				}
			}
		}

		[ClientRpc]
		public void UntreeClientRpc()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
				{
					ClientRpcParams val = default(ClientRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(3081810346u, val, (RpcDelivery)0);
					((NetworkBehaviour)this).__endSendClientRpc(ref val2, 3081810346u, val, (RpcDelivery)0);
				}
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
				{
					Plugin.Log.LogInfo((object)"UnTreeing");
					((MonoBehaviour)this).StartCoroutine(UntreeAndSwitch());
				}
			}
		}

		public IEnumerator UntreeAndSwitch()
		{
			base.inSpecialAnimation = true;
			if (((NetworkBehaviour)this).IsHost || ((NetworkBehaviour)this).IsServer)
			{
				base.creatureAnimator.SetBool("UnTree", true);
				base.creatureAnimator.SetBool("Tree", false);
			}
			yield return (object)new WaitForSeconds(2.5416f);
			if (((NetworkBehaviour)this).IsHost || ((NetworkBehaviour)this).IsServer)
			{
				base.creatureAnimator.SetBool("UnTree", false);
			}
			makechaseClientRpc();
			base.agent.angularSpeed = 100f;
			base.inSpecialAnimation = false;
		}

		public IEnumerator EatPlayer(ulong player)
		{
			PlayerControllerB PlayerObject = StartOfRound.Instance.allPlayerScripts[player];
			if (((NetworkBehaviour)this).IsHost || ((NetworkBehaviour)this).IsServer)
			{
				base.creatureAnimator.SetBool("Eating", true);
			}
			base.inSpecialAnimation = true;
			PlayerObject.isInElevator = false;
			PlayerObject.isInHangarShipRoom = false;
			yield return (object)new WaitForSeconds(7.29f);
			base.inSpecialAnimation = false;
			PlayerObject.KillPlayer(Vector3.zero, false, (CauseOfDeath)8, 0);
			makewanderClientRpc();
			if (((NetworkBehaviour)this).IsHost || ((NetworkBehaviour)this).IsServer)
			{
				base.creatureAnimator.SetBool("Eating", false);
			}
			base.inSpecialAnimationWithPlayer = null;
			PlayerObject.inSpecialInteractAnimation = false;
			PlayerObject.inAnimationWithEnemy = null;
		}

		protected override void __initializeVariables()
		{
			((EnemyAI)this).__initializeVariables();
		}

		[RuntimeInitializeOnLoadMethod]
		internal static void InitializeRPCS_SirenHeadAI()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Expected O, but got Unknown
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Expected O, but got Unknown
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Expected O, but got Unknown
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Expected O, but got Unknown
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Expected O, but got Unknown
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Expected O, but got Unknown
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Expected O, but got Unknown
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Expected O, but got Unknown
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Expected O, but got Unknown
			NetworkManager.__rpc_func_table.Add(3190762093u, new RpcReceiveHandler(__rpc_handler_3190762093));
			NetworkManager.__rpc_func_table.Add(2872467106u, new RpcReceiveHandler(__rpc_handler_2872467106));
			NetworkManager.__rpc_func_table.Add(2456587085u, new RpcReceiveHandler(__rpc_handler_2456587085));
			NetworkManager.__rpc_func_table.Add(3470109575u, new RpcReceiveHandler(__rpc_handler_3470109575));
			NetworkManager.__rpc_func_table.Add(2775163830u, new RpcReceiveHandler(__rpc_handler_2775163830));
			NetworkManager.__rpc_func_table.Add(1886140381u, new RpcReceiveHandler(__rpc_handler_1886140381));
			NetworkManager.__rpc_func_table.Add(3822494571u, new RpcReceiveHandler(__rpc_handler_3822494571));
			NetworkManager.__rpc_func_table.Add(1905488255u, new RpcReceiveHandler(__rpc_handler_1905488255));
			NetworkManager.__rpc_func_table.Add(1290495213u, new RpcReceiveHandler(__rpc_handler_1290495213));
			NetworkManager.__rpc_func_table.Add(2632362978u, new RpcReceiveHandler(__rpc_handler_2632362978));
			NetworkManager.__rpc_func_table.Add(3081810346u, new RpcReceiveHandler(__rpc_handler_3081810346));
		}

		private static void __rpc_handler_3190762093(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				int index = default(int);
				ByteUnpacker.ReadValueBitPacked(reader, ref index);
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((SirenHeadAI)(object)target).playSpotOneshotClientRpc(index);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_2872467106(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				int index = default(int);
				ByteUnpacker.ReadValueBitPacked(reader, ref index);
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((SirenHeadAI)(object)target).playWalkOneshotClientRpc(index);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_2456587085(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				int index = default(int);
				ByteUnpacker.ReadValueBitPacked(reader, ref index);
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((SirenHeadAI)(object)target).walkieChatterClientRpc(index);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_3470109575(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((SirenHeadAI)(object)target).maketreeClientRpc();
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_2775163830(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((SirenHeadAI)(object)target).makewanderClientRpc();
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_1886140381(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((SirenHeadAI)(object)target).makechaseClientRpc();
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_3822494571(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				bool flag = default(bool);
				((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref flag, default(ForPrimitives));
				string aIStart = null;
				if (flag)
				{
					((FastBufferReader)(ref reader)).ReadValueSafe(ref aIStart, false);
				}
				float num = default(float);
				((FastBufferReader)(ref reader)).ReadValueSafe<float>(ref num, default(ForPrimitives));
				float num2 = default(float);
				((FastBufferReader)(ref reader)).ReadValueSafe<float>(ref num2, default(ForPrimitives));
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((SirenHeadAI)(object)target).ConfigSyncClientRpc(aIStart, num, num2);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_1905488255(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				ulong player = default(ulong);
				ByteUnpacker.ReadValueBitPacked(reader, ref player);
				target.__rpc_exec_stage = (__RpcExecStage)1;
				((SirenHeadAI)(object)target).RequestStartEatingPlayerServerRpc(player);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_1290495213(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				ulong player = default(ulong);
				ByteUnpacker.ReadValueBitPacked(reader, ref player);
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((SirenHeadAI)(object)target).StartEatingPlayerClientRpc(player);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_2632362978(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				target.__rpc_exec_stage = (__RpcExecStage)1;
				((SirenHeadAI)(object)target).RequestUntreeServerRpc();
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_3081810346(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((SirenHeadAI)(object)target).UntreeClientRpc();
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		protected internal override string __getTypeName()
		{
			return "SirenHeadAI";
		}
	}
	public class SirenHeadAnimationCalls : MonoBehaviour
	{
		public void PlayFootstep(float filler)
		{
			((Component)this).gameObject.GetComponentInParent<SirenHeadAI>().PlayFootstep();
		}
	}
	internal class SirenHeadVars : MonoBehaviour
	{
		public Transform holdPlayerPoint;

		public AudioSource sfx;
	}
}
namespace LethalSirenHead.NetcodePatcher
{
	[AttributeUsage(AttributeTargets.Module)]
	internal class NetcodePatchedAssemblyAttribute : Attribute
	{
	}
}

plugins/LobbyCompatibility/BMX.LobbyCompatibility.dll

Decompiled 2 years ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Cryptography;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using LobbyCompatibility.Attributes;
using LobbyCompatibility.Behaviours;
using LobbyCompatibility.Configuration;
using LobbyCompatibility.Enums;
using LobbyCompatibility.Features;
using LobbyCompatibility.Models;
using LobbyCompatibility.Pooling;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Steamworks;
using Steamworks.Data;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.Pool;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("AmazingAssets.TerrainToMesh")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp-firstpass")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: IgnoresAccessChecksTo("ClientNetworkTransform")]
[assembly: IgnoresAccessChecksTo("DissonanceVoip")]
[assembly: IgnoresAccessChecksTo("Facepunch Transport for Netcode for GameObjects")]
[assembly: IgnoresAccessChecksTo("Facepunch.Steamworks.Win64")]
[assembly: IgnoresAccessChecksTo("Unity.AI.Navigation")]
[assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging")]
[assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging.DocCodeExamples")]
[assembly: IgnoresAccessChecksTo("Unity.Burst")]
[assembly: IgnoresAccessChecksTo("Unity.Burst.Unsafe")]
[assembly: IgnoresAccessChecksTo("Unity.Collections")]
[assembly: IgnoresAccessChecksTo("Unity.Collections.LowLevel.ILSupport")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem.ForUI")]
[assembly: IgnoresAccessChecksTo("Unity.Jobs")]
[assembly: IgnoresAccessChecksTo("Unity.Mathematics")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.Common")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.MetricTypes")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStats")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Component")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Configuration")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Implementation")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsReporting")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkProfiler.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkSolutionInterface")]
[assembly: IgnoresAccessChecksTo("Unity.Netcode.Components")]
[assembly: IgnoresAccessChecksTo("Unity.Netcode.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.Networking.Transport")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Csg")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.KdTree")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Poly2Tri")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Stl")]
[assembly: IgnoresAccessChecksTo("Unity.Profiling.Core")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.ShaderLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Config.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Authentication")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Analytics")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Configuration")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Device")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments.Internal")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Internal")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Networking")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Registration")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Scheduler")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Telemetry")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Threading")]
[assembly: IgnoresAccessChecksTo("Unity.Services.QoS")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Relay")]
[assembly: IgnoresAccessChecksTo("Unity.TextMeshPro")]
[assembly: IgnoresAccessChecksTo("Unity.Timeline")]
[assembly: IgnoresAccessChecksTo("Unity.VisualEffectGraph.Runtime")]
[assembly: IgnoresAccessChecksTo("UnityEngine.ARModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.NVIDIAModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UI")]
[assembly: AssemblyCompany("MaxWasUnavailable;legoandmars;xilophor")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Towards a future with fewer lobby incompatibility errors.")]
[assembly: AssemblyFileVersion("1.1.0.0")]
[assembly: AssemblyInformationalVersion("1.1.0+38181b0f6a37b2077f429a066e8ab4b22eb82ad8")]
[assembly: AssemblyProduct("LobbyCompatibility")]
[assembly: AssemblyTitle("BMX.LobbyCompatibility")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/MaxWasUnavailable/LobbyCompatibility")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.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.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[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 LobbyCompatibility
{
	[LobbyCompatibility(CompatibilityLevel.ClientOnly, VersionStrictness.Minor)]
	[BepInPlugin("BMX.LobbyCompatibility", "LobbyCompatibility", "1.1.0")]
	public class LobbyCompatibilityPlugin : BaseUnityPlugin
	{
		private bool _isPatched;

		private Harmony? Harmony { get; set; }

		internal static ManualLogSource? Logger { get; private set; }

		public static LobbyCompatibilityPlugin? Instance { get; private set; }

		public static Config? Config { get; private set; }

		private void Awake()
		{
			Instance = this;
			Logger = ((BaseUnityPlugin)this).Logger;
			Config = new Config(((BaseUnityPlugin)this).Config);
			PatchAll();
			Logger.LogInfo((object)"Plugin BMX.LobbyCompatibility is loaded!");
		}

		public void PatchAll()
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Expected O, but got Unknown
			//IL_004c: Expected O, but got Unknown
			if (_isPatched)
			{
				ManualLogSource? logger = Logger;
				if (logger != null)
				{
					logger.LogWarning((object)"Already patched!");
				}
				return;
			}
			ManualLogSource? logger2 = Logger;
			if (logger2 != null)
			{
				logger2.LogDebug((object)"Patching...");
			}
			if (Harmony == null)
			{
				Harmony val = new Harmony("BMX.LobbyCompatibility");
				Harmony val2 = val;
				Harmony = val;
			}
			Harmony.PatchAll();
			_isPatched = true;
			ManualLogSource? logger3 = Logger;
			if (logger3 != null)
			{
				logger3.LogDebug((object)"Patched!");
			}
		}

		public void UnpatchAll()
		{
			if (!_isPatched)
			{
				ManualLogSource? logger = Logger;
				if (logger != null)
				{
					logger.LogWarning((object)"Already unpatched!");
				}
				return;
			}
			ManualLogSource? logger2 = Logger;
			if (logger2 != null)
			{
				logger2.LogDebug((object)"Unpatching...");
			}
			Harmony.UnpatchSelf();
			_isPatched = false;
			ManualLogSource? logger3 = Logger;
			if (logger3 != null)
			{
				logger3.LogDebug((object)"Unpatched!");
			}
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "BMX.LobbyCompatibility";

		public const string PLUGIN_NAME = "LobbyCompatibility";

		public const string PLUGIN_VERSION = "1.1.0";
	}
}
namespace LobbyCompatibility.Pooling
{
	internal class PluginCategorySlotPool : MonoBehaviour
	{
		private PluginCategorySlot? _template;

		private Transform? _container;

		private IObjectPool<PluginCategorySlot>? _pool;

		public void InitializeUsingTemplate(PluginCategorySlot template, Transform container)
		{
			_container = container;
			_template = template;
			_pool = (IObjectPool<PluginCategorySlot>?)(object)new ObjectPool<PluginCategorySlot>((Func<PluginCategorySlot>)CreatePooledItem, (Action<PluginCategorySlot>)OnTakeFromPool, (Action<PluginCategorySlot>)OnReturnedToPool, (Action<PluginCategorySlot>)OnDestroyPoolObject, false, 10, 10000);
		}

		public PluginCategorySlot? Spawn(PluginDiffResult pluginDiffResult)
		{
			PluginCategorySlot pluginCategorySlot = SpawnInternal();
			pluginCategorySlot?.SetPluginDiffResult(pluginDiffResult);
			return pluginCategorySlot;
		}

		public void Release(PluginCategorySlot pluginCategorySlot)
		{
			if (!((Object)(object)pluginCategorySlot == (Object)null) && _pool != null)
			{
				_pool.Release(pluginCategorySlot);
			}
		}

		private PluginCategorySlot? SpawnInternal()
		{
			if ((Object)(object)_template == (Object)null || (Object)(object)_container == (Object)null || _pool == null)
			{
				ManualLogSource? logger = LobbyCompatibilityPlugin.Logger;
				if (logger != null)
				{
					logger.LogInfo((object)"PluginCategorySlotPool tried to spawn an item, but was not initialized properly.");
				}
				return null;
			}
			return _pool.Get();
		}

		private PluginCategorySlot CreatePooledItem()
		{
			if ((Object)(object)_template == (Object)null || (Object)(object)_container == (Object)null)
			{
				throw new NullReferenceException("Template is missing! Did it get destroyed?");
			}
			PluginCategorySlot pluginCategorySlot = Object.Instantiate<PluginCategorySlot>(_template, _container);
			((Component)pluginCategorySlot).gameObject.SetActive(true);
			return pluginCategorySlot;
		}

		private void OnTakeFromPool(PluginCategorySlot pluginCategorySlot)
		{
			((Component)pluginCategorySlot).gameObject.SetActive(true);
			((Component)pluginCategorySlot).transform.SetAsLastSibling();
		}

		private void OnReturnedToPool(PluginCategorySlot pluginCategorySlot)
		{
			((Component)pluginCategorySlot).gameObject.SetActive(false);
		}

		private void OnDestroyPoolObject(PluginCategorySlot pluginCategorySlot)
		{
			Object.Destroy((Object)(object)((Component)pluginCategorySlot).gameObject);
		}
	}
	internal class PluginDiffSlotPool : MonoBehaviour
	{
		private PluginDiffSlot? _template;

		private Transform? _container;

		private IObjectPool<PluginDiffSlot>? _pool;

		public void InitializeUsingTemplate(PluginDiffSlot template, Transform container)
		{
			_container = container;
			_template = template;
			_pool = (IObjectPool<PluginDiffSlot>?)(object)new ObjectPool<PluginDiffSlot>((Func<PluginDiffSlot>)CreatePooledItem, (Action<PluginDiffSlot>)OnTakeFromPool, (Action<PluginDiffSlot>)OnReturnedToPool, (Action<PluginDiffSlot>)OnDestroyPoolObject, false, 20, 10000);
		}

		public PluginDiffSlot? Spawn(PluginDiff pluginDiff, bool lobbyCompatibilityPresent)
		{
			PluginDiffSlot pluginDiffSlot = SpawnInternal();
			pluginDiffSlot?.SetPluginDiff(pluginDiff, lobbyCompatibilityPresent);
			return pluginDiffSlot;
		}

		public PluginDiffSlot? Spawn(string pluginNameText, string clientVersionText, string serverVersionText, Color color)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			PluginDiffSlot pluginDiffSlot = SpawnInternal();
			pluginDiffSlot?.SetText(pluginNameText, clientVersionText, serverVersionText, color);
			return pluginDiffSlot;
		}

		public void Release(PluginDiffSlot pluginDiffSlot)
		{
			if (!((Object)(object)pluginDiffSlot == (Object)null) && _pool != null)
			{
				_pool.Release(pluginDiffSlot);
			}
		}

		private PluginDiffSlot? SpawnInternal()
		{
			if ((Object)(object)_template == (Object)null || (Object)(object)_container == (Object)null || _pool == null)
			{
				ManualLogSource? logger = LobbyCompatibilityPlugin.Logger;
				if (logger != null)
				{
					logger.LogInfo((object)"PluginDiffSlotPool tried to spawn an item, but was not initialized properly.");
				}
				return null;
			}
			return _pool.Get();
		}

		private PluginDiffSlot CreatePooledItem()
		{
			if ((Object)(object)_template == (Object)null || (Object)(object)_container == (Object)null)
			{
				throw new NullReferenceException("Template is missing! Did it get destroyed?");
			}
			PluginDiffSlot pluginDiffSlot = Object.Instantiate<PluginDiffSlot>(_template, _container);
			((Component)pluginDiffSlot).gameObject.SetActive(true);
			return pluginDiffSlot;
		}

		private void OnTakeFromPool(PluginDiffSlot pluginDiffSlot)
		{
			((Component)pluginDiffSlot).gameObject.SetActive(true);
			((Component)pluginDiffSlot).transform.SetAsLastSibling();
		}

		private void OnReturnedToPool(PluginDiffSlot pluginDiffSlot)
		{
			((Component)pluginDiffSlot).gameObject.SetActive(false);
		}

		private void OnDestroyPoolObject(PluginDiffSlot pluginDiffSlot)
		{
			Object.Destroy((Object)(object)((Component)pluginDiffSlot).gameObject);
		}
	}
}
namespace LobbyCompatibility.Patches
{
	[HarmonyPatch(/*Could not decode attribute arguments.*/)]
	[HarmonyPriority(0)]
	[HarmonyWrapSafe]
	internal class ES3SettingsConstructorPrefix
	{
		[HarmonyPrefix]
		private static void FileSettings(ref string path)
		{
			path = ((path == "LCChallengeFile") ? "LCModdedChallengeFile" : path);
		}
	}
	[HarmonyPatch(typeof(ISteamUserStats), "FindOrCreateLeaderboard")]
	[HarmonyPriority(0)]
	[HarmonyWrapSafe]
	internal class FindOrCreateLeaderboardPrefix
	{
		[HarmonyPrefix]
		private static void Prefix(ref string pchLeaderboardName)
		{
			pchLeaderboardName = (pchLeaderboardName.StartsWith("challenge") ? ("modded_" + pchLeaderboardName) : pchLeaderboardName);
		}
	}
	[HarmonyPatch]
	[HarmonyPriority(0)]
	[HarmonyWrapSafe]
	internal static class GetLeaderboardForChallengeTranspiler
	{
		[HarmonyTargetMethod]
		private static MethodBase? TargetMethod()
		{
			return AccessTools.Method(typeof(MenuManager), "GetLeaderboardForChallenge", (Type[])null, (Type[])null).GetCustomAttribute<AsyncStateMachineAttribute>().StateMachineType.GetMethod("MoveNext", BindingFlags.Instance | BindingFlags.NonPublic);
		}

		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			return new CodeMatcher(instructions, (ILGenerator)null).SearchForward((Func<CodeInstruction, bool>)((CodeInstruction instruction) => CodeInstructionExtensions.OperandIs(instruction, (object)" Results"))).ThrowIfInvalid("Could not find leaderboard results text").SetOperandAndAdvance((object)" Results (Modded)")
				.InstructionEnumeration();
		}
	}
	[HarmonyPatch]
	[HarmonyPriority(800)]
	[HarmonyWrapSafe]
	internal class LoadLobbyListAndFilterTranspiler
	{
		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Expected O, but got Unknown
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Expected O, but got Unknown
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Expected O, but got Unknown
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Expected O, but got Unknown
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Expected O, but got Unknown
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Expected O, but got Unknown
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Expected O, but got Unknown
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Expected O, but got Unknown
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Expected O, but got Unknown
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Expected O, but got Unknown
			//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d8: Expected O, but got Unknown
			//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e6: Expected O, but got Unknown
			//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f4: Expected O, but got Unknown
			FieldInfo fieldInfo = AccessTools.Field(typeof(SteamLobbyManager), "currentLobbyList");
			FieldInfo fieldInfo2 = AccessTools.Field(typeof(LobbySlot), "thisLobby");
			FieldInfo fieldInfo3 = AccessTools.Field(typeof(SteamLobbyManager), "levelListContainer");
			MethodInfo methodInfo = AccessTools.Method(typeof(LoadLobbyListAndFilterTranspiler), "InitializeLobbySlot", (Type[])null, (Type[])null);
			MethodInfo methodInfo2 = AccessTools.Method(typeof(Lobby), "GetData", (Type[])null, (Type[])null);
			MethodInfo methodInfo3 = AccessTools.Method(typeof(LoadLobbyListAndFilterTranspiler), "ReplaceLobbyName", (Type[])null, (Type[])null);
			return new CodeMatcher(instructions, (ILGenerator)null).MatchForward(false, (CodeMatch[])(object)new CodeMatch[2]
			{
				new CodeMatch((OpCode?)OpCodes.Ldstr, (object)"name", (string)null),
				new CodeMatch((OpCode?)OpCodes.Call, (object)methodInfo2, (string)null)
			}).ThrowIfNotMatch("Unable to find Lobby.GetData(name) line.", Array.Empty<CodeMatch>()).Advance(2)
				.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
				{
					new CodeInstruction(OpCodes.Call, (object)methodInfo3)
				})
				.MatchForward(false, (CodeMatch[])(object)new CodeMatch[6]
				{
					new CodeMatch((OpCode?)OpCodes.Ldloc_1, (object)null, (string)null),
					new CodeMatch((OpCode?)OpCodes.Ldfld, (object)fieldInfo, (string)null),
					new CodeMatch((OpCode?)OpCodes.Ldarg_0, (object)null, (string)null),
					new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction inst) => inst.opcode == OpCodes.Ldfld), (string)null),
					new CodeMatch((OpCode?)OpCodes.Ldelem, (object)typeof(Lobby), (string)null),
					new CodeMatch((OpCode?)OpCodes.Stfld, (object)fieldInfo2, (string)null)
				})
				.ThrowIfNotMatch("Unable to find LobbySlot.thisLobby line.", Array.Empty<CodeMatch>())
				.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
				{
					new CodeInstruction(OpCodes.Dup, (object)null)
				})
				.Advance(6)
				.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[3]
				{
					new CodeInstruction(OpCodes.Ldloc_1, (object)null),
					new CodeInstruction(OpCodes.Ldfld, (object)fieldInfo3),
					new CodeInstruction(OpCodes.Call, (object)methodInfo)
				})
				.InstructionEnumeration();
		}

		private static void InitializeLobbySlot(LobbySlot lobbySlot, Transform levelListContainer)
		{
			ModdedLobbySlot moddedLobbySlot = ((Component)lobbySlot).gameObject.AddComponent<ModdedLobbySlot>();
			moddedLobbySlot.Setup(lobbySlot);
			moddedLobbySlot.SetParentContainer(levelListContainer.parent);
		}

		private static string ReplaceLobbyName(string lobbyName)
		{
			if (lobbyName.Length == 0)
			{
				return lobbyName;
			}
			return lobbyName.Replace("[MOD]", "").Replace("<size=0>unisex</size>", string.Empty);
		}
	}
	[HarmonyPatch]
	[HarmonyPriority(800)]
	[HarmonyWrapSafe]
	internal class LoadServerListTranspiler
	{
		[HarmonyTargetMethod]
		private static MethodBase? TargetMethod()
		{
			return HarmonyHelper.GetAsyncInfo(typeof(SteamLobbyManager), "LoadServerList");
		}

		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator ilGenerator)
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Expected O, but got Unknown
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Expected O, but got Unknown
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Expected O, but got Unknown
			//IL_00eb: Expected O, but got Unknown
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Expected O, but got Unknown
			MethodInfo searchCoroutineMethod = AccessTools.Method(typeof(MonoBehaviour), "StartCoroutine", new Type[1] { typeof(IEnumerator) }, (Type[])null);
			MethodInfo methodInfo = AccessTools.Method(typeof(LoadServerListTranspiler), "LoadListPostfix", (Type[])null, (Type[])null);
			Label label = default(Label);
			CodeMatcher obj = new CodeMatcher(instructions, ilGenerator).SearchForward((Func<CodeInstruction, bool>)((CodeInstruction inst) => CodeInstructionExtensions.Calls(inst, searchCoroutineMethod))).ThrowIfInvalid("Unable to find StartCoroutine.").Advance(1)
				.SetInstruction(new CodeInstruction(OpCodes.Nop, (object)null))
				.CreateLabel(ref label)
				.Advance(-7)
				.SetInstructionAndAdvance(new CodeInstruction(OpCodes.Br, (object)label))
				.SearchForward((Func<CodeInstruction, bool>)((CodeInstruction inst) => inst.opcode == OpCodes.Leave))
				.ThrowIfInvalid("Unable to find leave instruction.");
			CodeInstruction[] array = new CodeInstruction[2];
			CodeInstruction val = new CodeInstruction(OpCodes.Ldloc_1, (object)null);
			CodeInstruction val2 = val;
			array[0] = val;
			array[1] = new CodeInstruction(OpCodes.Call, (object)methodInfo);
			CodeMatcher val3 = obj.InsertAndAdvance((CodeInstruction[])(object)array);
			CodeInstructionExtensions.MoveLabelsTo(val3.Instruction, val2);
			return val3.InstructionEnumeration();
		}

		internal static async void LoadListPostfix(SteamLobbyManager steamLobbyManager)
		{
			LobbyQuery lobbyList = SteamMatchmaking.LobbyList;
			lobbyList.stringFilters = LobbyHelper.LatestLobbyRequestStringFilters;
			lobbyList.distance = LobbyHelper.LatestLobbyRequestDistanceFilter;
			ModdedLobbyFilter currentFilter = (((Object)(object)ModdedLobbyFilterDropdown.Instance != (Object)null) ? ModdedLobbyFilterDropdown.Instance.LobbyFilter : ModdedLobbyFilter.All);
			if (lobbyList.stringFilters.ContainsKey("tag"))
			{
				currentFilter = ModdedLobbyFilter.All;
			}
			Lobby[] filteredLobbies = null;
			if (PluginHelper.Checksum != "" && (currentFilter == ModdedLobbyFilter.CompatibleFirst || currentFilter == ModdedLobbyFilter.CompatibleOnly))
			{
				if (lobbyList.stringFilters.ContainsKey("checksum"))
				{
					lobbyList.stringFilters.Remove("checksum");
				}
				else
				{
					((LobbyQuery)(ref lobbyList)).WithKeyValue("checksum", PluginHelper.Checksum);
				}
				filteredLobbies = await ((LobbyQuery)(ref lobbyList)).RequestAsync();
			}
			Lobby[] source = LobbyHelper.FilterLobbies((Lobby[])(((object)steamLobbyManager.currentLobbyList) ?? ((object)new Lobby[0])), filteredLobbies, currentFilter);
			steamLobbyManager.currentLobbyList = source.ToArray();
			if (!source.Any())
			{
				((TMP_Text)steamLobbyManager.serverListBlankText).text = LobbyHelper.GetEmptyLobbyListString(currentFilter);
			}
			else
			{
				steamLobbyManager.loadLobbyListCoroutine = ((MonoBehaviour)steamLobbyManager).StartCoroutine(steamLobbyManager.loadLobbyListAndFilter(steamLobbyManager.currentLobbyList));
			}
		}
	}
	[HarmonyPatch(typeof(GameNetworkManager), "LobbyDataIsJoinable")]
	[HarmonyPriority(0)]
	[HarmonyWrapSafe]
	internal static class LobbyDataIsJoinablePostfix
	{
		[HarmonyPostfix]
		private static bool Postfix(bool isJoinable, ref Lobby lobby)
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			if (!isJoinable)
			{
				return false;
			}
			if (((Lobby)(ref lobby)).GetData("modded") != "true" && !PluginHelper.CanJoinVanillaLobbies())
			{
				Object.FindObjectOfType<MenuManager>().SetLoadingScreen(false, (RoomEnter)3, "You are using mods which aren't strictly client-side, but the lobby is not modded.");
				return PluginHelper.CanJoinVanillaLobbies() && isJoinable;
			}
			string text = GeneralExtensions.Join<char>((IEnumerable<char>)LobbyHelper.GetLobbyPlugins(lobby), (Func<char, string>)null, string.Empty);
			LobbyHelper.GetLobbyDiff(lobby, text);
			if (string.IsNullOrEmpty(text))
			{
				ManualLogSource? logger = LobbyCompatibilityPlugin.Logger;
				if (logger != null)
				{
					logger.LogWarning((object)"Lobby is modded but does not have any plugin information.");
				}
				return isJoinable;
			}
			bool flag = PluginHelper.MatchesTargetRequirements(PluginHelper.ParseLobbyPluginsMetadata(text));
			if (!flag)
			{
				ManualLogSource? logger2 = LobbyCompatibilityPlugin.Logger;
				if (logger2 != null)
				{
					logger2.LogWarning((object)"You are missing required plugins to join this lobby.");
				}
				Object.FindObjectOfType<MenuManager>().SetLoadingScreen(false, (RoomEnter)5, "You are missing required mods to join this lobby.");
			}
			return flag;
		}
	}
	[HarmonyPatch(typeof(GameNetworkManager), "LobbyDataIsJoinable")]
	[HarmonyPriority(0)]
	[HarmonyWrapSafe]
	internal static class LobbyDataIsJoinableTranspiler
	{
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Expected O, but got Unknown
			return new CodeMatcher(instructions, (ILGenerator)null).SearchForward((Func<CodeInstruction, bool>)((CodeInstruction instruction) => CodeInstructionExtensions.OperandIs(instruction, (object)"joinable"))).ThrowIfInvalid("Could not find joinable").RemoveInstructions(4)
				.Insert((CodeInstruction[])(object)new CodeInstruction[1]
				{
					new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(LobbyDataIsJoinableTranspiler), "IsJoinable", (Type[])null, (Type[])null))
				})
				.InstructionEnumeration();
		}

		private static bool IsJoinable(ref Lobby lobby)
		{
			if (!(((Lobby)(ref lobby)).GetData("_joinable") == "true"))
			{
				return ((Lobby)(ref lobby)).GetData("joinable") == "true";
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(MenuManager), "Start")]
	[HarmonyPriority(0)]
	[HarmonyWrapSafe]
	internal static class MenuManagerPostfix
	{
		[HarmonyPostfix]
		private static void Postfix(MenuManager __instance)
		{
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Expected O, but got Unknown
			if (__instance.isInitScene)
			{
				return;
			}
			Transform val = __instance.serverListUIContainer.transform.Find("ListPanel");
			Transform val2 = (((Object)(object)val != (Object)null) ? val.Find("Scroll View") : null);
			TextMeshProUGUI privatePublicDescription = __instance.privatePublicDescription;
			if (!((Object)(object)val == (Object)null) && !((Object)(object)val2 == (Object)null) && !((Object)(object)privatePublicDescription == (Object)null))
			{
				ManualLogSource? logger = LobbyCompatibilityPlugin.Logger;
				if (logger != null)
				{
					logger.LogInfo((object)"Initializing menu UI.");
				}
				((TMP_Text)__instance.leaderboardHeaderText).rectTransform.offsetMax = new Vector2(2000f, ((TMP_Text)__instance.leaderboardHeaderText).rectTransform.offsetMax.y);
				Transform parent = __instance.menuNotification.transform.parent;
				GameObject val3 = Object.Instantiate<GameObject>(__instance.menuNotification, parent);
				val3.AddComponent<ModListTooltipPanel>();
				val3.SetActive(true);
				GameObject panel = Object.Instantiate<GameObject>(__instance.menuNotification, parent);
				GameObject val4 = new GameObject("ModListPanel Handler");
				val4.transform.SetParent(parent);
				ModListPanel modListPanel = val4.AddComponent<ModListPanel>();
				modListPanel.SetupPanel(panel, val2, privatePublicDescription);
				Transform obj = val.Find("RefreshButton");
				Button val5 = ((obj != null) ? ((Component)obj).GetComponent<Button>() : null);
				if ((Object)(object)val5 != (Object)null)
				{
					UIHelper.ReskinRefreshButton(val5);
				}
				UIHelper.AddCustomFilterToLobbyList(val);
			}
		}
	}
	[HarmonyPatch(typeof(LobbyQuery), "RequestAsync")]
	[HarmonyPriority(0)]
	[HarmonyWrapSafe]
	internal static class RequestAsyncPrefix
	{
		[HarmonyPrefix]
		private static void Prefix(LobbyQuery __instance)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			LobbyHelper.LatestLobbyRequestStringFilters = __instance.stringFilters ?? new Dictionary<string, string>();
			LobbyHelper.LatestLobbyRequestDistanceFilter = __instance.distance;
		}
	}
	[HarmonyPatch(typeof(MenuManager), "SetLoadingScreen")]
	[HarmonyPriority(800)]
	[HarmonyWrapSafe]
	internal static class SetLoadingScreenPrefix
	{
		[HarmonyPrefix]
		private static bool Prefix(bool isLoading, RoomEnter result, MenuManager __instance)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			if (isLoading)
			{
				return true;
			}
			if ((int)result != 5)
			{
				return true;
			}
			__instance.MenuAudio.volume = 0.5f;
			__instance.menuButtons.SetActive(true);
			__instance.loadingScreen.SetActive(false);
			__instance.serverListUIContainer.SetActive(false);
			if ((Object)(object)ModListPanel.Instance != (Object)null)
			{
				ModListPanel.Instance.DisplayNotification(LobbyHelper.LatestLobbyDiff, "Error while joining...");
			}
			ManualLogSource? logger = LobbyCompatibilityPlugin.Logger;
			if (logger != null)
			{
				logger.LogDebug((object)"Error while joining! Logging Diff...");
			}
			ManualLogSource? logger2 = LobbyCompatibilityPlugin.Logger;
			if (logger2 != null)
			{
				logger2.LogDebug((object)GeneralExtensions.Join<PluginDiff>((IEnumerable<PluginDiff>)LobbyHelper.LatestLobbyDiff.PluginDiffs, (Func<PluginDiff, string>)((PluginDiff diff) => diff.GetDisplayText()), ", "));
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(GameNetworkManager), "SteamMatchmaking_OnLobbyCreated")]
	[HarmonyPriority(0)]
	[HarmonyWrapSafe]
	internal static class SteamMatchmakingOnLobbyCreatedPostfix
	{
		[HarmonyPostfix]
		private static void Postfix(Result result, ref Lobby lobby)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Invalid comparison between Unknown and I4
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			if ((int)result != 1)
			{
				return;
			}
			List<PluginInfoRecord> source = PluginHelper.GetAllPluginInfo().ToList();
			((Lobby)(ref lobby)).SetData("modded", "true");
			string[] array = PluginHelper.GetLobbyPluginsMetadata().ToArray();
			for (int i = 0; i < array.Length; i++)
			{
				((Lobby)(ref lobby)).SetData(string.Format("{0}{1}", "plugins", i), array[i] + ((i < array.Length - 1) ? "@" : string.Empty));
			}
			((Lobby)(ref lobby)).SetData("_joinable", ((Lobby)(ref lobby)).GetData("joinable"));
			((Lobby)(ref lobby)).SetData("checksum", PluginHelper.Checksum);
			if (source.Any(delegate(PluginInfoRecord plugin)
			{
				CompatibilityLevel? compatibilityLevel = plugin.CompatibilityLevel;
				if (compatibilityLevel.HasValue)
				{
					CompatibilityLevel valueOrDefault = compatibilityLevel.GetValueOrDefault();
					if ((uint)(valueOrDefault - 1) <= 2u)
					{
						return true;
					}
				}
				return false;
			}) && !LobbyHelper.LobbyNameContainsModIdentifier(lobby))
			{
				((Lobby)(ref lobby)).SetData("name", "[MOD]" + ((Lobby)(ref lobby)).GetData("name"));
			}
			((Lobby)(ref lobby)).SetData("name", ((Lobby)(ref lobby)).GetData("name") + "<size=0>unisex</size>");
			if (source.Any((PluginInfoRecord plugin) => plugin.CompatibilityLevel == CompatibilityLevel.Everyone))
			{
				ManualLogSource? logger = LobbyCompatibilityPlugin.Logger;
				if (logger != null)
				{
					logger.LogWarning((object)"You are hosting a lobby with required plugins. Disabling vanilla clients from joining.");
				}
				((Lobby)(ref lobby)).SetData("joinable", "false");
			}
		}
	}
}
namespace LobbyCompatibility.Models
{
	public record LobbyDiff(List<PluginDiff> PluginDiffs, bool LobbyCompatibilityPresent = true)
	{
		private LobbyDiffResult? _cachedResult;

		public string GetDisplayText(bool shortened = false)
		{
			LobbyDiffResult moddedLobbyType = GetModdedLobbyType();
			string text = ((moddedLobbyType != LobbyDiffResult.PresumedCompatible) ? moddedLobbyType.ToString() : (shortened ? "Compatible?" : "Presumed Compatible"));
			return "Mod Status: " + text;
		}

		internal LobbyDiffResult GetModdedLobbyType()
		{
			if (_cachedResult.HasValue)
			{
				return _cachedResult.Value;
			}
			LobbyDiffResult? lobbyDiffResult;
			if (!LobbyCompatibilityPresent)
			{
				lobbyDiffResult = (_cachedResult = LobbyDiffResult.Unknown);
				return lobbyDiffResult.Value;
			}
			bool flag = PluginDiffs.Any((PluginDiff pluginDiff) => pluginDiff.PluginDiffResult == PluginDiffResult.Unknown);
			if (PluginDiffs.Any((PluginDiff pluginDiff) => pluginDiff.PluginDiffResult != 0 && pluginDiff.PluginDiffResult != PluginDiffResult.Unknown))
			{
				lobbyDiffResult = (_cachedResult = LobbyDiffResult.Incompatible);
				return lobbyDiffResult.Value;
			}
			if (flag)
			{
				lobbyDiffResult = (_cachedResult = LobbyDiffResult.PresumedCompatible);
				return lobbyDiffResult.Value;
			}
			lobbyDiffResult = (_cachedResult = LobbyDiffResult.Compatible);
			return lobbyDiffResult.Value;
		}

		[CompilerGenerated]
		protected virtual bool PrintMembers(StringBuilder builder)
		{
			RuntimeHelpers.EnsureSufficientExecutionStack();
			builder.Append("PluginDiffs = ");
			builder.Append(PluginDiffs);
			builder.Append(", LobbyCompatibilityPresent = ");
			builder.Append(LobbyCompatibilityPresent.ToString());
			return true;
		}
	}
	public record PluginDiff(PluginDiffResult PluginDiffResult, string GUID, Version? ClientVersion, Version? ServerVersion)
	{
		public string GetDisplayText()
		{
			string text = GUID ?? "";
			if (ClientVersion != null)
			{
				text += $"-v{ClientVersion}";
			}
			if (PluginDiffResult == PluginDiffResult.ModVersionMismatch && ServerVersion != null)
			{
				text += $" — v{ServerVersion} was required";
			}
			return text;
		}

		public Color GetTextColor()
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			switch (PluginDiffResult)
			{
			case PluginDiffResult.Compatible:
				return LobbyCompatibilityPlugin.Config?.CompatibleColor.Value ?? Config.DefaultCompatibleColor;
			case PluginDiffResult.ServerMissingMod:
			case PluginDiffResult.ClientMissingMod:
			case PluginDiffResult.ModVersionMismatch:
				return LobbyCompatibilityPlugin.Config?.IncompatibleColor.Value ?? Config.DefaultIncompatibleColor;
			default:
				return LobbyCompatibilityPlugin.Config?.UnknownColor.Value ?? Config.DefaultUnknownColor;
			}
		}
	}
	[Serializable]
	public record PluginInfoRecord([property: JsonProperty("i")] string GUID, [property: JsonProperty("v"), JsonConverter(typeof(VersionConverter))] Version Version, [property: JsonProperty("c")] CompatibilityLevel? CompatibilityLevel, [property: JsonProperty("s")] VersionStrictness? VersionStrictness);
}
namespace LobbyCompatibility.Features
{
	internal static class HarmonyHelper
	{
		public static MethodInfo? GetAsyncInfo(Type type, string method)
		{
			return AccessTools.Method(type, method, (Type[])null, (Type[])null).GetCustomAttribute<AsyncStateMachineAttribute>().StateMachineType.GetMethod("MoveNext", BindingFlags.Instance | BindingFlags.NonPublic);
		}
	}
	public static class LobbyHelper
	{
		public static readonly Regex ModdedLobbyIdentifierRegex = new Regex("(\\bmod(s|ded)?\\b)", RegexOptions.IgnoreCase);

		public static Dictionary<string, string> LatestLobbyRequestStringFilters = new Dictionary<string, string>();

		public static LobbyDistanceFilter? LatestLobbyRequestDistanceFilter;

		private static List<PluginInfoRecord>? _clientPlugins;

		public static LobbyDiff LatestLobbyDiff { get; private set; } = new LobbyDiff(new List<PluginDiff>());


		private static Dictionary<ulong, LobbyDiff> LobbyDiffCache { get; } = new Dictionary<ulong, LobbyDiff>();


		public static LobbyDiff GetLobbyDiff(Lobby lobby)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			return GetLobbyDiff(lobby, null);
		}

		internal static LobbyDiff GetLobbyDiff(Lobby lobby, string? lobbyPluginString)
		{
			//IL_0007: 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)
			//IL_041e: Unknown result type (might be due to invalid IL or missing references)
			if (LobbyDiffCache.TryGetValue(SteamId.op_Implicit(((Lobby)(ref lobby)).Id), out LobbyDiff value))
			{
				LatestLobbyDiff = value;
				return value;
			}
			List<PluginInfoRecord> list = PluginHelper.ParseLobbyPluginsMetadata(lobbyPluginString ?? GetLobbyPlugins(lobby)).ToList();
			if (_clientPlugins == null)
			{
				_clientPlugins = PluginHelper.GetAllPluginInfo().ToList();
			}
			List<PluginDiff> list2 = new List<PluginDiff>();
			foreach (PluginInfoRecord lobbyPlugin in list)
			{
				PluginInfoRecord pluginInfoRecord = _clientPlugins.FirstOrDefault((PluginInfoRecord plugin) => plugin.GUID == lobbyPlugin.GUID);
				if (!lobbyPlugin.CompatibilityLevel.HasValue || !lobbyPlugin.VersionStrictness.HasValue)
				{
					Version version = pluginInfoRecord?.Version;
					list2.Add(new PluginDiff((!(version == lobbyPlugin.Version)) ? PluginDiffResult.Unknown : PluginDiffResult.Compatible, lobbyPlugin.GUID, version, lobbyPlugin.Version));
				}
				else if (pluginInfoRecord == null)
				{
					if (lobbyPlugin.CompatibilityLevel == CompatibilityLevel.Everyone)
					{
						list2.Add(new PluginDiff(PluginDiffResult.ClientMissingMod, lobbyPlugin.GUID, null, lobbyPlugin.Version));
					}
					else
					{
						list2.Add(new PluginDiff(PluginDiffResult.Compatible, lobbyPlugin.GUID, null, lobbyPlugin.Version));
					}
				}
				else if (pluginInfoRecord.CompatibilityLevel != lobbyPlugin.CompatibilityLevel)
				{
					list2.Add(new PluginDiff(PluginDiffResult.ModVersionMismatch, lobbyPlugin.GUID, pluginInfoRecord.Version, lobbyPlugin.Version));
				}
				else if (pluginInfoRecord.CompatibilityLevel != CompatibilityLevel.ClientOnly && !PluginHelper.MatchesVersion(pluginInfoRecord, lobbyPlugin))
				{
					list2.Add(new PluginDiff(PluginDiffResult.ModVersionMismatch, lobbyPlugin.GUID, pluginInfoRecord.Version, lobbyPlugin.Version));
				}
				else
				{
					list2.Add(new PluginDiff(PluginDiffResult.Compatible, lobbyPlugin.GUID, pluginInfoRecord.Version, lobbyPlugin.Version));
				}
			}
			foreach (PluginInfoRecord clientPlugin in _clientPlugins)
			{
				PluginInfoRecord pluginInfoRecord2 = list.FirstOrDefault((PluginInfoRecord plugin) => plugin.GUID == clientPlugin.GUID);
				if (!clientPlugin.CompatibilityLevel.HasValue || !clientPlugin.VersionStrictness.HasValue)
				{
					Version version2 = pluginInfoRecord2?.Version;
					if (version2 != clientPlugin.Version)
					{
						list2.Add(new PluginDiff(PluginDiffResult.Unknown, clientPlugin.GUID, clientPlugin.Version, version2));
					}
					continue;
				}
				if (pluginInfoRecord2 != null)
				{
					continue;
				}
				CompatibilityLevel? compatibilityLevel = clientPlugin.CompatibilityLevel;
				bool flag;
				if (compatibilityLevel.HasValue)
				{
					CompatibilityLevel valueOrDefault = compatibilityLevel.GetValueOrDefault();
					if ((uint)(valueOrDefault - 2) <= 1u)
					{
						flag = true;
						goto IL_0398;
					}
				}
				flag = false;
				goto IL_0398;
				IL_0398:
				if (flag)
				{
					list2.Add(new PluginDiff(PluginDiffResult.ServerMissingMod, clientPlugin.GUID, clientPlugin.Version, null));
				}
				else
				{
					list2.Add(new PluginDiff(PluginDiffResult.Compatible, clientPlugin.GUID, clientPlugin.Version, null));
				}
			}
			bool lobbyCompatibilityPresent = list.Any();
			LatestLobbyDiff = new LobbyDiff(list2, lobbyCompatibilityPresent);
			LobbyDiffCache.Add(SteamId.op_Implicit(((Lobby)(ref lobby)).Id), LatestLobbyDiff);
			return LatestLobbyDiff;
		}

		internal static string GetLobbyPlugins(Lobby lobby)
		{
			List<string> list = new List<string>();
			int num = 0;
			do
			{
				list.Insert(num, ((Lobby)(ref lobby)).GetData(string.Format("{0}{1}", "plugins", num)));
			}
			while (list[num++].Contains("@"));
			return GeneralExtensions.Join<string>((IEnumerable<string>)list, (Func<string, string>)null, string.Empty).Replace("@", string.Empty);
		}

		public static string GetCompatibilityHeader(PluginDiffResult pluginDiffResult)
		{
			return pluginDiffResult switch
			{
				PluginDiffResult.Compatible => "Compatible", 
				PluginDiffResult.ClientMissingMod => "Missing lobby-required mods", 
				PluginDiffResult.ServerMissingMod => "Incompatible with lobby", 
				PluginDiffResult.ModVersionMismatch => "Incompatible mod versions", 
				_ => "Unknown", 
			};
		}

		public static Lobby[] FilterLobbies(Lobby[] normalLobbies, Lobby[]? filteredLobbies, ModdedLobbyFilter currentFilter)
		{
			Lobby[] filteredLobbies2 = filteredLobbies;
			List<Lobby> list = new List<Lobby>();
			if (filteredLobbies2 != null)
			{
				normalLobbies = normalLobbies.Where((Lobby lobby) => !filteredLobbies2.Any((Lobby check) => ((object)(Lobby)(ref lobby)).Equals((object?)check))).ToArray();
			}
			if (currentFilter == ModdedLobbyFilter.VanillaAndUnknownOnly)
			{
				list.AddRange(FilterLobbiesByDiffResult(normalLobbies, LobbyDiffResult.Unknown));
			}
			else
			{
				bool flag = filteredLobbies2 != null;
				bool flag2 = flag;
				if (flag2)
				{
					bool flag3 = (uint)currentFilter <= 1u;
					flag2 = flag3;
				}
				if (flag2)
				{
					var (collection, lobbies) = SplitLobbiesByDiffResult(filteredLobbies2, LobbyDiffResult.Compatible);
					var (collection2, enumerable) = SplitLobbiesByDiffResult(normalLobbies, LobbyDiffResult.Compatible);
					list.AddRange(collection);
					list.AddRange(collection2);
					if (currentFilter == ModdedLobbyFilter.CompatibleFirst)
					{
						var (collection3, collection4) = SplitLobbiesByDiffResult(lobbies, LobbyDiffResult.PresumedCompatible);
						var (collection5, collection6) = SplitLobbiesByDiffResult(normalLobbies, LobbyDiffResult.PresumedCompatible);
						list.AddRange(collection3);
						list.AddRange(collection5);
						list.AddRange(collection4);
						list.AddRange(collection6);
					}
				}
				else if (filteredLobbies2 != null || currentFilter != 0)
				{
					list = ((filteredLobbies2 != null || currentFilter != ModdedLobbyFilter.CompatibleOnly) ? normalLobbies.ToList() : new List<Lobby>());
				}
				else
				{
					var (collection7, enumerable2) = SplitLobbiesByDiffResult(normalLobbies, LobbyDiffResult.Compatible);
					var (collection8, collection9) = SplitLobbiesByDiffResult(normalLobbies, LobbyDiffResult.PresumedCompatible);
					list.AddRange(collection7);
					list.AddRange(collection8);
					list.AddRange(collection9);
				}
			}
			return list.ToArray();
		}

		private static (IEnumerable<Lobby> matchedLobbies, IEnumerable<Lobby> unmatchedLobbies) SplitLobbiesByDiffResult(IEnumerable<Lobby> lobbies, LobbyDiffResult filteredLobbyDiffResult)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			List<Lobby> list = new List<Lobby>();
			List<Lobby> list2 = new List<Lobby>();
			foreach (Lobby lobby in lobbies)
			{
				LobbyDiffResult moddedLobbyType = GetLobbyDiff(lobby).GetModdedLobbyType();
				if (moddedLobbyType == filteredLobbyDiffResult)
				{
					list.Add(lobby);
				}
				else
				{
					list2.Add(lobby);
				}
			}
			return (list, list2);
		}

		private static IEnumerable<Lobby> FilterLobbiesByDiffResult(IEnumerable<Lobby> lobbies, LobbyDiffResult filteredLobbyDiffResult)
		{
			return SplitLobbiesByDiffResult(lobbies, filteredLobbyDiffResult).matchedLobbies;
		}

		public static string GetEmptyLobbyListString(ModdedLobbyFilter moddedLobbyFilter)
		{
			return moddedLobbyFilter switch
			{
				ModdedLobbyFilter.CompatibleOnly => "No available compatible\nservers to join.", 
				ModdedLobbyFilter.VanillaAndUnknownOnly => "No available vanilla or unknown\nservers to join.", 
				_ => "No available servers to join.", 
			};
		}

		public static bool LobbyNameContainsModIdentifier(Lobby lobby)
		{
			return ModdedLobbyIdentifierRegex.IsMatch(((Lobby)(ref lobby)).GetData("name"));
		}
	}
	public static class PluginHelper
	{
		private static readonly List<PluginInfoRecord> RegisteredPluginInfoRecords = new List<PluginInfoRecord>();

		private static string? _cachedChecksum;

		internal static string Checksum
		{
			get
			{
				return _cachedChecksum ?? GetRequiredPluginsChecksum();
			}
			set
			{
				_cachedChecksum = value;
			}
		}

		public static void RegisterPlugin(string guid, Version version, CompatibilityLevel compatibilityLevel, VersionStrictness versionStrictness)
		{
			RegisteredPluginInfoRecords.Add(new PluginInfoRecord(guid, version, compatibilityLevel, versionStrictness));
			_cachedChecksum = null;
		}

		private static bool HasCompatibilityAttribute(BaseUnityPlugin plugin)
		{
			return ((object)plugin)?.GetType().GetCustomAttributes(typeof(LobbyCompatibilityAttribute), inherit: false).Any() ?? false;
		}

		private static IEnumerable<PluginInfo> GetCompatibilityPlugins()
		{
			return from plugin in Chainloader.PluginInfos
				where HasCompatibilityAttribute(plugin.Value.Instance)
				select plugin.Value;
		}

		private static LobbyCompatibilityAttribute? GetCompatibilityAttribute(BaseUnityPlugin plugin)
		{
			return (LobbyCompatibilityAttribute)((object)plugin).GetType().GetCustomAttributes(typeof(LobbyCompatibilityAttribute), inherit: false).FirstOrDefault();
		}

		internal static IEnumerable<PluginInfoRecord> GetAllPluginInfo()
		{
			List<PluginInfoRecord> list = new List<PluginInfoRecord>();
			List<PluginInfo> list2 = GetCompatibilityPlugins().ToList();
			List<PluginInfo> list3 = (from plugin in Chainloader.PluginInfos.Values
				where plugin.Instance != null && !HasCompatibilityAttribute(plugin.Instance)
				select (plugin)).ToList();
			list2.RemoveAll((PluginInfo plugin) => RegisteredPluginInfoRecords.Any((PluginInfoRecord record) => record.GUID == plugin.Metadata.GUID));
			list3.RemoveAll((PluginInfo plugin) => RegisteredPluginInfoRecords.Any((PluginInfoRecord record) => record.GUID == plugin.Metadata.GUID));
			list.AddRange(list2.Select((PluginInfo plugin) => new PluginInfoRecord(plugin.Metadata.GUID, plugin.Metadata.Version, GetCompatibilityAttribute(plugin.Instance)?.CompatibilityLevel, GetCompatibilityAttribute(plugin.Instance)?.VersionStrictness)));
			list.AddRange(list3.Select((PluginInfo plugin) => new PluginInfoRecord(plugin.Metadata.GUID, plugin.Metadata.Version, null, null)));
			return list.Concat(RegisteredPluginInfoRecords);
		}

		internal static IEnumerable<string> GetLobbyPluginsMetadata()
		{
			string json = JsonConvert.SerializeObject((object)GetAllPluginInfo().ToList(), (JsonConverter[])(object)new JsonConverter[1] { (JsonConverter)new VersionConverter() });
			int maxChunkLength = 8191;
			for (int i = 0; i < json.Length; i += maxChunkLength)
			{
				if (maxChunkLength + i > json.Length)
				{
					maxChunkLength = json.Length - i;
				}
				yield return json.Substring(i, maxChunkLength);
			}
		}

		internal static IEnumerable<PluginInfoRecord> ParseLobbyPluginsMetadata(string json)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Expected O, but got Unknown
			try
			{
				return JsonConvert.DeserializeObject<List<PluginInfoRecord>>(json, (JsonConverter[])(object)new JsonConverter[1] { (JsonConverter)new VersionConverter() }) ?? new List<PluginInfoRecord>();
			}
			catch (Exception ex)
			{
				ManualLogSource? logger = LobbyCompatibilityPlugin.Logger;
				if (logger != null)
				{
					logger.LogError((object)"Failed to parse lobby plugins metadata.");
				}
				ManualLogSource? logger2 = LobbyCompatibilityPlugin.Logger;
				if (logger2 != null)
				{
					logger2.LogDebug((object)ex);
				}
				throw;
			}
		}

		internal static bool MatchesVersion(PluginInfoRecord source, PluginInfoRecord target)
		{
			if (source.VersionStrictness == VersionStrictness.None)
			{
				return true;
			}
			if (source.VersionStrictness == VersionStrictness.Major)
			{
				if (target.Version.Major != source.Version.Major)
				{
					return false;
				}
			}
			else if (source.VersionStrictness == VersionStrictness.Minor)
			{
				if (target.Version.Major != source.Version.Major || target.Version.Minor != source.Version.Minor)
				{
					return false;
				}
			}
			else if (source.VersionStrictness == VersionStrictness.Patch && target.Version != source.Version)
			{
				return false;
			}
			return true;
		}

		internal static bool MatchesTargetRequirements(IEnumerable<PluginInfoRecord> targetPluginInfo)
		{
			List<PluginInfoRecord> list = GetAllPluginInfo().ToList();
			List<PluginInfoRecord> list2 = targetPluginInfo.ToList();
			bool flag;
			foreach (PluginInfoRecord clientPlugin2 in list)
			{
				CompatibilityLevel? compatibilityLevel = clientPlugin2.CompatibilityLevel;
				if (compatibilityLevel.HasValue)
				{
					CompatibilityLevel valueOrDefault = compatibilityLevel.GetValueOrDefault();
					if ((uint)(valueOrDefault - 2) <= 1u)
					{
						flag = true;
						goto IL_005c;
					}
				}
				flag = false;
				goto IL_005c;
				IL_005c:
				if (!flag || list2.Any((PluginInfoRecord serverPlugin) => serverPlugin.GUID == clientPlugin2.GUID && MatchesVersion(clientPlugin2, serverPlugin)))
				{
					continue;
				}
				flag = false;
				goto IL_010a;
			}
			foreach (PluginInfoRecord serverPlugin2 in list2)
			{
				CompatibilityLevel? compatibilityLevel = serverPlugin2.CompatibilityLevel;
				if (!compatibilityLevel.HasValue || compatibilityLevel.GetValueOrDefault() != CompatibilityLevel.Everyone || list.Any((PluginInfoRecord clientPlugin) => clientPlugin.GUID == serverPlugin2.GUID && MatchesVersion(serverPlugin2, clientPlugin)))
				{
					continue;
				}
				flag = false;
				goto IL_010a;
			}
			return true;
			IL_010a:
			return flag;
		}

		internal static bool CanJoinVanillaLobbies()
		{
			return true;
		}

		public static IEnumerable<PluginDiff> FilterPluginDiffs(IEnumerable<PluginDiff> pluginDiffs, ModListFilter modListFilter)
		{
			return modListFilter switch
			{
				ModListFilter.Compatible => pluginDiffs.Where((PluginDiff x) => x.PluginDiffResult == PluginDiffResult.Compatible), 
				ModListFilter.Incompatible => pluginDiffs.Where((PluginDiff x) => x.PluginDiffResult == PluginDiffResult.ServerMissingMod || x.PluginDiffResult == PluginDiffResult.ClientMissingMod || x.PluginDiffResult == PluginDiffResult.ModVersionMismatch), 
				ModListFilter.Unknown => pluginDiffs.Where((PluginDiff x) => x.PluginDiffResult == PluginDiffResult.Unknown), 
				_ => pluginDiffs, 
			};
		}

		private static string GetRequiredPluginsChecksum()
		{
			List<PluginInfoRecord> list = GetAllPluginInfo().Where(delegate(PluginInfoRecord plugin)
			{
				CompatibilityLevel? compatibilityLevel = plugin.CompatibilityLevel;
				return compatibilityLevel.HasValue && compatibilityLevel.GetValueOrDefault() == CompatibilityLevel.Everyone;
			}).OrderBy<PluginInfoRecord, string>((PluginInfoRecord plugin) => plugin.GUID, StringComparer.Ordinal).ToList();
			if (!list.Any())
			{
				return _cachedChecksum = "";
			}
			string text = "";
			foreach (PluginInfoRecord item in list)
			{
				text += item.GUID;
				switch (item.VersionStrictness)
				{
				case VersionStrictness.Major:
					text += new Version(item.Version.Major, 0).ToString();
					break;
				case VersionStrictness.Minor:
					text += new Version(item.Version.Major, item.Version.Minor).ToString();
					break;
				case VersionStrictness.Patch:
					text += item.Version.ToString();
					break;
				}
			}
			byte[] array = SHA256.Create().ComputeHash(Encoding.UTF8.GetBytes(text));
			StringBuilder stringBuilder = new StringBuilder();
			byte[] array2 = array;
			foreach (byte b in array2)
			{
				stringBuilder.Append(b.ToString("X2"));
			}
			_cachedChecksum = stringBuilder.ToString();
			ManualLogSource? logger = LobbyCompatibilityPlugin.Logger;
			if (logger != null)
			{
				logger.LogDebug((object)_cachedChecksum);
			}
			return _cachedChecksum;
		}
	}
	internal static class TextureHelper
	{
		internal static Dictionary<string, Sprite?> SpriteCache = new Dictionary<string, Sprite>();

		public static Sprite? FindSpriteInAssembly(string path, Assembly? assembly = null)
		{
			if (SpriteCache.ContainsKey(path))
			{
				return SpriteCache[path];
			}
			if (assembly == null)
			{
				assembly = Assembly.GetExecutingAssembly();
			}
			if (assembly == null)
			{
				return null;
			}
			Sprite val = null;
			try
			{
				if (assembly.GetManifestResourceNames().Contains(path))
				{
					val = LoadSpriteRaw(GetResource(assembly, path));
				}
			}
			catch (Exception ex)
			{
				ManualLogSource? logger = LobbyCompatibilityPlugin.Logger;
				if (logger != null)
				{
					logger.LogError((object)("Unable to find texture in assembly! Exception: " + ex));
				}
			}
			SpriteCache.Add(path, val);
			return val;
		}

		public static byte[] GetResource(Assembly assembly, string resource)
		{
			using Stream stream = assembly.GetManifestResourceStream(resource) ?? throw new FileNotFoundException(resource);
			using MemoryStream memoryStream = new MemoryStream(new byte[stream.Length], writable: true);
			stream.CopyTo(memoryStream);
			return memoryStream.ToArray();
		}

		public static Sprite? LoadSpriteRaw(byte[] image, float pixelsPerUnit = 100f)
		{
			Texture2D val = LoadTextureRaw(image);
			if (!((Object)(object)val == (Object)null))
			{
				return LoadSpriteFromTexture(val, pixelsPerUnit);
			}
			return null;
		}

		public static Texture2D? LoadTextureRaw(byte[] file)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Expected O, but got Unknown
			if (file.Length != 0)
			{
				Texture2D val = new Texture2D(0, 0, (TextureFormat)4, false, false);
				if (ImageConversion.LoadImage(val, file))
				{
					return val;
				}
			}
			return null;
		}

		public static Sprite? LoadSpriteFromTexture(Texture2D spriteTexture, float pixelsPerUnit = 100f)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)spriteTexture == (Object)null)
			{
				return null;
			}
			Sprite val = Sprite.Create(spriteTexture, new Rect(0f, 0f, (float)((Texture)spriteTexture).width, (float)((Texture)spriteTexture).height), new Vector2(0f, 0f), pixelsPerUnit);
			((Object)val).name = ((Object)spriteTexture).name;
			return val;
		}
	}
	internal static class UIHelper
	{
		public static bool TryMultiplySizeDelta(Transform? transform, Vector2 multiplier)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)transform == (Object)null)
			{
				return false;
			}
			RectTransform component = ((Component)transform).GetComponent<RectTransform>();
			if ((Object)(object)component == (Object)null)
			{
				return false;
			}
			MultiplySizeDelta(component, multiplier);
			return true;
		}

		private static void MultiplySizeDelta(RectTransform rectTransform, Vector2 multiplier)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: 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_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			Vector2 sizeDelta = rectTransform.sizeDelta;
			rectTransform.sizeDelta = new Vector2(sizeDelta.x * multiplier.x, sizeDelta.y * multiplier.y);
		}

		public static void AddToAnchoredPosition(Transform? transform, Vector2 addition)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)transform == (Object)null))
			{
				RectTransform val = (RectTransform)(object)((transform is RectTransform) ? transform : null);
				if (val == null)
				{
					val = ((Component)transform).GetComponent<RectTransform>();
				}
				if (!((Object)(object)val == (Object)null))
				{
					val.anchoredPosition = new Vector2(val.anchoredPosition.x + addition.x, val.anchoredPosition.y + addition.y);
				}
			}
		}

		public static TextMeshProUGUI SetupTextAsTemplate(TextMeshProUGUI template, Transform parent, Color color, Vector2 size, float maxFontSize, float minFontSize, HorizontalAlignmentOptions alignment = 2, Vector2? defaultPosition = null)
		{
			//IL_002d: 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_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			TextMeshProUGUI val = Object.Instantiate<TextMeshProUGUI>(template, parent);
			((TMP_Text)val).rectTransform.anchoredPosition = (Vector2)(((??)defaultPosition) ?? new Vector2(0f, 0f));
			((TMP_Text)val).rectTransform.sizeDelta = size;
			((TMP_Text)val).horizontalAlignment = alignment;
			((TMP_Text)val).enableAutoSizing = true;
			((TMP_Text)val).fontSizeMax = maxFontSize;
			((TMP_Text)val).fontSizeMin = minFontSize;
			((TMP_Text)val).enableWordWrapping = false;
			((Graphic)val).color = color;
			((Component)val).gameObject.SetActive(false);
			return val;
		}

		public static RectTransform ApplyParentSize(GameObject uiElement, Transform parent)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			RectTransform val = uiElement.GetComponent<RectTransform>();
			if ((Object)(object)val == (Object)null)
			{
				val = uiElement.AddComponent<RectTransform>();
			}
			((Transform)val).SetParent(parent);
			val.anchorMin = new Vector2(0f, 1f);
			val.anchorMax = new Vector2(1f, 1f);
			val.pivot = new Vector2(0.5f, 0.5f);
			RectTransform obj = val;
			Vector2 offsetMin = (val.offsetMax = Vector2.zero);
			obj.offsetMin = offsetMin;
			((Transform)val).localRotation = Quaternion.identity;
			((Transform)val).localScale = Vector3.one;
			((Transform)val).localPosition = Vector3.zero;
			return val;
		}

		public static TextMeshProUGUI CreateTextFromTemplate(TextMeshProUGUI template, string content, float yPosition, Color? overrideColor = null)
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			TextMeshProUGUI val = Object.Instantiate<TextMeshProUGUI>(template, ((TMP_Text)template).transform.parent);
			if (overrideColor.HasValue)
			{
				((Graphic)val).color = overrideColor.Value;
			}
			((TMP_Text)val).rectTransform.anchoredPosition = new Vector2(((TMP_Text)val).rectTransform.anchoredPosition.x, yPosition);
			((TMP_Text)val).text = content;
			((Component)val).gameObject.SetActive(true);
			return val;
		}

		public static (List<PluginDiffSlot?> pluginDiffSlots, List<PluginCategorySlot?> pluginCategorySlots) GenerateDiffSlotsFromLobbyDiff(LobbyDiff lobbyDiff, PluginDiffSlotPool pluginDiffSlotPool, PluginCategorySlotPool pluginCategorySlotPool, ModListFilter? modListFilter = null, int? maxLines = null)
		{
			//IL_0218: Unknown result type (might be due to invalid IL or missing references)
			//IL_020c: Unknown result type (might be due to invalid IL or missing references)
			List<PluginDiffSlot> list = new List<PluginDiffSlot>();
			List<PluginCategorySlot> list2 = new List<PluginCategorySlot>();
			IEnumerable<PluginDiff> enumerable;
			if (!modListFilter.HasValue)
			{
				IEnumerable<PluginDiff> pluginDiffs = lobbyDiff.PluginDiffs;
				enumerable = pluginDiffs;
			}
			else
			{
				enumerable = PluginHelper.FilterPluginDiffs(lobbyDiff.PluginDiffs, modListFilter.Value);
			}
			IEnumerable<PluginDiff> source = enumerable;
			int num = 0;
			int num2 = 0;
			foreach (PluginDiffResult compatibilityResult in Enum.GetValues(typeof(PluginDiffResult)).Cast<PluginDiffResult>())
			{
				List<PluginDiff> list3 = source.Where((PluginDiff pluginDiff) => pluginDiff.PluginDiffResult == compatibilityResult).ToList();
				if (list3.Count == 0)
				{
					continue;
				}
				if (maxLines.HasValue && num >= maxLines - 1)
				{
					break;
				}
				PluginCategorySlot item = pluginCategorySlotPool.Spawn(compatibilityResult);
				list2.Add(item);
				num++;
				foreach (PluginDiff item2 in list3)
				{
					PluginDiffSlot pluginDiffSlot = pluginDiffSlotPool.Spawn(item2, lobbyDiff.LobbyCompatibilityPresent);
					if (!((Object)(object)pluginDiffSlot == (Object)null))
					{
						list.Add(pluginDiffSlot);
						num++;
						num2++;
						if (maxLines.HasValue && num >= maxLines)
						{
							break;
						}
					}
				}
			}
			int num3 = lobbyDiff.PluginDiffs.Count - num2;
			if (maxLines.HasValue && num >= maxLines && num3 > 0)
			{
				string pluginNameText = string.Format("{0} more mod{1}...", num3, (num3 == 1) ? "" : "s");
				PluginDiffSlot pluginDiffSlot2 = pluginDiffSlotPool.Spawn(pluginNameText, "", "", LobbyCompatibilityPlugin.Config?.UnknownColor.Value ?? Color.gray);
				if ((Object)(object)pluginDiffSlot2 != (Object)null)
				{
					list.Add(pluginDiffSlot2);
				}
			}
			return (list, list2);
		}

		public static void ClearSpawnedDiffSlots(PluginDiffSlotPool pluginDiffSlotPool, PluginCategorySlotPool pluginCategorySlotPool, ref List<PluginDiffSlot?> existingPluginDiffSlots, ref List<PluginCategorySlot?> existingPluginCategorySlots)
		{
			foreach (PluginDiffSlot existingPluginDiffSlot in existingPluginDiffSlots)
			{
				if (!((Object)(object)existingPluginDiffSlot == (Object)null))
				{
					pluginDiffSlotPool.Release(existingPluginDiffSlot);
				}
			}
			foreach (PluginCategorySlot existingPluginCategorySlot in existingPluginCategorySlots)
			{
				if (!((Object)(object)existingPluginCategorySlot == (Object)null))
				{
					pluginCategorySlotPool.Release(existingPluginCategorySlot);
				}
			}
			existingPluginDiffSlots.Clear();
			existingPluginCategorySlots.Clear();
		}

		public static void AddVerticalLayoutGroup(GameObject gameObject, bool addContentSizeFitter = true)
		{
			VerticalLayoutGroup val = gameObject.AddComponent<VerticalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)val).childControlHeight = false;
			((HorizontalOrVerticalLayoutGroup)val).childForceExpandHeight = false;
			if (addContentSizeFitter)
			{
				ContentSizeFitter val2 = ((Component)val).gameObject.AddComponent<ContentSizeFitter>();
				val2.verticalFit = (FitMode)2;
			}
		}

		public static void ReskinRefreshButton(Button refreshButton)
		{
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			object obj;
			if (refreshButton == null)
			{
				obj = null;
			}
			else
			{
				Transform obj2 = ((Component)refreshButton).transform.Find("Text (TMP)");
				obj = ((obj2 != null) ? ((Component)obj2).GetComponent<TextMeshProUGUI>() : null);
			}
			TextMeshProUGUI val = (TextMeshProUGUI)obj;
			object obj3;
			if (refreshButton == null)
			{
				obj3 = null;
			}
			else
			{
				Transform obj4 = ((Component)refreshButton).transform.Find("SelectionHighlight");
				obj3 = ((obj4 != null) ? ((Component)obj4).GetComponent<RectTransform>() : null);
			}
			RectTransform val2 = (RectTransform)obj3;
			Image val3 = ((val2 != null) ? ((Component)val2).GetComponent<Image>() : null);
			if (!((Object)(object)refreshButton == (Object)null) && !((Object)(object)val == (Object)null) && !((Object)(object)val2 == (Object)null) && !((Object)(object)val3 == (Object)null))
			{
				val2.anchoredPosition = new Vector2(140f, 17.5f);
				val2.sizeDelta = new Vector2(34f, 43.5f);
				RectTransform val4 = Object.Instantiate<RectTransform>(val2, ((TMP_Text)val).transform.parent, false);
				Image component = ((Component)val4).GetComponent<Image>();
				((Transform)val4).SetSiblingIndex(0);
				Color color = ((Graphic)component).color;
				((Graphic)component).color = new Color(color.r, color.g, color.b, 1f);
				component.sprite = TextureHelper.FindSpriteInAssembly("LobbyCompatibility.Resources.Refresh.png");
				val3.sprite = TextureHelper.FindSpriteInAssembly("LobbyCompatibility.Resources.InvertedRefresh.png");
				((Behaviour)val).enabled = false;
			}
		}

		public static void AddCustomFilterToLobbyList(Transform listPanel, float adjustment = -40f)
		{
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: 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_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Expected O, but got Unknown
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Expected O, but got Unknown
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Expected O, but got Unknown
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Expected O, but got Unknown
			Transform val = listPanel.Find("Dropdown");
			Transform val2 = listPanel.Find("ToggleChallengeSort");
			Transform obj = listPanel.Find("ServerTagInputField");
			RectTransform val3 = ((obj != null) ? ((Component)obj).GetComponent<RectTransform>() : null);
			object obj2;
			if (val3 == null)
			{
				obj2 = null;
			}
			else
			{
				Transform obj3 = ((Transform)val3).Find("Text Area/Placeholder");
				obj2 = ((obj3 != null) ? ((Component)obj3).GetComponent<TextMeshProUGUI>() : null);
			}
			TextMeshProUGUI val4 = (TextMeshProUGUI)obj2;
			if (!((Object)(object)val == (Object)null) && !((Object)(object)val2 == (Object)null) && !((Object)(object)val3 == (Object)null) && !((Object)(object)val4 == (Object)null))
			{
				AddToAnchoredPosition(val, new Vector2(adjustment, 0f));
				AddToAnchoredPosition(val2, new Vector2(adjustment, 0f));
				val3.offsetMax = new Vector2(val3.offsetMax.x + adjustment, val3.offsetMax.y);
				((TMP_Text)val4).text = "Server tag...";
				Transform val5 = Object.Instantiate<Transform>(val, val.parent, false);
				TMP_Dropdown component = ((Component)val5).GetComponent<TMP_Dropdown>();
				RectTransform component2 = ((Component)val5).GetComponent<RectTransform>();
				component2.anchoredPosition = new Vector2(adjustment, component2.anchoredPosition.y);
				component.captionText.fontSize = 10f;
				component.itemText.fontSize = 10f;
				component.ClearOptions();
				component.AddOptions(new List<OptionData>
				{
					new OptionData("Mods: Compatible first"),
					new OptionData("Mods: Compatible only"),
					new OptionData("Mods: Vanilla and Unknown only"),
					new OptionData("Mods: All")
				});
				ModdedLobbyFilterDropdown moddedLobbyFilterDropdown = ((Component)component).gameObject.AddComponent<ModdedLobbyFilterDropdown>();
				moddedLobbyFilterDropdown.SetDropdown(component);
				((UnityEventBase)component.onValueChanged).m_PersistentCalls.Clear();
				((UnityEvent<int>)(object)component.onValueChanged).AddListener((UnityAction<int>)moddedLobbyFilterDropdown.ChangeFilterType);
			}
		}
	}
}
namespace LobbyCompatibility.Enums
{
	public enum CompatibilityLevel
	{
		ClientOnly,
		ServerOnly,
		Everyone,
		ClientOptional
	}
	public enum LobbyDiffResult
	{
		Compatible,
		Incompatible,
		PresumedCompatible,
		Unknown
	}
	public static class LobbyMetadata
	{
		public const string Name = "name";

		public const string Tag = "tag";

		public const string Version = "vers";

		public const string Joinable = "joinable";

		public const string Modded = "modded";

		public const string JoinableModded = "_joinable";

		public const string Plugins = "plugins";

		public const string RequiredChecksum = "checksum";

		public const string ModdedLobbyPrefix = "[MOD]";
	}
	public enum ModdedLobbyFilter
	{
		CompatibleFirst,
		CompatibleOnly,
		VanillaAndUnknownOnly,
		All
	}
	public enum ModListFilter
	{
		All,
		Compatible,
		Incompatible,
		Unknown
	}
	public enum PluginDiffResult
	{
		Compatible,
		ServerMissingMod,
		ClientMissingMod,
		ModVersionMismatch,
		Unknown
	}
	public enum VersionStrictness
	{
		None,
		Major,
		Minor,
		Patch
	}
}
namespace LobbyCompatibility.Configuration
{
	public class Config
	{
		public static readonly Color DefaultCompatibleColor = Color.green;

		public static readonly Color DefaultIncompatibleColor = Color.red;

		public static readonly Color DefaultUnknownColor = Color.gray;

		public ConfigEntry<ModdedLobbyFilter> DefaultModdedLobbyFilter;

		public ConfigEntry<ModListFilter> DefaultModListTab;

		public ConfigEntry<Color> CompatibleColor;

		public ConfigEntry<Color> IncompatibleColor;

		public ConfigEntry<Color> UnknownColor;

		public Config(ConfigFile configFile)
		{
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: 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)
			DefaultModdedLobbyFilter = configFile.Bind<ModdedLobbyFilter>("General", "Default Lobby Filter Type", ModdedLobbyFilter.CompatibleFirst, "The default filter to apply when searching for a public lobby");
			DefaultModListTab = configFile.Bind<ModListFilter>("General", "Default ModList Tab", ModListFilter.All, "The default tab to use when viewing a lobby's mod list");
			CompatibleColor = configFile.Bind<Color>("Visual", "Compatible Plugin Color", DefaultCompatibleColor, "The color used to respresent compatible plugins");
			IncompatibleColor = configFile.Bind<Color>("Visual", "Incompatible Plugin Color", DefaultIncompatibleColor, "The color used to respresent incompatible plugins");
			UnknownColor = configFile.Bind<Color>("Visual", "Unknown Plugin Color", DefaultUnknownColor, "The color used to respresent unknown plugins");
		}
	}
}
namespace LobbyCompatibility.Behaviours
{
	public class ButtonEventHandler : MonoBehaviour, IPointerEnterHandler, IEventSystemHandler, IPointerExitHandler, IPointerClickHandler
	{
		private Color? _highlightedColor;

		private Sprite? _highlightedSprite;

		private Image? _image;

		private Color? _normalColor;

		private Sprite? _normalSprite;

		public event Action<bool>? OnHoverStateChanged;

		public event Action? OnClick;

		public void OnPointerClick(PointerEventData eventData)
		{
			this.OnClick?.Invoke();
		}

		public void OnPointerEnter(PointerEventData eventData)
		{
			this.OnHoverStateChanged?.Invoke(obj: true);
			SetHighlighted(highlighted: true);
		}

		public void OnPointerExit(PointerEventData eventData)
		{
			this.OnHoverStateChanged?.Invoke(obj: false);
			SetHighlighted(highlighted: false);
		}

		public void SetButtonImageData(Image image, Sprite normalSprite, Sprite highlightedSprite, Color normalColor, Color highlightedColor)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			_image = image;
			_normalSprite = normalSprite;
			_highlightedSprite = highlightedSprite;
			SetColor(normalColor, highlightedColor);
			SetHighlighted(highlighted: false);
		}

		public void SetColor(Color normalColor, Color highlightedColor)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			_normalColor = normalColor;
			_highlightedColor = highlightedColor;
			SetHighlighted(highlighted: false);
		}

		private void SetHighlighted(bool highlighted)
		{
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_image == (Object)null))
			{
				_image.sprite = (highlighted ? _highlightedSprite : _normalSprite);
				Color? val = (highlighted ? _highlightedColor : _normalColor);
				if (val.HasValue)
				{
					((Graphic)_image).color = val.Value;
				}
			}
		}
	}
	internal class ModdedLobbyFilterDropdown : MonoBehaviour
	{
		private TMP_Dropdown? _dropdown;

		private SteamLobbyManager? _steamLobbyManager;

		public ModdedLobbyFilter LobbyFilter { get; private set; }

		public static ModdedLobbyFilterDropdown? Instance { get; private set; }

		public void Awake()
		{
			UpdateLobbyFilter(LobbyCompatibilityPlugin.Config?.DefaultModdedLobbyFilter.Value ?? ModdedLobbyFilter.CompatibleFirst);
			if ((Object)(object)_dropdown != (Object)null)
			{
				_dropdown.SetValueWithoutNotify((int)LobbyFilter);
			}
			Instance = this;
			_steamLobbyManager = Object.FindObjectOfType<SteamLobbyManager>();
		}

		public void SetDropdown(TMP_Dropdown dropdown)
		{
			_dropdown = dropdown;
		}

		public void ChangeFilterType(int index)
		{
			UpdateLobbyFilter((ModdedLobbyFilter)index);
			if ((Object)(object)_steamLobbyManager != (Object)null)
			{
				_steamLobbyManager.RefreshServerListButton();
			}
		}

		private void UpdateLobbyFilter(ModdedLobbyFilter lobbyFilter)
		{
			LobbyFilter = lobbyFilter;
		}
	}
	public class ModdedLobbySlot : MonoBehaviour
	{
		private List<ButtonEventHandler> _buttonEventHandlers = new List<ButtonEventHandler>();

		private RectTransform? _buttonTransform;

		private Button? _joinButton;

		private LobbyDiff? _lobbyDiff;

		private LobbySlot? _lobbySlot;

		private Transform? _parentContainer;

		internal void Setup(LobbySlot lobbySlot)
		{
			//IL_000e: 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_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			_lobbySlot = lobbySlot;
			_lobbyDiff = LobbyHelper.GetLobbyDiff(_lobbySlot.thisLobby);
			TextMeshProUGUI playerCount = _lobbySlot.playerCount;
			if ((Object)(object)playerCount == (Object)null)
			{
				return;
			}
			_joinButton = ((Component)this).GetComponentInChildren<Button>();
			if (!((Object)(object)_joinButton == (Object)null))
			{
				Sprite lobbySprite = GetLobbySprite(_lobbyDiff.GetModdedLobbyType());
				Sprite lobbySprite2 = GetLobbySprite(_lobbyDiff.GetModdedLobbyType(), inverted: true);
				if ((Object)(object)lobbySprite != (Object)null && (Object)(object)lobbySprite2 != (Object)null && (Object)(object)_lobbySlot.LobbyName != (Object)null)
				{
					Vector3 localPosition = ((TMP_Text)playerCount).transform.localPosition;
					((TMP_Text)playerCount).transform.localPosition = new Vector3(32f, localPosition.y, localPosition.z);
					CreateModListButton(_joinButton, lobbySprite, lobbySprite2, ((Graphic)_lobbySlot.LobbyName).color, ((TMP_Text)playerCount).transform);
				}
			}
		}

		private void Start()
		{
			Button? joinButton = _joinButton;
			TextMeshProUGUI buttonText = ((joinButton != null) ? ((Component)joinButton).GetComponentInChildren<TextMeshProUGUI>() : null);
			LobbyDiffResult? lobbyDiffResult = _lobbyDiff?.GetModdedLobbyType();
			if (lobbyDiffResult.HasValue && !((Object)(object)_joinButton == (Object)null) && !((Object)(object)buttonText == (Object)null) && (lobbyDiffResult == LobbyDiffResult.Incompatible || lobbyDiffResult == LobbyDiffResult.Unknown))
			{
				_buttonEventHandlers.ForEach(delegate(ButtonEventHandler handler)
				{
					//IL_0007: Unknown result type (might be due to invalid IL or missing references)
					//IL_0012: Unknown result type (might be due to invalid IL or missing references)
					handler.SetColor(((Graphic)buttonText).color, ((Graphic)buttonText).color);
				});
				if (lobbyDiffResult == LobbyDiffResult.Incompatible)
				{
					((Selectable)_joinButton).interactable = false;
					SetupModListButtonEvents(_joinButton);
				}
			}
		}

		private void OnDestroy()
		{
			if (_buttonEventHandlers.Count == 0)
			{
				return;
			}
			foreach (ButtonEventHandler buttonEventHandler in _buttonEventHandlers)
			{
				if (!((Object)(object)buttonEventHandler == (Object)null))
				{
					buttonEventHandler.OnHoverStateChanged -= OnModListHoverStateChanged;
					buttonEventHandler.OnClick -= OnModListClick;
				}
			}
			_buttonEventHandlers.Clear();
		}

		public void SetParentContainer(Transform parentTransform)
		{
			_parentContainer = parentTransform;
		}

		private Button? CreateModListButton(Button original, Sprite sprite, Sprite invertedSprite, Color color, Transform parent)
		{
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			if (_lobbyDiff == null)
			{
				return null;
			}
			Button val = Object.Instantiate<Button>(original, parent);
			_buttonTransform = ((Component)val).GetComponent<RectTransform>();
			Transform obj = ((Component)val).transform.Find("SelectionHighlight");
			RectTransform val2 = ((obj != null) ? ((Component)obj).GetComponent<RectTransform>() : null);
			Image val3 = ((val2 != null) ? ((Component)val2).GetComponent<Image>() : null);
			if ((Object)(object)_buttonTransform == (Object)null || (Object)(object)val2 == (Object)null || (Object)(object)val3 == (Object)null)
			{
				return null;
			}
			TextMeshProUGUI componentInChildren = ((Component)val).GetComponentInChildren<TextMeshProUGUI>();
			if ((Object)(object)componentInChildren != (Object)null)
			{
				((Behaviour)componentInChildren).enabled = false;
			}
			((UnityEventBase)val.onClick).m_PersistentCalls.Clear();
			((Selectable)val).transition = (Transition)0;
			((Behaviour)((Selectable)val).animator).enabled = false;
			SetupButtonPositioning(_buttonTransform);
			SetupButtonImage(val2, val3);
			ButtonEventHandler buttonEventHandler = SetupModListButtonEvents(val);
			buttonEventHandler.SetButtonImageData(val3, sprite, invertedSprite, color, color);
			return val;
		}

		private void OnModListClick()
		{
			if (!(_lobbyDiff == null) && !((Object)(object)ModListPanel.Instance == (Object)null))
			{
				ModListPanel.Instance.DisplayNotification(_lobbyDiff);
			}
		}

		private void OnModListHoverStateChanged(bool hovered)
		{
			if (!(_lobbyDiff == null) && !((Object)(object)_buttonTransform == (Object)null) && !((Object)(object)_parentContainer == (Object)null) && !((Object)(object)ModListTooltipPanel.Instance == (Object)null))
			{
				if (hovered)
				{
					ModListTooltipPanel.Instance.DisplayNotification(_lobbyDiff, _buttonTransform, _parentContainer);
				}
				else
				{
					ModListTooltipPanel.Instance.HideNotification();
				}
			}
		}

		private ButtonEventHandler SetupModListButtonEvents(Button button)
		{
			ButtonEventHandler buttonEventHandler = ((Component)button).gameObject.AddComponent<ButtonEventHandler>();
			buttonEventHandler.OnHoverStateChanged += OnModListHoverStateChanged;
			buttonEventHandler.OnClick += OnModListClick;
			_buttonEventHandlers.Add(buttonEventHandler);
			return buttonEventHandler;
		}

		private void SetupButtonPositioning(RectTransform buttonTransform)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			buttonTransform.sizeDelta = new Vector2(30f, 30f);
			buttonTransform.offsetMin = new Vector2(-37f, -37f);
			buttonTransform.offsetMax = new Vector2(-9.3f, -7f);
			buttonTransform.anchoredPosition = new Vector2(-85f, -7f);
			((Transform)buttonTransform).localPosition = new Vector3(-5.5f, 1.25f, 0f);
			((Transform)buttonTransform).localScale = new Vector3(0.6f, 0.6f, 0.6f);
		}

		private void SetupButtonImage(RectTransform buttonImageTransform, Image buttonImage)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			buttonImageTransform.sizeDelta = new Vector2(31.5f, 30f);
			buttonImageTransform.offsetMin = new Vector2(0f, 0f);
			buttonImageTransform.offsetMax = new Vector2(31.5f, 30f);
			buttonImageTransform.anchoredPosition = new Vector2(14f, 15f);
			((Transform)buttonImageTransform).localScale = Vector3.one;
			((Behaviour)buttonImage).enabled = true;
		}

		private Sprite? GetLobbySprite(LobbyDiffResult lobbyDiffResult, bool inverted = false)
		{
			string text = "LobbyCompatibility.Resources.";
			if (inverted)
			{
				text += "Inverted";
			}
			switch (lobbyDiffResult)
			{
			case LobbyDiffResult.Compatible:
			case LobbyDiffResult.PresumedCompatible:
				text += "ModSettings";
				break;
			case LobbyDiffResult.Incompatible:
				text += "ModSettingsExclamationPoint";
				break;
			default:
				text += "ModSettingsQuestionMark";
				break;
			}
			return TextureHelper.FindSpriteInAssembly(text + ".png");
		}
	}
	public class ModListPanel : MonoBehaviour
	{
		public static ModListPanel? Instance;

		private static readonly Vector2 NotificationWidth = new Vector2(1.6f, 1.75f);

		private static readonly float TabPadding = 3f;

		private List<PluginDiffSlot?> _spawnedPluginDiffSlots = new List<PluginDiffSlot>();

		private List<PluginCategorySlot?> _spawnedPluginCategorySlots = new List<PluginCategorySlot>();

		private RectTransform? _panelTransform;

		private ScrollRect? _scrollRect;

		private TextMeshProUGUI? _titleText;

		private TextMeshProUGUI? _descriptionText;

		private List<ModListTab> _tabs = new List<ModListTab>();

		private ModListFilter _currentTab;

		private LobbyDiff? _lobbyDiff;

		private PluginDiffSlotPool? _pluginDiffSlotPool;

		private PluginCategorySlotPool? _pluginCategorySlotPool;

		private void Awake()
		{
			Instance = this;
		}

		public void SetupPanel(GameObject panel, Transform scrollViewTemplate, TextMeshProUGUI privatePublicDescription)
		{
			//IL_00f7: 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_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_020d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0228: Unknown result type (might be due to invalid IL or missing references)
			//IL_0235: Unknown result type (might be due to invalid IL or missing references)
			//IL_0244: Unknown result type (might be due to invalid IL or missing references)
			//IL_026b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0275: Expected O, but got Unknown
			Transform obj = panel.transform.Find("Panel");
			Image val = ((obj != null) ? ((Component)obj).GetComponent<Image>() : null);
			_panelTransform = ((val != null) ? ((Graphic)val).rectTransform : null);
			RectTransform? panelTransform = _panelTransform;
			object obj2;
			if (panelTransform == null)
			{
				obj2 = null;
			}
			else
			{
				Transform obj3 = ((Transform)panelTransform).Find("Image");
				obj2 = ((obj3 != null) ? ((Component)obj3).GetComponent<Image>() : null);
			}
			Image val2 = (Image)obj2;
			if ((Object)(object)val == (Object)null || (Object)(object)_panelTransform == (Object)null || (Object)(object)val2 == (Object)null)
			{
				return;
			}
			Transform obj4 = ((Transform)_panelTransform).Find("ResponseButton");
			Button val3 = ((obj4 != null) ? ((Component)obj4).GetComponent<Button>() : null);
			RectTransform val4 = ((val3 != null) ? ((Component)val3).GetComponent<RectTransform>() : null);
			if ((Object)(object)val3 == (Object)null || (Object)(object)val4 == (Object)null)
			{
				return;
			}
			Transform obj5 = ((Transform)_panelTransform).Find("NotificationText");
			_titleText = ((obj5 != null) ? ((Component)obj5).GetComponent<TextMeshProUGUI>() : null);
			if ((Object)(object)_titleText == (Object)null)
			{
				return;
			}
			((TMP_Text)_titleText).rectTransform.anchoredPosition = new Vector2(-2f, 155f);
			_descriptionText = Object.Instantiate<TextMeshProUGUI>(privatePublicDescription, ((TMP_Text)_titleText).transform.parent);
			((TMP_Text)_descriptionText).rectTransform.anchoredPosition = new Vector2(-3f, -60f);
			((TMP_Text)_descriptionText).rectTransform.sizeDelta = new Vector2(400f, ((TMP_Text)_descriptionText).rectTransform.sizeDelta.y);
			((TMP_Text)_descriptionText).text = "";
			_scrollRect = SetupScrollRect(_panelTransform, scrollViewTemplate, ((Graphic)_titleText).color);
			if (!((Object)(object)_scrollRect == (Object)null))
			{
				SetupModListSlots(_panelTransform, _scrollRect, ((Graphic)_titleText).color);
				((Graphic)val).color = new Color(((Graphic)val).color.r, ((Graphic)val).color.g, ((Graphic)val).color.b, 1f);
				UIHelper.TryMultiplySizeDelta((Transform?)(object)_panelTransform, NotificationWidth);
				UIHelper.TryMultiplySizeDelta(((Component)val2).transform, NotificationWidth);
				UIHelper.TryMultiplySizeDelta(((Transform)_panelTransform).Find("NotificationText"), NotificationWidth);
				val4.anchoredPosition = new Vector2(val4.anchoredPosition.x, -110.5f);
				((UnityEventBase)val3.onClick).m_PersistentCalls.Clear();
				((UnityEvent)val3.onClick).AddListener((UnityAction)delegate
				{
					SetPanelActive(active: false);
				});
				_tabs = SetupTabs(val2, val, val3);
				SetPanelActive(active: false);
			}
		}

		public List<ModListTab> SetupTabs(Image panelOutlineImage, Image panelImage, Button button)
		{
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01df: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0201: Unknown result type (might be due to invalid IL or missing references)
			//IL_0206: Unknown result type (might be due to invalid IL or missing references)
			//IL_0228: 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)
			//IL_024a: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a9: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_panelTransform == (Object)null)
			{
				return new List<ModListTab>();
			}
			List<ModListTab> list = new List<ModListTab>();
			List<ModListFilter> list2 = Enum.GetValues(typeof(ModListFilter)).Cast<ModListFilter>().ToList();
			Color unselectedColor = default(Color);
			for (int i = 0; i < list2.Count; i++)
			{
				Image val = Object.Instantiate<Image>(panelOutlineImage, ((Component)panelOutlineImage).transform.parent);
				((Graphic)val).rectTransform.sizeDelta = new Vector2(_panelTransform.sizeDelta.x / (float)list2.Count - TabPadding, 35f - TabPadding);
				float num = (float)i * (_panelTransform.sizeDelta.x + TabPadding) / (float)list2.Count;
				((Graphic)val).rectTransform.anchoredPosition = new Vector2((0f - _panelTransform.sizeDelta.x + ((Graphic)val).rectTransform.sizeDelta.x + (float)i) / 2f + num, (_panelTransform.sizeDelta.y + ((Graphic)val).rectTransform.sizeDelta.y - TabPadding) / 2f);
				val.sprite = null;
				((Graphic)val).color = ((Graphic)panelImage).color;
				Image val2 = Object.Instantiate<Image>(val, ((Component)val).transform, true);
				val2.sprite = panelOutlineImage.sprite;
				((Graphic)val2).color = ((Graphic)panelOutlineImage).color;
				((Graphic)val2).rectTransform.sizeDelta = ((Graphic)val2).rectTransform.sizeDelta + new Vector2(TabPadding, TabPadding);
				((Graphic)val2).rectTransform.anchoredPosition = ((Graphic)val2).rectTransform.anchoredPosition + new Vector2((0f - TabPadding) / 2f, 0f);
				Button val3 = Object.Instantiate<Button>(button, ((Component)val).transform);
				RectTransform component = ((Component)val3).GetComponent<RectTransform>();
				component.anchoredPosition = new Vector2((0f - TabPadding) / 2f - 0.4f, 0f);
				component.sizeDelta = ((Graphic)val2).rectTransform.sizeDelta + new Vector2(TabPadding, 0f);
				TextMeshProUGUI componentInChildren = ((Component)val3).GetComponentInChildren<TextMeshProUGUI>();
				((Component)val3).transform.SetAsFirstSibling();
				((Color)(ref unselectedColor))..ctor(((Graphic)val).color.r / 1.25f, ((Graphic)val).color.g / 1.25f, ((Graphic)val).color.b / 1.25f, 1f);
				((Component)val).transform.SetParent(((Transform)_panelTransform).parent);
				((Component)val).transform.SetSiblingIndex(1);
				ModListTab modListTab = ((Component)val).gameObject.AddComponent<ModListTab>();
				modListTab.Setup(val, val2, val3, componentInChildren, list2[i], ((Graphic)val).color, unselectedColor);
				modListTab.SetupEvents(SetTab);
				modListTab.SetSelectionStatus(list2[i] == LobbyCompatibilityPlugin.Config?.DefaultModListTab.Value);
				list.Add(modListTab);
			}
			return list;
		}

		private ScrollRect? SetupScrollRect(RectTransform panelTransform, Transform scrollViewTemplate, Color defaultTextColor)
		{
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			Transform val = Object.Instantiate<Transform>(scrollViewTemplate, (Transform)(object)panelTransform);
			RectTransform component = ((Component)val).GetComponent<RectTransform>();
			ScrollRect component2 = ((Component)val).GetComponent<ScrollRect>();
			if ((Object)(object)component == (Object)null || (Object)(object)component2 == (Object)null)
			{
				return null;
			}
			SteamLobbyManager componentInChildren = ((Component)val).GetComponentInChildren<SteamLobbyManager>();
			if ((Object)(object)componentInChildren != (Object)null)
			{
				Object.Destroy((Object)(object)componentInChildren);
			}
			component.anchoredPosition = new Vector2(15f, -30f);
			component.sizeDelta = new Vector2(-30f, -100f);
			component2.verticalNormalizedPosition = 1f;
			component2.verticalScrollbarVisibility = (ScrollbarVisibility)1;
			UIHelper.AddVerticalLayoutGroup(((Component)component2.content).gameObject);
			SetupLineSeperator(component2, defaultTextColor, 34.5f);
			SetupLineSeperator(component2, defaultTextColor, 106.5f);
			return component2;
		}

		private Image SetupLineSeperator(ScrollRect scrollRect, Color color, float xPosition)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("LineSeperator");
			Image val2 = val.AddComponent<Image>();
			val.transform.SetParent(((Transform)scrollRect.content).parent, false);
			((Graphic)val2).rectTransform.anchoredPosition = Vector2.op_Implicit(new Vector3(xPosition, 0f));
			((Graphic)val2).rectTransform.sizeDelta = Vector2.op_Implicit(new Vector3(1f, 200f));
			((Graphic)val2).color = color;
			return val2;
		}

		private void SetupModListSlots(RectTransform panelTransform, ScrollRect scrollRect, Color defaultTextColor)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: 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_00db: Unknown result type (might be due to invalid IL or missing referen

plugins/Mimics.dll

Decompiled 2 years ago
using System;
using System.CodeDom.Compiler;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using DunGen;
using GameNetcodeStuff;
using HarmonyLib;
using LethalCompanyMimics.Properties;
using Mimics.API;
using Mimics.NetcodePatcher;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.Events;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("Mimics")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("A mod that adds mimics to Lethal Company")]
[assembly: AssemblyFileVersion("2.6.0.0")]
[assembly: AssemblyInformationalVersion("2.6.0")]
[assembly: AssemblyProduct("Mimics")]
[assembly: AssemblyTitle("Mimics")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.6.0.0")]
[module: UnverifiableCode]
[module: NetcodePatchedAssembly]
internal class <Module>
{
	static <Module>()
	{
		NetworkVariableSerializationTypes.InitializeSerializer_UnmanagedByMemcpy<bool>();
		NetworkVariableSerializationTypes.InitializeEqualityChecker_UnmanagedIEquatable<bool>();
	}
}
namespace LethalCompanyMimics.Properties
{
	[GeneratedCode("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
	[DebuggerNonUserCode]
	[CompilerGenerated]
	internal class Resources
	{
		private static ResourceManager resourceMan;

		private static CultureInfo resourceCulture;

		[EditorBrowsable(EditorBrowsableState.Advanced)]
		internal static ResourceManager ResourceManager
		{
			get
			{
				if (resourceMan == null)
				{
					ResourceManager resourceManager = new ResourceManager("LethalCompanyMimics.Properties.Resources", typeof(Resources).Assembly);
					resourceMan = resourceManager;
				}
				return resourceMan;
			}
		}

		[EditorBrowsable(EditorBrowsableState.Advanced)]
		internal static CultureInfo Culture
		{
			get
			{
				return resourceCulture;
			}
			set
			{
				resourceCulture = value;
			}
		}

		internal static byte[] mimicdoor
		{
			get
			{
				object @object = ResourceManager.GetObject("mimicdoor", resourceCulture);
				return (byte[])@object;
			}
		}

		internal Resources()
		{
		}
	}
}
namespace Mimics
{
	[BepInPlugin("x753.Mimics", "Mimics", "2.6.0")]
	public class Mimics : BaseUnityPlugin
	{
		[HarmonyPatch(typeof(GameNetworkManager))]
		internal class GameNetworkManagerPatch
		{
			[HarmonyPatch("Start")]
			[HarmonyPostfix]
			private static void StartPatch()
			{
				((Component)GameNetworkManager.Instance).GetComponent<NetworkManager>().AddNetworkPrefab(MimicNetworkerPrefab);
			}
		}

		[HarmonyPatch(typeof(StartOfRound))]
		internal class StartOfRoundPatch
		{
			[HarmonyPatch("Start")]
			[HarmonyPostfix]
			private static void StartPatch(ref StartOfRound __instance)
			{
				if (((NetworkBehaviour)__instance).IsServer && (Object)(object)MimicNetworker.Instance == (Object)null)
				{
					GameObject val = Object.Instantiate<GameObject>(MimicNetworkerPrefab);
					val.GetComponent<NetworkObject>().Spawn(true);
					MimicNetworker.SpawnWeight0.Value = SpawnRates[0];
					MimicNetworker.SpawnWeight1.Value = SpawnRates[1];
					MimicNetworker.SpawnWeight2.Value = SpawnRates[2];
					MimicNetworker.SpawnWeight3.Value = SpawnRates[3];
					MimicNetworker.SpawnWeight4.Value = SpawnRates[4];
					MimicNetworker.SpawnWeightMax.Value = SpawnRates[5];
					MimicNetworker.SpawnRateDynamic.Value = DynamicSpawnRate;
				}
			}
		}

		[HarmonyPatch(typeof(Terminal))]
		internal class TerminalPatch
		{
			[HarmonyPatch("Start")]
			[HarmonyPostfix]
			private static void StartPatch(ref StartOfRound __instance)
			{
				//IL_0099: Unknown result type (might be due to invalid IL or missing references)
				//IL_009e: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b8: Expected O, but got Unknown
				//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e1: Expected O, but got Unknown
				Terminal val = Object.FindObjectOfType<Terminal>();
				if (!Object.op_Implicit((Object)(object)val.enemyFiles.Find((TerminalNode node) => node.creatureName == "Mimics")))
				{
					MimicCreatureID = val.enemyFiles.Count;
					MimicFile.creatureFileID = MimicCreatureID;
					val.enemyFiles.Add(MimicFile);
					TerminalKeyword val2 = val.terminalNodes.allKeywords.First((TerminalKeyword keyword) => keyword.word == "info");
					TerminalKeyword val3 = new TerminalKeyword
					{
						word = "mimics",
						isVerb = false,
						defaultVerb = val2
					};
					List<CompatibleNoun> list = val2.compatibleNouns.ToList();
					list.Add(new CompatibleNoun
					{
						noun = val3,
						result = MimicFile
					});
					val2.compatibleNouns = list.ToArray();
					List<TerminalKeyword> list2 = val.terminalNodes.allKeywords.ToList();
					list2.Add(val3);
					val.terminalNodes.allKeywords = list2.ToArray();
				}
			}
		}

		[HarmonyPatch(typeof(RoundManager))]
		internal class RoundManagerPatch
		{
			[HarmonyPatch("SetExitIDs")]
			[HarmonyPostfix]
			private static void SetExitIDsPatch(ref RoundManager __instance, Vector3 mainEntrancePosition)
			{
				//IL_058c: Unknown result type (might be due to invalid IL or missing references)
				//IL_059d: Unknown result type (might be due to invalid IL or missing references)
				//IL_05a2: Unknown result type (might be due to invalid IL or missing references)
				//IL_05a7: Unknown result type (might be due to invalid IL or missing references)
				//IL_05ac: Unknown result type (might be due to invalid IL or missing references)
				//IL_027d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0289: Unknown result type (might be due to invalid IL or missing references)
				//IL_029d: Unknown result type (might be due to invalid IL or missing references)
				//IL_02a2: Unknown result type (might be due to invalid IL or missing references)
				//IL_02a7: Unknown result type (might be due to invalid IL or missing references)
				//IL_02ba: Unknown result type (might be due to invalid IL or missing references)
				//IL_02ce: Unknown result type (might be due to invalid IL or missing references)
				//IL_02de: Unknown result type (might be due to invalid IL or missing references)
				//IL_02e3: Unknown result type (might be due to invalid IL or missing references)
				//IL_02ef: Unknown result type (might be due to invalid IL or missing references)
				//IL_02f6: Unknown result type (might be due to invalid IL or missing references)
				//IL_0302: Unknown result type (might be due to invalid IL or missing references)
				//IL_05bb: Unknown result type (might be due to invalid IL or missing references)
				//IL_05c0: Unknown result type (might be due to invalid IL or missing references)
				//IL_05c2: Unknown result type (might be due to invalid IL or missing references)
				//IL_05c4: Unknown result type (might be due to invalid IL or missing references)
				//IL_05f9: Unknown result type (might be due to invalid IL or missing references)
				//IL_063a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0716: Unknown result type (might be due to invalid IL or missing references)
				//IL_071b: Unknown result type (might be due to invalid IL or missing references)
				//IL_071f: Unknown result type (might be due to invalid IL or missing references)
				//IL_072b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0730: Unknown result type (might be due to invalid IL or missing references)
				//IL_0734: Unknown result type (might be due to invalid IL or missing references)
				//IL_0739: Unknown result type (might be due to invalid IL or missing references)
				//IL_06d1: Unknown result type (might be due to invalid IL or missing references)
				//IL_0385: Unknown result type (might be due to invalid IL or missing references)
				//IL_0396: Unknown result type (might be due to invalid IL or missing references)
				//IL_039b: Unknown result type (might be due to invalid IL or missing references)
				//IL_03a0: Unknown result type (might be due to invalid IL or missing references)
				//IL_03a5: Unknown result type (might be due to invalid IL or missing references)
				//IL_03af: Unknown result type (might be due to invalid IL or missing references)
				//IL_03b4: Unknown result type (might be due to invalid IL or missing references)
				//IL_03b9: Unknown result type (might be due to invalid IL or missing references)
				//IL_03bf: Unknown result type (might be due to invalid IL or missing references)
				//IL_03c7: Unknown result type (might be due to invalid IL or missing references)
				//IL_03d0: Unknown result type (might be due to invalid IL or missing references)
				//IL_03da: Unknown result type (might be due to invalid IL or missing references)
				//IL_045c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0464: Unknown result type (might be due to invalid IL or missing references)
				//IL_046d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0477: Unknown result type (might be due to invalid IL or missing references)
				//IL_0829: Unknown result type (might be due to invalid IL or missing references)
				//IL_0833: Expected O, but got Unknown
				//IL_0931: Unknown result type (might be due to invalid IL or missing references)
				//IL_0958: Unknown result type (might be due to invalid IL or missing references)
				//IL_08d2: Unknown result type (might be due to invalid IL or missing references)
				//IL_08f9: Unknown result type (might be due to invalid IL or missing references)
				//IL_0a0c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0a33: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)MimicNetworker.Instance == (Object)null)
				{
					return;
				}
				MimicsAPI.MainAPI.RefreshMimicEventHandler();
				MimicDoor.allMimics = new List<MimicDoor>();
				int num = 0;
				Dungeon currentDungeon = __instance.dungeonGenerator.Generator.CurrentDungeon;
				if (!InteriorWhitelist.Contains(((Object)currentDungeon.DungeonFlow).name.ToLower().Trim()))
				{
					return;
				}
				int num2 = 0;
				int[] array = new int[6]
				{
					MimicNetworker.SpawnWeight0.Value,
					MimicNetworker.SpawnWeight1.Value,
					MimicNetworker.SpawnWeight2.Value,
					MimicNetworker.SpawnWeight3.Value,
					MimicNetworker.SpawnWeight4.Value,
					MimicNetworker.SpawnWeightMax.Value
				};
				int num3 = 0;
				int[] array2 = array;
				foreach (int num4 in array2)
				{
					num3 += num4;
				}
				Random random = new Random(StartOfRound.Instance.randomMapSeed + 753);
				int num5 = random.Next(0, num3);
				int num6 = 0;
				for (int j = 0; j < array.Length; j++)
				{
					if (num5 < array[j] + num6)
					{
						num2 = j;
						break;
					}
					num6 += array[j];
				}
				if (num2 == 5)
				{
					num2 = 999;
				}
				EntranceTeleport[] array3 = Object.FindObjectsOfType<EntranceTeleport>(false);
				int num7 = (array3.Length - 2) / 2;
				if (MimicNetworker.SpawnRateDynamic.Value && num2 < num7 && num7 > 1)
				{
					num2 += random.Next(0, 2);
				}
				if (MimicNetworker.SpawnRateDynamic.Value && currentDungeon.AllTiles.Count > 100)
				{
					num2 += random.Next(0, 2);
				}
				if (((NetworkBehaviour)RoundManager.Instance).IsOwner)
				{
					Debug.Log((object)("I am the host. Desired mimics: " + num2));
				}
				else
				{
					Debug.Log((object)("I am the client. Desired mimics: " + num2));
				}
				List<Doorway> list = new List<Doorway>();
				Bounds val2 = default(Bounds);
				foreach (Tile allTile in currentDungeon.AllTiles)
				{
					foreach (Doorway unusedDoorway in allTile.UnusedDoorways)
					{
						if (!MimicsAPI.MainAPI.IgnoreDefaultPlacementValidation(unusedDoorway))
						{
							if (unusedDoorway.HasDoorPrefabInstance || (Object)(object)((Component)unusedDoorway).GetComponentInChildren<SpawnSyncedObject>(true) == (Object)null)
							{
								continue;
							}
							GameObject gameObject = ((Component)((Component)((Component)unusedDoorway).GetComponentInChildren<SpawnSyncedObject>(true)).transform.parent).gameObject;
							if (!((Object)gameObject).name.StartsWith("AlleyExitDoorContainer") || gameObject.activeSelf)
							{
								continue;
							}
							bool flag = false;
							Matrix4x4 val = Matrix4x4.TRS(((Component)unusedDoorway).transform.position, ((Component)unusedDoorway).transform.rotation, new Vector3(1f, 1f, 1f));
							((Bounds)(ref val2))..ctor(new Vector3(0f, 1.5f, 5.5f), new Vector3(2f, 6f, 8f));
							((Bounds)(ref val2)).center = ((Matrix4x4)(ref val)).MultiplyPoint3x4(((Bounds)(ref val2)).center);
							Collider[] array4 = Physics.OverlapBox(((Bounds)(ref val2)).center, ((Bounds)(ref val2)).extents, ((Component)unusedDoorway).transform.rotation, LayerMask.GetMask(new string[3] { "Room", "Railing", "MapHazards" }));
							Collider[] array5 = array4;
							int num8 = 0;
							if (num8 < array5.Length)
							{
								Collider val3 = array5[num8];
								flag = true;
							}
							if (flag)
							{
								continue;
							}
							foreach (Tile allTile2 in currentDungeon.AllTiles)
							{
								if (!((Object)(object)allTile == (Object)(object)allTile2))
								{
									Vector3 origin = ((Component)unusedDoorway).transform.position + 5f * ((Component)unusedDoorway).transform.forward;
									Bounds val4 = UnityUtil.CalculateProxyBounds(((Component)allTile2).gameObject, true, Vector3.up);
									Ray val5 = default(Ray);
									((Ray)(ref val5)).origin = origin;
									((Ray)(ref val5)).direction = Vector3.up;
									if (((Bounds)(ref val4)).IntersectRay(val5) && (((Object)allTile2).name.Contains("Catwalk") || ((Object)allTile2).name.Contains("LargeForkTile") || ((Object)allTile2).name.Contains("4x4BigStair") || ((Object)allTile2).name.Contains("ElevatorConnector") || (((Object)allTile2).name.Contains("StartRoom") && !((Object)allTile2).name.Contains("Manor"))))
									{
										flag = true;
									}
									val5 = default(Ray);
									((Ray)(ref val5)).origin = origin;
									((Ray)(ref val5)).direction = Vector3.down;
									if (((Bounds)(ref val4)).IntersectRay(val5) && (((Object)allTile2).name.Contains("MediumRoomHallway1B") || ((Object)allTile2).name.Contains("LargeForkTile") || ((Object)allTile2).name.Contains("4x4BigStair") || ((Object)allTile2).name.Contains("ElevatorConnector") || ((Object)allTile2).name.Contains("StartRoom")))
									{
										flag = true;
									}
								}
							}
							if (flag)
							{
								continue;
							}
						}
						if (MimicsAPI.MainAPI.IsPlacementValid(unusedDoorway))
						{
							list.Add(unusedDoorway);
						}
					}
				}
				Shuffle(list, StartOfRound.Instance.randomMapSeed);
				List<Vector3> list2 = new List<Vector3>();
				foreach (Doorway item in list)
				{
					if (num >= num2)
					{
						break;
					}
					bool flag2 = false;
					Vector3 val6 = ((Component)item).transform.position + 5f * ((Component)item).transform.forward;
					foreach (Vector3 item2 in list2)
					{
						if (Vector3.Distance(val6, item2) < 4f)
						{
							flag2 = true;
							break;
						}
					}
					if (flag2)
					{
						continue;
					}
					list2.Add(val6);
					GameObject gameObject2 = ((Component)((Component)((Component)item).GetComponentInChildren<SpawnSyncedObject>(true)).transform.parent).gameObject;
					GameObject val7 = Object.Instantiate<GameObject>(MimicPrefab, ((Component)item).transform);
					val7.transform.position = gameObject2.transform.position;
					MimicDoor component = val7.GetComponent<MimicDoor>();
					component.scanNode.creatureScanID = MimicCreatureID;
					AudioSource[] componentsInChildren = val7.GetComponentsInChildren<AudioSource>(true);
					foreach (AudioSource val8 in componentsInChildren)
					{
						val8.volume = MimicVolume / 100f;
						val8.outputAudioMixerGroup = StartOfRound.Instance.ship3DAudio.outputAudioMixerGroup;
					}
					if (SpawnRates[5] == 9753 && num == 0)
					{
						val7.transform.position = new Vector3(-7f, 0f, -10f);
					}
					MimicDoor.allMimics.Add(component);
					component.mimicIndex = num;
					num++;
					GameObject gameObject3 = ((Component)((Component)item).transform.GetChild(0)).gameObject;
					gameObject3.SetActive(false);
					Bounds bounds = ((Collider)component.frameBox).bounds;
					Vector3 center = ((Bounds)(ref bounds)).center;
					bounds = ((Collider)component.frameBox).bounds;
					Collider[] array6 = Physics.OverlapBox(center, ((Bounds)(ref bounds)).extents, Quaternion.identity);
					foreach (Collider val9 in array6)
					{
						if (((Object)((Component)val9).gameObject).name.Contains("Shelf"))
						{
							((Component)val9).gameObject.SetActive(false);
						}
					}
					Light componentInChildren = gameObject2.GetComponentInChildren<Light>(true);
					((Component)componentInChildren).transform.parent.SetParent(val7.transform);
					MeshRenderer[] componentsInChildren2 = val7.GetComponentsInChildren<MeshRenderer>();
					MeshRenderer[] array7 = componentsInChildren2;
					foreach (MeshRenderer val10 in array7)
					{
						Material[] materials = ((Renderer)val10).materials;
						foreach (Material val11 in materials)
						{
							val11.shader = ((Renderer)gameObject3.GetComponentInChildren<MeshRenderer>(true)).material.shader;
							val11.renderQueue = ((Renderer)gameObject3.GetComponentInChildren<MeshRenderer>(true)).material.renderQueue;
						}
					}
					component.interactTrigger.onInteract = new InteractEvent();
					((UnityEvent<PlayerControllerB>)(object)component.interactTrigger.onInteract).AddListener((UnityAction<PlayerControllerB>)component.TouchMimic);
					MimicsAPI.MainAPI.OnMimicCreated(component, item);
					if (MimicsAPI.MainAPI.OverrideDefaultImperfectionCreation(component, item))
					{
						MimicsAPI.MainAPI.OnMimicCreateImperfections(component);
						break;
					}
					if (MimicPerfection)
					{
						continue;
					}
					component.interactTrigger.timeToHold = 0.9f;
					if (!ColorBlindMode)
					{
						if ((StartOfRound.Instance.randomMapSeed + num) % 2 == 0)
						{
							((Renderer)val7.GetComponentsInChildren<MeshRenderer>()[0]).material.color = new Color(0.490566f, 0.1226415f, 0.1302275f);
							((Renderer)val7.GetComponentsInChildren<MeshRenderer>()[1]).material.color = new Color(0.4339623f, 0.1043965f, 0.1150277f);
							componentInChildren.colorTemperature = 1250f;
						}
						else
						{
							((Renderer)val7.GetComponentsInChildren<MeshRenderer>()[0]).material.color = new Color(0.5f, 0.1580188f, 0.1657038f);
							((Renderer)val7.GetComponentsInChildren<MeshRenderer>()[1]).material.color = new Color(43f / 106f, 0.1358579f, 0.1393619f);
							componentInChildren.colorTemperature = 1300f;
						}
					}
					else if ((StartOfRound.Instance.randomMapSeed + num) % 2 == 0)
					{
						component.interactTrigger.timeToHold = 1.1f;
					}
					else
					{
						component.interactTrigger.timeToHold = 1f;
					}
					if (!EasyMode)
					{
						continue;
					}
					Random random2 = new Random(StartOfRound.Instance.randomMapSeed + num);
					switch (random2.Next(0, 4))
					{
					case 0:
						if (!ColorBlindMode)
						{
							((Renderer)val7.GetComponentsInChildren<MeshRenderer>()[0]).material.color = new Color(0.489f, 0.2415526f, 0.1479868f);
							((Renderer)val7.GetComponentsInChildren<MeshRenderer>()[1]).material.color = new Color(0.489f, 0.2415526f, 0.1479868f);
						}
						else
						{
							component.interactTrigger.timeToHold = 1.5f;
						}
						break;
					case 1:
						component.interactTrigger.hoverTip = "Feed : [LMB]";
						component.interactTrigger.holdTip = "Feed : [LMB]";
						break;
					case 2:
						component.interactTrigger.hoverIcon = component.LostFingersIcon;
						break;
					case 3:
						component.interactTrigger.holdTip = "DIE : [LMB]";
						component.interactTrigger.timeToHold = 0.5f;
						break;
					default:
						component.interactTrigger.hoverTip = "BUG, REPORT TO DEVELOPER";
						break;
					}
				}
			}
		}

		[HarmonyPatch(typeof(SprayPaintItem))]
		internal class SprayPaintItemPatch
		{
			private static FieldInfo SprayHit = typeof(SprayPaintItem).GetField("sprayHit", BindingFlags.Instance | BindingFlags.NonPublic);

			[HarmonyPatch("SprayPaintClientRpc")]
			[HarmonyPostfix]
			private static void SprayPaintClientRpcPatch(SprayPaintItem __instance, Vector3 sprayPos, Vector3 sprayRot)
			{
				//IL_0019: Unknown result type (might be due to invalid IL or missing references)
				//IL_001e: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)MimicNetworker.Instance == (Object)null)
				{
					return;
				}
				RaycastHit val = (RaycastHit)SprayHit.GetValue(__instance);
				if ((Object)(object)((RaycastHit)(ref val)).collider != (Object)null && ((Object)((RaycastHit)(ref val)).collider).name == "MimicSprayCollider")
				{
					MimicDoor component = ((Component)((Component)((RaycastHit)(ref val)).collider).transform.parent.parent).GetComponent<MimicDoor>();
					component.sprayCount++;
					if (component.sprayCount > 8)
					{
						MimicNetworker.Instance.MimicAddAnger(1, component.mimicIndex);
					}
				}
			}
		}

		[HarmonyPatch(typeof(LockPicker))]
		internal class LockPickerPatch
		{
			private static FieldInfo RayHit = typeof(LockPicker).GetField("hit", BindingFlags.Instance | BindingFlags.NonPublic);

			[HarmonyPatch("ItemActivate")]
			[HarmonyPostfix]
			private static void ItemActivatePatch(LockPicker __instance, bool used, bool buttonDown = true)
			{
				//IL_0019: Unknown result type (might be due to invalid IL or missing references)
				//IL_001e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0032: Unknown result type (might be due to invalid IL or missing references)
				//IL_0038: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)MimicNetworker.Instance == (Object)null)
				{
					return;
				}
				RaycastHit val = (RaycastHit)RayHit.GetValue(__instance);
				if (!((Object)(object)((GrabbableObject)__instance).playerHeldBy == (Object)null) && !((object)(RaycastHit)(ref val)).Equals((object)default(RaycastHit)) && !((Object)(object)((RaycastHit)(ref val)).transform.parent == (Object)null))
				{
					Transform parent = ((RaycastHit)(ref val)).transform.parent;
					if (((Object)parent).name.StartsWith("MimicDoor"))
					{
						MimicNetworker.Instance.MimicLockPick(__instance, ((Component)parent).GetComponent<MimicDoor>().mimicIndex);
					}
				}
			}
		}

		private const string modGUID = "x753.Mimics";

		private const string modName = "Mimics";

		private const string modVersion = "2.6.0";

		private readonly Harmony harmony = new Harmony("x753.Mimics");

		internal static ManualLogSource MimicsLogger;

		private static Mimics Instance;

		public static GameObject MimicPrefab;

		public static GameObject MimicNetworkerPrefab;

		public static TerminalNode MimicFile;

		public static int MimicCreatureID;

		public static int[] SpawnRates;

		public static bool MimicPerfection;

		public static bool EasyMode;

		public static bool ColorBlindMode;

		public static float MimicVolume;

		public static bool DynamicSpawnRate;

		public static List<string> InteriorWhitelist;

		private void Awake()
		{
			AssetBundle val = AssetBundle.LoadFromMemory(Resources.mimicdoor);
			MimicPrefab = val.LoadAsset<GameObject>("Assets/MimicDoor.prefab");
			MimicNetworkerPrefab = val.LoadAsset<GameObject>("Assets/MimicNetworker.prefab");
			MimicFile = val.LoadAsset<TerminalNode>("Assets/MimicFile.asset");
			if ((Object)(object)Instance == (Object)null)
			{
				Instance = this;
			}
			harmony.PatchAll();
			MimicsLogger = Logger.CreateLogSource("x753.Mimics");
			MimicsLogger.LogInfo((object)"Plugin Mimics is loaded!!");
			string value = ((BaseUnityPlugin)this).Config.Bind<string>("Compatibility", "Interior Whitelist", "Level1Flow, Level1Flow3Exits, Level1FlowExtraLarge, Level2Flow, SDMLevel", "Comma separated list of interiors that mimics can spawn in. Not all interiors will work.").Value;
			InteriorWhitelist = (from s in value.ToLower().Split(',')
				select s.Trim()).ToList();
			SpawnRates = new int[6]
			{
				((BaseUnityPlugin)this).Config.Bind<int>("Spawn Rate", "Zero Mimics", 23, "Weight of zero mimics spawning").Value,
				((BaseUnityPlugin)this).Config.Bind<int>("Spawn Rate", "One Mimic", 69, "Weight of one mimic spawning").Value,
				((BaseUnityPlugin)this).Config.Bind<int>("Spawn Rate", "Two Mimics", 7, "Weight of two mimics spawning").Value,
				((BaseUnityPlugin)this).Config.Bind<int>("Spawn Rate", "Three Mimics", 1, "Weight of three mimics spawning").Value,
				((BaseUnityPlugin)this).Config.Bind<int>("Spawn Rate", "Four Mimics", 0, "Weight of four mimics spawning").Value,
				((BaseUnityPlugin)this).Config.Bind<int>("Spawn Rate", "Maximum Mimics", 0, "Weight of maximum mimics spawning").Value
			};
			DynamicSpawnRate = ((BaseUnityPlugin)this).Config.Bind<bool>("Spawn Rate", "Dynamic Spawn Rate", true, "Increases mimic spawn rate based on dungeon size and the number of instances of the real thing.").Value;
			MimicPerfection = ((BaseUnityPlugin)this).Config.Bind<bool>("Difficulty", "Perfect Mimics", false, "Select this if you want mimics to be the exact same color as the real thing. Overrides all difficulty settings.").Value;
			EasyMode = ((BaseUnityPlugin)this).Config.Bind<bool>("Difficulty", "Easy Mode", false, "Each mimic will have one of several possible imperfections to help you tell if it's a mimic.").Value;
			ColorBlindMode = ((BaseUnityPlugin)this).Config.Bind<bool>("Difficulty", "Color Blind Mode", false, "Replaces all color differences with another way to differentiate mimics.").Value;
			MimicVolume = ((BaseUnityPlugin)this).Config.Bind<int>("General", "SFX Volume", 100, "Volume of the mimic's SFX (0-100)").Value;
			if (MimicVolume < 0f)
			{
				MimicVolume = 0f;
			}
			if (MimicVolume > 100f)
			{
				MimicVolume = 100f;
			}
			((BaseUnityPlugin)this).Config.Bind<int>("Difficulty", "Difficulty Level", 0, "This is an old setting, ignore it.");
			((BaseUnityPlugin)this).Config.Remove(((BaseUnityPlugin)this).Config["Difficulty", "Difficulty Level"].Definition);
			((BaseUnityPlugin)this).Config.Bind<int>("Spawn Rate", "Five Mimics", 0, "This is an old setting, ignore it.");
			((BaseUnityPlugin)this).Config.Remove(((BaseUnityPlugin)this).Config["Spawn Rate", "Five Mimics"].Definition);
			((BaseUnityPlugin)this).Config.Save();
			Type[] types = Assembly.GetExecutingAssembly().GetTypes();
			Type[] array = types;
			foreach (Type type in array)
			{
				MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic);
				MethodInfo[] array2 = methods;
				foreach (MethodInfo methodInfo in array2)
				{
					object[] customAttributes = methodInfo.GetCustomAttributes(typeof(RuntimeInitializeOnLoadMethodAttribute), inherit: false);
					if (customAttributes.Length != 0)
					{
						methodInfo.Invoke(null, null);
					}
				}
			}
		}

		public static void Shuffle<T>(IList<T> list, int seed)
		{
			Random random = new Random(seed);
			int num = list.Count;
			while (num > 1)
			{
				num--;
				int index = random.Next(num + 1);
				T value = list[index];
				list[index] = list[num];
				list[num] = value;
			}
		}
	}
	public class MimicNetworker : NetworkBehaviour
	{
		public static MimicNetworker Instance;

		public static NetworkVariable<int> SpawnWeight0 = new NetworkVariable<int>(0, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0);

		public static NetworkVariable<int> SpawnWeight1 = new NetworkVariable<int>(0, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0);

		public static NetworkVariable<int> SpawnWeight2 = new NetworkVariable<int>(0, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0);

		public static NetworkVariable<int> SpawnWeight3 = new NetworkVariable<int>(0, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0);

		public static NetworkVariable<int> SpawnWeight4 = new NetworkVariable<int>(0, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0);

		public static NetworkVariable<int> SpawnWeightMax = new NetworkVariable<int>(0, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0);

		public static NetworkVariable<bool> SpawnRateDynamic = new NetworkVariable<bool>(false, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0);

		private void Awake()
		{
			Instance = this;
		}

		public void MimicAttack(int playerId, int mimicIndex, bool ownerOnly = false)
		{
			if (((NetworkBehaviour)this).IsOwner)
			{
				Instance.MimicAttackClientRpc(playerId, mimicIndex);
			}
			else if (!ownerOnly)
			{
				Instance.MimicAttackServerRpc(playerId, mimicIndex);
			}
		}

		[ClientRpc]
		public void MimicAttackClientRpc(int playerId, int mimicIndex)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)base.__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
				{
					ClientRpcParams val = default(ClientRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(2885019175u, val, (RpcDelivery)0);
					BytePacker.WriteValueBitPacked(val2, playerId);
					BytePacker.WriteValueBitPacked(val2, mimicIndex);
					((NetworkBehaviour)this).__endSendClientRpc(ref val2, 2885019175u, val, (RpcDelivery)0);
				}
				if ((int)base.__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
				{
					((MonoBehaviour)this).StartCoroutine(MimicDoor.allMimics[mimicIndex].Attack(playerId));
				}
			}
		}

		[ServerRpc(RequireOwnership = false)]
		public void MimicAttackServerRpc(int playerId, int mimicIndex)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
				{
					ServerRpcParams val = default(ServerRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(1024971481u, val, (RpcDelivery)0);
					BytePacker.WriteValueBitPacked(val2, playerId);
					BytePacker.WriteValueBitPacked(val2, mimicIndex);
					((NetworkBehaviour)this).__endSendServerRpc(ref val2, 1024971481u, val, (RpcDelivery)0);
				}
				if ((int)base.__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost))
				{
					Instance.MimicAttackClientRpc(playerId, mimicIndex);
				}
			}
		}

		public void MimicAddAnger(int amount, int mimicIndex)
		{
			if (((NetworkBehaviour)this).IsOwner)
			{
				Instance.MimicAddAngerClientRpc(amount, mimicIndex);
			}
			else
			{
				Instance.MimicAddAngerServerRpc(amount, mimicIndex);
			}
		}

		[ClientRpc]
		public void MimicAddAngerClientRpc(int amount, int mimicIndex)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)base.__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
				{
					ClientRpcParams val = default(ClientRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(1137632670u, val, (RpcDelivery)0);
					BytePacker.WriteValueBitPacked(val2, amount);
					BytePacker.WriteValueBitPacked(val2, mimicIndex);
					((NetworkBehaviour)this).__endSendClientRpc(ref val2, 1137632670u, val, (RpcDelivery)0);
				}
				if ((int)base.__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
				{
					((MonoBehaviour)this).StartCoroutine(MimicDoor.allMimics[mimicIndex].AddAnger(amount));
				}
			}
		}

		[ServerRpc(RequireOwnership = false)]
		public void MimicAddAngerServerRpc(int amount, int mimicIndex)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
				{
					ServerRpcParams val = default(ServerRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(669208889u, val, (RpcDelivery)0);
					BytePacker.WriteValueBitPacked(val2, amount);
					BytePacker.WriteValueBitPacked(val2, mimicIndex);
					((NetworkBehaviour)this).__endSendServerRpc(ref val2, 669208889u, val, (RpcDelivery)0);
				}
				if ((int)base.__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost))
				{
					Instance.MimicAddAngerClientRpc(amount, mimicIndex);
				}
			}
		}

		public void MimicLockPick(LockPicker lockPicker, int mimicIndex, bool ownerOnly = false)
		{
			int playerId = (int)((GrabbableObject)lockPicker).playerHeldBy.playerClientId;
			if (((NetworkBehaviour)this).IsOwner)
			{
				Instance.MimicLockPickClientRpc(playerId, mimicIndex);
			}
			else if (!ownerOnly)
			{
				Instance.MimicLockPickServerRpc(playerId, mimicIndex);
			}
		}

		[ClientRpc]
		public void MimicLockPickClientRpc(int playerId, int mimicIndex)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)base.__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
				{
					ClientRpcParams val = default(ClientRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(3716888238u, val, (RpcDelivery)0);
					BytePacker.WriteValueBitPacked(val2, playerId);
					BytePacker.WriteValueBitPacked(val2, mimicIndex);
					((NetworkBehaviour)this).__endSendClientRpc(ref val2, 3716888238u, val, (RpcDelivery)0);
				}
				if ((int)base.__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
				{
					((MonoBehaviour)this).StartCoroutine(MimicDoor.allMimics[mimicIndex].MimicLockPick(playerId));
				}
			}
		}

		[ServerRpc(RequireOwnership = false)]
		public void MimicLockPickServerRpc(int playerId, int mimicIndex)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
				{
					ServerRpcParams val = default(ServerRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(1897916243u, val, (RpcDelivery)0);
					BytePacker.WriteValueBitPacked(val2, playerId);
					BytePacker.WriteValueBitPacked(val2, mimicIndex);
					((NetworkBehaviour)this).__endSendServerRpc(ref val2, 1897916243u, val, (RpcDelivery)0);
				}
				if ((int)base.__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost))
				{
					Instance.MimicLockPickClientRpc(playerId, mimicIndex);
				}
			}
		}

		protected override void __initializeVariables()
		{
			if (SpawnWeight0 == null)
			{
				throw new Exception("MimicNetworker.SpawnWeight0 cannot be null. All NetworkVariableBase instances must be initialized.");
			}
			((NetworkVariableBase)SpawnWeight0).Initialize((NetworkBehaviour)(object)this);
			((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)SpawnWeight0, "SpawnWeight0");
			base.NetworkVariableFields.Add((NetworkVariableBase)(object)SpawnWeight0);
			if (SpawnWeight1 == null)
			{
				throw new Exception("MimicNetworker.SpawnWeight1 cannot be null. All NetworkVariableBase instances must be initialized.");
			}
			((NetworkVariableBase)SpawnWeight1).Initialize((NetworkBehaviour)(object)this);
			((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)SpawnWeight1, "SpawnWeight1");
			base.NetworkVariableFields.Add((NetworkVariableBase)(object)SpawnWeight1);
			if (SpawnWeight2 == null)
			{
				throw new Exception("MimicNetworker.SpawnWeight2 cannot be null. All NetworkVariableBase instances must be initialized.");
			}
			((NetworkVariableBase)SpawnWeight2).Initialize((NetworkBehaviour)(object)this);
			((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)SpawnWeight2, "SpawnWeight2");
			base.NetworkVariableFields.Add((NetworkVariableBase)(object)SpawnWeight2);
			if (SpawnWeight3 == null)
			{
				throw new Exception("MimicNetworker.SpawnWeight3 cannot be null. All NetworkVariableBase instances must be initialized.");
			}
			((NetworkVariableBase)SpawnWeight3).Initialize((NetworkBehaviour)(object)this);
			((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)SpawnWeight3, "SpawnWeight3");
			base.NetworkVariableFields.Add((NetworkVariableBase)(object)SpawnWeight3);
			if (SpawnWeight4 == null)
			{
				throw new Exception("MimicNetworker.SpawnWeight4 cannot be null. All NetworkVariableBase instances must be initialized.");
			}
			((NetworkVariableBase)SpawnWeight4).Initialize((NetworkBehaviour)(object)this);
			((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)SpawnWeight4, "SpawnWeight4");
			base.NetworkVariableFields.Add((NetworkVariableBase)(object)SpawnWeight4);
			if (SpawnWeightMax == null)
			{
				throw new Exception("MimicNetworker.SpawnWeightMax cannot be null. All NetworkVariableBase instances must be initialized.");
			}
			((NetworkVariableBase)SpawnWeightMax).Initialize((NetworkBehaviour)(object)this);
			((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)SpawnWeightMax, "SpawnWeightMax");
			base.NetworkVariableFields.Add((NetworkVariableBase)(object)SpawnWeightMax);
			if (SpawnRateDynamic == null)
			{
				throw new Exception("MimicNetworker.SpawnRateDynamic cannot be null. All NetworkVariableBase instances must be initialized.");
			}
			((NetworkVariableBase)SpawnRateDynamic).Initialize((NetworkBehaviour)(object)this);
			((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)SpawnRateDynamic, "SpawnRateDynamic");
			base.NetworkVariableFields.Add((NetworkVariableBase)(object)SpawnRateDynamic);
			((NetworkBehaviour)this).__initializeVariables();
		}

		[RuntimeInitializeOnLoadMethod]
		internal static void InitializeRPCS_MimicNetworker()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Expected O, but got Unknown
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Expected O, but got Unknown
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Expected O, but got Unknown
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Expected O, but got Unknown
			NetworkManager.__rpc_func_table.Add(2885019175u, new RpcReceiveHandler(__rpc_handler_2885019175));
			NetworkManager.__rpc_func_table.Add(1024971481u, new RpcReceiveHandler(__rpc_handler_1024971481));
			NetworkManager.__rpc_func_table.Add(1137632670u, new RpcReceiveHandler(__rpc_handler_1137632670));
			NetworkManager.__rpc_func_table.Add(669208889u, new RpcReceiveHandler(__rpc_handler_669208889));
			NetworkManager.__rpc_func_table.Add(3716888238u, new RpcReceiveHandler(__rpc_handler_3716888238));
			NetworkManager.__rpc_func_table.Add(1897916243u, new RpcReceiveHandler(__rpc_handler_1897916243));
		}

		private static void __rpc_handler_2885019175(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				int playerId = default(int);
				ByteUnpacker.ReadValueBitPacked(reader, ref playerId);
				int mimicIndex = default(int);
				ByteUnpacker.ReadValueBitPacked(reader, ref mimicIndex);
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((MimicNetworker)(object)target).MimicAttackClientRpc(playerId, mimicIndex);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_1024971481(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				int playerId = default(int);
				ByteUnpacker.ReadValueBitPacked(reader, ref playerId);
				int mimicIndex = default(int);
				ByteUnpacker.ReadValueBitPacked(reader, ref mimicIndex);
				target.__rpc_exec_stage = (__RpcExecStage)1;
				((MimicNetworker)(object)target).MimicAttackServerRpc(playerId, mimicIndex);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_1137632670(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				int amount = default(int);
				ByteUnpacker.ReadValueBitPacked(reader, ref amount);
				int mimicIndex = default(int);
				ByteUnpacker.ReadValueBitPacked(reader, ref mimicIndex);
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((MimicNetworker)(object)target).MimicAddAngerClientRpc(amount, mimicIndex);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_669208889(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				int amount = default(int);
				ByteUnpacker.ReadValueBitPacked(reader, ref amount);
				int mimicIndex = default(int);
				ByteUnpacker.ReadValueBitPacked(reader, ref mimicIndex);
				target.__rpc_exec_stage = (__RpcExecStage)1;
				((MimicNetworker)(object)target).MimicAddAngerServerRpc(amount, mimicIndex);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_3716888238(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				int playerId = default(int);
				ByteUnpacker.ReadValueBitPacked(reader, ref playerId);
				int mimicIndex = default(int);
				ByteUnpacker.ReadValueBitPacked(reader, ref mimicIndex);
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((MimicNetworker)(object)target).MimicLockPickClientRpc(playerId, mimicIndex);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_1897916243(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				int playerId = default(int);
				ByteUnpacker.ReadValueBitPacked(reader, ref playerId);
				int mimicIndex = default(int);
				ByteUnpacker.ReadValueBitPacked(reader, ref mimicIndex);
				target.__rpc_exec_stage = (__RpcExecStage)1;
				((MimicNetworker)(object)target).MimicLockPickServerRpc(playerId, mimicIndex);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		protected internal override string __getTypeName()
		{
			return "MimicNetworker";
		}
	}
	public class MimicDoor : MonoBehaviour
	{
		public GameObject playerTarget;

		public BoxCollider frameBox;

		public Sprite LostFingersIcon;

		public Animator mimicAnimator;

		public GameObject grabPoint;

		public InteractTrigger interactTrigger;

		public ScanNodeProperties scanNode;

		public int anger;

		public bool angering;

		public int sprayCount;

		private bool attacking;

		public static List<MimicDoor> allMimics;

		public int mimicIndex;

		private static MethodInfo RetractClaws = typeof(LockPicker).GetMethod("RetractClaws", BindingFlags.Instance | BindingFlags.NonPublic);

		public void TouchMimic(PlayerControllerB player)
		{
			if (!attacking)
			{
				MimicNetworker.Instance.MimicAttack((int)player.playerClientId, mimicIndex);
			}
		}

		public IEnumerator Attack(int playerId)
		{
			PlayerControllerB player = StartOfRound.Instance.allPlayerScripts[playerId];
			MimicsAPI.MainAPI.OnMimicAttackStart(this, player);
			attacking = true;
			interactTrigger.interactable = false;
			mimicAnimator.SetTrigger("Attack");
			playerTarget.transform.position = ((Component)player).transform.position;
			yield return (object)new WaitForSeconds(0.1f);
			playerTarget.transform.position = ((Component)player).transform.position;
			yield return (object)new WaitForSeconds(0.1f);
			playerTarget.transform.position = ((Component)player).transform.position;
			yield return (object)new WaitForSeconds(0.1f);
			playerTarget.transform.position = ((Component)player).transform.position;
			yield return (object)new WaitForSeconds(0.1f);
			float num = Vector3.Distance(((Component)GameNetworkManager.Instance.localPlayerController).transform.position, ((Component)frameBox).transform.position);
			if (num < 8f)
			{
				HUDManager.Instance.ShakeCamera((ScreenShakeType)1);
			}
			else if (num < 14f)
			{
				HUDManager.Instance.ShakeCamera((ScreenShakeType)0);
			}
			yield return (object)new WaitForSeconds(0.2f);
			if (((NetworkBehaviour)player).IsOwner && Vector3.Distance(((Component)player).transform.position, ((Component)this).transform.position) < 8.45f)
			{
				player.KillPlayer(Vector3.zero, true, (CauseOfDeath)0, 0);
			}
			float startTime = Time.timeSinceLevelLoad;
			yield return (object)new WaitUntil((Func<bool>)(() => (Object)(object)player.deadBody != (Object)null || Time.timeSinceLevelLoad - startTime > 4f));
			if ((Object)(object)player.deadBody != (Object)null)
			{
				player.deadBody.attachedTo = grabPoint.transform;
				player.deadBody.attachedLimb = player.deadBody.bodyParts[5];
				player.deadBody.matchPositionExactly = true;
				for (int i = 0; i < player.deadBody.bodyParts.Length; i++)
				{
					((Component)player.deadBody.bodyParts[i]).GetComponent<Collider>().excludeLayers = LayerMask.op_Implicit(-1);
				}
			}
			yield return (object)new WaitForSeconds(2f);
			if ((Object)(object)player.deadBody != (Object)null)
			{
				player.deadBody.attachedTo = null;
				player.deadBody.attachedLimb = null;
				player.deadBody.matchPositionExactly = false;
				((Component)((Component)player.deadBody).transform.GetChild(0)).gameObject.SetActive(false);
				player.deadBody = null;
			}
			yield return (object)new WaitForSeconds(4.5f);
			attacking = false;
			interactTrigger.interactable = true;
			MimicsAPI.MainAPI.OnMimicAttackEnd(this);
		}

		public IEnumerator MimicLockPick(int playerId)
		{
			if (angering || attacking)
			{
				yield break;
			}
			LockPicker lockPicker = default(LockPicker);
			ref LockPicker reference = ref lockPicker;
			GrabbableObject currentlyHeldObjectServer = StartOfRound.Instance.allPlayerScripts[playerId].currentlyHeldObjectServer;
			reference = (LockPicker)(object)((currentlyHeldObjectServer is LockPicker) ? currentlyHeldObjectServer : null);
			if ((Object)(object)lockPicker == (Object)null)
			{
				yield break;
			}
			attacking = true;
			interactTrigger.interactable = false;
			AudioSource component = ((Component)lockPicker).GetComponent<AudioSource>();
			component.PlayOneShot(lockPicker.placeLockPickerClips[Random.Range(0, lockPicker.placeLockPickerClips.Length)]);
			lockPicker.armsAnimator.SetBool("mounted", true);
			lockPicker.armsAnimator.SetBool("picking", true);
			component.Play();
			component.pitch = Random.Range(0.94f, 1.06f);
			lockPicker.isOnDoor = true;
			lockPicker.isPickingLock = true;
			((GrabbableObject)lockPicker).grabbable = false;
			if (((NetworkBehaviour)lockPicker).IsOwner)
			{
				((GrabbableObject)lockPicker).playerHeldBy.DiscardHeldObject(true, ((NetworkBehaviour)MimicNetworker.Instance).NetworkObject, ((Component)this).transform.position + ((Component)this).transform.up * 1.5f - ((Component)this).transform.forward * 1.15f, true);
			}
			float startTime = Time.timeSinceLevelLoad;
			yield return (object)new WaitUntil((Func<bool>)(() => !((GrabbableObject)lockPicker).isHeld || Time.timeSinceLevelLoad - startTime > 10f));
			((Component)lockPicker).transform.localEulerAngles = new Vector3(((Component)this).transform.eulerAngles.x, ((Component)this).transform.eulerAngles.y + 90f, ((Component)this).transform.eulerAngles.z);
			yield return (object)new WaitForSeconds(5f);
			RetractClaws.Invoke(lockPicker, null);
			((Component)lockPicker).transform.SetParent((Transform)null);
			((GrabbableObject)lockPicker).startFallingPosition = ((Component)lockPicker).transform.position;
			((GrabbableObject)lockPicker).FallToGround(false);
			((GrabbableObject)lockPicker).grabbable = true;
			yield return (object)new WaitForSeconds(1f);
			anger = 3;
			attacking = false;
			interactTrigger.interactable = false;
			PlayerControllerB val = null;
			float num = 9999f;
			PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts;
			foreach (PlayerControllerB val2 in allPlayerScripts)
			{
				float num2 = Vector3.Distance(((Component)this).transform.position, ((Component)val2).transform.position);
				if (num2 < num)
				{
					num = num2;
					val = val2;
				}
			}
			if ((Object)(object)val != (Object)null)
			{
				MimicNetworker.Instance.MimicAttackClientRpc((int)val.playerClientId, mimicIndex);
			}
			else
			{
				interactTrigger.interactable = true;
			}
		}

		public IEnumerator AddAnger(int amount)
		{
			if (angering || attacking)
			{
				yield break;
			}
			angering = true;
			anger += amount;
			if (anger == 1)
			{
				Sprite oldIcon2 = interactTrigger.hoverIcon;
				interactTrigger.hoverIcon = LostFingersIcon;
				mimicAnimator.SetTrigger("Growl");
				yield return (object)new WaitForSeconds(2.75f);
				interactTrigger.hoverIcon = oldIcon2;
				sprayCount = 0;
				angering = false;
				yield break;
			}
			if (anger == 2)
			{
				interactTrigger.holdTip = "DIE : [LMB]";
				interactTrigger.timeToHold = 0.25f;
				Sprite oldIcon2 = interactTrigger.hoverIcon;
				interactTrigger.hoverIcon = LostFingersIcon;
				mimicAnimator.SetTrigger("Growl");
				yield return (object)new WaitForSeconds(2.75f);
				interactTrigger.hoverIcon = oldIcon2;
				sprayCount = 0;
				angering = false;
				yield break;
			}
			if (anger > 2)
			{
				PlayerControllerB val = null;
				float num = 9999f;
				PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts;
				foreach (PlayerControllerB val2 in allPlayerScripts)
				{
					float num2 = Vector3.Distance(((Component)this).transform.position, ((Component)val2).transform.position);
					if (num2 < num)
					{
						num = num2;
						val = val2;
					}
				}
				if ((Object)(object)val != (Object)null)
				{
					MimicNetworker.Instance.MimicAttackClientRpc((int)val.playerClientId, mimicIndex);
				}
			}
			sprayCount = 0;
			angering = false;
		}
	}
	public class MimicCollider : MonoBehaviour, IHittable
	{
		public MimicDoor mimic;

		bool IHittable.Hit(int force, Vector3 hitDirection, PlayerControllerB playerWhoHit = null, bool playHitSFX = false, int hitID = -1)
		{
			MimicNetworker.Instance.MimicAddAnger(force, mimic.mimicIndex);
			return true;
		}
	}
	public class MimicListener : MonoBehaviour, INoiseListener
	{
		public MimicDoor mimic;

		private int tolerance = 100;

		void INoiseListener.DetectNoise(Vector3 noisePosition, float noiseLoudness, int timesPlayedInOneSpot, int noiseID)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			if ((noiseLoudness >= 0.9f || noiseID == 101158) && Vector3.Distance(noisePosition, ((Component)mimic).transform.position) < 5f)
			{
				switch (noiseID)
				{
				case 75:
					tolerance--;
					break;
				case 5:
					tolerance -= 15;
					break;
				case 101158:
					tolerance -= 35;
					break;
				default:
					tolerance -= 30;
					break;
				}
				if (tolerance <= 0)
				{
					tolerance = 100;
					MimicNetworker.Instance.MimicAddAnger(1, mimic.mimicIndex);
				}
			}
		}
	}
}
namespace Mimics.API
{
	public static class MimicsAPI
	{
		private static MainMimicsAPI _API;

		internal static MainMimicsAPI MainAPI
		{
			get
			{
				if (_API == null)
				{
					_API = new MainMimicsAPI();
				}
				return _API;
			}
		}

		public static IMimicsAPI GetAPI()
		{
			return MainAPI;
		}
	}
	public interface IMimicsAPI
	{
		void RegisterMimicEventHandler(MimicEventHandler handler);

		MimicEventHandler GetCurrentMimicEventHandler();
	}
	internal class MainMimicsAPI : IMimicsAPI
	{
		internal List<MimicEventHandler> mimicEventHandlers = new List<MimicEventHandler>();

		internal MimicEventHandler _currentMimicEventHandler;

		public void RegisterMimicEventHandler(MimicEventHandler handler)
		{
			Mimics.MimicsLogger.LogInfo((object)("Registered handler for " + handler.ModGUID));
			mimicEventHandlers.Add(handler);
		}

		public MimicEventHandler GetCurrentMimicEventHandler()
		{
			return _currentMimicEventHandler;
		}

		internal void RefreshMimicEventHandler()
		{
			_currentMimicEventHandler = null;
			foreach (MimicEventHandler mimicEventHandler in mimicEventHandlers)
			{
				try
				{
					if (mimicEventHandler.IsMyInteriorLoaded && (_currentMimicEventHandler == null || mimicEventHandler.Priority > _currentMimicEventHandler.Priority))
					{
						_currentMimicEventHandler = mimicEventHandler;
					}
				}
				catch (Exception ex)
				{
					string text = ((_currentMimicEventHandler != null) ? _currentMimicEventHandler.ModGUID : "NULL");
					Mimics.MimicsLogger.LogError((object)("Error with IsMyInteriorLoaded/Priority function for handler " + mimicEventHandler.ModGUID + " or " + text));
					Mimics.MimicsLogger.LogError((object)ex.ToString());
				}
			}
		}

		internal bool IgnoreDefaultPlacementValidation(Doorway doorway)
		{
			try
			{
				if (_currentMimicEventHandler == null)
				{
					return false;
				}
				return _currentMimicEventHandler.IgnoreDefaultPlacementValidation(doorway);
			}
			catch (Exception ex)
			{
				Mimics.MimicsLogger.LogError((object)("Error with IgnoreDefaultPlacementValidation function for handler " + _currentMimicEventHandler.ModGUID));
				Mimics.MimicsLogger.LogError((object)ex.ToString());
			}
			return false;
		}

		internal bool IsPlacementValid(Doorway doorway)
		{
			try
			{
				if (_currentMimicEventHandler == null)
				{
					return true;
				}
				return _currentMimicEventHandler.IsPlacementValid(doorway);
			}
			catch (Exception ex)
			{
				Mimics.MimicsLogger.LogError((object)("Error with IsPlacementValid function for handler " + _currentMimicEventHandler.ModGUID));
				Mimics.MimicsLogger.LogError((object)ex.ToString());
			}
			return true;
		}

		internal bool OverrideDefaultImperfectionCreation(MimicDoor mimicDoor, Doorway doorway)
		{
			try
			{
				if (_currentMimicEventHandler == null)
				{
					return false;
				}
				return _currentMimicEventHandler.OverrideDefaultImperfectionCreation(mimicDoor, doorway);
			}
			catch (Exception ex)
			{
				Mimics.MimicsLogger.LogError((object)("Error with OverrideDefaultImperfectionCreation function for handler " + _currentMimicEventHandler.ModGUID));
				Mimics.MimicsLogger.LogError((object)ex.ToString());
			}
			return false;
		}

		internal void OnMimicCreated(MimicDoor mimicDoor, Doorway doorway)
		{
			try
			{
				_currentMimicEventHandler?.OnMimicCreated(mimicDoor, doorway);
			}
			catch (Exception ex)
			{
				Mimics.MimicsLogger.LogError((object)("Error with OnMimicCreated function for handler " + _currentMimicEventHandler.ModGUID));
				Mimics.MimicsLogger.LogError((object)ex.ToString());
			}
		}

		internal void OnMimicCreateImperfections(MimicDoor mimicDoor)
		{
			try
			{
				_currentMimicEventHandler?.OnMimicCreateImperfections(mimicDoor);
			}
			catch (Exception ex)
			{
				Mimics.MimicsLogger.LogError((object)("Error with OnMimicCreateImperfections function for handler " + _currentMimicEventHandler.ModGUID));
				Mimics.MimicsLogger.LogError((object)ex.ToString());
			}
		}

		internal void OnMimicAttackStart(MimicDoor mimicDoor, PlayerControllerB playerToAttack)
		{
			try
			{
				_currentMimicEventHandler?.OnMimicAttackStart(mimicDoor, playerToAttack);
			}
			catch (Exception ex)
			{
				Mimics.MimicsLogger.LogError((object)("Error with OnMimicAttackStart function for handler " + _currentMimicEventHandler.ModGUID));
				Mimics.MimicsLogger.LogError((object)ex.ToString());
			}
		}

		internal void OnMimicAttackEnd(MimicDoor mimicDoor)
		{
			try
			{
				_currentMimicEventHandler?.OnMimicAttackEnd(mimicDoor);
			}
			catch (Exception ex)
			{
				Mimics.MimicsLogger.LogError((object)("Error with OnMimicAttackEnd function for handler " + _currentMimicEventHandler.ModGUID));
				Mimics.MimicsLogger.LogError((object)ex.ToString());
			}
		}
	}
	public abstract class MimicEventHandler
	{
		public abstract string ModGUID { get; }

		public virtual bool IsMyInteriorLoaded => false;

		public virtual int Priority => 0;

		public virtual bool IsPlacementValid(Doorway doorway)
		{
			return true;
		}

		public virtual bool IgnoreDefaultPlacementValidation(Doorway doorway)
		{
			return false;
		}

		public virtual bool OverrideDefaultImperfectionCreation(MimicDoor mimicDoor, Doorway doorway)
		{
			return false;
		}

		public virtual void OnMimicCreated(MimicDoor mimicDoor, Doorway doorway)
		{
		}

		public virtual void OnMimicCreateImperfections(MimicDoor mimicDoor)
		{
		}

		public virtual void OnMimicAttackStart(MimicDoor mimicDoor, PlayerControllerB playerToAttack)
		{
		}

		public virtual void OnMimicAttackEnd(MimicDoor mimicDoor)
		{
		}
	}
}
namespace Mimics.NetcodePatcher
{
	[AttributeUsage(AttributeTargets.Module)]
	internal class NetcodePatchedAssemblyAttribute : Attribute
	{
	}
}

plugins/MoreInteriors/MoreInteriorsDunGen.dll

Decompiled 2 years ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using DunGen.Graph;
using HarmonyLib;
using LethalLevelLoader;
using LethalLib.Modules;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.AI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("")]
[assembly: AssemblyCompany("MoreInteriorsDunGen")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("A template for Lethal Company")]
[assembly: AssemblyFileVersion("2.0.0.0")]
[assembly: AssemblyInformationalVersion("2.0.0")]
[assembly: AssemblyProduct("MoreInteriorsDunGen")]
[assembly: AssemblyTitle("MoreInteriorsDunGen")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.0.0.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 MoreInteriorsDunGen
{
	[BepInPlugin("MoreInteriors", "MoreInteriors", "2.5.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class MoreInteriorsDunGen : BaseUnityPlugin
	{
		[HarmonyPatch(typeof(Object))]
		private class ItemGroupPatch
		{
			[HarmonyPatch("Equals")]
			[HarmonyPrefix]
			public static bool FixItemGroupEquals(ref bool __result, object __instance, object other)
			{
				//IL_000d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0013: Expected O, but got Unknown
				//IL_002b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0031: Expected O, but got Unknown
				ItemGroup val = (ItemGroup)((__instance is ItemGroup) ? __instance : null);
				if ((Object)(object)val != (Object)null)
				{
					ItemGroup val2 = (ItemGroup)((other is ItemGroup) ? other : null);
					if ((Object)(object)val2 != (Object)null)
					{
						__result = val.itemSpawnTypeName == val2.itemSpawnTypeName;
						return false;
					}
				}
				return true;
			}
		}

		private readonly Harmony harmony = new Harmony("MoreInteriors");

		public static MoreInteriorsDunGen Instance;

		public GameObject netManagerPrefab;

		internal ManualLogSource mls;

		public static AssetBundle BunkerAssets;

		private ConfigEntry<int> configBunkerRarity;

		private ConfigEntry<string> configBunkerMoons;

		private ConfigEntry<string> configBunkerMoonsList;

		private ConfigEntry<bool> configGuaranteedBunker;

		private ConfigEntry<int> configLengthOverride;

		private ConfigEntry<int> configOutpost31Rarity;

		private string[] configBunkerMoonsValues = new string[1] { "list" };

		public GameObject energyCorePrefab;

		public GameObject energyCorePrefabTurnedOff;

		public GameObject EnergyCores;

		public GameObject Rat;

		public GameObject RatSpawn;

		private void Awake()
		{
			//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d8: Expected O, but got Unknown
			//IL_0208: Unknown result type (might be due to invalid IL or missing references)
			//IL_0212: Expected O, but got Unknown
			//IL_0238: Unknown result type (might be due to invalid IL or missing references)
			//IL_0242: Expected O, but got Unknown
			//IL_0264: Unknown result type (might be due to invalid IL or missing references)
			//IL_026e: Expected O, but got Unknown
			//IL_02ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b5: Expected O, but got Unknown
			//IL_02db: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e5: Expected O, but got Unknown
			//IL_03f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ff: Expected O, but got Unknown
			//IL_040e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0418: Expected O, but got Unknown
			//IL_045f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0469: Expected O, but got Unknown
			//IL_04b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ba: Expected O, but got Unknown
			//IL_0504: Unknown result type (might be due to invalid IL or missing references)
			//IL_050b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0515: Expected O, but got Unknown
			//IL_055f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0566: Unknown result type (might be due to invalid IL or missing references)
			//IL_0570: Expected O, but got Unknown
			//IL_0691: Unknown result type (might be due to invalid IL or missing references)
			//IL_069b: Expected O, but got Unknown
			//IL_0665: Unknown result type (might be due to invalid IL or missing references)
			//IL_066f: Expected O, but got Unknown
			if ((Object)(object)Instance == (Object)null)
			{
				Instance = this;
			}
			Type[] types = Assembly.GetExecutingAssembly().GetTypes();
			Type[] array = types;
			foreach (Type type in array)
			{
				MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic);
				MethodInfo[] array2 = methods;
				foreach (MethodInfo methodInfo in array2)
				{
					object[] customAttributes = methodInfo.GetCustomAttributes(typeof(RuntimeInitializeOnLoadMethodAttribute), inherit: false);
					if (customAttributes.Length != 0)
					{
						methodInfo.Invoke(null, null);
						mls.LogInfo((object)"Invoked method with RuntimeInitializeOnLoadMethodAttribute");
					}
				}
			}
			mls = Logger.CreateLogSource("MoreInteriorsDunGen");
			string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
			BunkerAssets = AssetBundle.LoadFromFile(Path.Combine(directoryName, "moreinterior_dungen"));
			if ((Object)(object)BunkerAssets == (Object)null)
			{
				mls.LogError((object)"Failed to load Bunker Dungeon assets.");
			}
			else
			{
				mls.LogInfo((object)"Bunker Assets loaded successfully");
			}
			DungeonFlow val = BunkerAssets.LoadAsset<DungeonFlow>("assets/lethalbunker/bunker data/bunkerflow.asset");
			if ((Object)(object)val == (Object)null)
			{
				mls.LogError((object)"Failed to load Bunker Dungeon Flow.");
			}
			AudioClip val2 = BunkerAssets.LoadAsset<AudioClip>("Assets/LethalBunker/ScrapPrefabs/AnimateClips/Bunker Entrance.ogg");
			if ((Object)(object)val2 == (Object)null)
			{
				mls.LogError((object)"Failed to load Bunker Dungeon Flow.");
			}
			else
			{
				mls.LogInfo((object)"Was loaded was called");
			}
			configBunkerRarity = ((BaseUnityPlugin)this).Config.Bind<int>("Bunker Interior", "BunkerRarity", 150, new ConfigDescription("The chance that the bunker tileset will be chosen. The higher the value, the higher the chance. By default, the bunker will appear on valid moons with a roughly one in two chance.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 99999), Array.Empty<object>()));
			configBunkerMoons = ((BaseUnityPlugin)this).Config.Bind<string>("Bunker Interior", "BunkerMoons", "list", new ConfigDescription("Use 'list' to specify a custom list of moons for the bunker to appear on. Individual moons can be added to the list by editing the BunkerDungeonMoonsList config entry.", (AcceptableValueBase)(object)new AcceptableValueList<string>(configBunkerMoonsValues), Array.Empty<object>()));
			configBunkerMoonsList = ((BaseUnityPlugin)this).Config.Bind<string>("Bunker Interior", "BunkerDungeonMoonsList", "March,Offense", new ConfigDescription("Note: Requires 'BunkerMoons' to be set to 'list'. \nCan be used to specify a list of moons with individual rarities for moons to spawn on. \nRarity values will override the default rarity value provided in Bunker Rarity and will override BunkerGuaranteed. To guarantee dungeon spawning on a moon, assign arbitrarily high rarity value (e.g.  99999). \nMoons and rarities should be provided as a comma-separated list in the following format: 'Name:Rarity' Example: March:150,Offense:150 \nNote: Moon names are checked by string matching, i.e. the moon name 'dine' would enable spawning on 'dine', 'diner' and 'undine'. Be careful with modded moon names.", (AcceptableValueBase)null, Array.Empty<object>()));
			configGuaranteedBunker = ((BaseUnityPlugin)this).Config.Bind<bool>("Bunker Interior", "BunkerGuaranteed", false, new ConfigDescription("If enabled, the bunker will be effectively guaranteed to spawn. Only recommended for debugging/sightseeing purposes.", (AcceptableValueBase)null, Array.Empty<object>()));
			configLengthOverride = ((BaseUnityPlugin)this).Config.Bind<int>("Bunker Length", "BunkerLengthOverride", -1, new ConfigDescription(string.Format("if not -1, Overrides the Bunker length to what you set. 1 = 1 times big. 2 = twice as big. and so and so forth ", "2.5.0", val.Length.Min), (AcceptableValueBase)null, Array.Empty<object>()));
			configOutpost31Rarity = ((BaseUnityPlugin)this).Config.Bind<int>("Outpost 31", "Outpost31Rarity", 99999, new ConfigDescription("Rarity at which the bunker appears on Outpost31. Lower this value to decrease the frequency of bunkers spawning on this moon. To ensure that the bunker spawns on Outpost31, do not set a value lower than  99999.", (AcceptableValueBase)null, Array.Empty<object>()));
			if (configLengthOverride.Value != -1)
			{
				mls.LogInfo((object)$"Bunker Length Override has been set to {configLengthOverride.Value}. Be careful with this value");
				val.Length.Min = configLengthOverride.Value;
				val.Length.Max = configLengthOverride.Value;
			}
			ExtendedDungeonFlow val3 = ScriptableObject.CreateInstance<ExtendedDungeonFlow>();
			val3.contentSourceName = "MoreInteriors";
			val3.dungeonFlow = val;
			val3.dungeonFirstTimeAudio = val2;
			val3.dungeonDefaultRarity = 0;
			int num = (configGuaranteedBunker.Value ? 99999 : configBunkerRarity.Value);
			int num2 = (configGuaranteedBunker.Value ? 99999 : configOutpost31Rarity.Value);
			if (configBunkerMoons.Value.ToLowerInvariant() == "all")
			{
				val3.manualContentSourceNameReferenceList.Add(new StringWithRarity("Lethal Company", num));
				val3.manualContentSourceNameReferenceList.Add(new StringWithRarity("Custom", num));
				mls.LogInfo((object)"Registered Bunker Interior on all Moons, Includes Modded Moons.");
			}
			else if (configBunkerMoons.Value.ToLowerInvariant() == "vanilla")
			{
				val3.manualContentSourceNameReferenceList.Add(new StringWithRarity("Lethal Company", num));
				mls.LogInfo((object)"Registered Bunker Interior on all vanilla moons.");
			}
			else if (configBunkerMoons.Value.ToLowerInvariant() == "modded")
			{
				val3.manualContentSourceNameReferenceList.Add(new StringWithRarity("Custom", num));
				mls.LogInfo((object)"Registered Bunker Interior on all modded moons.");
			}
			else if (configBunkerMoons.Value.ToLowerInvariant() == "paid")
			{
				val3.dynamicRoutePricesList.Add(new Vector2WithRarity(new Vector2(1f, 9999f), num));
				mls.LogInfo((object)"Registered Bunker Interior on all paid moons.");
			}
			else if (configBunkerMoons.Value.ToLowerInvariant() == "free")
			{
				val3.dynamicRoutePricesList.Add(new Vector2WithRarity(new Vector2(0f, 0f), num));
				mls.LogInfo((object)"Registered Bunker Interior on all free moons.");
			}
			else if (configBunkerMoons.Value.ToLowerInvariant() == "list" && configBunkerMoonsList.Value != null)
			{
				string[] array3 = configBunkerMoonsList.Value.Split(',');
				string[] array4 = array3;
				foreach (string text in array4)
				{
					StringWithRarity val4 = ParseMoonString(text, num);
					if (val4 != null)
					{
						val3.manualPlanetNameReferenceList.Add(val4);
						mls.LogInfo((object)$"Registered Bunker Interior on moon name {val4.Name} with rarity {val4.Rarity}");
						continue;
					}
					if (val4 == null)
					{
						mls.LogWarning((object)"No moon Added to list value!");
					}
					val3.manualPlanetNameReferenceList.Add(new StringWithRarity(text, num));
				}
				val3.manualContentSourceNameReferenceList.Add(new StringWithRarity("Outpost 31", num2));
				mls.LogInfo((object)$"Registered Bunker Interior on moon name Outpost 31 with rarity {num2}");
			}
			else
			{
				mls.LogError((object)"Invalid 'BunkerDungeonMoons' config value! ");
			}
			PatchedContent.RegisterExtendedDungeonFlow(val3);
			mls.LogInfo((object)"Loaded Extended DungeonFlow");
			val3.dungeonSizeMin = 1f;
			val3.dungeonSizeMax = 1f;
			val3.dungeonSizeLerpPercentage = 0f;
			harmony.PatchAll(typeof(MoreInteriorsDunGen));
			harmony.PatchAll(typeof(Object));
			harmony.PatchAll(typeof(StartOfRound));
			Item val5 = BunkerAssets.LoadAsset<Item>("Assets/LethalBunker/Bunker Data/EnergyCore.asset");
			Items.RegisterItem(val5);
			NetworkPrefabs.RegisterNetworkPrefab(val5.spawnPrefab);
			Object.Instantiate<Item>(val5);
			if ((Object)(object)val5 == (Object)null)
			{
				mls.LogError((object)"EnergyCore is null");
			}
			energyCorePrefab = BunkerAssets.LoadAsset<GameObject>("Assets/LethalBunker/Prefab Pieces/EnergyCore.prefab");
			NetworkPrefabs.RegisterNetworkPrefab(energyCorePrefab);
			if ((Object)(object)energyCorePrefab == (Object)null)
			{
				mls.LogError((object)"energyCorePrefab is null");
			}
			energyCorePrefabTurnedOff = BunkerAssets.LoadAsset<GameObject>("Assets/LethalBunker/Prefab Pieces/EnergyCoreTurnedoff.prefab");
			NetworkPrefabs.RegisterNetworkPrefab(energyCorePrefab);
			if ((Object)(object)energyCorePrefabTurnedOff == (Object)null)
			{
				mls.LogError((object)"energyCorePrefabTurnedOff is null");
			}
			Rat = BunkerAssets.LoadAsset<GameObject>("Assets/LethalBunker/Ai Scripting/Rats/RatEntityAI.prefab");
			NetworkPrefabs.RegisterNetworkPrefab(Rat);
			if ((Object)(object)Rat == (Object)null)
			{
				mls.LogError((object)"Rat is null");
			}
			int num3 = 1;
			Item val6 = BunkerAssets.LoadAsset<Item>("Assets/LethalBunker/ScrapPrefabs/ArmyHelmet.asset");
			mls.LogInfo((object)val6);
			if ((Object)(object)val6 == (Object)null)
			{
				mls.LogError((object)"Failed to load ArmyHelmet asset.");
				return;
			}
			NetworkPrefabs.RegisterNetworkPrefab(val6.spawnPrefab);
			if ((Object)(object)val6.spawnPrefab == (Object)null)
			{
				mls.LogError((object)"Failed to register ArmyHelmet spawn prefab.");
				return;
			}
			Items.RegisterScrap(val6, num3, (LevelTypes)(-1));
			if ((Object)(object)val6 == (Object)null)
			{
				mls.LogError((object)"Failed to register ArmyHelmet item.");
				return;
			}
			int num4 = 1;
			Item val7 = BunkerAssets.LoadAsset<Item>("Assets/LethalBunker/ScrapPrefabs/ArmyCanteen.asset");
			mls.LogInfo((object)val7);
			if ((Object)(object)val7 == (Object)null)
			{
				mls.LogError((object)"Failed to load Canteen asset.");
				return;
			}
			NetworkPrefabs.RegisterNetworkPrefab(val7.spawnPrefab);
			if ((Object)(object)val7.spawnPrefab == (Object)null)
			{
				mls.LogError((object)"Failed to register Canteen spawn prefab.");
				return;
			}
			Items.RegisterScrap(val7, num4, (LevelTypes)(-1));
			if ((Object)(object)val7 == (Object)null)
			{
				mls.LogError((object)"Failed to register Canteen item.");
				return;
			}
			int num5 = 1;
			Item val8 = BunkerAssets.LoadAsset<Item>("Assets/LethalBunker/ScrapPrefabs/Gramophone.asset");
			mls.LogInfo((object)val8);
			if ((Object)(object)val8 == (Object)null)
			{
				mls.LogError((object)"Failed to load Gramophone asset.");
				return;
			}
			NetworkPrefabs.RegisterNetworkPrefab(val8.spawnPrefab);
			if ((Object)(object)val8.spawnPrefab == (Object)null)
			{
				mls.LogError((object)"Failed to register Gramophone spawn prefab.");
				return;
			}
			Items.RegisterScrap(val8, num5, (LevelTypes)(-1));
			if ((Object)(object)val8 == (Object)null)
			{
				mls.LogError((object)"Failed to register Gramophone item.");
				return;
			}
			int num6 = 1;
			Item val9 = BunkerAssets.LoadAsset<Item>("Assets/LethalBunker/ScrapPrefabs/OldRadio.asset");
			mls.LogInfo((object)val9);
			if ((Object)(object)val9 == (Object)null)
			{
				mls.LogError((object)"Failed to load OldRadio asset.");
				return;
			}
			NetworkPrefabs.RegisterNetworkPrefab(val9.spawnPrefab);
			if ((Object)(object)val9.spawnPrefab == (Object)null)
			{
				mls.LogError((object)"Failed to register OldRadio spawn prefab.");
				return;
			}
			Items.RegisterScrap(val9, num6, (LevelTypes)(-1));
			if ((Object)(object)val9 == (Object)null)
			{
				mls.LogError((object)"Failed to register OldRadio item.");
				return;
			}
			int num7 = 1;
			Item val10 = BunkerAssets.LoadAsset<Item>("Assets/LethalBunker/ScrapPrefabs/RockingHorse.asset");
			mls.LogInfo((object)val10);
			if ((Object)(object)val10 == (Object)null)
			{
				mls.LogError((object)"Failed to load RockingHorse asset.");
				return;
			}
			NetworkPrefabs.RegisterNetworkPrefab(val10.spawnPrefab);
			if ((Object)(object)val10.spawnPrefab == (Object)null)
			{
				mls.LogError((object)"Failed to register RockingHorse spawn prefab.");
				return;
			}
			Items.RegisterScrap(val10, num7, (LevelTypes)(-1));
			if ((Object)(object)val10 == (Object)null)
			{
				mls.LogError((object)"Failed to register RockingHorse item.");
				return;
			}
			int num8 = 1;
			Item val11 = BunkerAssets.LoadAsset<Item>("Assets/LethalBunker/ScrapPrefabs/TypeWriter.asset");
			mls.LogInfo((object)val11);
			if ((Object)(object)val11 == (Object)null)
			{
				mls.LogError((object)"Failed to load TypeWriter asset.");
				return;
			}
			NetworkPrefabs.RegisterNetworkPrefab(val11.spawnPrefab);
			if ((Object)(object)val11.spawnPrefab == (Object)null)
			{
				mls.LogError((object)"Failed to register TypeWriter spawn prefab.");
				return;
			}
			Items.RegisterScrap(val11, num8, (LevelTypes)(-1));
			if ((Object)(object)val11 == (Object)null)
			{
				mls.LogError((object)"Failed to register TypeWriter item.");
				return;
			}
			int num9 = 1;
			Item val12 = BunkerAssets.LoadAsset<Item>("Assets/LethalBunker/ScrapPrefabs/WheelRim.asset");
			mls.LogInfo((object)val12);
			if ((Object)(object)val12 == (Object)null)
			{
				mls.LogError((object)"Failed to load WheelRim asset.");
				return;
			}
			NetworkPrefabs.RegisterNetworkPrefab(val12.spawnPrefab);
			if ((Object)(object)val12.spawnPrefab == (Object)null)
			{
				mls.LogError((object)"Failed to register WheelRim spawn prefab.");
				return;
			}
			Items.RegisterScrap(val12, num9, (LevelTypes)(-1));
			if ((Object)(object)val12 == (Object)null)
			{
				mls.LogError((object)"Failed to register WheelRim item.");
				return;
			}
			int num10 = 1;
			Item val13 = BunkerAssets.LoadAsset<Item>("Assets/LethalBunker/ScrapPrefabs/WireSpool.asset");
			mls.LogInfo((object)val13);
			if ((Object)(object)val13 == (Object)null)
			{
				mls.LogError((object)"Failed to load WireSpool asset.");
				return;
			}
			NetworkPrefabs.RegisterNetworkPrefab(val13.spawnPrefab);
			if ((Object)(object)val13.spawnPrefab == (Object)null)
			{
				mls.LogError((object)"Failed to register WireSpool spawn prefab.");
				return;
			}
			Items.RegisterScrap(val13, num10, (LevelTypes)(-1));
			if ((Object)(object)val13 == (Object)null)
			{
				mls.LogError((object)"Failed to register WireSpool item.");
				return;
			}
			mls.LogInfo((object)"Successfully Registed all Items and Energycores");
			mls.LogInfo((object)"More interiors for Lethal Company [Version 2.5.0] successfully loaded.");
		}

		public static StringWithRarity ParseMoonString(string moonString, int newRarity)
		{
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Expected O, but got Unknown
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Expected O, but got Unknown
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Expected O, but got Unknown
			if (string.IsNullOrEmpty(moonString))
			{
				return null;
			}
			string[] array = moonString.Split(':');
			if (array.Length != 2)
			{
				return new StringWithRarity(array[0], newRarity);
			}
			try
			{
				int num = int.Parse(array[1]);
				return new StringWithRarity(array[0], num);
			}
			catch (FormatException)
			{
				return new StringWithRarity(array[0], newRarity);
			}
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "MoreInteriorsDunGen";

		public const string PLUGIN_NAME = "MoreInteriorsDunGen";

		public const string PLUGIN_VERSION = "2.0.0";
	}
}
namespace MoreInteriorsDunGen.RatAI
{
	public class RatAI : MonoBehaviour
	{
		private enum HidingStatus
		{
			None,
			Hidding,
			InHole
		}

		public static RatAI Instance;

		private int currentWaypointIndex = 0;

		private NavMeshAgent agent;

		private Vector3 _currentDestination;

		[SerializeField]
		private Vector3 _waypointEndPosition;

		[SerializeField]
		private GameObject _waypointsParentGo;

		[SerializeField]
		private Transform[] _waypoints;

		[SerializeField]
		private int _numOfWaypoints;

		[SerializeField]
		private bool _reachedEnd;

		[SerializeField]
		private HidingStatus _currentState;

		[SerializeField]
		private float detectionRange = 5f;

		[SerializeField]
		private List<Transform> hidingSpots;

		private void Start()
		{
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			agent = ((Component)this).GetComponent<NavMeshAgent>();
			agent.speed = 7f;
			agent.acceleration = 10f;
			GameObject[] array = GameObject.FindGameObjectsWithTag("AINode");
			_waypoints = (Transform[])(object)new Transform[array.Length];
			for (int i = 0; i < array.Length; i++)
			{
				_waypoints[i] = array[i].transform;
			}
			agent.destination = _waypoints[0].position;
			agent.destination = _currentDestination;
		}

		private void Update()
		{
			if (!agent.isStopped)
			{
				Move();
			}
		}

		public void Move()
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			if (_currentState == HidingStatus.None && agent.remainingDistance < 1f)
			{
				int num = Random.Range(0, _waypoints.Length);
				agent.destination = _waypoints[num].position;
			}
			else if (_currentState == HidingStatus.Hidding)
			{
				int index = Random.Range(0, hidingSpots.Count);
				Transform val = hidingSpots[index];
				agent.destination = val.position;
			}
		}

		private IEnumerator WaitToRun()
		{
			yield return (object)new WaitForSeconds(3f);
			_currentState = HidingStatus.None;
			agent.destination = _waypoints[currentWaypointIndex].position;
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}

plugins/MoreSuits.dll

Decompiled 2 years ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using HarmonyLib;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("MoreSuits")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("A mod that adds more suit options to Lethal Company")]
[assembly: AssemblyFileVersion("1.4.3.0")]
[assembly: AssemblyInformationalVersion("1.4.3")]
[assembly: AssemblyProduct("MoreSuits")]
[assembly: AssemblyTitle("MoreSuits")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.4.3.0")]
[module: UnverifiableCode]
namespace MoreSuits;

[BepInPlugin("x753.More_Suits", "More Suits", "1.4.3")]
public class MoreSuitsMod : BaseUnityPlugin
{
	[HarmonyPatch(typeof(StartOfRound))]
	internal class StartOfRoundPatch
	{
		[HarmonyPatch("Start")]
		[HarmonyPrefix]
		private static void StartPatch(ref StartOfRound __instance)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			//IL_0695: Unknown result type (might be due to invalid IL or missing references)
			//IL_069a: Unknown result type (might be due to invalid IL or missing references)
			//IL_06a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_06a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0402: Unknown result type (might be due to invalid IL or missing references)
			//IL_0409: Expected O, but got Unknown
			//IL_0310: Unknown result type (might be due to invalid IL or missing references)
			//IL_0317: Expected O, but got Unknown
			//IL_05b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0204: Unknown result type (might be due to invalid IL or missing references)
			//IL_020b: Expected O, but got Unknown
			try
			{
				if (SuitsAdded)
				{
					return;
				}
				int count = __instance.unlockablesList.unlockables.Count;
				UnlockableItem val = new UnlockableItem();
				int num = 0;
				for (int i = 0; i < __instance.unlockablesList.unlockables.Count; i++)
				{
					UnlockableItem val2 = __instance.unlockablesList.unlockables[i];
					if (!((Object)(object)val2.suitMaterial != (Object)null) || !val2.alreadyUnlocked)
					{
						continue;
					}
					val = val2;
					List<string> list = Directory.GetDirectories(Paths.PluginPath, "moresuits", SearchOption.AllDirectories).ToList();
					List<string> list2 = new List<string>();
					List<string> list3 = new List<string>();
					List<string> list4 = DisabledSuits.ToLower().Replace(".png", "").Split(',')
						.ToList();
					List<string> list5 = new List<string>();
					if (!LoadAllSuits)
					{
						foreach (string item2 in list)
						{
							if (File.Exists(Path.Combine(item2, "!less-suits.txt")))
							{
								string[] collection = new string[9] { "glow", "kirby", "knuckles", "luigi", "mario", "minion", "skeleton", "slayer", "smile" };
								list5.AddRange(collection);
								break;
							}
						}
					}
					foreach (string item3 in list)
					{
						if (item3 != "")
						{
							string[] files = Directory.GetFiles(item3, "*.png");
							string[] files2 = Directory.GetFiles(item3, "*.matbundle");
							list2.AddRange(files);
							list3.AddRange(files2);
						}
					}
					list3.Sort();
					list2.Sort();
					try
					{
						foreach (string item4 in list3)
						{
							Object[] array = AssetBundle.LoadFromFile(item4).LoadAllAssets();
							foreach (Object val3 in array)
							{
								if (val3 is Material)
								{
									Material item = (Material)val3;
									customMaterials.Add(item);
								}
							}
						}
					}
					catch (Exception ex)
					{
						Debug.Log((object)("Something went wrong with More Suits! Could not load materials from asset bundle(s). Error: " + ex));
					}
					foreach (string item5 in list2)
					{
						if (list4.Contains(Path.GetFileNameWithoutExtension(item5).ToLower()))
						{
							continue;
						}
						string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
						if (list5.Contains(Path.GetFileNameWithoutExtension(item5).ToLower()) && item5.Contains(directoryName))
						{
							continue;
						}
						UnlockableItem val4;
						Material val5;
						if (Path.GetFileNameWithoutExtension(item5).ToLower() == "default")
						{
							val4 = val;
							val5 = val4.suitMaterial;
						}
						else
						{
							val4 = JsonUtility.FromJson<UnlockableItem>(JsonUtility.ToJson((object)val));
							val5 = Object.Instantiate<Material>(val4.suitMaterial);
						}
						byte[] array2 = File.ReadAllBytes(item5);
						Texture2D val6 = new Texture2D(2, 2);
						ImageConversion.LoadImage(val6, array2);
						val6.Apply(true, true);
						val5.mainTexture = (Texture)(object)val6;
						val4.unlockableName = Path.GetFileNameWithoutExtension(item5);
						try
						{
							string path = Path.Combine(Path.GetDirectoryName(item5), "advanced", val4.unlockableName + ".json");
							if (File.Exists(path))
							{
								string[] array3 = File.ReadAllLines(path);
								for (int j = 0; j < array3.Length; j++)
								{
									string[] array4 = array3[j].Trim().Split(':');
									if (array4.Length != 2)
									{
										continue;
									}
									string text = array4[0].Trim('"', ' ', ',');
									string text2 = array4[1].Trim('"', ' ', ',');
									if (text2.Contains(".png"))
									{
										byte[] array5 = File.ReadAllBytes(Path.Combine(Path.GetDirectoryName(item5), "advanced", text2));
										Texture2D val7 = new Texture2D(2, 2);
										ImageConversion.LoadImage(val7, array5);
										val7.Apply(true, true);
										val5.SetTexture(text, (Texture)(object)val7);
										continue;
									}
									if (text == "PRICE" && int.TryParse(text2, out var result))
									{
										try
										{
											if (!UnlockAll)
											{
												val4 = AddToRotatingShop(val4, result, __instance.unlockablesList.unlockables.Count);
											}
										}
										catch (Exception ex2)
										{
											Debug.Log((object)("Something went wrong with More Suits! Could not add a suit to the rotating shop. Error: " + ex2));
										}
										continue;
									}
									switch (text2)
									{
									case "KEYWORD":
										val5.EnableKeyword(text);
										continue;
									case "DISABLEKEYWORD":
										val5.DisableKeyword(text);
										continue;
									case "SHADERPASS":
										val5.SetShaderPassEnabled(text, true);
										continue;
									case "DISABLESHADERPASS":
										val5.SetShaderPassEnabled(text, false);
										continue;
									}
									float result2;
									Vector4 vector;
									if (text == "SHADER")
									{
										Shader shader = Shader.Find(text2);
										val5.shader = shader;
									}
									else if (text == "MATERIAL")
									{
										foreach (Material customMaterial in customMaterials)
										{
											if (((Object)customMaterial).name == text2)
											{
												val5 = Object.Instantiate<Material>(customMaterial);
												val5.mainTexture = (Texture)(object)val6;
												break;
											}
										}
									}
									else if (float.TryParse(text2, out result2))
									{
										val5.SetFloat(text, result2);
									}
									else if (TryParseVector4(text2, out vector))
									{
										val5.SetVector(text, vector);
									}
								}
							}
						}
						catch (Exception ex3)
						{
							Debug.Log((object)("Something went wrong with More Suits! Error: " + ex3));
						}
						val4.suitMaterial = val5;
						if (val4.unlockableName.ToLower() != "default")
						{
							if (num == MaxSuits)
							{
								Debug.Log((object)"Attempted to add a suit, but you've already reached the max number of suits! Modify the config if you want more.");
								continue;
							}
							__instance.unlockablesList.unlockables.Add(val4);
							num++;
						}
					}
					SuitsAdded = true;
					break;
				}
				UnlockableItem val8 = JsonUtility.FromJson<UnlockableItem>(JsonUtility.ToJson((object)val));
				val8.alreadyUnlocked = false;
				val8.hasBeenMoved = false;
				val8.placedPosition = Vector3.zero;
				val8.placedRotation = Vector3.zero;
				val8.unlockableType = 753;
				while (__instance.unlockablesList.unlockables.Count < count + MaxSuits)
				{
					__instance.unlockablesList.unlockables.Add(val8);
				}
			}
			catch (Exception ex4)
			{
				Debug.Log((object)("Something went wrong with More Suits! Error: " + ex4));
			}
		}

		[HarmonyPatch("PositionSuitsOnRack")]
		[HarmonyPrefix]
		private static bool PositionSuitsOnRackPatch(ref StartOfRound __instance)
		{
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			List<UnlockableSuit> source = Object.FindObjectsOfType<UnlockableSuit>().ToList();
			source = source.OrderBy((UnlockableSuit suit) => suit.syncedSuitID.Value).ToList();
			int num = 0;
			foreach (UnlockableSuit item in source)
			{
				AutoParentToShip component = ((Component)item).gameObject.GetComponent<AutoParentToShip>();
				component.overrideOffset = true;
				float num2 = 0.18f;
				if (MakeSuitsFitOnRack && source.Count > 13)
				{
					num2 /= (float)Math.Min(source.Count, 20) / 12f;
				}
				component.positionOffset = new Vector3(-2.45f, 2.75f, -8.41f) + __instance.rightmostSuitPosition.forward * num2 * (float)num;
				component.rotationOffset = new Vector3(0f, 90f, 0f);
				num++;
			}
			return false;
		}
	}

	private const string modGUID = "x753.More_Suits";

	private const string modName = "More Suits";

	private const string modVersion = "1.4.3";

	private readonly Harmony harmony = new Harmony("x753.More_Suits");

	private static MoreSuitsMod Instance;

	public static bool SuitsAdded = false;

	public static string DisabledSuits;

	public static bool LoadAllSuits;

	public static bool MakeSuitsFitOnRack;

	public static bool UnlockAll;

	public static int MaxSuits;

	public static List<Material> customMaterials = new List<Material>();

	private static TerminalNode cancelPurchase;

	private static TerminalKeyword buyKeyword;

	private void Awake()
	{
		if ((Object)(object)Instance == (Object)null)
		{
			Instance = this;
		}
		DisabledSuits = ((BaseUnityPlugin)this).Config.Bind<string>("General", "Disabled Suit List", "UglySuit751.png,UglySuit752.png,UglySuit753.png", "Comma-separated list of suits that shouldn't be loaded").Value;
		LoadAllSuits = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Ignore !less-suits.txt", false, "If true, ignores the !less-suits.txt file and will attempt to load every suit, except those in the disabled list. This should be true if you're not worried about having too many suits.").Value;
		MakeSuitsFitOnRack = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Make Suits Fit on Rack", true, "If true, squishes the suits together so more can fit on the rack.").Value;
		UnlockAll = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Unlock All Suits", false, "If true, unlocks all custom suits that would normally be sold in the shop.").Value;
		MaxSuits = ((BaseUnityPlugin)this).Config.Bind<int>("General", "Max Suits", 100, "The maximum number of suits to load. If you have more, some will be ignored.").Value;
		harmony.PatchAll();
		((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin More Suits is loaded!");
	}

	private static UnlockableItem AddToRotatingShop(UnlockableItem newSuit, int price, int unlockableID)
	{
		//IL_0065: Unknown result type (might be due to invalid IL or missing references)
		//IL_006a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0070: 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_010b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0111: Expected O, but got Unknown
		//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d4: Expected O, but got Unknown
		//IL_0298: Unknown result type (might be due to invalid IL or missing references)
		//IL_029f: Expected O, but got Unknown
		Terminal val = Object.FindObjectOfType<Terminal>();
		for (int i = 0; i < val.terminalNodes.allKeywords.Length; i++)
		{
			if (((Object)val.terminalNodes.allKeywords[i]).name == "Buy")
			{
				buyKeyword = val.terminalNodes.allKeywords[i];
				break;
			}
		}
		newSuit.alreadyUnlocked = false;
		newSuit.hasBeenMoved = false;
		newSuit.placedPosition = Vector3.zero;
		newSuit.placedRotation = Vector3.zero;
		newSuit.shopSelectionNode = ScriptableObject.CreateInstance<TerminalNode>();
		((Object)newSuit.shopSelectionNode).name = newSuit.unlockableName + "SuitBuy1";
		newSuit.shopSelectionNode.creatureName = newSuit.unlockableName + " suit";
		newSuit.shopSelectionNode.displayText = "You have requested to order " + newSuit.unlockableName + " suits.\nTotal cost of item: [totalCost].\n\nPlease CONFIRM or DENY.\n\n";
		newSuit.shopSelectionNode.clearPreviousText = true;
		newSuit.shopSelectionNode.shipUnlockableID = unlockableID;
		newSuit.shopSelectionNode.itemCost = price;
		newSuit.shopSelectionNode.overrideOptions = true;
		CompatibleNoun val2 = new CompatibleNoun();
		val2.noun = ScriptableObject.CreateInstance<TerminalKeyword>();
		val2.noun.word = "confirm";
		val2.noun.isVerb = true;
		val2.result = ScriptableObject.CreateInstance<TerminalNode>();
		((Object)val2.result).name = newSuit.unlockableName + "SuitBuyConfirm";
		val2.result.creatureName = "";
		val2.result.displayText = "Ordered " + newSuit.unlockableName + " suits! Your new balance is [playerCredits].\n\n";
		val2.result.clearPreviousText = true;
		val2.result.shipUnlockableID = unlockableID;
		val2.result.buyUnlockable = true;
		val2.result.itemCost = price;
		val2.result.terminalEvent = "";
		CompatibleNoun val3 = new CompatibleNoun();
		val3.noun = ScriptableObject.CreateInstance<TerminalKeyword>();
		val3.noun.word = "deny";
		val3.noun.isVerb = true;
		if ((Object)(object)cancelPurchase == (Object)null)
		{
			cancelPurchase = ScriptableObject.CreateInstance<TerminalNode>();
		}
		val3.result = cancelPurchase;
		((Object)val3.result).name = "MoreSuitsCancelPurchase";
		val3.result.displayText = "Cancelled order.\n";
		newSuit.shopSelectionNode.terminalOptions = (CompatibleNoun[])(object)new CompatibleNoun[2] { val2, val3 };
		TerminalKeyword val4 = ScriptableObject.CreateInstance<TerminalKeyword>();
		((Object)val4).name = newSuit.unlockableName + "Suit";
		val4.word = newSuit.unlockableName.ToLower() + " suit";
		val4.defaultVerb = buyKeyword;
		CompatibleNoun val5 = new CompatibleNoun();
		val5.noun = val4;
		val5.result = newSuit.shopSelectionNode;
		List<CompatibleNoun> list = buyKeyword.compatibleNouns.ToList();
		list.Add(val5);
		buyKeyword.compatibleNouns = list.ToArray();
		List<TerminalKeyword> list2 = val.terminalNodes.allKeywords.ToList();
		list2.Add(val4);
		list2.Add(val2.noun);
		list2.Add(val3.noun);
		val.terminalNodes.allKeywords = list2.ToArray();
		return newSuit;
	}

	public static bool TryParseVector4(string input, out Vector4 vector)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_0051: Unknown result type (might be due to invalid IL or missing references)
		//IL_0056: Unknown result type (might be due to invalid IL or missing references)
		vector = Vector4.zero;
		string[] array = input.Split(',');
		if (array.Length == 4 && float.TryParse(array[0], out var result) && float.TryParse(array[1], out var result2) && float.TryParse(array[2], out var result3) && float.TryParse(array[3], out var result4))
		{
			vector = new Vector4(result, result2, result3, result4);
			return true;
		}
		return false;
	}
}

plugins/ReservedFlashlightSlot.dll

Decompiled 2 years ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using LethalCompanyInputUtils.Api;
using ReservedFlashlightSlot.Config;
using ReservedFlashlightSlot.Patches;
using ReservedItemSlotCore;
using ReservedItemSlotCore.Config;
using ReservedItemSlotCore.Data;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.InputSystem;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("ReservedFlashlightSlot")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ReservedFlashlightSlot")]
[assembly: AssemblyCopyright("Copyright ©  2023")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("5b7d6563-4e51-4a69-bcf9-fa1dea6eff75")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace ReservedFlashlightSlot
{
	[BepInPlugin("FlipMods.ReservedFlashlightSlot", "ReservedFlashlightSlot", "2.0.4")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		public static Plugin instance;

		private static ManualLogSource logger;

		private Harmony _harmony;

		public static ReservedItemSlotData flashlightSlotData;

		public static ReservedItemData flashlightData;

		public static ReservedItemData proFlashlightData;

		public static ReservedItemData laserPointerData;

		public static List<ReservedItemData> additionalItemData = new List<ReservedItemData>();

		private void Awake()
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Expected O, but got Unknown
			instance = this;
			CreateCustomLogger();
			ConfigSettings.BindConfigSettings();
			CreateReservedItemSlots();
			CreateAdditionalReservedItemSlots();
			_harmony = new Harmony("ReservedFlashlightSlot");
			PatchAll();
			Log("ReservedFlashlightSlot loaded");
		}

		private void CreateReservedItemSlots()
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Expected O, but got Unknown
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: 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_00a3: Expected O, but got Unknown
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Expected O, but got Unknown
			flashlightSlotData = ReservedItemSlotData.CreateReservedItemSlotData("flashlight", ConfigSettings.overrideItemSlotPriority.Value, ConfigSettings.overridePurchasePrice.Value);
			flashlightData = flashlightSlotData.AddItemToReservedItemSlot(new ReservedItemData("Flashlight", (PlayerBone)4, new Vector3(0.2f, 0.25f, 0f), new Vector3(90f, 0f, 0f)));
			proFlashlightData = flashlightSlotData.AddItemToReservedItemSlot(new ReservedItemData("Pro-flashlight", (PlayerBone)4, new Vector3(0.2f, 0.25f, 0f), new Vector3(90f, 0f, 0f)));
			laserPointerData = flashlightSlotData.AddItemToReservedItemSlot(new ReservedItemData("Laser pointer", (PlayerBone)4, new Vector3(0.2f, 0.25f, 0f), new Vector3(90f, 0f, 0f)));
		}

		private void CreateAdditionalReservedItemSlots()
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Expected O, but got Unknown
			string[] array = ConfigSettings.ParseAdditionalItems();
			string[] array2 = array;
			foreach (string text in array2)
			{
				if (!flashlightSlotData.ContainsItem(text))
				{
					LogWarning("Adding additional item to reserved item slot. Item: " + text);
					ReservedItemData val = new ReservedItemData(text, (PlayerBone)0, default(Vector3), default(Vector3));
					additionalItemData.Add(val);
					flashlightSlotData.AddItemToReservedItemSlot(val);
				}
			}
		}

		private void PatchAll()
		{
			IEnumerable<Type> enumerable;
			try
			{
				enumerable = Assembly.GetExecutingAssembly().GetTypes();
			}
			catch (ReflectionTypeLoadException ex)
			{
				enumerable = ex.Types.Where((Type t) => t != null);
			}
			foreach (Type item in enumerable)
			{
				_harmony.PatchAll(item);
			}
		}

		private void CreateCustomLogger()
		{
			try
			{
				logger = Logger.CreateLogSource($"{((BaseUnityPlugin)this).Info.Metadata.Name}-{((BaseUnityPlugin)this).Info.Metadata.Version}");
			}
			catch
			{
				logger = ((BaseUnityPlugin)this).Logger;
			}
		}

		public static void Log(string message)
		{
			logger.LogInfo((object)message);
		}

		public static void LogError(string message)
		{
			logger.LogError((object)message);
		}

		public static void LogWarning(string message)
		{
			logger.LogWarning((object)message);
		}

		public static bool IsModLoaded(string guid)
		{
			return Chainloader.PluginInfos.ContainsKey(guid);
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "FlipMods.ReservedFlashlightSlot";

		public const string PLUGIN_NAME = "ReservedFlashlightSlot";

		public const string PLUGIN_VERSION = "2.0.4";
	}
}
namespace ReservedFlashlightSlot.Patches
{
	[HarmonyPatch]
	public static class FlashlightPatcher
	{
		public static PlayerControllerB localPlayerController => StartOfRound.Instance?.localPlayerController;

		public static PlayerControllerB GetPreviousPlayerHeldBy(FlashlightItem flashlightItem)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			return (PlayerControllerB)Traverse.Create((object)flashlightItem).Field("previousPlayerHeldBy").GetValue();
		}

		public static FlashlightItem GetMainFlashlight(PlayerControllerB playerController)
		{
			FlashlightItem currentlySelectedFlashlight = GetCurrentlySelectedFlashlight(playerController);
			if (Object.op_Implicit((Object)(object)currentlySelectedFlashlight))
			{
				return currentlySelectedFlashlight;
			}
			GrabbableObject obj = playerController?.pocketedFlashlight;
			FlashlightItem val = (FlashlightItem)(object)((obj is FlashlightItem) ? obj : null);
			FlashlightItem reservedFlashlight = GetReservedFlashlight(playerController);
			return (Object.op_Implicit((Object)(object)val) && (!Object.op_Implicit((Object)(object)reservedFlashlight) || (((GrabbableObject)val).isBeingUsed && !((GrabbableObject)reservedFlashlight).isBeingUsed))) ? val : reservedFlashlight;
		}

		public static FlashlightItem GetReservedFlashlight(PlayerControllerB playerController)
		{
			ReservedItemSlotData val = default(ReservedItemSlotData);
			ReservedPlayerData value;
			return (FlashlightItem)((SessionManager.TryGetUnlockedItemSlotData(Plugin.flashlightSlotData.slotName, ref val) && ReservedPlayerData.allPlayerData.TryGetValue(playerController, out value)) ? /*isinst with value type is only supported in some contexts*/: null);
		}

		public static FlashlightItem GetCurrentlySelectedFlashlight(PlayerControllerB playerController)
		{
			return (FlashlightItem)((playerController.currentItemSlot >= 0 && playerController.currentItemSlot < playerController.ItemSlots.Length) ? /*isinst with value type is only supported in some contexts*/: null);
		}

		public static FlashlightItem GetFirstFlashlightItem(PlayerControllerB playerController)
		{
			GrabbableObject[] itemSlots = playerController.ItemSlots;
			foreach (GrabbableObject val in itemSlots)
			{
				if ((Object)(object)val != (Object)null)
				{
					FlashlightItem val2 = (FlashlightItem)(object)((val is FlashlightItem) ? val : null);
					if (val2 != null)
					{
						return val2;
					}
				}
			}
			return null;
		}

		[HarmonyPatch(typeof(FlashlightItem), "PocketItem")]
		[HarmonyPostfix]
		private static void OnPocketFlashlight(FlashlightItem __instance)
		{
			OnPocketFlashlightLocal(__instance);
		}

		[HarmonyPatch(typeof(FlashlightItem), "PocketFlashlightClientRpc")]
		[HarmonyPostfix]
		private static void OnPocketFlashlightClientRpc(bool stillUsingFlashlight, FlashlightItem __instance)
		{
			PlayerControllerB val = ((GrabbableObject)(__instance?)).playerHeldBy;
			if (Object.op_Implicit((Object)(object)val) && !((Object)(object)val == (Object)(object)localPlayerController) && NetworkManager.Singleton.IsClient && (int)Traverse.Create((object)__instance).Field("__rpc_exec_stage").GetValue() == 2)
			{
				OnPocketFlashlightLocal(__instance);
			}
		}

		private static void OnPocketFlashlightLocal(FlashlightItem flashlightItem)
		{
			PlayerControllerB val = ((GrabbableObject)(flashlightItem?)).playerHeldBy;
			if (!Object.op_Implicit((Object)(object)val))
			{
				return;
			}
			GrabbableObject pocketedFlashlight = val.pocketedFlashlight;
			FlashlightItem val2 = (FlashlightItem)(object)((pocketedFlashlight is FlashlightItem) ? pocketedFlashlight : null);
			if (((GrabbableObject)flashlightItem).isBeingUsed)
			{
				if (Object.op_Implicit((Object)(object)val2) && (Object)(object)val2 != (Object)(object)flashlightItem)
				{
					UpdateFlashlightState(val2, active: false);
				}
				UpdateFlashlightState(flashlightItem, active: true);
				val.pocketedFlashlight = (GrabbableObject)(object)flashlightItem;
			}
		}

		[HarmonyPatch(typeof(FlashlightItem), "EquipItem")]
		[HarmonyPostfix]
		private static void OnEquipFlashlight(FlashlightItem __instance)
		{
			PlayerControllerB val = ((GrabbableObject)(__instance?)).playerHeldBy;
			if (!Object.op_Implicit((Object)(object)val))
			{
				return;
			}
			GrabbableObject pocketedFlashlight = val.pocketedFlashlight;
			FlashlightItem val2 = (FlashlightItem)(object)((pocketedFlashlight is FlashlightItem) ? pocketedFlashlight : null);
			if (!((Object)(object)__instance != (Object)(object)val2))
			{
				return;
			}
			if (((GrabbableObject)__instance).isBeingUsed)
			{
				UpdateFlashlightState(__instance, active: true);
				if (Object.op_Implicit((Object)(object)val2))
				{
					UpdateFlashlightState(val2, active: false);
				}
			}
			else if (Object.op_Implicit((Object)(object)val2) && ((GrabbableObject)val2).isBeingUsed)
			{
				UpdateFlashlightState(__instance, active: false);
				UpdateFlashlightState(val2, active: true);
			}
		}

		[HarmonyPatch(typeof(FlashlightItem), "DiscardItem")]
		[HarmonyPostfix]
		private static void ResetPocketedFlashlightPost(FlashlightItem __instance)
		{
			if (!Object.op_Implicit((Object)(object)__instance))
			{
				return;
			}
			PlayerControllerB val = GetPreviousPlayerHeldBy(__instance);
			if (!Object.op_Implicit((Object)(object)val))
			{
				PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts;
				foreach (PlayerControllerB val2 in allPlayerScripts)
				{
					if ((Object)(object)__instance == (Object)(object)val2.pocketedFlashlight)
					{
						val = val2;
						break;
					}
				}
				if (!Object.op_Implicit((Object)(object)val))
				{
					return;
				}
			}
			FlashlightItem currentlySelectedFlashlight = GetCurrentlySelectedFlashlight(val);
			FlashlightItem reservedFlashlight = GetReservedFlashlight(val);
			GrabbableObject pocketedFlashlight = val.pocketedFlashlight;
			FlashlightItem val3 = (FlashlightItem)(object)((pocketedFlashlight is FlashlightItem) ? pocketedFlashlight : null);
			if ((Object)(object)__instance == (Object)(object)val3)
			{
				FlashlightItem val4 = ((Object.op_Implicit((Object)(object)reservedFlashlight) && (!Object.op_Implicit((Object)(object)currentlySelectedFlashlight) || (((GrabbableObject)reservedFlashlight).isBeingUsed && !((GrabbableObject)currentlySelectedFlashlight).isBeingUsed))) ? reservedFlashlight : currentlySelectedFlashlight);
				val.pocketedFlashlight = null;
				if (Object.op_Implicit((Object)(object)val4))
				{
					if ((Object)(object)val4 != (Object)(object)currentlySelectedFlashlight)
					{
						val.pocketedFlashlight = (GrabbableObject)(object)val4;
					}
					UpdateFlashlightState(val4, ((GrabbableObject)val4).isBeingUsed);
				}
			}
			else if ((Object)(object)val3 != (Object)null && ((GrabbableObject)val3).isBeingUsed)
			{
				UpdateFlashlightState(val3, active: true);
			}
		}

		[HarmonyPatch(typeof(FlashlightItem), "SwitchFlashlight")]
		[HarmonyPostfix]
		private static void OnToggleFlashlight(bool on, FlashlightItem __instance)
		{
			PlayerControllerB val = ((GrabbableObject)(__instance?)).playerHeldBy;
			if (!Object.op_Implicit((Object)(object)val))
			{
				return;
			}
			GrabbableObject pocketedFlashlight = val.pocketedFlashlight;
			FlashlightItem val2 = (FlashlightItem)(object)((pocketedFlashlight is FlashlightItem) ? pocketedFlashlight : null);
			if (!((GrabbableObject)__instance).isBeingUsed)
			{
				if ((Object)(object)__instance == (Object)(object)val2)
				{
					val.pocketedFlashlight = null;
				}
				return;
			}
			Traverse.Create((object)__instance).Field("previousPlayerHeldBy").SetValue((object)val);
			if ((Object)(object)val2 != (Object)null && (Object)(object)val2 != (Object)(object)__instance)
			{
				if (((GrabbableObject)val2).isBeingUsed)
				{
					val2.SwitchFlashlight(false);
					UpdateFlashlightState(val2, active: false);
				}
				val.pocketedFlashlight = null;
			}
			if ((Object)(object)__instance != (Object)(object)GetCurrentlySelectedFlashlight(val))
			{
				val.pocketedFlashlight = (GrabbableObject)(object)__instance;
			}
			UpdateFlashlightState(__instance, active: true);
		}

		internal static void UpdateFlashlightState(FlashlightItem flashlightItem, bool active)
		{
			PlayerControllerB val = ((GrabbableObject)(flashlightItem?)).playerHeldBy;
			if (Object.op_Implicit((Object)(object)val))
			{
				((GrabbableObject)flashlightItem).isBeingUsed = active;
				bool flag = active && ((Object)(object)flashlightItem == (Object)(object)GetCurrentlySelectedFlashlight(val) || ((Object)(object)val != (Object)(object)localPlayerController && (Object)(object)flashlightItem == (Object)(object)GetReservedFlashlight(val)));
				bool flag2 = active && !flag;
				((Behaviour)flashlightItem.flashlightBulb).enabled = flag;
				((Behaviour)flashlightItem.flashlightBulbGlow).enabled = flag;
				flashlightItem.usingPlayerHelmetLight = flag2;
				((Behaviour)val.helmetLight).enabled = flag2;
				if (flag2)
				{
					val.ChangeHelmetLight(flashlightItem.flashlightTypeID, true);
				}
				((Renderer)flashlightItem.flashlightMesh).sharedMaterials[1] = (flag ? flashlightItem.bulbLight : flashlightItem.bulbDark);
			}
		}
	}
}
namespace ReservedFlashlightSlot.Input
{
	internal class IngameKeybinds : LcInputActions
	{
		internal static IngameKeybinds Instance = new IngameKeybinds();

		[InputAction("<Keyboard>/f", Name = "[ReservedItemSlots]\nToggle flashlight")]
		public InputAction ToggleFlashlightHotkey { get; set; }

		internal static InputActionAsset GetAsset()
		{
			return ((LcInputActions)Instance).Asset;
		}
	}
	internal class InputUtilsCompat
	{
		internal static InputActionAsset Asset => IngameKeybinds.GetAsset();

		internal static bool Enabled => Plugin.IsModLoaded("com.rune580.LethalCompanyInputUtils");

		public static InputAction ToggleFlashlightHotkey => IngameKeybinds.Instance.ToggleFlashlightHotkey;
	}
	[HarmonyPatch]
	public static class KeybindDisplayNames
	{
		public static bool usingControllerPrevious = false;

		public static string[] keyboardKeywords = new string[2] { "keyboard", "mouse" };

		public static string[] controllerKeywords = new string[2] { "gamepad", "controller" };

		public static bool usingController => StartOfRound.Instance.localPlayerUsingController;

		public static string GetKeybindDisplayName(InputAction inputAction)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			if (inputAction == null || !inputAction.enabled)
			{
				return "";
			}
			int num = (usingController ? 1 : 0);
			InputBinding val = inputAction.bindings[num];
			string effectivePath = ((InputBinding)(ref val)).effectivePath;
			return GetKeybindDisplayName(effectivePath);
		}

		public static string GetKeybindDisplayName(string controlPath)
		{
			if (controlPath.Length <= 1)
			{
				return "";
			}
			string text = controlPath.ToLower();
			int num = text.IndexOf(">/");
			text = ((num >= 0) ? text.Substring(num + 2) : text);
			if (text.Contains("not-bound"))
			{
				return "";
			}
			text = text.Replace("leftalt", "Alt");
			text = text.Replace("rightalt", "Alt");
			text = text.Replace("leftctrl", "Ctrl");
			text = text.Replace("rightctrl", "Ctrl");
			text = text.Replace("leftshift", "Shift");
			text = text.Replace("rightshift", "Shift");
			text = text.Replace("leftbutton", "LMB");
			text = text.Replace("rightbutton", "RMB");
			text = text.Replace("middlebutton", "MMB");
			text = text.Replace("lefttrigger", "LT");
			text = text.Replace("righttrigger", "RT");
			text = text.Replace("leftshoulder", "LB");
			text = text.Replace("rightshoulder", "RB");
			text = text.Replace("leftstickpress", "LS");
			text = text.Replace("rightstickpress", "RS");
			text = text.Replace("dpad/", "DPad-");
			text = text.Replace("backquote", "`");
			try
			{
				text = char.ToUpper(text[0]) + text.Substring(1);
			}
			catch
			{
			}
			return text;
		}
	}
	[HarmonyPatch]
	internal static class Keybinds
	{
		public static InputActionAsset Asset;

		public static InputActionMap ActionMap;

		private static InputAction ActivateFlashlightAction;

		public static PlayerControllerB localPlayerController => StartOfRound.Instance?.localPlayerController;

		[HarmonyPatch(typeof(PreInitSceneScript), "Awake")]
		[HarmonyPrefix]
		public static void AddToKeybindMenu()
		{
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Expected O, but got Unknown
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			Plugin.Log("Initializing hotkeys.");
			if (InputUtilsCompat.Enabled)
			{
				Asset = InputUtilsCompat.Asset;
				ActionMap = Asset.actionMaps[0];
				ActivateFlashlightAction = InputUtilsCompat.ToggleFlashlightHotkey;
			}
			else
			{
				Asset = ScriptableObject.CreateInstance<InputActionAsset>();
				ActionMap = new InputActionMap("ReservedItemSlots");
				InputActionSetupExtensions.AddActionMap(Asset, ActionMap);
				ActivateFlashlightAction = InputActionSetupExtensions.AddAction(ActionMap, "ReservedItemSlots.ToggleFlashlight", (InputActionType)0, "<keyboard>/f", (string)null, (string)null, (string)null, (string)null);
			}
		}

		[HarmonyPatch(typeof(StartOfRound), "OnEnable")]
		[HarmonyPostfix]
		public static void OnEnable()
		{
			Asset.Enable();
			ActivateFlashlightAction.performed += OnActivateFlashlightPerformed;
		}

		[HarmonyPatch(typeof(StartOfRound), "OnDisable")]
		[HarmonyPostfix]
		public static void OnDisable()
		{
			Asset.Disable();
			ActivateFlashlightAction.performed -= OnActivateFlashlightPerformed;
		}

		private static void OnActivateFlashlightPerformed(CallbackContext context)
		{
			if ((Object)(object)localPlayerController == (Object)null || !localPlayerController.isPlayerControlled || (((NetworkBehaviour)localPlayerController).IsServer && !localPlayerController.isHostPlayerObject) || !((CallbackContext)(ref context)).performed || ShipBuildModeManager.Instance.InBuildMode || localPlayerController.inTerminalMenu || ReservedPlayerData.localPlayerData.timeSinceSwitchingSlots < 0.075f || localPlayerController.isTypingChat || localPlayerController.inTerminalMenu || localPlayerController.quickMenuManager.isMenuOpen || localPlayerController.isPlayerDead || localPlayerController.isGrabbingObjectAnimation || ReservedPlayerData.localPlayerData.isGrabbingReservedItem)
			{
				return;
			}
			FlashlightItem val = FlashlightPatcher.GetMainFlashlight(localPlayerController);
			if (!Object.op_Implicit((Object)(object)val))
			{
				val = FlashlightPatcher.GetFirstFlashlightItem(localPlayerController);
				if (!Object.op_Implicit((Object)(object)val))
				{
					return;
				}
			}
			bool flag = !((GrabbableObject)val).isBeingUsed;
			if (flag && (Object)(object)val != (Object)(object)FlashlightPatcher.GetCurrentlySelectedFlashlight(localPlayerController))
			{
				localPlayerController.pocketedFlashlight = (GrabbableObject)(object)val;
			}
			((GrabbableObject)val).UseItemOnClient(flag);
			Traverse.Create((object)localPlayerController).Field("timeSinceSwitchingSlots").SetValue((object)0);
		}
	}
}
namespace ReservedFlashlightSlot.Config
{
	public static class ConfigSettings
	{
		public static ConfigEntry<int> overrideItemSlotPriority;

		public static ConfigEntry<int> overridePurchasePrice;

		public static ConfigEntry<string> additionalItemsInSlot;

		public static Dictionary<string, ConfigEntryBase> currentConfigEntries = new Dictionary<string, ConfigEntryBase>();

		public static void BindConfigSettings()
		{
			Plugin.Log("BindingConfigs");
			overrideItemSlotPriority = AddConfigEntry<int>(((BaseUnityPlugin)Plugin.instance).Config.Bind<int>("Server-side", "FlashlightSlotPriorityOverride", 200, "[Host only] Manually set the priority for this item slot. Higher priority slots will come first in the reserved item slots, which will appear below the other slots. Negative priority items will appear on the left side of the screen, this is disabled in the core mod's config."));
			overridePurchasePrice = AddConfigEntry<int>(((BaseUnityPlugin)Plugin.instance).Config.Bind<int>("Server-side", "FlashlightSlotPriceOverride", 200, "[Host only] Manually set the price for this item in the store. Setting 0 will force this item to be unlocked immediately after the game starts."));
			additionalItemsInSlot = AddConfigEntry<string>(((BaseUnityPlugin)Plugin.instance).Config.Bind<string>("Server-side", "AdditionalItemsInSlot", "", "[Host only] Syntax: \"Item1,Item name2\" (without quotes). When adding items, use the item's name as it appears in game. Include spaces if there are spaces in the item name. Adding items that do not exist, or that are from a mod which is not enabled will not cause any problems.\nNOTE: IF YOU ARE USING A TRANSLATION MOD, YOU MAY NEED TO ADD THE TRANSLATED NAME OF ANY ITEM YOU WANT IN THIS SLOT."));
			additionalItemsInSlot.Value = additionalItemsInSlot.Value.Replace(", ", ",");
			TryRemoveOldConfigSettings();
		}

		public static ConfigEntry<T> AddConfigEntry<T>(ConfigEntry<T> configEntry)
		{
			currentConfigEntries.Add(((ConfigEntryBase)configEntry).Definition.Key, (ConfigEntryBase)(object)configEntry);
			return configEntry;
		}

		public static string[] ParseAdditionalItems()
		{
			return ConfigSettings.ParseItemNames(additionalItemsInSlot.Value);
		}

		public static void TryRemoveOldConfigSettings()
		{
			HashSet<string> hashSet = new HashSet<string>();
			HashSet<string> hashSet2 = new HashSet<string>();
			foreach (ConfigEntryBase value in currentConfigEntries.Values)
			{
				hashSet.Add(value.Definition.Section);
				hashSet2.Add(value.Definition.Key);
			}
			try
			{
				ConfigFile config = ((BaseUnityPlugin)Plugin.instance).Config;
				string configFilePath = config.ConfigFilePath;
				if (!File.Exists(configFilePath))
				{
					return;
				}
				string text = File.ReadAllText(configFilePath);
				string[] array = File.ReadAllLines(configFilePath);
				string text2 = "";
				for (int i = 0; i < array.Length; i++)
				{
					array[i] = array[i].Replace("\n", "");
					if (array[i].Length <= 0)
					{
						continue;
					}
					if (array[i].StartsWith("["))
					{
						if (text2 != "" && !hashSet.Contains(text2))
						{
							text2 = "[" + text2 + "]";
							int num = text.IndexOf(text2);
							int num2 = text.IndexOf(array[i]);
							text = text.Remove(num, num2 - num);
						}
						text2 = array[i].Replace("[", "").Replace("]", "").Trim();
					}
					else
					{
						if (!(text2 != ""))
						{
							continue;
						}
						if (i <= array.Length - 4 && array[i].StartsWith("##"))
						{
							int j;
							for (j = 1; i + j < array.Length && array[i + j].Length > 3; j++)
							{
							}
							if (hashSet.Contains(text2))
							{
								int num3 = array[i + j - 1].IndexOf("=");
								string item = array[i + j - 1].Substring(0, num3 - 1);
								if (!hashSet2.Contains(item))
								{
									int num4 = text.IndexOf(array[i]);
									int num5 = text.IndexOf(array[i + j - 1]) + array[i + j - 1].Length;
									text = text.Remove(num4, num5 - num4);
								}
							}
							i += j - 1;
						}
						else if (array[i].Length > 3)
						{
							text = text.Replace(array[i], "");
						}
					}
				}
				if (!hashSet.Contains(text2))
				{
					text2 = "[" + text2 + "]";
					int num6 = text.IndexOf(text2);
					text = text.Remove(num6, text.Length - num6);
				}
				while (text.Contains("\n\n\n"))
				{
					text = text.Replace("\n\n\n", "\n\n");
				}
				File.WriteAllText(configFilePath, text);
				config.Reload();
			}
			catch
			{
			}
		}
	}
}

plugins/ReservedItemSlotCore.dll

Decompiled 2 years ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using LethalCompanyInputUtils.Api;
using ReservedItemSlotCore.Compatibility;
using ReservedItemSlotCore.Config;
using ReservedItemSlotCore.Data;
using ReservedItemSlotCore.Input;
using ReservedItemSlotCore.Networking;
using ReservedItemSlotCore.Patches;
using TMPro;
using TooManyEmotes;
using Unity.Collections;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("ReservedItemSlotCore")]
[assembly: AssemblyDescription("Mod made by flipf17")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ReservedItemSlotCore")]
[assembly: AssemblyCopyright("Copyright ©  2023")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("238ce080-e339-46b6-9b08-992a950453a1")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: InternalsVisibleTo("ReservedFlashlightSlot")]
[assembly: InternalsVisibleTo("ReservedWalkieSlot")]
[assembly: InternalsVisibleTo("ReservedWeaponSlot")]
[assembly: InternalsVisibleTo("ReservedSprayPaintSlot")]
[assembly: InternalsVisibleTo("ReservedUtilitySlot")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace ReservedItemSlotCore
{
	[HarmonyPatch]
	internal static class ItemNameMap
	{
		private static Dictionary<string, Item> originalNameToItemMap = new Dictionary<string, Item>();

		private static Dictionary<Item, string> itemToNameMap = new Dictionary<Item, string>();

		[HarmonyPatch(typeof(StartOfRound), "Start")]
		[HarmonyPrefix]
		private static void RecordOriginalItemNames(StartOfRound __instance)
		{
			List<Item> list = __instance?.allItemsList?.itemsList;
			if (list == null)
			{
				Plugin.LogError("Failed to record original item names. This might be fine if you're not using translation/localization mods. (no guarantees)");
				return;
			}
			foreach (Item item in list)
			{
				string text = item?.itemName;
				if (text != null && text.Length > 0)
				{
					if (!itemToNameMap.ContainsKey(item))
					{
						itemToNameMap.Add(item, text);
					}
					if (!originalNameToItemMap.ContainsKey(text))
					{
						originalNameToItemMap.Add(text, item);
					}
				}
			}
		}

		internal static string GetItemName(GrabbableObject grabbableObject)
		{
			if ((Object)(object)grabbableObject?.itemProperties == (Object)null)
			{
				return "";
			}
			string itemName = GetItemName(grabbableObject.itemProperties);
			return (itemName != null) ? itemName : "";
		}

		internal static string GetItemName(Item item)
		{
			if ((Object)(object)item == (Object)null)
			{
				return "";
			}
			if (itemToNameMap.TryGetValue(item, out var value) && value != null)
			{
				return value;
			}
			return "";
		}
	}
	[BepInPlugin("FlipMods.ReservedItemSlotCore", "ReservedItemSlotCore", "2.0.27")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	internal class Plugin : BaseUnityPlugin
	{
		private Harmony _harmony;

		public static Plugin instance;

		private static ManualLogSource logger;

		public static List<ReservedItemSlotData> customItemSlots = new List<ReservedItemSlotData>();

		private void Awake()
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Expected O, but got Unknown
			instance = this;
			CreateCustomLogger();
			ConfigSettings.BindConfigSettings();
			AddCustomItemSlots();
			if (InputUtilsCompat.Enabled)
			{
				InputUtilsCompat.Init();
			}
			_harmony = new Harmony("ReservedItemSlotCore");
			PatchAll();
			Log("ReservedItemSlotCore loaded");
		}

		private void AddCustomItemSlots()
		{
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			foreach (CustomItemSlotConfigEntry customItemSlotConfig in ConfigSettings.customItemSlotConfigs)
			{
				if (!(customItemSlotConfig.customItemSlotName == "") && customItemSlotConfig.customItemSlotItems.Length != 0)
				{
					ReservedItemSlotData reservedItemSlotData = ReservedItemSlotData.CreateReservedItemSlotData(customItemSlotConfig.customItemSlotName, customItemSlotConfig.customItemSlotPriority, customItemSlotConfig.customItemSlotPrice);
					string[] customItemSlotItems = customItemSlotConfig.customItemSlotItems;
					foreach (string itemName in customItemSlotItems)
					{
						ReservedItemData itemData = new ReservedItemData(itemName);
						reservedItemSlotData.AddItemToReservedItemSlot(itemData);
						customItemSlots.Add(reservedItemSlotData);
					}
				}
			}
		}

		private void PatchAll()
		{
			IEnumerable<Type> enumerable;
			try
			{
				enumerable = Assembly.GetExecutingAssembly().GetTypes();
			}
			catch (ReflectionTypeLoadException ex)
			{
				enumerable = ex.Types.Where((Type t) => t != null);
			}
			foreach (Type item in enumerable)
			{
				_harmony.PatchAll(item);
			}
		}

		private void CreateCustomLogger()
		{
			try
			{
				logger = Logger.CreateLogSource($"{((BaseUnityPlugin)this).Info.Metadata.Name}-{((BaseUnityPlugin)this).Info.Metadata.Version}");
			}
			catch
			{
				logger = ((BaseUnityPlugin)this).Logger;
			}
		}

		public static void Log(string message)
		{
			logger.LogInfo((object)message);
		}

		public static void LogError(string message)
		{
			logger.LogError((object)message);
		}

		public static void LogWarning(string message)
		{
			logger.LogWarning((object)message);
		}

		public static bool IsModLoaded(string guid)
		{
			return Chainloader.PluginInfos.ContainsKey(guid);
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "FlipMods.ReservedItemSlotCore";

		public const string PLUGIN_NAME = "ReservedItemSlotCore";

		public const string PLUGIN_VERSION = "2.0.27";
	}
	[HarmonyPatch]
	public static class ReservedHotbarManager
	{
		public static int indexInHotbar = 0;

		public static int indexInReservedHotbar = 0;

		internal static List<ReservedItemSlotData> currentlyToggledItemSlots = new List<ReservedItemSlotData>();

		public static PlayerControllerB localPlayerController => StartOfRound.Instance?.localPlayerController;

		public static ReservedPlayerData localPlayerData => ReservedPlayerData.localPlayerData;

		public static int reservedHotbarSize => SessionManager.numReservedItemSlotsUnlocked;

		public static bool isToggledInReservedSlots
		{
			get
			{
				ReservedItemSlotData currentlySelectedReservedItemSlot = localPlayerData.GetCurrentlySelectedReservedItemSlot();
				return ConfigSettings.toggleFocusReservedHotbar.Value || (currentlyToggledItemSlots != null && currentlySelectedReservedItemSlot != null && currentlyToggledItemSlots.Contains(currentlySelectedReservedItemSlot));
			}
		}

		[HarmonyPatch(typeof(StartOfRound), "Awake")]
		[HarmonyPrefix]
		public static void InitSession(StartOfRound __instance)
		{
			currentlyToggledItemSlots = new List<ReservedItemSlotData>();
			ReservedPlayerData.allPlayerData.Clear();
			indexInHotbar = 0;
			indexInReservedHotbar = -1;
		}

		public static void ForceToggleReservedHotbar(params ReservedItemSlotData[] reservedItemSlots)
		{
			if (((NetworkBehaviour)localPlayerController).IsOwner && localPlayerController.isPlayerControlled && (!((NetworkBehaviour)localPlayerController).IsServer || localPlayerController.isHostPlayerObject) && HUDPatcher.hasReservedItemSlotsAndEnabled && reservedHotbarSize > 0 && CanSwapHotbars() && reservedItemSlots != null && reservedItemSlots.Length != 0 && !((Object)(object)localPlayerController == (Object)null))
			{
				currentlyToggledItemSlots = new List<ReservedItemSlotData>(reservedItemSlots);
				int num = currentlyToggledItemSlots.First().GetReservedItemSlotIndex() + localPlayerData.reservedHotbarStartIndex;
				bool active = ReservedPlayerData.localPlayerData.IsReservedItemSlot(num);
				if (currentlyToggledItemSlots.Contains(localPlayerData.GetCurrentlySelectedReservedItemSlot()))
				{
					FocusReservedHotbarSlots(active: false);
					return;
				}
				HUDPatcher.UpdateToggledReservedItemSlotsUI();
				FocusReservedHotbarSlots(active, num);
			}
		}

		public static void FocusReservedHotbarSlots(bool active, int forceSlot = -1)
		{
			if (!HUDPatcher.hasReservedItemSlotsAndEnabled || (reservedHotbarSize <= 0 && active) || (ReservedPlayerData.localPlayerData.currentItemSlotIsReserved == active && (forceSlot == -1 || localPlayerData.currentItemSlot == forceSlot)))
			{
				return;
			}
			if (forceSlot != -1)
			{
				active = localPlayerData.IsReservedItemSlot(forceSlot);
			}
			ReservedPlayerData reservedPlayerData = ReservedPlayerData.localPlayerData;
			indexInHotbar = Mathf.Clamp(indexInHotbar, 0, localPlayerController.ItemSlots.Length - 1);
			indexInHotbar = ((!reservedPlayerData.IsReservedItemSlot(indexInHotbar)) ? indexInHotbar : 0);
			indexInReservedHotbar = Mathf.Clamp(indexInReservedHotbar, reservedPlayerData.reservedHotbarStartIndex, reservedPlayerData.reservedHotbarEndIndexExcluded - 1);
			int num = Mathf.Clamp(localPlayerController.currentItemSlot, 0, localPlayerController.ItemSlots.Length);
			int i = num;
			bool flag = active;
			if (flag && (!reservedPlayerData.IsReservedItemSlot(num) || forceSlot != -1))
			{
				indexInHotbar = num;
				indexInHotbar = ((!reservedPlayerData.IsReservedItemSlot(indexInHotbar)) ? indexInHotbar : 0);
				if (forceSlot != -1 && reservedPlayerData.IsReservedItemSlot(forceSlot))
				{
					indexInReservedHotbar = forceSlot;
				}
				i = indexInReservedHotbar;
				if ((Object)(object)localPlayerController.ItemSlots[i] == (Object)null && reservedPlayerData.GetNumHeldReservedItems() > 0)
				{
					for (i = reservedPlayerData.reservedHotbarStartIndex; i < reservedPlayerData.reservedHotbarEndIndexExcluded && !((Object)(object)localPlayerController.ItemSlots[i] != (Object)null); i++)
					{
					}
				}
				Plugin.Log("Focusing reserved hotbar slots. NewIndex: " + i + " OldIndex: " + num + " ReservedStartIndex: " + ReservedPlayerData.localPlayerData.reservedHotbarStartIndex);
			}
			else if (!flag && (ReservedPlayerData.localPlayerData.IsReservedItemSlot(num) || forceSlot != -1))
			{
				indexInReservedHotbar = Mathf.Clamp(num, reservedPlayerData.reservedHotbarStartIndex, reservedPlayerData.reservedHotbarEndIndexExcluded - 1);
				if (forceSlot != -1 && !reservedPlayerData.IsReservedItemSlot(forceSlot))
				{
					indexInHotbar = forceSlot;
				}
				i = indexInHotbar;
				Plugin.Log("Unfocusing reserved hotbar slots. NewIndex: " + i + " OldIndex: " + num + " ReservedStartIndex: " + ReservedPlayerData.localPlayerData.reservedHotbarStartIndex);
			}
			if (i < 0)
			{
				Plugin.LogError("Swapping to hotbar slot: " + i + ". Maybe send these logs to Flip? :)");
			}
			else if (i >= localPlayerController.ItemSlots.Length)
			{
				Plugin.LogError("Swapping to hotbar slot: " + i + " InventorySize: " + localPlayerController.ItemSlots.Length + ". Maybe send these logs to Flip? :)");
			}
			SyncManager.SwapHotbarSlot(i);
			if (localPlayerController.currentItemSlot != i)
			{
				Plugin.LogWarning("OnFocusReservedHotbarSlots - New hotbar index does not match target hotbar index. Tried to swap to index: " + i + " Current index: " + localPlayerController.currentItemSlot + " Tried swapping to reserved hotbar: " + active);
			}
		}

		public static bool CanSwapHotbars()
		{
			if (!HUDPatcher.hasReservedItemSlotsAndEnabled)
			{
				return false;
			}
			if (TooManyEmotes_Compat.Enabled && TooManyEmotes_Compat.IsLocalPlayerPerformingCustomEmote() && !TooManyEmotes_Compat.CanMoveWhileEmoting())
			{
				return false;
			}
			return ReservedPlayerData.localPlayerData.grabbingReservedItemData == null && !localPlayerController.isGrabbingObjectAnimation && !localPlayerController.quickMenuManager.isMenuOpen && !localPlayerController.inSpecialInteractAnimation && !localPlayerData.throwingObject && !localPlayerController.isTypingChat && !localPlayerController.twoHanded && !localPlayerController.activatingItem && !localPlayerController.jetpackControls && !localPlayerController.disablingJetpackControls && !localPlayerController.inTerminalMenu && !localPlayerController.isPlayerDead && !(localPlayerData.timeSinceSwitchingSlots < 0.3f);
		}

		internal static void OnSwapToReservedHotbar()
		{
			if (!localPlayerData.currentItemSlotIsReserved)
			{
				return;
			}
			if (localPlayerData.currentItemSlotIsReserved)
			{
				indexInReservedHotbar = localPlayerController.currentItemSlot;
			}
			ReservedItemSlotData currentlySelectedReservedItemSlot = localPlayerData.GetCurrentlySelectedReservedItemSlot();
			if (isToggledInReservedSlots && currentlyToggledItemSlots != null && !currentlyToggledItemSlots.Contains(currentlySelectedReservedItemSlot))
			{
				currentlyToggledItemSlots = null;
			}
			if (HUDPatcher.reservedItemSlots == null)
			{
				return;
			}
			foreach (Image reservedItemSlot in HUDPatcher.reservedItemSlots)
			{
				CanvasGroup component = ((Component)reservedItemSlot).GetComponent<CanvasGroup>();
				if ((Object)(object)component != (Object)null)
				{
					component.ignoreParentGroups = true;
				}
			}
		}

		internal static void OnSwapToVanillaHotbar()
		{
			if (localPlayerData.currentItemSlotIsReserved)
			{
				return;
			}
			if (!localPlayerData.currentItemSlotIsReserved)
			{
				indexInHotbar = localPlayerController.currentItemSlot;
			}
			currentlyToggledItemSlots = null;
			if (HUDPatcher.reservedItemSlots == null)
			{
				return;
			}
			foreach (Image reservedItemSlot in HUDPatcher.reservedItemSlots)
			{
				CanvasGroup component = ((Component)reservedItemSlot).GetComponent<CanvasGroup>();
				if ((Object)(object)component != (Object)null)
				{
					component.ignoreParentGroups = ConfigSettings.preventReservedItemSlotFade.Value;
				}
			}
		}

		[HarmonyPatch(typeof(PlayerControllerB), "LateUpdate")]
		[HarmonyPrefix]
		private static void RefocusReservedHotbarAfterAnimation(PlayerControllerB __instance)
		{
			if (HUDPatcher.hasReservedItemSlotsAndEnabled && !((Object)(object)__instance != (Object)(object)localPlayerController) && !ConfigSettings.toggleFocusReservedHotbar.Value && Keybinds.holdingModifierKey != ReservedPlayerData.localPlayerData.currentItemSlotIsReserved && !isToggledInReservedSlots && CanSwapHotbars())
			{
				FocusReservedHotbarSlots(Keybinds.holdingModifierKey);
			}
		}

		[HarmonyPatch(typeof(PlayerControllerB), "UpdateSpecialAnimationValue")]
		[HarmonyPostfix]
		private static void UpdateReservedHotbarAfterAnimation(bool specialAnimation, PlayerControllerB __instance)
		{
			if (HUDPatcher.hasReservedItemSlotsAndEnabled && !((Object)(object)__instance != (Object)(object)localPlayerController) && !specialAnimation && !ConfigSettings.toggleFocusReservedHotbar.Value && ReservedPlayerData.localPlayerData.currentItemSlotIsReserved != Keybinds.holdingModifierKey)
			{
				FocusReservedHotbarSlots(Keybinds.holdingModifierKey);
			}
		}
	}
	[HarmonyPatch]
	public static class SessionManager
	{
		internal static List<ReservedItemSlotData> unlockedReservedItemSlots = new List<ReservedItemSlotData>();

		internal static Dictionary<string, ReservedItemSlotData> unlockedReservedItemSlotsDict = new Dictionary<string, ReservedItemSlotData>();

		internal static List<ReservedItemSlotData> pendingUnlockedReservedItemSlots = new List<ReservedItemSlotData>();

		internal static Dictionary<string, ReservedItemSlotData> pendingUnlockedReservedItemSlotsDict = new Dictionary<string, ReservedItemSlotData>();

		private static Dictionary<string, ReservedItemData> allReservedItemData = new Dictionary<string, ReservedItemData>();

		internal static bool gameStarted = false;

		internal static List<ReservedItemSlotData> allUnlockableReservedItemSlots => SyncManager.unlockableReservedItemSlots;

		internal static Dictionary<string, ReservedItemSlotData> allUnlockableReservedItemSlotsDict => SyncManager.unlockableReservedItemSlotsDict;

		public static int numReservedItemSlotsUnlocked => (unlockedReservedItemSlots != null) ? unlockedReservedItemSlots.Count : 0;

		[HarmonyPatch(typeof(StartOfRound), "Awake")]
		[HarmonyPrefix]
		private static void InitSession()
		{
			unlockedReservedItemSlots.Clear();
			unlockedReservedItemSlotsDict.Clear();
			pendingUnlockedReservedItemSlots.Clear();
			pendingUnlockedReservedItemSlotsDict.Clear();
			allReservedItemData.Clear();
		}

		public static void UnlockReservedItemSlot(ReservedItemSlotData itemSlotData)
		{
			Plugin.Log("Unlocking reserved item slot: " + itemSlotData.slotName);
			if (!SyncManager.isSynced)
			{
				if (!pendingUnlockedReservedItemSlotsDict.ContainsKey(itemSlotData.slotName))
				{
					pendingUnlockedReservedItemSlotsDict.Add(itemSlotData.slotName, itemSlotData);
					pendingUnlockedReservedItemSlots.Add(itemSlotData);
				}
				return;
			}
			if (!unlockedReservedItemSlotsDict.ContainsKey(itemSlotData.slotName))
			{
				unlockedReservedItemSlotsDict.Add(itemSlotData.slotName, itemSlotData);
				if (!unlockedReservedItemSlots.Contains(itemSlotData))
				{
					int num = -1;
					for (int i = 0; i < unlockedReservedItemSlots.Count; i++)
					{
						if (itemSlotData.slotPriority > unlockedReservedItemSlots[i].slotPriority)
						{
							num = i;
							break;
						}
					}
					if (num == -1)
					{
						num = unlockedReservedItemSlots.Count;
					}
					unlockedReservedItemSlots.Insert(num, itemSlotData);
					foreach (ReservedPlayerData value in ReservedPlayerData.allPlayerData.Values)
					{
						if (unlockedReservedItemSlots.Count == 1)
						{
							value.reservedHotbarStartIndex = value.itemSlots.Length;
						}
						int index = value.reservedHotbarStartIndex + num;
						List<GrabbableObject> list = new List<GrabbableObject>(value.itemSlots);
						list.Insert(index, null);
						value.playerController.ItemSlots = list.ToArray();
						value.hotbarSize = list.Count;
					}
				}
			}
			if (ReservedHotbarManager.indexInReservedHotbar < ReservedPlayerData.localPlayerData.reservedHotbarStartIndex || ReservedHotbarManager.indexInReservedHotbar >= ReservedPlayerData.localPlayerData.reservedHotbarEndIndexExcluded)
			{
				ReservedHotbarManager.indexInReservedHotbar = ReservedPlayerData.localPlayerData.reservedHotbarStartIndex;
			}
			UpdateReservedItemsList();
			HUDPatcher.OnUpdateReservedItemSlots();
		}

		internal static void UnlockAllPendingItemSlots()
		{
			foreach (ReservedItemSlotData pendingUnlockedReservedItemSlot in pendingUnlockedReservedItemSlots)
			{
				UnlockReservedItemSlot(pendingUnlockedReservedItemSlot);
			}
			pendingUnlockedReservedItemSlots.Clear();
			pendingUnlockedReservedItemSlotsDict.Clear();
		}

		public static ReservedItemSlotData GetUnlockedReservedItemSlot(int indexInUnlockedItemSlots)
		{
			return (unlockedReservedItemSlots != null && indexInUnlockedItemSlots >= 0 && indexInUnlockedItemSlots < unlockedReservedItemSlots.Count) ? unlockedReservedItemSlots[indexInUnlockedItemSlots] : null;
		}

		public static ReservedItemSlotData GetUnlockedReservedItemSlot(string itemSlotName)
		{
			if (TryGetUnlockedItemSlotData(itemSlotName, out var itemSlotData))
			{
				return itemSlotData;
			}
			return null;
		}

		public static bool IsItemSlotUnlocked(ReservedItemSlotData itemSlotData)
		{
			return itemSlotData != null && IsItemSlotUnlocked(itemSlotData.slotName);
		}

		public static bool IsItemSlotUnlocked(string itemSlotName)
		{
			return unlockedReservedItemSlotsDict.ContainsKey(itemSlotName);
		}

		internal static void UpdateReservedItemsList()
		{
			if (unlockedReservedItemSlots == null)
			{
				return;
			}
			allReservedItemData.Clear();
			foreach (ReservedItemSlotData unlockedReservedItemSlot in unlockedReservedItemSlots)
			{
				if (unlockedReservedItemSlot.reservedItemData == null)
				{
					continue;
				}
				foreach (ReservedItemData value in unlockedReservedItemSlot.reservedItemData.Values)
				{
					if (!allReservedItemData.ContainsKey(value.itemName))
					{
						allReservedItemData.Add(value.itemName, value);
					}
				}
			}
		}

		[HarmonyPatch(typeof(StartOfRound), "ResetShip")]
		[HarmonyPostfix]
		private static void OnResetShip()
		{
			if (SyncManager.enablePurchasingItemSlots)
			{
				ResetProgress();
			}
		}

		[HarmonyPatch(typeof(GameNetworkManager), "SaveGameValues")]
		[HarmonyPostfix]
		private static void OnSaveGameValues()
		{
			if (NetworkManager.Singleton.IsHost && StartOfRound.Instance.inShipPhase && SyncManager.enablePurchasingItemSlots)
			{
				SaveGameValues();
			}
		}

		[HarmonyPatch(typeof(StartOfRound), "LoadUnlockables")]
		[HarmonyPostfix]
		private static void OnLoadGameValues()
		{
			if (NetworkManager.Singleton.IsServer && SyncManager.isSynced && SyncManager.enablePurchasingItemSlots)
			{
				LoadGameValues();
			}
		}

		internal static void ResetProgress(bool force = false)
		{
			if (!SyncManager.enablePurchasingItemSlots && !force)
			{
				return;
			}
			foreach (ReservedPlayerData value in ReservedPlayerData.allPlayerData.Values)
			{
				GrabbableObject[] itemSlots = value.playerController.ItemSlots;
				List<GrabbableObject> list = new List<GrabbableObject>();
				for (int i = 0; i < itemSlots.Length; i++)
				{
					if (i < value.reservedHotbarStartIndex || i >= value.reservedHotbarEndIndexExcluded)
					{
						list.Add(itemSlots[i]);
					}
				}
				value.playerController.ItemSlots = list.ToArray();
			}
			unlockedReservedItemSlots?.Clear();
			unlockedReservedItemSlotsDict?.Clear();
			pendingUnlockedReservedItemSlots?.Clear();
			pendingUnlockedReservedItemSlotsDict?.Clear();
			List<Image> list2 = new List<Image>();
			List<Image> list3 = new List<Image>();
			for (int j = 0; j < HUDManager.Instance.itemSlotIconFrames.Length; j++)
			{
				Image val = HUDManager.Instance.itemSlotIconFrames[j];
				Image item = HUDManager.Instance.itemSlotIcons[j];
				if (!HUDPatcher.reservedItemSlots.Contains(val))
				{
					list2.Add(val);
					list3.Add(item);
				}
				else
				{
					Object.Destroy((Object)(object)((Component)val).gameObject);
				}
			}
			HUDPatcher.reservedItemSlots.Clear();
			HUDManager.Instance.itemSlotIconFrames = list2.ToArray();
			HUDManager.Instance.itemSlotIcons = list3.ToArray();
			foreach (ReservedPlayerData value2 in ReservedPlayerData.allPlayerData.Values)
			{
				if (value2.playerController.currentItemSlot < 0 || value2.playerController.currentItemSlot >= value2.playerController.ItemSlots.Length)
				{
					PlayerPatcher.SwitchToItemSlot(value2.playerController, 0);
				}
				value2.reservedHotbarStartIndex = value2.itemSlots.Length;
			}
			foreach (ReservedItemSlotData allUnlockableReservedItemSlot in allUnlockableReservedItemSlots)
			{
				if (allUnlockableReservedItemSlot.purchasePrice <= 0)
				{
					UnlockReservedItemSlot(allUnlockableReservedItemSlot);
				}
			}
			HUDPatcher.OnUpdateReservedItemSlots();
			if (NetworkManager.Singleton.IsServer)
			{
				ES3.DeleteKey("ReservedItemSlots.UnlockedItemSlots", GameNetworkManager.Instance.currentSaveFileName);
			}
		}

		internal static void SaveGameValues()
		{
			if (!NetworkManager.Singleton.IsServer || unlockedReservedItemSlots == null)
			{
				return;
			}
			List<string> list = new List<string>();
			foreach (ReservedItemSlotData unlockedReservedItemSlot in unlockedReservedItemSlots)
			{
				if (!list.Contains(unlockedReservedItemSlot.slotName))
				{
					list.Add(unlockedReservedItemSlot.slotName);
				}
			}
			Plugin.LogWarning("Saving " + list.Count + " unlocked reserved item slots.");
			string[] array = list.ToArray();
			ES3.Save<string[]>("ReservedItemSlots.UnlockedItemSlots", array, GameNetworkManager.Instance.currentSaveFileName);
		}

		internal static void LoadGameValues()
		{
			if (!NetworkManager.Singleton.IsServer || SyncManager.unlockableReservedItemSlotsDict == null)
			{
				return;
			}
			string[] array = ES3.Load<string[]>("ReservedItemSlots.UnlockedItemSlots", GameNetworkManager.Instance.currentSaveFileName, new string[0]);
			Plugin.LogWarning("Loading " + array.Length + " unlocked reserved item slots.");
			string[] array2 = array;
			foreach (string key in array2)
			{
				if (SyncManager.unlockableReservedItemSlotsDict.TryGetValue(key, out var value))
				{
					UnlockReservedItemSlot(value);
					SyncManager.SendUnlockItemSlotToClients(value.slotId);
				}
			}
		}

		public static bool IsReservedItem(GrabbableObject grabbableObject)
		{
			string itemName = ItemNameMap.GetItemName(grabbableObject);
			return IsReservedItem(itemName) || ((Object)(object)grabbableObject?.itemProperties != (Object)null && IsReservedItem(grabbableObject.itemProperties.itemName));
		}

		public static bool IsReservedItem(string itemName)
		{
			return allReservedItemData.ContainsKey(itemName);
		}

		public static bool TryGetUnlockedItemSlotData(string itemSlotName, out ReservedItemSlotData itemSlotData)
		{
			itemSlotData = null;
			unlockedReservedItemSlotsDict.TryGetValue(itemSlotName, out itemSlotData);
			return itemSlotData != null;
		}

		public static bool TryGetUnlockedItemData(GrabbableObject item, out ReservedItemData itemData)
		{
			itemData = null;
			string itemName = ItemNameMap.GetItemName(item);
			return TryGetUnlockedItemData(itemName, out itemData) || ((Object)(object)item?.itemProperties != (Object)null && TryGetUnlockedItemData(item.itemProperties.itemName, out itemData));
		}

		public static bool TryGetUnlockedItemData(string itemName, out ReservedItemData itemData)
		{
			itemData = null;
			return allReservedItemData.TryGetValue(itemName, out itemData);
		}
	}
}
namespace ReservedItemSlotCore.Patches
{
	[HarmonyPatch]
	internal static class DropReservedItemPatcher
	{
		private static HashSet<PlayerControllerB> playersDiscardingItems = new HashSet<PlayerControllerB>();

		private static PlayerControllerB localPlayerController => StartOfRound.Instance?.localPlayerController;

		[HarmonyPatch(typeof(PlayerControllerB), "SetObjectAsNoLongerHeld")]
		[HarmonyPostfix]
		private static void OnSetObjectNoLongerHeld(bool droppedInElevator, bool droppedInShipRoom, Vector3 targetFloorPosition, GrabbableObject dropObject, PlayerControllerB __instance)
		{
			OnDiscardItem(__instance);
		}

		[HarmonyPatch(typeof(PlayerControllerB), "PlaceGrabbableObject")]
		[HarmonyPostfix]
		private static void OnPlaceGrabbableObject(Transform parentObject, Vector3 positionOffset, bool matchRotationOfParent, GrabbableObject placeObject, PlayerControllerB __instance)
		{
			OnDiscardItem(__instance);
		}

		[HarmonyPatch(typeof(PlayerControllerB), "DestroyItemInSlot")]
		[HarmonyPostfix]
		private static void OnDestroyItem(int itemSlot, PlayerControllerB __instance)
		{
			if ((Object)(object)__instance == (Object)(object)localPlayerController && itemSlot >= ReservedPlayerData.localPlayerData.reservedHotbarStartIndex && itemSlot < ReservedPlayerData.localPlayerData.reservedHotbarEndIndexExcluded)
			{
				HUDPatcher.UpdateUI();
			}
		}

		[HarmonyPatch(typeof(PlayerControllerB), "DespawnHeldObjectOnClient")]
		[HarmonyPostfix]
		private static void OnDespawnItem(PlayerControllerB __instance)
		{
			if ((Object)(object)__instance == (Object)(object)localPlayerController)
			{
				HUDPatcher.UpdateUI();
			}
		}

		[HarmonyPatch(typeof(PlayerControllerB), "DropAllHeldItems")]
		[HarmonyPostfix]
		private static void OnDropAllHeldItems(PlayerControllerB __instance)
		{
			if ((Object)(object)__instance == (Object)(object)localPlayerController)
			{
				HUDPatcher.UpdateUI();
			}
		}

		private static void OnDiscardItem(PlayerControllerB playerController)
		{
			if (!((Object)(object)playerController != (Object)null) || playersDiscardingItems.Contains(playerController) || !ReservedPlayerData.allPlayerData.TryGetValue(playerController, out var value) || !value.currentItemSlotIsReserved || !((Object)(object)value.currentlySelectedItem == (Object)null))
			{
				return;
			}
			if (value.GetNumHeldReservedItems() > 0)
			{
				int num = value.CallGetNextItemSlot(forward: true);
				if (!value.IsReservedItemSlot(num) && !value.IsReservedItemSlot(ReservedHotbarManager.indexInHotbar))
				{
					num = ReservedHotbarManager.indexInHotbar;
				}
				playersDiscardingItems.Add(playerController);
				((MonoBehaviour)playerController).StartCoroutine(SwitchToItemSlotAfterDelay(playerController, num));
			}
			if ((Object)(object)playerController == (Object)(object)localPlayerController)
			{
				HUDPatcher.UpdateUI();
			}
		}

		private static IEnumerator SwitchToItemSlotAfterDelay(PlayerControllerB playerController, int slot)
		{
			if ((Object)(object)playerController == (Object)(object)localPlayerController)
			{
				yield return (object)new WaitUntil((Func<bool>)(() => (Object)(object)playerController.currentlyHeldObjectServer == (Object)null));
			}
			yield return (object)new WaitForEndOfFrame();
			playersDiscardingItems.Remove(playerController);
			if (playerController.currentItemSlot != slot && ReservedPlayerData.allPlayerData.TryGetValue(playerController, out var playerData))
			{
				playerData.CallSwitchToItemSlot(slot);
			}
		}

		[HarmonyPatch(typeof(PlayerControllerB), "ScrollMouse_performed")]
		[HarmonyPrefix]
		public static bool PreventItemSwappingDroppingItem(CallbackContext context, PlayerControllerB __instance)
		{
			if ((Object)(object)__instance == (Object)(object)localPlayerController && playersDiscardingItems.Contains(__instance))
			{
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch]
	public static class HUDPatcher
	{
		private static bool usingController = false;

		private static float itemSlotWidth;

		private static float itemSlotSpacing;

		private static float xPos;

		private static float defaultItemSlotSpacing;

		private static Vector2 defaultItemSlotSize;

		private static TextMeshProUGUI hotkeyTooltip;

		public static List<Image> reservedItemSlots = new List<Image>();

		public static HashSet<ReservedItemSlotData> toggledReservedItemSlots = new HashSet<ReservedItemSlotData>();

		private static bool lerpToggledItemSlotFrames = false;

		private static float largestPositionDifference = 0f;

		private static bool currentApplyHotbarPlusFormatting;

		private static bool currentHideEmptySlots;

		public static PlayerControllerB localPlayerController => StartOfRound.Instance?.localPlayerController;

		public static ReservedPlayerData localPlayerData => ReservedPlayerData.localPlayerData;

		public static bool localPlayerUsingController => (Object)(object)StartOfRound.Instance != (Object)null && StartOfRound.Instance.localPlayerUsingController;

		public static bool hasReservedItemSlotsAndEnabled => reservedItemSlots != null && reservedItemSlots.Count > 0 && ((Component)reservedItemSlots[0]).gameObject.activeSelf && ((Behaviour)reservedItemSlots[0]).enabled;

		[HarmonyPatch(typeof(HUDManager), "Awake")]
		[HarmonyPostfix]
		public static void Initialize(HUDManager __instance)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			CanvasScaler componentInParent = ((Component)__instance.itemSlotIconFrames[0]).GetComponentInParent<CanvasScaler>();
			AspectRatioFitter componentInParent2 = ((Component)__instance.itemSlotIconFrames[0]).GetComponentInParent<AspectRatioFitter>();
			itemSlotWidth = ((Component)__instance.itemSlotIconFrames[0]).GetComponent<RectTransform>().sizeDelta.x;
			itemSlotSpacing = 1.125f * itemSlotWidth;
			xPos = componentInParent.referenceResolution.x / 2f / componentInParent2.aspectRatio - itemSlotWidth / 4f;
			defaultItemSlotSpacing = itemSlotSpacing;
			defaultItemSlotSize = ((Graphic)__instance.itemSlotIconFrames[0]).rectTransform.sizeDelta;
			reservedItemSlots.Clear();
		}

		[HarmonyPatch(typeof(StartOfRound), "Update")]
		[HarmonyPrefix]
		public static void UpdateUsingController(StartOfRound __instance)
		{
			if (!((Object)(object)__instance.localPlayerController == (Object)null) && !((Object)(object)hotkeyTooltip == (Object)null) && ((Component)hotkeyTooltip).gameObject.activeSelf && ((Behaviour)hotkeyTooltip).enabled)
			{
				if (__instance.localPlayerUsingController != usingController)
				{
					usingController = __instance.localPlayerUsingController;
					UpdateHotkeyTooltipText();
				}
				LerpItemSlotFrames();
			}
		}

		private static void LerpItemSlotFrames()
		{
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			if (!lerpToggledItemSlotFrames)
			{
				return;
			}
			if (largestPositionDifference < 2f && largestPositionDifference != -1f)
			{
				lerpToggledItemSlotFrames = false;
			}
			for (int i = 0; i < SessionManager.numReservedItemSlotsUnlocked; i++)
			{
				ReservedItemSlotData unlockedReservedItemSlot = SessionManager.GetUnlockedReservedItemSlot(i);
				Image val = HUDManager.Instance.itemSlotIconFrames[ReservedPlayerData.localPlayerData.reservedHotbarStartIndex + i];
				bool flag = unlockedReservedItemSlot.slotPriority >= 0 || !ConfigSettings.displayNegativePrioritySlotsLeftSideOfScreen.Value;
				Vector2 anchoredPosition = ((Graphic)val).rectTransform.anchoredPosition;
				anchoredPosition.x = (flag ? xPos : (0f - xPos));
				if (ReservedHotbarManager.isToggledInReservedSlots && ReservedHotbarManager.currentlyToggledItemSlots != null && ReservedHotbarManager.currentlyToggledItemSlots.Contains(unlockedReservedItemSlot))
				{
					anchoredPosition.x += itemSlotWidth / 2f * (float)((!flag) ? 1 : (-1));
				}
				float num = Mathf.Abs(anchoredPosition.x - ((Graphic)val).rectTransform.anchoredPosition.x);
				largestPositionDifference = Mathf.Max(largestPositionDifference, num);
				if (lerpToggledItemSlotFrames)
				{
					((Graphic)val).rectTransform.anchoredPosition = Vector2.Lerp(((Graphic)val).rectTransform.anchoredPosition, anchoredPosition, Time.deltaTime * 10f);
				}
				else
				{
					((Graphic)val).rectTransform.anchoredPosition = anchoredPosition;
				}
			}
		}

		public static void OnUpdateReservedItemSlots()
		{
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			if (reservedItemSlots == null || SessionManager.numReservedItemSlotsUnlocked <= 0 || reservedItemSlots.Count == SessionManager.numReservedItemSlotsUnlocked)
			{
				return;
			}
			List<Image> list = new List<Image>(HUDManager.Instance.itemSlotIconFrames);
			List<Image> list2 = new List<Image>(HUDManager.Instance.itemSlotIcons);
			for (int i = reservedItemSlots.Count; i < SessionManager.numReservedItemSlotsUnlocked; i++)
			{
				GameObject val = Object.Instantiate<GameObject>(((Component)list[0]).gameObject, ((Component)list[0]).transform.parent);
				Image component = val.GetComponent<Image>();
				Image component2 = ((Component)((Component)component).transform.GetChild(0)).GetComponent<Image>();
				((Component)component).transform.localScale = ((Component)list[0]).transform.localScale;
				((Transform)((Graphic)component).rectTransform).eulerAngles = ((Transform)((Graphic)list[0]).rectTransform).eulerAngles;
				((Transform)((Graphic)component2).rectTransform).eulerAngles = ((Transform)((Graphic)list2[0]).rectTransform).eulerAngles;
				CanvasGroup val2 = ((Component)component).gameObject.AddComponent<CanvasGroup>();
				val2.ignoreParentGroups = ConfigSettings.preventReservedItemSlotFade.Value;
				val2.alpha = 1f;
				component.fillMethod = list[0].fillMethod;
				component.sprite = list[0].sprite;
				((Graphic)component).material = ((Graphic)list[0]).material;
				if (Plugin.IsModLoaded("xuxiaolan.hotbarrd"))
				{
					component.overrideSprite = list[0].overrideSprite;
				}
				int index = ReservedPlayerData.localPlayerData.reservedHotbarStartIndex + reservedItemSlots.Count;
				list.Insert(index, component);
				list2.Insert(index, component2);
				reservedItemSlots.Add(component);
			}
			HUDManager.Instance.itemSlotIconFrames = list.ToArray();
			HUDManager.Instance.itemSlotIcons = list2.ToArray();
			UpdateUI();
		}

		public static void UpdateUI()
		{
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_0312: Unknown result type (might be due to invalid IL or missing references)
			//IL_0414: Unknown result type (might be due to invalid IL or missing references)
			//IL_0348: Unknown result type (might be due to invalid IL or missing references)
			//IL_0366: Unknown result type (might be due to invalid IL or missing references)
			//IL_037b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0388: Unknown result type (might be due to invalid IL or missing references)
			//IL_0392: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c2: 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_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_0256: Unknown result type (might be due to invalid IL or missing references)
			if (reservedItemSlots.Count != SessionManager.numReservedItemSlotsUnlocked)
			{
				Plugin.LogError("Called UpdateUI with mismatched unlocked reserved item slots and reserved item slot hud elements.");
				return;
			}
			int num = 0;
			int num2 = 0;
			Transform val = null;
			Vector2 anchoredPosition = default(Vector2);
			for (int i = 0; i < SessionManager.numReservedItemSlotsUnlocked; i++)
			{
				ReservedItemSlotData unlockedReservedItemSlot = SessionManager.GetUnlockedReservedItemSlot(i);
				int num3 = Array.IndexOf(HUDManager.Instance.itemSlotIconFrames, reservedItemSlots[i]);
				Image val2 = HUDManager.Instance.itemSlotIconFrames[ReservedPlayerData.localPlayerData.reservedHotbarStartIndex + i];
				Image val3 = HUDManager.Instance.itemSlotIcons[ReservedPlayerData.localPlayerData.reservedHotbarStartIndex + i];
				float currentItemSlotSpacing = GetCurrentItemSlotSpacing();
				if (HotbarPlus_Compat.Enabled && !ConfigSettings.applyHotbarPlusFormatting.Value)
				{
					((Graphic)val2).rectTransform.sizeDelta = defaultItemSlotSize;
					currentItemSlotSpacing = defaultItemSlotSpacing;
				}
				GrabbableObject reservedItem = ReservedPlayerData.localPlayerData.GetReservedItem(unlockedReservedItemSlot);
				((Object)val2).name = "Slot" + i + " [ReservedItemSlot] (" + unlockedReservedItemSlot.slotName + ")";
				((Vector2)(ref anchoredPosition))..ctor(xPos, ((Graphic)HUDManager.Instance.itemSlotIconFrames[0]).rectTransform.anchoredPosition.y);
				if (unlockedReservedItemSlot.slotPriority >= 0 || !ConfigSettings.displayNegativePrioritySlotsLeftSideOfScreen.Value)
				{
					anchoredPosition.x = xPos;
					anchoredPosition.y = ((Graphic)HUDManager.Instance.itemSlotIconFrames[0]).rectTransform.anchoredPosition.y + currentItemSlotSpacing * (float)num;
					if (!ConfigSettings.hideEmptyReservedItemSlots.Value || (Object)(object)reservedItem != (Object)null)
					{
						if (!Object.op_Implicit((Object)(object)val))
						{
							val = ((Component)val2).transform;
						}
						num++;
					}
					else
					{
						anchoredPosition.y = -1000f;
					}
				}
				else
				{
					anchoredPosition.x = 0f - xPos;
					anchoredPosition.y = ((Graphic)HUDManager.Instance.itemSlotIconFrames[0]).rectTransform.anchoredPosition.y + currentItemSlotSpacing * (float)num2;
					if (!ConfigSettings.hideEmptyReservedItemSlots.Value || (Object)(object)reservedItem != (Object)null)
					{
						num2++;
					}
					else
					{
						anchoredPosition.y = -1000f;
					}
				}
				((Graphic)val2).rectTransform.anchoredPosition = anchoredPosition;
				if ((Object)(object)reservedItem != (Object)null)
				{
					((Behaviour)val3).enabled = true;
					val3.sprite = reservedItem.itemProperties.itemIcon;
				}
				else
				{
					((Behaviour)val3).enabled = false;
					val3.sprite = null;
				}
			}
			if (SessionManager.numReservedItemSlotsUnlocked > 0 && !ConfigSettings.hideFocusHotbarTooltip.Value)
			{
				if ((Object)(object)hotkeyTooltip == (Object)null)
				{
					hotkeyTooltip = new GameObject("ReservedItemSlotTooltip", new Type[2]
					{
						typeof(RectTransform),
						typeof(TextMeshProUGUI)
					}).GetComponent<TextMeshProUGUI>();
				}
				RectTransform rectTransform = ((TMP_Text)hotkeyTooltip).rectTransform;
				((Transform)rectTransform).parent = val;
				if (Object.op_Implicit((Object)(object)val))
				{
					((Transform)rectTransform).localScale = Vector3.one;
					rectTransform.sizeDelta = new Vector2(((Graphic)HUDManager.Instance.itemSlotIconFrames[0]).rectTransform.sizeDelta.x * 2f, 10f);
					rectTransform.pivot = Vector2.one / 2f;
					rectTransform.anchoredPosition3D = new Vector3(0f, (0f - rectTransform.sizeDelta.x / 2f) * 1.2f, 0f);
					((TMP_Text)hotkeyTooltip).font = ((TMP_Text)HUDManager.Instance.controlTipLines[0]).font;
					((TMP_Text)hotkeyTooltip).fontSize = 7f;
					((TMP_Text)hotkeyTooltip).alignment = (TextAlignmentOptions)514;
					UpdateHotkeyTooltipText();
				}
				else
				{
					((Transform)rectTransform).localScale = Vector3.zero;
				}
			}
			currentApplyHotbarPlusFormatting = ConfigSettings.applyHotbarPlusFormatting.Value;
			currentHideEmptySlots = ConfigSettings.hideEmptyReservedItemSlots.Value;
		}

		public static void UpdateHotkeyTooltipText()
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)localPlayerController == (Object)null) && !((Object)(object)hotkeyTooltip == (Object)null) && Keybinds.FocusReservedHotbarAction != null && !Plugin.IsModLoaded("com.potatoepet.AdvancedCompany"))
			{
				int num = (localPlayerUsingController ? 1 : 0);
				InputBinding val = Keybinds.FocusReservedHotbarAction.bindings[num];
				string keybindDisplayName = KeybindDisplayNames.GetKeybindDisplayName(((InputBinding)(ref val)).effectivePath);
				((TMP_Text)hotkeyTooltip).text = (ConfigSettings.toggleFocusReservedHotbar.Value ? $"Toggle: [{keybindDisplayName}]" : $"Hold: [{keybindDisplayName}]");
			}
		}

		public static void UpdateToggledReservedItemSlotsUI()
		{
			if (ReservedHotbarManager.currentlyToggledItemSlots != null)
			{
				toggledReservedItemSlots = new HashSet<ReservedItemSlotData>(ReservedHotbarManager.currentlyToggledItemSlots);
			}
			else
			{
				toggledReservedItemSlots.Clear();
			}
			lerpToggledItemSlotFrames = true;
			largestPositionDifference = -1f;
		}

		private static float GetCurrentItemSlotSpacing()
		{
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				Image val = HUDManager.Instance.itemSlotIconFrames[0];
				Image val2 = HUDManager.Instance.itemSlotIconFrames[1];
				if (((Object)val).name.ToLower().Contains("reserved") || ((Object)val2).name.ToLower().Contains("reserved"))
				{
					return defaultItemSlotSpacing;
				}
				return Mathf.Abs(((Graphic)val2).rectTransform.anchoredPosition.x - ((Graphic)val).rectTransform.anchoredPosition.x);
			}
			catch
			{
			}
			return defaultItemSlotSpacing;
		}

		[HarmonyPatch(typeof(QuickMenuManager), "CloseQuickMenu")]
		[HarmonyPostfix]
		public static void OnCloseQuickMenu()
		{
			if ((HotbarPlus_Compat.Enabled && currentApplyHotbarPlusFormatting != ConfigSettings.applyHotbarPlusFormatting.Value) || currentHideEmptySlots != ConfigSettings.hideEmptyReservedItemSlots.Value)
			{
				UpdateUI();
			}
		}
	}
	[HarmonyPatch]
	internal class MaskedEnemyPatcher
	{
		[HarmonyPatch(typeof(MaskedPlayerEnemy), "Awake")]
		[HarmonyPrefix]
		public static void InitMaskedEnemy(MaskedPlayerEnemy __instance)
		{
			if (ConfigSettings.showReservedItemsHolsteredMaskedEnemy.Value && !MaskedEnemyData.allMaskedEnemyData.ContainsKey(__instance))
			{
				MaskedEnemyData.allMaskedEnemyData.Add(__instance, new MaskedEnemyData(__instance));
			}
		}

		[HarmonyPatch(typeof(MaskedPlayerEnemy), "OnDestroy")]
		[HarmonyPrefix]
		public static void OnDestroy(MaskedPlayerEnemy __instance)
		{
			if (MaskedEnemyData.allMaskedEnemyData.TryGetValue(__instance, out var value))
			{
				value.DestroyEquippedItems();
				MaskedEnemyData.allMaskedEnemyData.Remove(__instance);
			}
		}

		[HarmonyPatch(typeof(MaskedPlayerEnemy), "Update")]
		[HarmonyPostfix]
		public static void Update(MaskedPlayerEnemy __instance)
		{
			if (ConfigSettings.showReservedItemsHolsteredMaskedEnemy.Value && MaskedEnemyData.allMaskedEnemyData.TryGetValue(__instance, out var value) && (Object)(object)value.originallyMimickingPlayer == (Object)null && (Object)(object)value.maskedEnemy.mimickingPlayer != (Object)null)
			{
				AddReservedItemsToMaskedEnemy(__instance);
			}
		}

		public static void AddReservedItemsToMaskedEnemy(MaskedPlayerEnemy maskedEnemy)
		{
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			if (!ConfigSettings.showReservedItemsHolsteredMaskedEnemy.Value || !MaskedEnemyData.allMaskedEnemyData.TryGetValue(maskedEnemy, out var value))
			{
				return;
			}
			value.originallyMimickingPlayer = value.maskedEnemy.mimickingPlayer;
			if (!ReservedPlayerData.allPlayerData.TryGetValue(value.originallyMimickingPlayer, out var value2))
			{
				Plugin.LogWarning("Failed to mimic player's equipped reserved items. Could not retrieve player data from: " + value.originallyMimickingPlayer.playerUsername);
				return;
			}
			for (int i = value2.reservedHotbarStartIndex; i < value2.reservedHotbarEndIndexExcluded; i++)
			{
				GrabbableObject val = value2.playerController.ItemSlots[i];
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				int index = i - value2.reservedHotbarStartIndex;
				ReservedItemSlotData reservedItemSlotData = SessionManager.unlockedReservedItemSlots[index];
				ReservedItemData reservedItemData = reservedItemSlotData.GetReservedItemData(val);
				if (reservedItemData.holsteredParentBone == PlayerBone.None)
				{
					continue;
				}
				Transform bone = value.boneMap.GetBone(reservedItemData.holsteredParentBone);
				if ((Object)(object)bone == (Object)null)
				{
					Plugin.LogWarning("Failed to get bone from masked enemy: " + reservedItemData.holsteredParentBone);
					continue;
				}
				GameObject val2 = Object.Instantiate<GameObject>(((Component)val).gameObject, bone);
				val2.transform.localEulerAngles = reservedItemData.holsteredRotationOffset;
				val2.transform.localPosition = reservedItemData.holsteredPositionOffset;
				val2.transform.localScale = ((Component)val).transform.localScale;
				val2.layer = 6;
				MeshRenderer[] componentsInChildren = val2.GetComponentsInChildren<MeshRenderer>();
				foreach (MeshRenderer val3 in componentsInChildren)
				{
					if (!((Object)val3).name.Contains("ScanNode") && !((Component)val3).gameObject.CompareTag("DoNotSet") && !((Component)val3).gameObject.CompareTag("InteractTrigger"))
					{
						((Component)val3).gameObject.layer = 6;
					}
				}
				if (val is FlashlightItem)
				{
					Light[] componentsInChildren2 = val2.GetComponentsInChildren<Light>();
					foreach (Light val4 in componentsInChildren2)
					{
						((Behaviour)val4).enabled = false;
					}
				}
				else
				{
					Light[] componentsInChildren3 = val2.GetComponentsInChildren<Light>();
					foreach (Light val5 in componentsInChildren3)
					{
						((Behaviour)val5).enabled = true;
					}
				}
				GrabbableObject componentInChildren = val2.GetComponentInChildren<GrabbableObject>();
				if ((Object)(object)componentInChildren != (Object)null)
				{
					componentInChildren.playerHeldBy = null;
					FlashlightItem val6 = (FlashlightItem)(object)((componentInChildren is FlashlightItem) ? componentInChildren : null);
					if ((Object)(object)val6 != (Object)null)
					{
						((Behaviour)val6.flashlightBulb).enabled = true;
						((Behaviour)val6.flashlightBulbGlow).enabled = true;
						((Renderer)val6.flashlightMesh).sharedMaterials[1] = val6.bulbLight;
					}
					ReservedItemsPatcher.ForceEnableItemMesh(componentInChildren, enabled: true);
					componentInChildren.EnablePhysics(false);
				}
				Object.DestroyImmediate((Object)(object)val2.GetComponentInChildren<NetworkObject>());
				Collider[] componentsInChildren4 = val2.GetComponentsInChildren<Collider>();
				foreach (Collider val7 in componentsInChildren4)
				{
					Object.DestroyImmediate((Object)(object)val7);
				}
				MonoBehaviour[] componentsInChildren5 = val2.GetComponentsInChildren<MonoBehaviour>();
				foreach (MonoBehaviour val8 in componentsInChildren5)
				{
					Object.DestroyImmediate((Object)(object)val8);
				}
			}
		}
	}
	[HarmonyPatch]
	internal static class MouseScrollPatcher
	{
		private static bool scrollingItemSlots;

		public static PlayerControllerB localPlayerController => StartOfRound.Instance?.localPlayerController;

		[HarmonyPatch(typeof(PlayerControllerB), "NextItemSlot")]
		[HarmonyPrefix]
		public static void CorrectReservedScrollDirectionNextItemSlot(ref bool forward)
		{
			if (Keybinds.scrollingReservedHotbar)
			{
				forward = Keybinds.RawScrollAction.ReadValue<float>() > 0f;
			}
		}

		[HarmonyPatch(typeof(PlayerControllerB), "SwitchItemSlotsServerRpc")]
		[HarmonyPrefix]
		public static void CorrectReservedScrollDirectionServerRpc(ref bool forward)
		{
			if (Keybinds.scrollingReservedHotbar)
			{
				forward = Keybinds.RawScrollAction.ReadValue<float>() > 0f;
			}
		}

		[HarmonyPatch(typeof(PlayerControllerB), "ScrollMouse_performed")]
		[HarmonyPrefix]
		public static bool PreventInvertedScrollingReservedHotbar(CallbackContext context)
		{
			if (StartOfRound.Instance.localPlayerUsingController || SessionManager.numReservedItemSlotsUnlocked <= 0 || HUDPatcher.reservedItemSlots == null || localPlayerController.inTerminalMenu)
			{
				return true;
			}
			if (ReservedPlayerData.localPlayerData.currentItemSlotIsReserved)
			{
				if (!HUDPatcher.hasReservedItemSlotsAndEnabled)
				{
					return true;
				}
				if (!Keybinds.scrollingReservedHotbar || (ReservedPlayerData.localPlayerData.GetNumHeldReservedItems() == 1 && (Object)(object)ReservedPlayerData.localPlayerData.currentlySelectedItem != (Object)null && !ReservedHotbarManager.isToggledInReservedSlots))
				{
					return false;
				}
			}
			return true;
		}

		[HarmonyPatch(typeof(PlayerControllerB), "ScrollMouse_performed")]
		[HarmonyPostfix]
		public static void ScrollReservedItemSlots(CallbackContext context)
		{
			scrollingItemSlots = false;
		}
	}
	[HarmonyPatch]
	internal static class PlayerPatcher
	{
		private static int INTERACTABLE_OBJECT_MASK = 0;

		public static int vanillaHotbarSize = 4;

		private static bool initialized = false;

		public static PlayerControllerB localPlayerController => StartOfRound.Instance?.localPlayerController;

		public static Dictionary<PlayerControllerB, ReservedPlayerData> allPlayerData => ReservedPlayerData.allPlayerData;

		public static ReservedPlayerData localPlayerData => ReservedPlayerData.localPlayerData;

		public static int reservedHotbarSize => SessionManager.numReservedItemSlotsUnlocked;

		[HarmonyPatch(typeof(StartOfRound), "Awake")]
		[HarmonyPrefix]
		public static void InitSession(StartOfRound __instance)
		{
			initialized = false;
			vanillaHotbarSize = 4;
			ReservedPlayerData.allPlayerData?.Clear();
		}

		[HarmonyPatch(typeof(PlayerControllerB), "Awake")]
		[HarmonyPostfix]
		public static void InitializePlayerController(PlayerControllerB __instance)
		{
			if (!initialized)
			{
				vanillaHotbarSize = __instance.ItemSlots.Length;
				INTERACTABLE_OBJECT_MASK = (int)Traverse.Create((object)__instance).Field("interactableObjectsMask").GetValue();
				initialized = true;
			}
		}

		[HarmonyPatch(typeof(PlayerControllerB), "Start")]
		[HarmonyPrefix]
		public static void InitializePlayerControllerLate(PlayerControllerB __instance)
		{
			ReservedPlayerData value = new ReservedPlayerData(__instance);
			if (!allPlayerData.ContainsKey(__instance))
			{
				Plugin.Log("Initializing ReservedPlayerData for player: " + ((Object)__instance).name);
				allPlayerData.Add(__instance, value);
			}
		}

		[HarmonyPatch(typeof(PlayerControllerB), "LateUpdate")]
		[HarmonyPostfix]
		public static void CheckForChangedInventorySize(PlayerControllerB __instance)
		{
			if (!SyncManager.isSynced || !ReservedPlayerData.allPlayerData.TryGetValue(__instance, out var value) || !SyncManager.canUseModDisabledOnHost || (Object)(object)__instance != (Object)(object)localPlayerController || reservedHotbarSize <= 0 || value.hotbarSize == __instance.ItemSlots.Length)
			{
				return;
			}
			Plugin.LogWarning("On update inventory size for player: " + ((Object)__instance).name + " - Old hotbar size: " + value.hotbarSize + " - New hotbar size: " + __instance.ItemSlots.Length);
			value.hotbarSize = __instance.ItemSlots.Length;
			int num = -1;
			if ((Object)(object)__instance == (Object)(object)localPlayerController)
			{
				if (HUDPatcher.reservedItemSlots != null && HUDPatcher.reservedItemSlots.Count > 0)
				{
					num = Array.IndexOf(HUDManager.Instance.itemSlotIconFrames, HUDPatcher.reservedItemSlots[0]);
					Plugin.Log("OnUpdateInventorySize A for local player: " + ((Object)__instance).name + " NewReservedItemsStartIndex: " + num);
				}
				if (num == -1)
				{
					for (int i = 0; i < HUDManager.Instance.itemSlotIconFrames.Length; i++)
					{
						if (((Object)HUDManager.Instance.itemSlotIconFrames[i]).name.ToLower().Contains("reserved"))
						{
							num = i;
							Plugin.Log("OnUpdateInventorySize B for local player: " + ((Object)__instance).name + " NewReservedItemsStartIndex: " + num);
							break;
						}
					}
				}
			}
			if (num == -1)
			{
				num = value.reservedHotbarStartIndex;
				Plugin.Log("OnUpdateInventorySize C for player: " + ((Object)__instance).name + " NewReservedItemsStartIndex: " + num);
			}
			if (num == -1)
			{
				num = vanillaHotbarSize;
				Plugin.Log("OnUpdateInventorySize D for player: " + ((Object)__instance).name + " NewReservedItemsStartIndex: " + num);
			}
			value.reservedHotbarStartIndex = num;
			if (value.reservedHotbarStartIndex < 0)
			{
				Plugin.LogError("Set new reserved start index to slot: " + value.reservedHotbarStartIndex + ". Maybe share these logs with Flip? :)");
			}
			if (value.reservedHotbarEndIndexExcluded - 1 >= value.playerController.ItemSlots.Length)
			{
				Plugin.LogError("Set new reserved start index to slot: " + value.reservedHotbarStartIndex + " Last reserved slot index: " + (value.reservedHotbarEndIndexExcluded - 1) + " Inventory size: " + value.playerController.ItemSlots.Length + ". Maybe share these logs with Flip? :)");
			}
			if (value.isLocalPlayer)
			{
				HUDPatcher.UpdateUI();
			}
		}

		[HarmonyPatch(typeof(PlayerControllerB), "BeginGrabObject")]
		[HarmonyPrefix]
		public static bool BeginGrabReservedItemPrefix(PlayerControllerB __instance)
		{
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			if ((!SyncManager.isSynced && !SyncManager.canUseModDisabledOnHost) || !HUDPatcher.hasReservedItemSlotsAndEnabled)
			{
				return true;
			}
			localPlayerData.grabbingReservedItemSlotData = null;
			localPlayerData.grabbingReservedItemData = null;
			localPlayerData.grabbingReservedItem = null;
			localPlayerData.previousHotbarIndex = -1;
			if (__instance.twoHanded || __instance.sinkingValue > 0.73f)
			{
				return true;
			}
			Ray val = default(Ray);
			((Ray)(ref val))..ctor(((Component)__instance.gameplayCamera).transform.position, ((Component)__instance.gameplayCamera).transform.forward);
			RaycastHit val2 = default(RaycastHit);
			if (Physics.Raycast(val, ref val2, __instance.grabDistance, INTERACTABLE_OBJECT_MASK) && ((Component)((RaycastHit)(ref val2)).collider).gameObject.layer != 8 && ((Component)((RaycastHit)(ref val2)).collider).tag == "PhysicsProp")
			{
				GrabbableObject component = ((Component)((Component)((RaycastHit)(ref val2)).collider).transform).gameObject.GetComponent<GrabbableObject>();
				if ((Object)(object)component != (Object)null && !__instance.inSpecialInteractAnimation && !component.isHeld && !component.isPocketed)
				{
					NetworkObject networkObject = ((NetworkBehaviour)component).NetworkObject;
					if ((Object)(object)networkObject != (Object)null && networkObject.IsSpawned && SessionManager.TryGetUnlockedItemData(component, out var itemData))
					{
						localPlayerData.grabbingReservedItemData = itemData;
						localPlayerData.grabbingReservedItem = component;
						localPlayerData.previousHotbarIndex = Mathf.Clamp(__instance.currentItemSlot, 0, __instance.ItemSlots.Length - 1);
						Plugin.Log("Beginning grab on reserved item: " + itemData.itemName + " Previous item slot: " + localPlayerData.previousHotbarIndex);
					}
				}
			}
			return true;
		}

		[HarmonyPatch(typeof(PlayerControllerB), "BeginGrabObject")]
		[HarmonyPostfix]
		public static void BeginGrabReservedItemPostfix(PlayerControllerB __instance)
		{
			if (localPlayerData != null && localPlayerData.isGrabbingReservedItem && !localPlayerData.IsReservedItemSlot(localPlayerData.previousHotbarIndex))
			{
				SetSpecialGrabAnimationBool(__instance, setTrue: false);
				SetSpecialGrabAnimationBool(__instance, (Object)(object)localPlayerData.previouslyHeldItem != (Object)null, localPlayerData.previouslyHeldItem);
				__instance.playerBodyAnimator.SetBool("GrabValidated", true);
				__instance.playerBodyAnimator.SetBool("GrabInvalidated", false);
				__instance.playerBodyAnimator.ResetTrigger("SwitchHoldAnimation");
				__instance.playerBodyAnimator.ResetTrigger("SwitchHoldAnimationTwoHanded");
				if ((Object)(object)localPlayerData.previouslyHeldItem != (Object)null)
				{
					__instance.playerBodyAnimator.ResetTrigger(localPlayerData.previouslyHeldItem.itemProperties.pocketAnim);
				}
				__instance.twoHanded = (Object)(object)localPlayerData.previouslyHeldItem != (Object)null && localPlayerData.previouslyHeldItem.itemProperties.twoHanded;
				__instance.twoHandedAnimation = (Object)(object)localPlayerData.previouslyHeldItem != (Object)null && localPlayerData.previouslyHeldItem.itemProperties.twoHandedAnimation;
			}
		}

		[HarmonyPatch(typeof(PlayerControllerB), "GrabObjectClientRpc")]
		[HarmonyPrefix]
		public static void GrabReservedItemClientRpcPrefix(bool grabValidated, NetworkObjectReference grabbedObject, PlayerControllerB __instance)
		{
			if ((!SyncManager.isSynced && !SyncManager.canUseModDisabledOnHost) || !NetworkHelper.IsClientExecStage((NetworkBehaviour)(object)__instance) || !ReservedPlayerData.allPlayerData.TryGetValue(__instance, out var value))
			{
				return;
			}
			NetworkObject val = default(NetworkObject);
			GrabbableObject val2 = default(GrabbableObject);
			if ((Object)(object)NetworkManager.Singleton != (Object)null && NetworkManager.Singleton.IsListening && grabValidated && ((NetworkObjectReference)(ref grabbedObject)).TryGet(ref val, (NetworkManager)null) && ((Component)val).TryGetComponent<GrabbableObject>(ref val2) && SessionManager.TryGetUnlockedItemData(val2, out var itemData))
			{
				ReservedItemSlotData firstEmptySlotForReservedItem = value.GetFirstEmptySlotForReservedItem(itemData.itemName);
				if (firstEmptySlotForReservedItem != null)
				{
					value.grabbingReservedItemSlotData = firstEmptySlotForReservedItem;
					value.grabbingReservedItemData = itemData;
					value.grabbingReservedItem = val2;
					value.previousHotbarIndex = Mathf.Clamp(__instance.currentItemSlot, 0, __instance.ItemSlots.Length - 1);
					return;
				}
			}
			value.grabbingReservedItemSlotData = null;
			value.grabbingReservedItemData = null;
			value.grabbingReservedItem = null;
			value.previousHotbarIndex = -1;
		}

		[HarmonyPatch(typeof(PlayerControllerB), "GrabObjectClientRpc")]
		[HarmonyPostfix]
		public static void GrabReservedItemClientRpcPostfix(bool grabValidated, NetworkObjectReference grabbedObject, PlayerControllerB __instance)
		{
			if ((!SyncManager.isSynced && !SyncManager.canUseModDisabledOnHost) || !NetworkHelper.IsClientExecStage((NetworkBehaviour)(object)__instance) || !ReservedPlayerData.allPlayerData.TryGetValue(__instance, out var value) || !value.isGrabbingReservedItem)
			{
				return;
			}
			if ((Object)(object)NetworkManager.Singleton != (Object)null && NetworkManager.Singleton.IsListening)
			{
				NetworkObject val = default(NetworkObject);
				GrabbableObject val2 = default(GrabbableObject);
				if (grabValidated && ((NetworkObjectReference)(ref grabbedObject)).TryGet(ref val, (NetworkManager)null) && ((Component)val).TryGetComponent<GrabbableObject>(ref val2))
				{
					if (SessionManager.TryGetUnlockedItemData(val2, out var itemData))
					{
						if (!value.IsReservedItemSlot(value.previousHotbarIndex))
						{
							if ((Object)(object)value.previouslyHeldItem != (Object)null)
							{
								value.previouslyHeldItem.EnableItemMeshes(true);
							}
							ReservedItemsPatcher.ForceEnableItemMesh(value.grabbingReservedItem, enabled: false);
							Traverse.Create((object)val2).Field("previousPlayerHeldBy").SetValue((object)__instance);
							if (value.isLocalPlayer)
							{
								int num = value.reservedHotbarStartIndex + value.grabbingReservedItemSlotData.GetReservedItemSlotIndex();
								((Component)HUDManager.Instance.itemSlotIconFrames[num]).GetComponent<Animator>().SetBool("selectedSlot", false);
								((Component)HUDManager.Instance.itemSlotIconFrames[value.previousHotbarIndex]).GetComponent<Animator>().SetBool("selectedSlot", true);
								((Component)HUDManager.Instance.itemSlotIconFrames[num]).GetComponent<Animator>().Play("PanelLines", 0, 1f);
								((Component)HUDManager.Instance.itemSlotIconFrames[value.previousHotbarIndex]).GetComponent<Animator>().Play("PanelEnlarge", 0, 1f);
							}
							else
							{
								SwitchToItemSlot(__instance, value.previousHotbarIndex);
								if (itemData.showOnPlayerWhileHolstered)
								{
									val2.EnableItemMeshes(true);
								}
							}
							SetSpecialGrabAnimationBool(__instance, setTrue: false);
							SetSpecialGrabAnimationBool(__instance, (Object)(object)value.previouslyHeldItem != (Object)null, value.previouslyHeldItem);
							__instance.playerBodyAnimator.SetBool("GrabValidated", true);
							__instance.playerBodyAnimator.SetBool("GrabInvalidated", false);
							__instance.playerBodyAnimator.ResetTrigger("SwitchHoldAnimation");
							__instance.playerBodyAnimator.ResetTrigger("SwitchHoldAnimationTwoHanded");
							if ((Object)(object)value.previouslyHeldItem != (Object)null)
							{
								__instance.playerBodyAnimator.ResetTrigger(value.previouslyHeldItem.itemProperties.pocketAnim);
							}
							__instance.twoHanded = (Object)(object)value.previouslyHeldItem != (Object)null && value.previouslyHeldItem.itemProperties.twoHanded;
							__instance.twoHandedAnimation = (Object)(object)value.previouslyHeldItem != (Object)null && value.previouslyHeldItem.itemProperties.twoHandedAnimation;
						}
						if (value.isLocalPlayer)
						{
							HUDPatcher.UpdateUI();
							return;
						}
						value.grabbingReservedItemSlotData = null;
						value.grabbingReservedItemData = null;
						value.grabbingReservedItem = null;
						value.previousHotbarIndex = -1;
						return;
					}
				}
				else if (value.isLocalPlayer)
				{
					Plugin.LogWarning("Failed to validate ReservedItemGrab by the local player. Object id: " + ((NetworkObjectReference)(ref grabbedObject)).NetworkObjectId + ". Internal error?");
					Traverse.Create((object)localPlayerController).Field("grabInvalidated").SetValue((object)true);
				}
				else
				{
					Plugin.LogWarning("Failed to validate ReservedItemGrab by player with id: " + ((Object)__instance).name + ". Object id: " + ((NetworkObjectReference)(ref grabbedObject)).NetworkObjectId + ". Internal error?");
				}
			}
			value.grabbingReservedItemSlotData = null;
			value.grabbingReservedItemData = null;
			value.grabbingReservedItem = null;
			value.previousHotbarIndex = -1;
		}

		[HarmonyPatch(typeof(GrabbableObject), "GrabItemOnClient")]
		[HarmonyPrefix]
		public static void OnReservedItemGrabbed(GrabbableObject __instance)
		{
			if (localPlayerData.grabbingReservedItemData != null && (Object)(object)__instance == (Object)(object)GetCurrentlyGrabbingObject(localPlayerController))
			{
				((MonoBehaviour)localPlayerController).StartCoroutine(OnReservedItemGrabbedEndOfFrame());
			}
			IEnumerator OnReservedItemGrabbedEndOfFrame()
			{
				yield return (object)new WaitForEndOfFrame();
				if (localPlayerData.isGrabbingReservedItem)
				{
					if (localPlayerData.previousHotbarIndex < 0 || localPlayerData.previousHotbarIndex >= localPlayerController.ItemSlots.Length || localPlayerData.IsReservedItemSlot(localPlayerData.previousHotbarIndex))
					{
						localPlayerData.previousHotbarIndex = 0;
					}
					SwitchToItemSlot(localPlayerController, localPlayerData.previousHotbarIndex);
					GrabbableObject obj = __instance;
					if (obj != null)
					{
						obj.PocketItem();
					}
					SetSpecialGrabAnimationBool(localPlayerController, setTrue: false);
					SetSpecialGrabAnimationBool(localPlayerController, (Object)(object)localPlayerData.previouslyHeldItem != (Object)null, localPlayerData.previouslyHeldItem);
					localPlayerController.playerBodyAnimator.SetBool("GrabValidated", true);
					localPlayerController.playerBodyAnimator.SetBool("GrabInvalidated", false);
					localPlayerController.playerBodyAnimator.ResetTrigger("SwitchHoldAnimation");
					localPlayerController.isGrabbingObjectAnimation = false;
					localPlayerController.playerBodyAnimator.ResetTrigger("SwitchHoldAnimationTwoHanded");
					if ((Object)(object)localPlayerData.previouslyHeldItem != (Object)null)
					{
						localPlayerController.playerBodyAnimator.ResetTrigger(localPlayerData.previouslyHeldItem.itemProperties.pocketAnim);
					}
					localPlayerController.twoHanded = (Object)(object)localPlayerData.previouslyHeldItem != (Object)null && localPlayerData.previouslyHeldItem.itemProperties.twoHanded;
					localPlayerController.twoHandedAnimation = (Object)(object)localPlayerData.previouslyHeldItem != (Object)null && localPlayerData.previouslyHeldItem.itemProperties.twoHandedAnimation;
				}
				localPlayerData.grabbingReservedItemSlotData = null;
				localPlayerData.grabbingReservedItemData = null;
				localPlayerData.grabbingReservedItem = null;
				localPlayerData.previousHotbarIndex = -1;
			}
		}

		[HarmonyPatch(typeof(PlayerControllerB), "SwitchToItemSlot")]
		[HarmonyPrefix]
		private static void UpdateLastSelectedHotbarIndex(int slot, PlayerControllerB __instance)
		{
			int currentItemSlot = __instance.currentItemSlot;
			if (ReservedPlayerData.allPlayerData.TryGetValue(__instance, out var value))
			{
				if (value.IsReservedItemSlot(currentItemSlot))
				{
					ReservedHotbarManager.indexInReservedHotbar = currentItemSlot;
				}
				else
				{
					ReservedHotbarManager.indexInHotbar = currentItemSlot;
				}
			}
		}

		[HarmonyPatch(typeof(PlayerControllerB), "SwitchToItemSlot")]
		[HarmonyPostfix]
		private static void UpdateFocusReservedHotbar(int slot, PlayerControllerB __instance)
		{
			if (HUDPatcher.hasReservedItemSlotsAndEnabled && ReservedPlayerData.allPlayerData.TryGetValue(__instance, out var value))
			{
				bool inReservedHotbarSlots = value.inReservedHotbarSlots;
				value.inReservedHotbarSlots = value.IsReservedItemSlot(__instance.currentItemSlot);
				bool flag = false;
				if (inReservedHotbarSlots != value.inReservedHotbarSlots || (value.inReservedHotbarSlots && ReservedHotbarManager.isToggledInReservedSlots && ReservedHotbarManager.currentlyToggledItemSlots != null && !ReservedHotbarManager.currentlyToggledItemSlots.Contains(value.GetCurrentlySelectedReservedItemSlot())))
				{
					flag = true;
				}
				if (value.inReservedHotbarSlots)
				{
					ReservedHotbarManager.OnSwapToReservedHotbar();
				}
				else
				{
					ReservedHotbarManager.OnSwapToVanillaHotbar();
				}
				if (flag)
				{
					HUDPatcher.UpdateToggledReservedItemSlotsUI();
				}
			}
		}

		[HarmonyPatch(typeof(PlayerControllerB), "FirstEmptyItemSlot")]
		[HarmonyPostfix]
		private static void GetReservedItemSlotPlacementIndex(ref int __result, PlayerControllerB __instance)
		{
			if (reservedHotbarSize <= 0 || !HUDPatcher.hasReservedItemSlotsAndEnabled || !ReservedPlayerData.allPlayerData.TryGetValue(__instance, out var value))
			{
				return;
			}
			ReservedItemData grabbingReservedItemData = value.grabbingReservedItemData;
			if (grabbingReservedItemData != null)
			{
				ReservedItemSlotData firstEmptySlotForReservedItem = value.GetFirstEmptySlotForReservedItem(grabbingReservedItemData.itemName);
				if (firstEmptySlotForReservedItem != null)
				{
					__result = firstEmptySlotForReservedItem.GetIndexInInventory(__instance);
					return;
				}
				value.grabbingReservedItemSlotData = null;
				value.grabbingReservedItemData = null;
				value.grabbingReservedItem = null;
				value.previousHotbarIndex = -1;
			}
			if (!value.IsReservedItemSlot(__result))
			{
				return;
			}
			__result = -1;
			for (int i = 0; i < __instance.ItemSlots.Length; i++)
			{
				if (!value.IsReservedItemSlot(i) && (Object)(object)__instance.ItemSlots[i] == (Object)null)
				{
					__result = i;
					break;
				}
			}
		}

		[HarmonyPatch(typeof(PlayerControllerB), "NextItemSlot")]
		[HarmonyPostfix]
		private static void OnNextItemSlot(ref int __result, bool forward, PlayerControllerB __instance)
		{
			if (reservedHotbarSize <= 0 || !HUDPatcher.hasReservedItemSlotsAndEnabled || !ReservedPlayerData.allPlayerData.TryGetValue(__instance, out var value))
			{
				return;
			}
			bool inReservedHotbarSlots = value.inReservedHotbarSlots;
			bool flag = value.IsReservedItemSlot(__result);
			bool flag2 = inReservedHotbarSlots;
			if (inReservedHotbarSlots)
			{
				ReservedItemSlotData unlockedReservedItemSlot = SessionManager.GetUnlockedReservedItemSlot(__result - value.reservedHotbarStartIndex);
				if (ReservedHotbarManager.isToggledInReservedSlots && !ConfigSettings.toggleFocusReservedHotbar.Value && !Keybinds.holdingModifierKey && ReservedHotbarManager.currentlyToggledItemSlots != null && (!flag || (Object)(object)value.itemSlots[__result] == (Object)null || !ReservedHotbarManager.currentlyToggledItemSlots.Contains(unlockedReservedItemSlot)))
				{
					__result = ReservedHotbarManager.indexInHotbar;
					return;
				}
			}
			if (flag == flag2 && (!flag || (Object)(object)__instance.ItemSlots[__result] != (Object)null))
			{
				return;
			}
			int num = (forward ? 1 : (-1));
			__result = __instance.currentItemSlot + num;
			__result = ((__result < 0) ? (__instance.ItemSlots.Length - 1) : ((__result < __instance.ItemSlots.Length) ? __result : 0));
			flag = value.IsReservedItemSlot(__result);
			if (!flag2)
			{
				if (flag)
				{
					__result = (forward ? ((value.reservedHotbarStartIndex + reservedHotbarSize) % __instance.ItemSlots.Length) : (value.reservedHotbarStartIndex - 1));
				}
				return;
			}
			__result = (flag ? __result : (forward ? value.reservedHotbarStartIndex : (value.reservedHotbarStartIndex + reservedHotbarSize - 1)));
			int numHeldReservedItems = value.GetNumHeldReservedItems();
			while (numHeldReservedItems > 0 && __result != value.currentItemSlot && (Object)(object)__instance.ItemSlots[__result] == (Object)null)
			{
				__result += num;
				__result = ((!value.IsReservedItemSlot(__result)) ? (forward ? value.reservedHotbarStartIndex : (value.reservedHotbarStartIndex + reservedHotbarSize - 1)) : __result);
			}
		}

		[HarmonyPatch(typeof(HUDManager), "ClearControlTips")]
		[HarmonyPrefix]
		private static bool PreventClearControlTipsGrabbingReservedItem(HUDManager __instance)
		{
			return ReservedPlayerData.localPlayerData == null || (Object)(object)ReservedPlayerData.localPlayerData.grabbingReservedItem == (Object)null;
		}

		[HarmonyPatch(typeof(GrabbableObject), "SetControlTipsForItem")]
		[HarmonyPrefix]
		private static bool PreventUpdateControlTipsGrabbingReservedItem(GrabbableObject __instance)
		{
			return ReservedPlayerData.localPlayerData == null || (Object)(object)ReservedPlayerData.localPlayerData.grabbingReservedItem != (Object)(object)__instance;
		}

		private static GrabbableObject GetCurrentlyGrabbingObject(PlayerControllerB playerController)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			return (GrabbableObject)Traverse.Create((object)playerController).Field("currentlyGrabbingObject").GetValue();
		}

		private static void SetCurrentlyGrabbingObject(PlayerControllerB playerController, GrabbableObject grabbable)
		{
			Traverse.Create((object)playerController).Field("currentlyGrabbingObject").SetValue((object)grabbable);
		}

		public static bool ReservedItemIsBeingGrabbed(GrabbableObject grabbableObject)
		{
			if ((Object)(object)grabbableObject == (Object)null)
			{
				return false;
			}
			foreach (ReservedPlayerData value in ReservedPlayerData.allPlayerData.Values)
			{
				if ((Object)(object)grabbableObject == (Object)(object)value.grabbingReservedItem)
				{
					return true;
				}
			}
			return false;
		}

		public static void SetSpecialGrabAnimationBool(PlayerControllerB playerController, bool setTrue, GrabbableObject currentItem = null)
		{
			MethodInfo method = ((object)playerController).GetType().GetMethod("SetSpecialGrabAnimationBool", BindingFlags.Instance | BindingFlags.NonPublic);
			method.Invoke(playerController, new object[2] { setTrue, currentItem });
		}

		public static void SwitchToItemSlot(PlayerControllerB playerController, int slot, GrabbableObject fillSlotWithItem = null)
		{
			MethodInfo method = ((object)playerController).GetType().GetMethod("SwitchToItemSlot", BindingFlags.Instance | BindingFlags.NonPublic);
			method.Invoke(playerController, new object[2] { slot, fillSlotWithItem });
			if (ReservedPlayerData.allPlayerData.TryGetValue(playerController, out var value))
			{
				value.timeSinceSwitchingSlots = 0f;
			}
		}
	}
	[HarmonyPatch]
	internal static class ReservedItemsPatcher
	{
		public static bool ignoreMeshOverride;

		public static PlayerControllerB localPlayerController => StartOfRound.Instance?.localPlayerController;

		[HarmonyPatch(typeof(GrabbableObject), "PocketItem")]
		[HarmonyPostfix]
		public static void OnPocketReservedItem(GrabbableObject __instance)
		{
			if (!ConfigSettings.showReservedItemsHolstered.Value || (Object)(object)__instance.playerHeldBy == (Object)null || !ReservedPlayerData.allPlayerData.TryGetValue(__instance.playerHeldBy, out var value) || !SessionManager.TryGetUnlockedItemData(__instance, out var itemData) || !value.IsItemInReservedItemSlot(__instance) || !itemData.showOnPlayerWhileHolstered)
			{
				return;
			}
			MeshRenderer[] componentsInChildren = ((Component)__instance).GetComponentsInChildren<MeshRenderer>();
			foreach (MeshRenderer val in componentsInChildren)
			{
				if (!((Component)val).gameObject.CompareTag("DoNotSet") && !((Component)val).gameObject.CompareTag("InteractTrigger") && ((Component)val).gameObject.layer != 14 && ((Component)val).gameObject.layer != 22)
				{
					((Component)val).gameObject.layer = (value.isLocalPlayer ? 23 : 6);
				}
			}
			__instance.parentObject = value.boneMap.GetBone(itemData.holsteredParentBone);
			ForceEnableItemMesh(__instance, enabled: true);
		}

		[HarmonyPatch(typeof(GrabbableObject), "EquipItem")]
		[HarmonyPostfix]
		public static void OnEquipReservedItem(GrabbableObject __instance)
		{
			if (!ConfigSettings.showReservedItemsHolstered.Value || (Object)(object)__instance.playerHeldBy == (Object)null || !ReservedPlayerData.allPlayerData.TryGetValue(__instance.playerHeldBy, out var value) || !SessionManager.TryGetUnlockedItemData(__instance, out var itemData) || !value.IsItemInReservedItemSlot(__instance) || !itemData.showOnPlayerWhileHolstered)
			{
				return;
			}
			MeshRenderer[] componentsInChildren = ((Component)__instance).GetComponentsInChildren<MeshRenderer>();
			foreach (MeshRenderer val in componentsInChildren)
			{
				if (!((Component)val).gameObject.CompareTag("DoNotSet") && !((Component)val).gameObject.CompareTag("InteractTrigger") && ((Component)val).gameObject.layer != 14 && ((Component)val).gameObject.layer != 22)
				{
					((Component)val).gameObject.layer = 6;
				}
			}
			__instance.parentObject = (value.isLocalPlayer ? __instance.playerHeldBy.localItemHolder : __instance.playerHeldBy.serverItemHolder);
		}

		[HarmonyPatch(typeof(GrabbableObject), "DiscardItem")]
		[HarmonyPostfix]
		public static void ResetReservedItemLayer(GrabbableObject __instance)
		{
			if (!SessionManager.TryGetUnlockedItemData(__instance, out var itemData) || !itemData.showOnPlayerWhileHolstered)
			{
				return;
			}
			MeshRenderer[] componentsInChildren = ((Component)__instance).GetComponentsInChildren<MeshRenderer>();
			foreach (MeshRenderer val in componentsInChildren)
			{
				if (!((Component)val).gameObject.CompareTag("DoNotSet") && !((Component)val).gameObject.CompareTag("InteractTrigger") && ((Component)val).gameObject.layer != 14 && ((Component)val).gameObject.layer != 22)
				{
					((Component)val).gameObject.layer = 6;
				}
			}
		}

		[HarmonyPatch(typeof(GrabbableObject), "LateUpdate")]
		[HarmonyPostfix]
		public static void SetHolsteredPositionRotation(GrabbableObject __instance)
		{
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			if (ConfigSettings.showReservedItemsHolstered.Value && !((Object)(object)__instance.playerHeldBy == (Object)null) && !((Object)(object)__instance.parentObject == (Object)null) && ReservedPlayerData.allPlayerData.TryGetValue(__instance.playerHeldBy, out var value) && SessionManager.TryGetUnlockedItemData(__instance, out var itemData) && value.IsItemInReservedItemSlot(__instance) && itemData.showOnPlayerWhileHolstered && (Object)(object)__instance != (Object)(object)value.currentlySelectedItem)
			{
				Transform transform = ((Component)__instance.parentObject).transform;
				((Component)__instance).transform.rotation = ((Component)__instance.parentObject).transform.rotation * Quaternion.Euler(itemData.holsteredRotationOffset);
				((Component)__instance).transform.position = transform.position + transform.rotation * itemData.holsteredPositionOffset;
			}
		}

		[HarmonyPatch(typeof(GrabbableObject), "EnableItemMeshes")]
		[HarmonyPrefix]
		public static void OnEnableItemMeshes(ref bool enable, GrabbableObject __instance)
		{
			if (ConfigSettings.showReservedItemsHolstered.Value)
			{
				if ((Object)(object)__instance.playerHeldBy != (Object)null && !ignoreMeshOverride && ReservedPlayerData.allPlayerData.TryGetValue(__instance.playerHeldBy, out var value) && SessionManager.TryGetUnlockedItemData(__instance, out var itemData) && value.IsItemInReservedItemSlot(__instance) && itemData.showOnPlayerWhileHolstered && (Object)(object)value.currentlySelectedItem != (Object)(object)__instance && !PlayerPatcher.ReservedItemIsBeingGrabbed(__instance))
				{
					enable = true;
				}
				ignoreMeshOverride = false;
			}
		}

		public static void ForceEnableItemMesh(GrabbableObject grabbableObject, bool enabled)
		{
			ignoreMeshOverride = true;
			grabbableObject.EnableItemMeshes(enabled);
		}
	}
	[HarmonyPatch]
	internal static class SyncAlreadyHeldObjectsPatcher
	{
		[HarmonyPatch(typeof(StartOfRound), "SyncAlreadyHeldObjectsClientRpc")]
		[HarmonyPrefix]
		private static bool SyncAlreadyHeldReservedObjectsClientRpc(ref NetworkObjectReference[] gObjects, ref int[] playersHeldBy, ref int[] itemSlotNumbers, ref int[] isObjectPocketed, int syncWithClient, StartOfRound __instance)
		{
			if ((Object)(object)NetworkManager.Singleton == (Object)null || !NetworkManager.Singleton.IsListening)
			{
				return true;
			}
			if ((NetworkHelper.IsClientExecStage((NetworkBehaviour)(object)__instance) || (!NetworkManager.Singleton.IsServer && !NetworkManager.Singleton.IsHost)) && (!NetworkHelper.IsClientExecStage((NetworkBehaviour)(object)__instance) || (!NetworkManager.Singleton.IsClient && !NetworkManager.Singleton.IsHost) || syncWithClient != (int)NetworkManager.Singleton.LocalClientId))
			{
				return false;
			}
			bool flag = false;
			List<NetworkObjectReference> list = new List<NetworkObjectReference>(gObjects);
			List<int> list2 = new List<int>(playersHeldBy);
			List<int> list3 = new List<int>(itemSlotNumbers);
			List<int> list4 = new List<int>(isObjectPocketed);
			for (int num = itemSlotNumbers.Length - 1; num >= 0; num--)
			{
				if (itemSlotNumbers[num] >= __instance.localPlayerController.ItemSlots.Length)
				{
					list.RemoveAt(num);
					list2.RemoveAt(num);
					list3.RemoveAt(num);
					list4.Remove(num);
					flag = true;
				}
			}
			if (flag)
			{
				gObjects = list.ToArray();
				playersHeldBy = list2.ToArray();
				itemSlotNumbers = list3.ToArray();
				isObjectPocketed = list4.ToArray();
			}
			return true;
		}
	}
	[HarmonyPatch]
	internal static class TerminalPatcher
	{
		public static Terminal terminalInstance;

		public static bool initializedTerminalNodes;

		public static ReservedItemSlotData purchasingItemSlot;

		[HarmonyPatch(typeof(Terminal), "Awake")]
		[HarmonyPrefix]
		public static void InitializeTerminal(Terminal __instance)
		{
			terminalInstance = __instance;
			initializedTerminalNodes = false;
			EditExistingTerminalNodes();
		}

		[HarmonyPatch(typeof(Terminal), "BeginUsingTerminal")]
		[HarmonyPrefix]
		public static void OnBeginUsingTerminal(Terminal __instance)
		{
			if (!initializedTerminalNodes && SyncManager.isSynced)
			{
				EditExistingTerminalNodes();
			}
		}

		public static void EditExistingTerminalNodes()
		{
			if (!SyncManager.isSynced)
			{
				return;
			}
			initializedTerminalNodes = true;
			if (!SyncManager.enablePurchasingItemSlots)
			{
				return;
			}
			foreach (TerminalNode specialNode in terminalInstance.terminalNodes.specialNodes)
			{
				if (((Object)specialNode).name == "Start" && !specialNode.displayText.Contains("[ReservedItemSlots]"))
				{
					string text = "Type \"Help\" for a list of commands.";
					int num = specialNode.displayText.IndexOf(text);
					if (num != -1)
					{
						num += text.Length;
						string value = "\n\n[ReservedItemSlots]\nType \"Reserved\" to purchase reserved item slots.";
						specialNode.displayText = specialNode.displayText.Insert(num, value);
					}
					else
					{
						Debug.LogError((object)"Failed to add reserved item slots tip to terminal. Maybe an update broke it?");
					}
				}
				else if (((Object)specialNode).name == "HelpCommands" && !specialNode.displayText.Contains(">RESERVED"))
				{
					string value2 = "[numberOfItemsOnRoute]";
					int num2 = specialNode.displayText.IndexOf(value2);
					if (num2 != -1)
					{
						string text2 = ">RESERVED\n";
						text2 += "Purchase reserved item slots.\n\n";
						specialNode.displayText = specialNode.displayText.Insert(num2, text2);
					}
				}
			}
		}

		[HarmonyPatch(typeof(Terminal), "TextPostProcess")]
		[HarmonyPrefix]
		public static void TextPostProcess(ref string modifiedDisplayText, TerminalNode node)
		{
			if (modifiedDisplayText.Length <= 0)
			{
				return;
			}
			string text = "[[[reservedItemSlotsSelectionList]]]";
			if (!modifiedDisplayText.Contains(text))
			{
				return;
			}
			int num = modifiedDisplayText.IndexOf(text);
			int num2 = num + text.Length;
			string oldValue = modifiedDisplayText.Substring(num, num2 - num);
			string text2 = "";
			if (!SyncManager.enablePurchasingItemSlots)
			{
				text2 += "Every reserved item slot is unlocked!\n\n";
			}
			else
			{
				text2 += "Reserved Item Slots\n------------------------------\n\n";
				text2 += "To purchase a reserved item slot, type the following command.\n> RESERVED [item_slot]\n\n";
				int num3 = 0;
				foreach (ReservedItemSlotData value in SyncManager.unlockableReservedItemSlotsDict.Values)
				{
					num3 = Mathf.Max(num3, value.slotName.Length);
				}
				foreach (ReservedItemSlotData value2 in SyncManager.unlockableReservedItemSlotsDict.Values)
				{
					string arg = (SessionManager.IsItemSlotUnlocked(value2) ? "[Purchased]" : ("$" + value2.purchasePrice));
					text2 += $"* {value2.slotDisplayName}{new string(' ', num3 - value2.slotDisplayName.Length)}   //   {arg}\n";
				}
			}
			modifiedDisplayText = modifiedDisplayText.Replace(oldValue, text2);
		}

		[HarmonyPatch(typeof(Terminal), "ParsePlayerSentence")]
		[HarmonyPrefix]
		public static bool ParsePlayerSentence(ref TerminalNode __result, Terminal __instance)
		{
			if (__instance.screenText.text.Length <= 0)
			{
				return true;
			}
			string text = __instance.screenText.text.Substring(__instance.screenText.text.Length - __instance.textAdded).ToLower();
			string[] array = text.Split(new char[1] { ' ' });
			ReservedItemSlotData reservedItemSlotData = null;
			if (!SyncManager.isSynced)
			{
				if (text.StartsWith("reserved"))
				{
					__result = BuildTerminalNodeHostDoesNotHaveMod();
					return false;
				}
				return true;
			}
			if (purchasingItemSlot != null)
			{
				if ("confirm".StartsWith(text))
				{
					if (purchasingItemSlot.isUnlocked)
					{
						Debug.LogWarning((object)("Attempted to confirm purchase on reserved item slot that was already unlocked. Item slot: " + purchasingItemSlot.slotDisplayName));
						__result = BuildTerminalNodeAlreadyUnlocked(purchasingItemSlot);
					}
					else if (terminalInstance.groupCredits < purchasingItemSlot.purchasePrice)
					{
						Debug.LogWarning((object)("Attempted to confirm purchase with insufficient credits. Current credits: " + terminalInstance.groupCredits + " Required credits: " + purchasingItemSlot.purchasePrice));
						__result = BuildTerminalNodeInsufficientFunds(purchasingItemSlot);
					}
					else
					{
						Debug.Log((object)("Purchasing reserved item slot: " + purchasingItemSlot.slotDisplayName + ". Price: " + purchasingItemSlot.purchasePrice));
						Terminal obj = terminalInstance;
						obj.groupCredits -= purchasingItemSlot.purchasePrice;
						terminalInstance.BuyItemsServerRpc(new int[0], terminalInstance.groupCredits, terminalInstance.numberOfItemsInDropship);
						SyncManager.SendUnlockItemSlotUpdateToServer(purchasingItemSlot.slotId);
						__result = BuildTerminalNodeOnPurchased(purchasingItemSlot, terminalInstance.groupCredits);
					}
				}
				else
				{
					Plugin.Log("Canceling order.");
					__result = BuildCustomTerminalNode("Canceled order.\n\n");
				}
				purchasingItemSlot = null;
				return false;
			}
			purchasingItemSlot = null;
			if (array.Length == 0 || array[0] != "reserved")
			{
				return true;
			}
			if (array.Length == 1)
			{
				__result = BuildTerminalNodeHome();
				return false;
			}
			string text2 = text.Substring(9);
			reservedItemSlotData = TryGetReservedItemSlot(text2);
			if (reservedItemSlotData != null)
			{
				if (SessionManager.IsItemSlotUnlocked(reservedItemSlotData))
				{
					Plugin.LogWarning("Attempted to start purchase on reserved item slot that was already unlocked. Item slot: " + reservedItemSlotData.slotName);
					__result = BuildTerminalNodeAlreadyUnlocked(reservedItemSlotData);
				}
				else if (terminalInstance.groupCredits < reservedItemSlotData.purchasePrice)
				{
					Plugin.LogWarning("Attempted to start purchase with insufficient credits. Current credits: " + terminalInstance.groupCredits + ". Item slot price: " + reservedItemSlotData.purchasePrice);
					__result = BuildTerminalNodeInsufficientFunds(reservedItemSlotData);
				}
				else
				{
					Plugin.Log("Started purchasing reserved item slot: " + reservedItemSlotData.slotName);
					purchasingItemSlot = reservedItemSlotData;
					__result = BuildTerminalNodeConfirmDenyPurchase(reservedItemSlotData);
				}
				return false;
			}
			Plugin.LogWarning("Attempted to start purchase on invalid reserved item slot. Item slot: " + text2);
			__result = BuildTerminalNodeInvalidReservedItemSlot(text2);
			return false;
		}

		private static TerminalNode BuildTerminalNodeHome()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			return new TerminalNode
			{
				displayText = "[ReservedItemSlots]\n\nStore\n------------------------------\n[[[reservedItemSlotsSelectionList]]]\n\n",
				clearPreviousText = true,
				acceptAnything = false
			};
		}

		private static TerminalNode BuildTerminalNodeConfirmDenyPurchase(ReservedItemSlotData itemSlotData)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			TerminalNode val = new TerminalNode();
			val.displayText = "You have requested to purchase a reserved item slot for $" + itemSlotData.purchasePrice + " credits.\n> [" + itemSlotData.slotDisplayName + "]\n\n";
			val.isConfirmationNode = true;
			val.acceptAnything = false;
			val.clearPreviousText = true;
			TerminalNode val2 = val;
			val2.displayText = val2.displayText + "Credit balance: $" + terminalInstance.groupCredits + "\n";
			val2.displayText += "\n";
			val2.displayText += "Please CONFIRM or DENY.\n\n";
			return val2;
		}

		private static TerminalNode BuildTerminalNodeOnPurchased(ReservedItemSlotData itemSlotData, int newGroupCredits)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: 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)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Expected O, but got Unknown
			TerminalNode val = new TerminalNode
			{
				displayText = "You have successfully purchased a new reserved item slot!\n> [" + itemSlotData.slotDisplayName + "]\n\n",
				buyUnlockable = true,
				clearPreviousText = true,
				acceptAnything = false,
				playSyncedClip = 0
			};
			val.displayText = val.displayText + "New credit balance: $" + newGroupCredits + "\n\n";
			return val;
		}

		private static TerminalNode BuildTerminalNodeAlreadyUnlocked(ReservedItemSlotData itemSlot)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: 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)
			//IL_0030: Expected O, but got Unknown
			return new TerminalNode
			{
				displayText = "You have already purchased this reserved item slot!\n> [" + itemSlot.slotDisplayName + "]\n\n",
				clearPreviousText = false,
				acceptAnything = false
			};
		}

		private static TerminalNode BuildTerminalNodeInsufficientFunds(ReservedItemSlotData itemSlot)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			TerminalNode val = new TerminalNode();
			val.displayText = "You could not afford this reserved item slot!\n> [" + itemSlot.slotDisplayName + "]\n\nCredit balance is $" + terminalInstance.groupCredits + "\n";
			val.clearPreviousText = true;
			val.acceptAnything = false;
			TerminalNode val2 = val;
			val2.displayText = val2.displayText + "Price of reserved item slot is $" + itemSlot.purchasePrice + "\n\n";
			return val2;
		}

		private static TerminalNode BuildTerminalNodeInvalidReservedItemSlot(string reservedItemSlotName = "")
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			TerminalNode val = new TerminalNode
			{
				displayText = "Reserved item slot does not exist.",
				clearPreviousText = false,
				acceptAnything = false
			};
			if (reservedItemSlotName != "")
			{
				val.displayText = val.displayText + "\n\"" + reservedItemSlotName + "\"";
			}
			val.displayText += "\n";
			return val;
		}

		private static TerminalNode BuildTerminalNodeHostDoesNotHaveMod(string itemSlotName = "")
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			TerminalNode val = new TerminalNode
			{
				displayText = "You cannot use the reserved item slot commands until you have synced with the host.\n\nYou may also be seeing this because the host does not have this mod.\n\n",
				clearPreviousText = true,
				acceptAnything = false
			};
			if (itemSlotName != "")
			{
				val.displayText = val.displayText + "\n\"" + itemSlotName + "\"";
			}
			val.displayText += "\n";
			return val;
		}

		private static TerminalNode BuildCustomTerminalNode(string displayText, bool clearPreviousText = false, bool acceptAnything = false, bool isConfirmationNode = false)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			return new TerminalNode
			{
				displayText = displayText,
				clearPreviousText = clearPreviousText,
				acceptAnything = false,
				isConfirmationNode = isConfirmationNode
			};
		}

		private static ReservedItemSlotData TryGetReservedItemSlot(string itemSlotNameInput)
		{
			ReservedItemSlotData reservedItemSlotData = null;
			foreach (ReservedItemSlotData unlockableReservedItemSlot in SyncManager.unlockableReservedItemSlots)
			{
				string text = unlockableReservedItemSlot.slotDisplayName.ToLower();
				if ((itemSlotNameInput == text || (itemSlotNameInput.Length >= 4 && text.StartsWith(itemSlotNameInput))) && (reservedItemSlotData == null || text.Length < reservedItemSlotData.slotDisplayName.Length) && !"the company".StartsWith(itemSlotNameInput) && !"company".StartsWith(itemSlotNameInput))
				{
					reservedItemSlotData = unlockableReservedItemSlot;
				}
			}
			return reservedItemSlotData;
		}
	}
}
namespace ReservedItemSlotCore.Networking
{
	internal static class NetworkHelper
	{
		private static int NONE_EXEC_STAGE = 0;

		private static int SERVER_EXEC_STAGE = 1;

		private static int CLIENT_EXEC_STAGE = 2;

		internal static int GetExecStage(NetworkBehaviour __instance)
		{
			return (int)Traverse.Create((object)__instance).Field("__rpc_exec_stage").GetValue();
		}

		internal static bool IsClientExecStage(NetworkBehaviour __instance)
		{
			return GetExecStage(__instance) == CLIENT_EXEC_STAGE;
		}

		internal static bool IsServerExecStage(NetworkBehaviour __instance)
		{
			return GetExecStage(__instance) == SERVER_EXEC_STAGE;
		}

		internal static bool IsValidClientRpcExecStage(NetworkBehaviour __instance)
		{
			NetworkManager singleton = NetworkManager.Singleton;
			if ((Object)(object)singleton == (Object)null || !singleton.IsListening)
			{
				return false;
			}
			int num = (int)Traverse.Create((object)__instance).Field("__rpc_exec_stage").GetValue();
			if ((singleton.IsServer || singleton.IsHost) && num != 2)
			{
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch]
	internal static class SyncManager
	{
		private static bool requestedSyncHeldObjects = false;

		public static List<ReservedItemSlotData> unlockableReservedItemSlots = new List<ReservedItemSlotData>();

		public static Dictionary<string, ReservedItemSlotData> unlockableReservedItemSlotsDict = new Dictionary<string, ReservedItemSlotData>();

		public static List<ReservedItemData> reservedItems = new List<ReservedItemData>();

		public static Dictionary<string, ReservedItemData> reservedItemsDict = new Dictionary<string, ReservedItemData>();

		public static PlayerControllerB localPlayerController => StartOfRound.Instance?.localPlayerController;

		public static bool enablePurchasingItemSlots { get; internal set; } = false;


		internal static bool canUseModDisabledOnHost => ConfigSettings.forceEnableThisModIfNotEnabledOnHost.Value;

		public static bool isSynced { get; internal set; } = false;


		public static bool IsReservedItem(string itemName)
		{
			if (itemName == null)
			{
				return false;
			}
			foreach (ReservedItemSlotData unlockableReservedItemSlot in unlockableReservedItemSlots)
			{
				if (unlockableReservedItemSlot.ContainsItem(itemName))
				{
					return true;
				}
			}
			return false;
		}

		[HarmonyPatch(typeof(StartOfRound), "Awake")]
		[HarmonyPrefix]
		public static void ResetValues(StartOfRound __instance)
		{
			isSynced = false;
			requestedSyncHeldObjects = false;
			unlockableReservedItemSlots?.Clear();
			unlockableReservedItemSlotsDict?.Clear();
			enablePurchasingItemSlots = false;
			reservedItems?.Clear();
			reservedItemsDict?.Clear();
		}

		[HarmonyPatch(typeof(PlayerControllerB), "ConnectClientToPlayerObject")]
		[HarmonyPostfix]
		public static void Init(PlayerControllerB __instance)
		{
			//IL_026f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0279: Expected O, but got Unknown
			//IL_0290: Unknown result type (might be due to invalid IL or missing references)
			//IL_029a: Expected O, but got Unknown
			//IL_02b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bb: Expected O, but got Unknown
			//IL_02d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02dc: Expected O, but got Unknown
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Expected O, but got Unknown
			//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dc: Expected O, but got Unknown
			//IL_01f3: Un

plugins/Scopophobia/Scopophobia.dll

Decompiled 2 years ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using LethalLib;
using LethalLib.Modules;
using Scopophobia;
using Scopophobia.NetcodePatcher;
using Scopophobia.Patches;
using Unity.Collections;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.AI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyCompany("Scopophobia")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Adds the Shy Guy (SCP-096) to Lethal Company. Fully custom animations and behavior. Model from SCP: Containment Breach.. Patched for v50")]
[assembly: AssemblyFileVersion("1.1.1.0")]
[assembly: AssemblyInformationalVersion("1.1.1")]
[assembly: AssemblyProduct("Scopophobia")]
[assembly: AssemblyTitle("Scopophobia")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = "")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.1.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
[module: NetcodePatchedAssembly]
[Serializable]
public class SyncedInstance<T>
{
	[NonSerialized]
	protected static int IntSize = 4;

	internal static CustomMessagingManager MessageManager => NetworkManager.Singleton.CustomMessagingManager;

	internal static bool IsClient => NetworkManager.Singleton.IsClient;

	internal static bool IsHost => NetworkManager.Singleton.IsHost;

	public static T Default { get; private set; }

	public static T Instance { get; private set; }

	public static bool Synced { get; internal set; }

	protected void InitInstance(T instance)
	{
		Default = instance;
		Instance = instance;
		IntSize = 4;
	}

	internal static void SyncInstance(byte[] data)
	{
		Instance = DeserializeFromBytes(data);
		Synced = true;
	}

	internal static void RevertSync()
	{
		Instance = Default;
		Synced = false;
	}

	public static byte[] SerializeToBytes(T val)
	{
		BinaryFormatter binaryFormatter = new BinaryFormatter();
		using MemoryStream memoryStream = new MemoryStream();
		try
		{
			binaryFormatter.Serialize(memoryStream, val);
			return memoryStream.ToArray();
		}
		catch (Exception arg)
		{
			Plugin.logger.LogError((object)$"Error serializing instance: {arg}");
			return null;
		}
	}

	public static T DeserializeFromBytes(byte[] data)
	{
		BinaryFormatter binaryFormatter = new BinaryFormatter();
		using MemoryStream serializationStream = new MemoryStream(data);
		try
		{
			return (T)binaryFormatter.Deserialize(serializationStream);
		}
		catch (Exception arg)
		{
			Plugin.logger.LogError((object)$"Error deserializing instance: {arg}");
			return default(T);
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute([In] int obj0)
		{
			Version = obj0;
		}
	}
}
namespace ShyGuy.AI
{
	public class ShyGuyAI : EnemyAI
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static RpcReceiveHandler <0>____rpc_handler_2556963367;

			public static RpcReceiveHandler <1>____rpc_handler_2298532976;

			public static RpcReceiveHandler <2>____rpc_handler_652446748;

			public static RpcReceiveHandler <3>____rpc_handler_2536632143;

			public static RpcReceiveHandler <4>____rpc_handler_1207108010;

			public static RpcReceiveHandler <5>____rpc_handler_1413965488;
		}

		private Transform localPlayerCamera;

		private Vector3 mainEntrancePosition;

		public Collider mainCollider;

		public AudioSource farAudio;

		public AudioSource footstepSource;

		public AudioClip screamSFX;

		public AudioClip panicSFX;

		public AudioClip crySFX;

		public AudioClip crySittingSFX;

		public AudioClip killPlayerSFX;

		[Header("Containment Breach Sounds")]
		public AudioClip screamSFX_CB;

		public AudioClip panicSFX_CB;

		public AudioClip crySFX_CB;

		public AudioClip killPlayerSFX_CB;

		[Header("Alpha Containment Breach Sounds")]
		public AudioClip screamSFX_ACB;

		public AudioClip panicSFX_ACB;

		public AudioClip crySFX_ACB;

		public AudioClip killPlayerSFX_ACB;

		[Header("Secret Laboratory Sounds")]
		public AudioClip screamSFX_SL;

		public AudioClip panicSFX_SL;

		public AudioClip crySFX_SL;

		public AudioClip killPlayerSFX_SL;

		public Material bloodyMaterial;

		public AISearchRoutine roamMap;

		public Transform shyGuyFace;

		private Vector3 spawnPosition;

		private Vector3 previousPosition;

		private int previousState = -1;

		private float roamWaitTime = 40f;

		private bool roamShouldSit;

		private bool sitting;

		private float lastRunSpeed;

		private float seeFaceTime;

		private float triggerTime;

		private float triggerDuration = 66.4f;

		private float timeToTrigger = 0.5f;

		private float lastInterval = Time.realtimeSinceStartup;

		private bool inKillAnimation;

		public List<PlayerControllerB> SCP096Targets = new List<PlayerControllerB>();

		public override void Start()
		{
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Expected O, but got Unknown
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Expected O, but got Unknown
			//IL_030e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0313: Unknown result type (might be due to invalid IL or missing references)
			//IL_031f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0342: Unknown result type (might be due to invalid IL or missing references)
			//IL_0349: Unknown result type (might be due to invalid IL or missing references)
			//IL_034f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0357: Unknown result type (might be due to invalid IL or missing references)
			//IL_035c: Unknown result type (might be due to invalid IL or missing references)
			//IL_040d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0417: Expected O, but got Unknown
			((EnemyAI)this).Start();
			triggerDuration = Config.triggerTime;
			Transform val = null;
			Queue<Transform> queue = new Queue<Transform>();
			queue.Enqueue(((Component)this).transform);
			while (queue.Count > 0)
			{
				Transform val2 = queue.Dequeue();
				if (((Object)val2).name == "lefteye")
				{
					val = val2;
					break;
				}
				foreach (Transform item3 in val2)
				{
					Transform item = item3;
					queue.Enqueue(item);
				}
			}
			Transform val3 = null;
			queue = new Queue<Transform>();
			queue.Enqueue(((Component)this).transform);
			while (queue.Count > 0)
			{
				Transform val4 = queue.Dequeue();
				if (((Object)val4).name == "righteye")
				{
					val3 = val4;
					break;
				}
				foreach (Transform item4 in val4)
				{
					Transform item2 = item4;
					queue.Enqueue(item2);
				}
			}
			if (!Config.hasGlowingEyes && (Object)(object)val != (Object)null && (Object)(object)val3 != (Object)null)
			{
				((Component)val).gameObject.SetActive(false);
				((Component)val3).gameObject.SetActive(false);
			}
			if (Config.bloodyTexture && (Object)(object)bloodyMaterial != (Object)null)
			{
				Transform val5 = ((Component)this).transform.Find("SCP096Model");
				if ((Object)(object)val5 != (Object)null)
				{
					Transform val6 = val5.Find("tsg_placeholder");
					if ((Object)(object)val6 != (Object)null)
					{
						SkinnedMeshRenderer component = ((Component)val6).GetComponent<SkinnedMeshRenderer>();
						if ((Object)(object)component != (Object)null)
						{
							((Renderer)component).material = bloodyMaterial;
						}
					}
				}
			}
			switch (Config.soundPack)
			{
			case "SCPCB":
				screamSFX = screamSFX_CB;
				crySFX = crySFX_CB;
				crySittingSFX = crySFX_CB;
				panicSFX = panicSFX_CB;
				killPlayerSFX = killPlayerSFX_CB;
				break;
			case "SCPCBOld":
				screamSFX = screamSFX_ACB;
				crySFX = crySFX_ACB;
				crySittingSFX = crySFX_ACB;
				panicSFX = panicSFX_ACB;
				killPlayerSFX = killPlayerSFX_ACB;
				break;
			case "SecretLab":
				screamSFX = screamSFX_SL;
				crySFX = crySFX_SL;
				crySittingSFX = crySFX_SL;
				panicSFX = panicSFX_SL;
				killPlayerSFX = killPlayerSFX_SL;
				break;
			}
			localPlayerCamera = ((Component)GameNetworkManager.Instance.localPlayerController.gameplayCamera).transform;
			spawnPosition = ((Component)this).transform.position;
			base.isOutside = ((Component)this).transform.position.y > -80f;
			mainEntrancePosition = RoundManager.Instance.GetNavMeshPosition(RoundManager.FindMainEntrancePosition(true, base.isOutside), default(NavMeshHit), 5f, -1);
			if (base.isOutside)
			{
				if (base.allAINodes == null || base.allAINodes.Length == 0)
				{
					base.allAINodes = GameObject.FindGameObjectsWithTag("OutsideAINode");
				}
				if ((Object)(object)GameNetworkManager.Instance.localPlayerController != (Object)null)
				{
					((EnemyAI)this).EnableEnemyMesh(!StartOfRound.Instance.hangarDoorsClosed || !GameNetworkManager.Instance.localPlayerController.isInHangarShipRoom, false);
				}
			}
			else if (base.allAINodes == null || base.allAINodes.Length == 0)
			{
				base.allAINodes = GameObject.FindGameObjectsWithTag("AINode");
			}
			base.path1 = new NavMeshPath();
			base.openDoorSpeedMultiplier = 450f;
			SetShyGuyInitialValues();
		}

		private void CalculateAnimationSpeed()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = ((Component)this).transform.position - previousPosition;
			float num = ((Vector3)(ref val)).magnitude;
			if (num > 0f)
			{
				num = 1f;
			}
			lastRunSpeed = Mathf.Lerp(lastRunSpeed, num, 5f * Time.deltaTime);
			base.creatureAnimator.SetFloat("VelocityZ", lastRunSpeed);
			previousPosition = ((Component)this).transform.position;
		}

		public override void DoAIInterval()
		{
			//IL_05b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_05c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_050d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0518: Unknown result type (might be due to invalid IL or missing references)
			//IL_0644: Unknown result type (might be due to invalid IL or missing references)
			//IL_064a: Unknown result type (might be due to invalid IL or missing references)
			//IL_02db: 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_066d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0537: Unknown result type (might be due to invalid IL or missing references)
			//IL_0542: Unknown result type (might be due to invalid IL or missing references)
			//IL_0547: Unknown result type (might be due to invalid IL or missing references)
			((EnemyAI)this).DoAIInterval();
			if (StartOfRound.Instance.livingPlayers == 0)
			{
				lastInterval = Time.realtimeSinceStartup;
				return;
			}
			if (base.isEnemyDead)
			{
				lastInterval = Time.realtimeSinceStartup;
				return;
			}
			if (!((NetworkBehaviour)this).IsServer && ((NetworkBehaviour)this).IsOwner && base.currentBehaviourStateIndex != 2)
			{
				((EnemyAI)this).ChangeOwnershipOfEnemy(StartOfRound.Instance.allPlayerScripts[0].actualClientId);
			}
			switch (base.currentBehaviourStateIndex)
			{
			case 0:
			{
				if (base.stunNormalizedTimer > 0f)
				{
					base.agent.speed = 0f;
				}
				else if (sitting)
				{
					base.agent.speed = 0f;
				}
				else
				{
					roamWaitTime -= Time.realtimeSinceStartup - lastInterval;
					base.openDoorSpeedMultiplier = 1f;
					base.agent.speed = 2.75f * Config.speedDocileMultiplier;
				}
				base.movingTowardsTargetPlayer = false;
				base.agent.stoppingDistance = 4f;
				base.addPlayerVelocityToDestination = 0f;
				PlayerControllerB targetPlayer2 = base.targetPlayer;
				if (roamWaitTime <= 20f && roamMap.inProgress && (Object)(object)base.targetPlayer == (Object)null)
				{
					((EnemyAI)this).StopSearch(roamMap, true);
					lastInterval = Time.realtimeSinceStartup;
				}
				else if (roamWaitTime > 2.5f && roamWaitTime <= 15f && !roamMap.inProgress && (Object)(object)base.targetPlayer == (Object)null && roamShouldSit)
				{
					sitting = true;
					base.creatureAnimator.SetBool("Sitting", true);
					float time = base.creatureVoice.time;
					base.creatureVoice.volume = 0.3f;
					base.creatureVoice.clip = crySittingSFX;
					base.creatureVoice.Play();
					base.creatureVoice.time = time;
					lastInterval = Time.realtimeSinceStartup;
				}
				else if (!((Object)(object)base.targetPlayer != (Object)null) && (Object)(object)base.targetPlayer == (Object)null && !roamMap.inProgress && roamWaitTime <= 0f)
				{
					if (!sitting)
					{
						roamShouldSit = Random.Range(1, 5) == 1;
						roamWaitTime = Random.Range(25f, 32.5f);
						((EnemyAI)this).StartSearch(spawnPosition, roamMap);
						lastInterval = Time.realtimeSinceStartup;
						break;
					}
					sitting = false;
					roamShouldSit = false;
					roamWaitTime = Random.Range(21f, 25f);
					base.creatureAnimator.SetBool("Sitting", false);
					float time2 = base.creatureVoice.time;
					base.creatureVoice.volume = 0.3f;
					base.creatureVoice.clip = crySFX;
					base.creatureVoice.Play();
					base.creatureVoice.time = time2;
					lastInterval = Time.realtimeSinceStartup;
				}
				break;
			}
			case 1:
				base.agent.speed = 0f;
				lastInterval = Time.realtimeSinceStartup;
				base.movingTowardsTargetPlayer = false;
				break;
			case 2:
			{
				base.agent.stoppingDistance = 0f;
				base.agent.avoidancePriority = 60;
				base.openDoorSpeedMultiplier = 450f;
				mainCollider.isTrigger = true;
				base.addPlayerVelocityToDestination = 1f;
				if (inKillAnimation)
				{
					base.agent.speed = 0f;
				}
				else
				{
					base.agent.speed = Mathf.Clamp(base.agent.speed + (Time.realtimeSinceStartup - lastInterval) * Config.speedRageMultiplier * 1.1f, 5f * Config.speedRageMultiplier, 14.75f * Config.speedRageMultiplier);
				}
				if (SCP096Targets.Count <= 0)
				{
					SitDown();
					break;
				}
				PlayerControllerB targetPlayer = base.targetPlayer;
				float num = float.PositiveInfinity;
				foreach (PlayerControllerB sCP096Target in SCP096Targets)
				{
					bool flag = sCP096Target.isInsideFactory == !base.isOutside;
					bool flag2 = true;
					if (!Config.canExitFacility && !flag)
					{
						flag2 = false;
					}
					if (!sCP096Target.isPlayerDead && flag2)
					{
						if (((EnemyAI)this).PlayerIsTargetable(sCP096Target, false, true) && Vector3.Distance(((Component)sCP096Target).transform.position, ((Component)this).transform.position) < num)
						{
							num = Vector3.Magnitude(((Component)sCP096Target).transform.position - ((Component)this).transform.position);
							base.targetPlayer = sCP096Target;
						}
					}
					else
					{
						AddTargetToList((int)sCP096Target.actualClientId, remove: true);
					}
				}
				if ((Object)(object)base.targetPlayer != (Object)null)
				{
					base.creatureAnimator.SetFloat("DistanceToTarget", Vector3.Distance(((Component)this).transform.position, ((Component)base.targetPlayer).transform.position));
					if (roamMap.inProgress)
					{
						((EnemyAI)this).StopSearch(roamMap, true);
					}
					if ((Object)(object)base.targetPlayer != (Object)(object)targetPlayer)
					{
						((EnemyAI)this).ChangeOwnershipOfEnemy(base.targetPlayer.actualClientId);
					}
					if (base.targetPlayer.isInsideFactory != !base.isOutside)
					{
						if (Vector3.Distance(((Component)this).transform.position, mainEntrancePosition) < 2f)
						{
							TeleportEnemy(RoundManager.FindMainEntrancePosition(true, !base.isOutside), !base.isOutside);
							base.agent.speed = 0f;
						}
						else
						{
							base.movingTowardsTargetPlayer = false;
							((EnemyAI)this).SetDestinationToPosition(mainEntrancePosition, false);
						}
					}
					else
					{
						((EnemyAI)this).SetMovingTowardsTargetPlayer(base.targetPlayer);
					}
				}
				else if (SCP096Targets.Count <= 0)
				{
					SitDown();
				}
				break;
			}
			default:
				lastInterval = Time.realtimeSinceStartup;
				break;
			}
		}

		public void TeleportEnemy(Vector3 pos, bool setOutside)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			Vector3 navMeshPosition = RoundManager.Instance.GetNavMeshPosition(pos, default(NavMeshHit), 5f, -1);
			if (((NetworkBehaviour)this).IsOwner)
			{
				((Behaviour)base.agent).enabled = false;
				((Component)this).transform.position = navMeshPosition;
				((Behaviour)base.agent).enabled = true;
			}
			else
			{
				((Component)this).transform.position = navMeshPosition;
			}
			base.serverPosition = navMeshPosition;
			SetEnemyOutside(setOutside);
			EntranceTeleport val = RoundManager.FindMainEntranceScript(setOutside);
			if (val.doorAudios != null && val.doorAudios.Length != 0)
			{
				val.entrancePointAudio.PlayOneShot(val.doorAudios[0]);
				WalkieTalkie.TransmitOneShotAudio(val.entrancePointAudio, val.doorAudios[0], 1f);
			}
		}

		public override void Update()
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01df: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
			if (base.isEnemyDead || (Object)(object)GameNetworkManager.Instance == (Object)null)
			{
				return;
			}
			CalculateAnimationSpeed();
			bool flag = GameNetworkManager.Instance.localPlayerController.HasLineOfSightToPosition(shyGuyFace.position, Config.faceTriggerRange, 45, -1f);
			if (flag)
			{
				float num = Quaternion.Angle(((Component)GameNetworkManager.Instance.localPlayerController.gameplayCamera).transform.rotation, shyGuyFace.rotation);
				if (!(num <= 145f))
				{
					flag = false;
				}
			}
			if (flag)
			{
				seeFaceTime += Time.deltaTime;
				if (seeFaceTime >= Config.faceTriggerGracePeriod)
				{
					GameNetworkManager.Instance.localPlayerController.JumpToFearLevel(1.25f, true);
					if (!Config.hasMaxTargets || SCP096Targets.Count < Config.maxTargets)
					{
						AddTargetToList((int)GameNetworkManager.Instance.localPlayerController.playerClientId);
					}
					if (base.currentBehaviourStateIndex == 0)
					{
						((EnemyAI)this).SwitchToBehaviourState(1);
					}
				}
			}
			else
			{
				seeFaceTime = Mathf.Clamp(seeFaceTime - Time.deltaTime, 0f, timeToTrigger);
				if (GameNetworkManager.Instance.localPlayerController.HasLineOfSightToPosition(((Component)this).transform.position + Vector3.up * 1f, 30f, 60, -1f) && base.currentBehaviourStateIndex == 0)
				{
					if (!base.thisNetworkObject.IsOwner)
					{
						((EnemyAI)this).ChangeOwnershipOfEnemy(GameNetworkManager.Instance.localPlayerController.actualClientId);
					}
					if (Vector3.Distance(((Component)this).transform.position, ((Component)GameNetworkManager.Instance.localPlayerController).transform.position) < 10f)
					{
						GameNetworkManager.Instance.localPlayerController.JumpToFearLevel(0.65f, true);
					}
					else
					{
						GameNetworkManager.Instance.localPlayerController.JumpToFearLevel(0.25f, true);
					}
				}
			}
			switch (base.currentBehaviourStateIndex)
			{
			case 0:
				if (previousState != 0)
				{
					SetShyGuyInitialValues();
					previousState = 0;
					mainCollider.isTrigger = true;
					farAudio.volume = 0f;
					base.creatureVoice.volume = 0.3f;
					base.creatureVoice.clip = crySFX;
					base.creatureVoice.Play();
				}
				if (!base.creatureVoice.isPlaying)
				{
					base.creatureVoice.volume = 0.3f;
					base.creatureVoice.clip = crySFX;
					base.creatureVoice.Play();
				}
				break;
			case 1:
				if (previousState != 1)
				{
					previousState = 1;
					sitting = false;
					mainCollider.isTrigger = true;
					base.creatureAnimator.SetBool("Rage", false);
					base.creatureAnimator.SetBool("Sitting", false);
					base.creatureAnimator.SetBool("triggered", true);
					base.creatureVoice.Stop();
					farAudio.volume = 0.275f;
					farAudio.PlayOneShot(panicSFX);
					base.agent.speed = 0f;
					triggerTime = triggerDuration;
				}
				triggerTime -= Time.deltaTime;
				if (triggerTime <= 0f)
				{
					((EnemyAI)this).SwitchToBehaviourState(2);
				}
				break;
			case 2:
				mainCollider.isTrigger = true;
				if (previousState != 2)
				{
					mainCollider.isTrigger = true;
					previousState = 2;
					base.creatureAnimator.SetBool("Rage", true);
					base.creatureAnimator.SetBool("triggered", false);
					farAudio.Stop();
					farAudio.volume = 0.4f;
					farAudio.clip = screamSFX;
					farAudio.Play();
				}
				break;
			}
			((EnemyAI)this).Update();
		}

		public void SetEnemyOutside(bool outside = false)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			base.isOutside = outside;
			mainEntrancePosition = RoundManager.Instance.GetNavMeshPosition(RoundManager.FindMainEntrancePosition(true, outside), default(NavMeshHit), 5f, -1);
			if (outside)
			{
				base.allAINodes = GameObject.FindGameObjectsWithTag("OutsideAINode");
			}
			else
			{
				base.allAINodes = GameObject.FindGameObjectsWithTag("AINode");
			}
		}

		public override void OnCollideWithPlayer(Collider other)
		{
			if (!Object.op_Implicit((Object)(object)((Component)other).gameObject.GetComponent<PlayerControllerB>()))
			{
				return;
			}
			((EnemyAI)this).OnCollideWithPlayer(other);
			if (!inKillAnimation && !base.isEnemyDead && base.currentBehaviourStateIndex == 2)
			{
				PlayerControllerB val = ((EnemyAI)this).MeetsStandardPlayerCollisionConditions(other, false, false);
				if ((Object)(object)val != (Object)null)
				{
					inKillAnimation = true;
					((MonoBehaviour)this).StartCoroutine(killPlayerAnimation((int)val.playerClientId));
					KillPlayerServerRpc((int)val.playerClientId);
				}
			}
		}

		[ServerRpc(RequireOwnership = false)]
		private void KillPlayerServerRpc(int playerId)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Invalid comparison between Unknown and I4
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Invalid comparison between Unknown and I4
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
				{
					ServerRpcParams val = default(ServerRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(2556963367u, val, (RpcDelivery)0);
					BytePacker.WriteValueBitPacked(val2, playerId);
					((NetworkBehaviour)this).__endSendServerRpc(ref val2, 2556963367u, val, (RpcDelivery)0);
				}
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost))
				{
					KillPlayerClientRpc(playerId);
				}
			}
		}

		[ClientRpc]
		private void KillPlayerClientRpc(int playerId)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Invalid comparison between Unknown and I4
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Invalid comparison between Unknown and I4
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
				{
					ClientRpcParams val = default(ClientRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(2298532976u, val, (RpcDelivery)0);
					BytePacker.WriteValueBitPacked(val2, playerId);
					((NetworkBehaviour)this).__endSendClientRpc(ref val2, 2298532976u, val, (RpcDelivery)0);
				}
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
				{
					((MonoBehaviour)this).StartCoroutine(killPlayerAnimation(playerId));
				}
			}
		}

		private IEnumerator killPlayerAnimation(int playerId)
		{
			inKillAnimation = true;
			PlayerControllerB playerScript = StartOfRound.Instance.allPlayerScripts[playerId];
			if (base.isOutside && ((Component)this).transform.position.y < -80f)
			{
				SetEnemyOutside();
			}
			else if (!base.isOutside && ((Component)this).transform.position.y > -80f)
			{
				SetEnemyOutside(outside: true);
			}
			int preAmount = SCP096Targets.Count;
			playerScript.KillPlayer(Vector3.zero, true, (CauseOfDeath)6, 0);
			AddTargetToList(playerId, remove: true);
			base.creatureSFX.PlayOneShot(killPlayerSFX);
			base.creatureAnimator.SetInteger("TargetsLeft", preAmount - 1);
			base.creatureAnimator.SetTrigger("kill");
			if (preAmount - 1 <= 0)
			{
				SitDown();
			}
			if (Config.deathMakesBloody && (Object)(object)bloodyMaterial != (Object)null)
			{
				Transform model = ((Component)this).transform.Find("SCP096Model");
				if ((Object)(object)model != (Object)null)
				{
					Transform modelMesh = model.Find("tsg_placeholder");
					if ((Object)(object)modelMesh != (Object)null)
					{
						SkinnedMeshRenderer skinnedModel = ((Component)modelMesh).GetComponent<SkinnedMeshRenderer>();
						if ((Object)(object)skinnedModel != (Object)null)
						{
							((Renderer)skinnedModel).material = bloodyMaterial;
						}
					}
				}
			}
			yield return (object)new WaitForSeconds(1f);
			inKillAnimation = false;
		}

		public void SitDown()
		{
			((EnemyAI)this).SwitchToBehaviourState(0);
			SitDownOnLocalClient();
			SitDownServerRpc();
		}

		[ServerRpc(RequireOwnership = false)]
		private void SitDownServerRpc()
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Invalid comparison between Unknown and I4
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Invalid comparison between Unknown and I4
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
				{
					ServerRpcParams val = default(ServerRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(652446748u, val, (RpcDelivery)0);
					((NetworkBehaviour)this).__endSendServerRpc(ref val2, 652446748u, val, (RpcDelivery)0);
				}
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost))
				{
					SitDownClientRpc();
				}
			}
		}

		[ClientRpc]
		private void SitDownClientRpc()
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Invalid comparison between Unknown and I4
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Invalid comparison between Unknown and I4
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
				{
					ClientRpcParams val = default(ClientRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(2536632143u, val, (RpcDelivery)0);
					((NetworkBehaviour)this).__endSendClientRpc(ref val2, 2536632143u, val, (RpcDelivery)0);
				}
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
				{
					SitDownOnLocalClient();
				}
			}
		}

		public void SitDownOnLocalClient()
		{
			sitting = true;
			roamWaitTime = Random.Range(45f, 50f);
			base.creatureAnimator.SetBool("Rage", false);
			base.creatureAnimator.SetBool("Sitting", true);
		}

		public void AddTargetToList(int playerId, bool remove = false)
		{
			PlayerControllerB item = StartOfRound.Instance.allPlayerScripts[playerId];
			if (remove)
			{
				if (!SCP096Targets.Contains(item))
				{
					return;
				}
			}
			else if (SCP096Targets.Contains(item))
			{
				return;
			}
			AddTargetToListOnLocalClient(playerId, remove);
			AddTargetToListServerRpc(playerId, remove);
		}

		[ServerRpc(RequireOwnership = false)]
		public void AddTargetToListServerRpc(int playerId, bool remove)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Invalid comparison between Unknown and I4
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Invalid comparison between Unknown and I4
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: 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)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
				{
					ServerRpcParams val = default(ServerRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(1207108010u, val, (RpcDelivery)0);
					BytePacker.WriteValueBitPacked(val2, playerId);
					((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref remove, default(ForPrimitives));
					((NetworkBehaviour)this).__endSendServerRpc(ref val2, 1207108010u, val, (RpcDelivery)0);
				}
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost))
				{
					AddTargetToListClientRpc(playerId, remove);
				}
			}
		}

		[ClientRpc]
		public void AddTargetToListClientRpc(int playerId, bool remove)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Invalid comparison between Unknown and I4
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Invalid comparison between Unknown and I4
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: 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)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
				{
					ClientRpcParams val = default(ClientRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(1413965488u, val, (RpcDelivery)0);
					BytePacker.WriteValueBitPacked(val2, playerId);
					((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref remove, default(ForPrimitives));
					((NetworkBehaviour)this).__endSendClientRpc(ref val2, 1413965488u, val, (RpcDelivery)0);
				}
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
				{
					AddTargetToListOnLocalClient(playerId, remove);
				}
			}
		}

		public void AddTargetToListOnLocalClient(int playerId, bool remove)
		{
			PlayerControllerB item = StartOfRound.Instance.allPlayerScripts[playerId];
			if (remove)
			{
				if (SCP096Targets.Contains(item))
				{
					SCP096Targets.Remove(item);
				}
			}
			else if (!SCP096Targets.Contains(item))
			{
				SCP096Targets.Add(item);
			}
		}

		private void SetShyGuyInitialValues()
		{
			mainCollider = ((Component)this).gameObject.GetComponentInChildren<Collider>();
			farAudio = ((Component)((Component)this).transform.Find("FarAudio")).GetComponent<AudioSource>();
			base.targetPlayer = null;
			inKillAnimation = false;
			SCP096Targets.Clear();
			base.creatureAnimator.SetFloat("VelocityX", 0f);
			base.creatureAnimator.SetFloat("VelocityZ", 0f);
			base.creatureAnimator.SetFloat("DistanceToTarget", 999f);
			base.creatureAnimator.SetInteger("SitActionTimer", 0);
			base.creatureAnimator.SetInteger("TargetsLeft", 0);
			base.creatureAnimator.SetBool("Rage", false);
			base.creatureAnimator.SetBool("Sitting", false);
			base.creatureAnimator.SetBool("triggered", false);
			mainCollider.isTrigger = true;
			farAudio.volume = 0f;
			farAudio.Stop();
			base.creatureVoice.Stop();
		}

		protected override void __initializeVariables()
		{
			((EnemyAI)this).__initializeVariables();
		}

		[RuntimeInitializeOnLoadMethod]
		internal static void InitializeRPCS_ShyGuyAI()
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Expected O, but got Unknown
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Expected O, but got Unknown
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Expected O, but got Unknown
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Expected O, but got Unknown
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Expected O, but got Unknown
			Dictionary<uint, RpcReceiveHandler> _rpc_func_table = NetworkManager.__rpc_func_table;
			object obj = <>O.<0>____rpc_handler_2556963367;
			if (obj == null)
			{
				RpcReceiveHandler val = __rpc_handler_2556963367;
				<>O.<0>____rpc_handler_2556963367 = val;
				obj = (object)val;
			}
			_rpc_func_table.Add(2556963367u, (RpcReceiveHandler)obj);
			Dictionary<uint, RpcReceiveHandler> _rpc_func_table2 = NetworkManager.__rpc_func_table;
			object obj2 = <>O.<1>____rpc_handler_2298532976;
			if (obj2 == null)
			{
				RpcReceiveHandler val2 = __rpc_handler_2298532976;
				<>O.<1>____rpc_handler_2298532976 = val2;
				obj2 = (object)val2;
			}
			_rpc_func_table2.Add(2298532976u, (RpcReceiveHandler)obj2);
			Dictionary<uint, RpcReceiveHandler> _rpc_func_table3 = NetworkManager.__rpc_func_table;
			object obj3 = <>O.<2>____rpc_handler_652446748;
			if (obj3 == null)
			{
				RpcReceiveHandler val3 = __rpc_handler_652446748;
				<>O.<2>____rpc_handler_652446748 = val3;
				obj3 = (object)val3;
			}
			_rpc_func_table3.Add(652446748u, (RpcReceiveHandler)obj3);
			Dictionary<uint, RpcReceiveHandler> _rpc_func_table4 = NetworkManager.__rpc_func_table;
			object obj4 = <>O.<3>____rpc_handler_2536632143;
			if (obj4 == null)
			{
				RpcReceiveHandler val4 = __rpc_handler_2536632143;
				<>O.<3>____rpc_handler_2536632143 = val4;
				obj4 = (object)val4;
			}
			_rpc_func_table4.Add(2536632143u, (RpcReceiveHandler)obj4);
			Dictionary<uint, RpcReceiveHandler> _rpc_func_table5 = NetworkManager.__rpc_func_table;
			object obj5 = <>O.<4>____rpc_handler_1207108010;
			if (obj5 == null)
			{
				RpcReceiveHandler val5 = __rpc_handler_1207108010;
				<>O.<4>____rpc_handler_1207108010 = val5;
				obj5 = (object)val5;
			}
			_rpc_func_table5.Add(1207108010u, (RpcReceiveHandler)obj5);
			Dictionary<uint, RpcReceiveHandler> _rpc_func_table6 = NetworkManager.__rpc_func_table;
			object obj6 = <>O.<5>____rpc_handler_1413965488;
			if (obj6 == null)
			{
				RpcReceiveHandler val6 = __rpc_handler_1413965488;
				<>O.<5>____rpc_handler_1413965488 = val6;
				obj6 = (object)val6;
			}
			_rpc_func_table6.Add(1413965488u, (RpcReceiveHandler)obj6);
		}

		private static void __rpc_handler_2556963367(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				int playerId = default(int);
				ByteUnpacker.ReadValueBitPacked(reader, ref playerId);
				((NetworkBehaviour)(ShyGuyAI)(object)target).__rpc_exec_stage = (__RpcExecStage)1;
				((ShyGuyAI)(object)target).KillPlayerServerRpc(playerId);
				((NetworkBehaviour)(ShyGuyAI)(object)target).__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_2298532976(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				int playerId = default(int);
				ByteUnpacker.ReadValueBitPacked(reader, ref playerId);
				((NetworkBehaviour)(ShyGuyAI)(object)target).__rpc_exec_stage = (__RpcExecStage)2;
				((ShyGuyAI)(object)target).KillPlayerClientRpc(playerId);
				((NetworkBehaviour)(ShyGuyAI)(object)target).__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_652446748(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				((NetworkBehaviour)(ShyGuyAI)(object)target).__rpc_exec_stage = (__RpcExecStage)1;
				((ShyGuyAI)(object)target).SitDownServerRpc();
				((NetworkBehaviour)(ShyGuyAI)(object)target).__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_2536632143(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				((NetworkBehaviour)(ShyGuyAI)(object)target).__rpc_exec_stage = (__RpcExecStage)2;
				((ShyGuyAI)(object)target).SitDownClientRpc();
				((NetworkBehaviour)(ShyGuyAI)(object)target).__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_1207108010(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0019: 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)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				int playerId = default(int);
				ByteUnpacker.ReadValueBitPacked(reader, ref playerId);
				bool remove = default(bool);
				((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref remove, default(ForPrimitives));
				((NetworkBehaviour)(ShyGuyAI)(object)target).__rpc_exec_stage = (__RpcExecStage)1;
				((ShyGuyAI)(object)target).AddTargetToListServerRpc(playerId, remove);
				((NetworkBehaviour)(ShyGuyAI)(object)target).__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_1413965488(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0019: 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)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				int playerId = default(int);
				ByteUnpacker.ReadValueBitPacked(reader, ref playerId);
				bool remove = default(bool);
				((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref remove, default(ForPrimitives));
				((NetworkBehaviour)(ShyGuyAI)(object)target).__rpc_exec_stage = (__RpcExecStage)2;
				((ShyGuyAI)(object)target).AddTargetToListClientRpc(playerId, remove);
				((NetworkBehaviour)(ShyGuyAI)(object)target).__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		protected override string __getTypeName()
		{
			return "ShyGuyAI";
		}
	}
}
namespace Scopophobia
{
	[Serializable]
	public class Config : SyncedInstance<Config>
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static HandleNamedMessageDelegate <0>__OnRequestSync;

			public static HandleNamedMessageDelegate <1>__OnReceiveSync;
		}

		public static ConfigEntry<bool> AppearsConfig;

		public static ConfigEntry<bool> HasGlowingEyesConfig;

		public static ConfigEntry<string> SoundPackConfig;

		public static ConfigEntry<bool> BloodyTextureConfig;

		public static ConfigEntry<bool> DeathMakesBloodyConfig;

		public static ConfigEntry<float> SpeedDocileMultiplierConfig;

		public static ConfigEntry<float> SpeedRageMultiplierConfig;

		public static ConfigEntry<int> SpawnRarityConfig;

		public static ConfigEntry<float> TriggerTimeConfig;

		public static ConfigEntry<float> FaceTriggerRangeConfig;

		public static ConfigEntry<float> FaceTriggerGracePeriodConfig;

		public static ConfigEntry<bool> HasMaxTargetsConfig;

		public static ConfigEntry<int> MaxTargetsConfig;

		public static ConfigEntry<bool> CanExitFacilityConfig;

		public static ConfigEntry<int> MaxSpawnCountConfig;

		public static ConfigEntry<bool> CanSpawnOutsideConfig;

		public static ConfigEntry<bool> SpawnOutsideHardPlanetsConfig;

		public static ConfigEntry<float> StartEnemySpawnCurveConfig;

		public static ConfigEntry<float> MidEnemySpawnCurveConfig;

		public static ConfigEntry<float> EndEnemySpawnCurveConfig;

		public static bool appears;

		public static bool hasGlowingEyes;

		public static string soundPack;

		public static bool bloodyTexture;

		public static bool deathMakesBloody;

		public static float speedDocileMultiplier;

		public static float speedRageMultiplier;

		public static int spawnRarity;

		public static float triggerTime;

		public static float faceTriggerRange;

		public static float faceTriggerGracePeriod;

		public static bool hasMaxTargets;

		public static int maxTargets;

		public static bool canExitFacility;

		public static bool canSpawnOutside;

		public static int maxSpawnCount;

		public static bool spawnsOutside;

		public static bool spawnOutsideHardPlanets;

		public static float startEnemySpawnCurve;

		public static float midEnemySpawnCurve;

		public static float endEnemySpawnCurve;

		public Config(ConfigFile cfg)
		{
			InitInstance(this);
			AppearsConfig = cfg.Bind<bool>("General", "Enable the Shy Guy", true, "Allows the Shy Guy to spawn in-game.");
			HasGlowingEyesConfig = cfg.Bind<bool>("Appearance", "Glowing Eyes", true, "Gives the Shy Guy glowing eyes similar to the Bracken/Flowerman.");
			BloodyTextureConfig = cfg.Bind<bool>("Appearance", "Bloody Texture", false, "Gives the Shy Guy his bloodier, original texture from SCP: Containment Breach.");
			DeathMakesBloodyConfig = cfg.Bind<bool>("Appearance", "Bloody Death", true, "Causes the Shy Guy's material to become bloody once getting his first kill. Useless if Bloody Texture is enabled lol");
			SoundPackConfig = cfg.Bind<string>("Appearance", "Sound Pack (Curated, SCPCB, SCPCBOld, SecretLab)", "Curated", "Determines the sounds the Shy Guy uses. (SOME MAY NOT SYNC WELL WITH TRIGGER TIME) (Curated = Default, curated for the Lethal Company experience) (SCPCB = SCP-096 sounds from SCP: Containment Breach) (SCPCBOld = Old alpha SCP-096 sounds from SCP: Containment Breach) (SecretLab = SCP-096 sounds from SCP: Secret Laboratory)");
			SpeedDocileMultiplierConfig = cfg.Bind<float>("Values", "Speed Multiplier (Docile)", 1f, "Determines the speed multiplier of the Shy Guy while docile.");
			SpeedRageMultiplierConfig = cfg.Bind<float>("Values", "Speed Multiplier (Rage)", 1f, "Determines the speed multiplier of the Shy Guy while enraged.");
			SpawnRarityConfig = cfg.Bind<int>("Values", "Spawn Rarity", 15, "Determines the spawn weight of the Shy Guy. Higher weights mean the Shy Guy is more likely appear. (just dont set this astronomically high)");
			TriggerTimeConfig = cfg.Bind<float>("Values.Triggering", "Trigger Time", 66.4f, "Determines how long the Shy Guy must remain in the Triggered state to become fully enraged.");
			FaceTriggerRangeConfig = cfg.Bind<float>("Values.Triggering", "Face Trigger Range", 17.5f, "Determines the face's trigger radius.");
			FaceTriggerGracePeriodConfig = cfg.Bind<float>("Values.Triggering", "Face Trigger Grace Period", 0.5f, "Determines the grace period when you see the face of the Shy Guy before he becomes enraged.");
			HasMaxTargetsConfig = cfg.Bind<bool>("Values.Triggering", "Has Max Targets", false, "Determines if the Shy Guy has a maximum amount of targets.");
			MaxTargetsConfig = cfg.Bind<int>("Values.Triggering", "Max Targets", 32, "Determines the max amount of targets the Shy Guy can have. (requires HasMaxTargets)");
			CanExitFacilityConfig = cfg.Bind<bool>("Values.Triggering", "Can Exit Facility", true, "Determines if the Shy Guy can exit the facility and into the outdoors (and vice versa) to attack its target.");
			MaxSpawnCountConfig = cfg.Bind<int>("Values.Spawning", "Max Spawn Count", 1, "Determines how many Shy Guy can spawn total.");
			CanSpawnOutsideConfig = cfg.Bind<bool>("Values.Spawning", "Can Spawn Outside", true, "Determines if the Shy Guy can spawn outside. ");
			SpawnOutsideHardPlanetsConfig = cfg.Bind<bool>("Values.Spawning", "Spawn Outside Only Hard Moons", true, "If set to true, the Shy Guy will only spawn outside on the highest-difficulty/modded moons.");
			StartEnemySpawnCurveConfig = cfg.Bind<float>("Values.Spawning", "Start Spawn Curve", 0.2f, "Spawn curve for the Shy Guy when the day starts. (typically 0-1)");
			MidEnemySpawnCurveConfig = cfg.Bind<float>("Values.Spawning", "Midday Spawn Curve", 1f, "Spawn curve for the Shy Guy midday. (typically 0-1)");
			EndEnemySpawnCurveConfig = cfg.Bind<float>("Values.Spawning", "End of Day Spawn Curve", 0.75f, "Spawn curve for the Shy Guy at the end of day. (typically 0-1)");
			appears = AppearsConfig.Value;
			hasGlowingEyes = HasGlowingEyesConfig.Value;
			bloodyTexture = BloodyTextureConfig.Value;
			deathMakesBloody = DeathMakesBloodyConfig.Value;
			soundPack = SoundPackConfig.Value;
			speedDocileMultiplier = SpeedDocileMultiplierConfig.Value;
			speedRageMultiplier = SpeedRageMultiplierConfig.Value;
			spawnRarity = SpawnRarityConfig.Value;
			triggerTime = TriggerTimeConfig.Value;
			faceTriggerRange = FaceTriggerRangeConfig.Value;
			faceTriggerGracePeriod = FaceTriggerGracePeriodConfig.Value;
			hasMaxTargets = HasMaxTargetsConfig.Value;
			maxTargets = MaxTargetsConfig.Value;
			canExitFacility = CanExitFacilityConfig.Value;
			maxSpawnCount = MaxSpawnCountConfig.Value;
			canSpawnOutside = CanSpawnOutsideConfig.Value;
			spawnOutsideHardPlanets = SpawnOutsideHardPlanetsConfig.Value;
			startEnemySpawnCurve = StartEnemySpawnCurveConfig.Value;
			midEnemySpawnCurve = MidEnemySpawnCurveConfig.Value;
			endEnemySpawnCurve = EndEnemySpawnCurveConfig.Value;
		}

		public static void RequestSync()
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			if (!SyncedInstance<Config>.IsClient)
			{
				return;
			}
			FastBufferWriter val = default(FastBufferWriter);
			((FastBufferWriter)(ref val))..ctor(SyncedInstance<Config>.IntSize, (Allocator)2, -1);
			try
			{
				SyncedInstance<Config>.MessageManager.SendNamedMessage("Scopophobia_OnRequestConfigSync", 0uL, val, (NetworkDelivery)3);
			}
			finally
			{
				((IDisposable)(FastBufferWriter)(ref val)).Dispose();
			}
		}

		public static void OnRequestSync(ulong clientId, FastBufferReader _)
		{
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			if (!SyncedInstance<Config>.IsHost)
			{
				return;
			}
			Plugin.logger.LogInfo((object)$"Config sync request received from client: {clientId}");
			byte[] array = SyncedInstance<Config>.SerializeToBytes(SyncedInstance<Config>.Instance);
			int num = array.Length;
			FastBufferWriter val = default(FastBufferWriter);
			((FastBufferWriter)(ref val))..ctor(num + SyncedInstance<Config>.IntSize, (Allocator)2, -1);
			try
			{
				((FastBufferWriter)(ref val)).WriteValueSafe<int>(ref num, default(ForPrimitives));
				((FastBufferWriter)(ref val)).WriteBytesSafe(array, -1, 0);
				SyncedInstance<Config>.MessageManager.SendNamedMessage("Scopophobia_OnReceiveConfigSync", clientId, val, (NetworkDelivery)3);
			}
			catch (Exception arg)
			{
				Plugin.logger.LogInfo((object)$"Error occurred syncing config with client: {clientId}\n{arg}");
			}
			finally
			{
				((IDisposable)(FastBufferWriter)(ref val)).Dispose();
			}
		}

		public static void OnReceiveSync(ulong _, FastBufferReader reader)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			if (!((FastBufferReader)(ref reader)).TryBeginRead(SyncedInstance<Config>.IntSize))
			{
				Plugin.logger.LogError((object)"Config sync error: Could not begin reading buffer.");
				return;
			}
			int num = default(int);
			((FastBufferReader)(ref reader)).ReadValueSafe<int>(ref num, default(ForPrimitives));
			if (!((FastBufferReader)(ref reader)).TryBeginRead(num))
			{
				Plugin.logger.LogError((object)"Config sync error: Host could not sync.");
				return;
			}
			byte[] data = new byte[num];
			((FastBufferReader)(ref reader)).ReadBytesSafe(ref data, num, 0);
			SyncedInstance<Config>.SyncInstance(data);
			Plugin.logger.LogInfo((object)"Successfully synced config with host.");
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(PlayerControllerB), "ConnectClientToPlayerObject")]
		public static void InitializeLocalPlayer()
		{
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Expected O, but got Unknown
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Expected O, but got Unknown
			if (SyncedInstance<Config>.IsHost)
			{
				CustomMessagingManager messageManager = SyncedInstance<Config>.MessageManager;
				object obj = <>O.<0>__OnRequestSync;
				if (obj == null)
				{
					HandleNamedMessageDelegate val = OnRequestSync;
					<>O.<0>__OnRequestSync = val;
					obj = (object)val;
				}
				messageManager.RegisterNamedMessageHandler("Scopophobia_OnRequestConfigSync", (HandleNamedMessageDelegate)obj);
				SyncedInstance<Config>.Synced = true;
				return;
			}
			SyncedInstance<Config>.Synced = false;
			CustomMessagingManager messageManager2 = SyncedInstance<Config>.MessageManager;
			object obj2 = <>O.<1>__OnReceiveSync;
			if (obj2 == null)
			{
				HandleNamedMessageDelegate val2 = OnReceiveSync;
				<>O.<1>__OnReceiveSync = val2;
				obj2 = (object)val2;
			}
			messageManager2.RegisterNamedMessageHandler("Scopophobia_OnReceiveConfigSync", (HandleNamedMessageDelegate)obj2);
			RequestSync();
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(GameNetworkManager), "StartDisconnect")]
		public static void PlayerLeave()
		{
			SyncedInstance<Config>.RevertSync();
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "Scopophobia";

		public const string PLUGIN_NAME = "Scopophobia";

		public const string PLUGIN_VERSION = "1.1.2";
	}
	[BepInPlugin("Scopophobia", "Scopophobia", "1.1.2")]
	public class ScopophobiaPlugin : BaseUnityPlugin
	{
		private readonly Harmony harmony = new Harmony("Scopophobia");

		public static EnemyType shyGuy;

		public static AssetBundle Assets;

		public static bool spawnsOutside;

		public static SpawnableEnemyWithRarity maskedPrefab;

		public static ManualLogSource logger;

		public static SpawnableEnemyWithRarity shyPrefab;

		public static Config MyConfig { get; internal set; }

		internal Assembly assembly => Assembly.GetExecutingAssembly();

		internal string GetFilePath(string path)
		{
			return assembly.Location.Replace(assembly.GetName().Name + ".dll", path);
		}

		private void LoadAssets()
		{
			try
			{
				Assets = AssetBundle.LoadFromFile(GetFilePath("scp096"));
			}
			catch (Exception arg)
			{
				logger.LogError((object)$"Failed to load asset bundle! {arg}");
			}
		}

		private void Awake()
		{
			harmony.PatchAll(typeof(Config));
			LoadAssets();
			logger = ((BaseUnityPlugin)this).Logger;
			MyConfig = new Config(((BaseUnityPlugin)this).Config);
			ConfigEntry<bool> val = default(ConfigEntry<bool>);
			((BaseUnityPlugin)this).Config.TryGetEntry<bool>("General", "Enable the Shy Guy", ref val);
			if (!val.Value)
			{
				return;
			}
			ConfigEntry<int> val2 = default(ConfigEntry<int>);
			((BaseUnityPlugin)this).Config.TryGetEntry<int>("Values", "Spawn Rarity", ref val2);
			int num = val2?.Value ?? 15;
			shyGuy = Assets.LoadAsset<EnemyType>("ShyGuyDef.asset");
			TerminalNode val3 = Assets.LoadAsset<TerminalNode>("ShyGuyTerminal.asset");
			TerminalKeyword val4 = Assets.LoadAsset<TerminalKeyword>("ShyGuyKeyword.asset");
			NetworkPrefabs.RegisterNetworkPrefab(shyGuy.enemyPrefab);
			Enemies.RegisterEnemy(shyGuy, num, (LevelTypes)(-1), (SpawnType)0, val3, val4);
			Type[] types = Assembly.GetExecutingAssembly().GetTypes();
			Type[] array = types;
			Type[] array2 = array;
			foreach (Type type in array2)
			{
				MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic);
				MethodInfo[] array3 = methods;
				MethodInfo[] array4 = array3;
				foreach (MethodInfo methodInfo in array4)
				{
					object[] customAttributes = methodInfo.GetCustomAttributes(typeof(RuntimeInitializeOnLoadMethodAttribute), inherit: false);
					if (customAttributes.Length != 0)
					{
						methodInfo.Invoke(null, null);
					}
				}
			}
			logger.LogInfo((object)"Scopophobia | SCP-096 has entered the facility. All remaining personnel proceed with caution.");
			logger.LogInfo((object)"Patched for v50 by TheUnknownCod3r, originally by JasperCreations");
			harmony.PatchAll(typeof(Plugin));
			harmony.PatchAll(typeof(GetShyGuyPrefabForLaterUse));
			harmony.PatchAll(typeof(ShyGuySpawnSettings));
		}
	}
}
namespace Scopophobia.Patches
{
	[HarmonyPatch]
	internal class GetShyGuyPrefabForLaterUse
	{
		[HarmonyPatch(typeof(Terminal), "Start")]
		[HarmonyPostfix]
		private static void SavesPrefabForLaterUse(ref SelectableLevel[] ___moonsCatalogueList)
		{
			SelectableLevel[] array = ___moonsCatalogueList;
			SelectableLevel[] array2 = array;
			SelectableLevel[] array3 = array2;
			foreach (SelectableLevel val in array3)
			{
				foreach (SpawnableEnemyWithRarity enemy in val.Enemies)
				{
					if (enemy.enemyType.enemyName == "Shy guy")
					{
						ScopophobiaPlugin.shyPrefab = enemy;
					}
				}
			}
		}
	}
	[HarmonyPatch(typeof(RoundManager))]
	internal class ShyGuySpawnSettings
	{
		public static string[] nonoOutside = new string[5] { "Level1Experimentation", "Level2Assurance", "Level3Vow", "Level4March", "Level7Offense" };

		[HarmonyPatch("BeginEnemySpawning")]
		[HarmonyPrefix]
		private static void UpdateSpawnRates(ref SelectableLevel ___currentLevel)
		{
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Expected O, but got Unknown
			if (!Config.appears || ScopophobiaPlugin.shyPrefab == null)
			{
				return;
			}
			try
			{
				SpawnableEnemyWithRarity shyPrefab = ScopophobiaPlugin.shyPrefab;
				List<SpawnableEnemyWithRarity> enemies = ___currentLevel.Enemies;
				for (int i = 0; i < ___currentLevel.Enemies.Count; i++)
				{
					SpawnableEnemyWithRarity val = ___currentLevel.Enemies[i];
					if (val.enemyType.enemyName == "Shy guy")
					{
						enemies.Remove(val);
					}
				}
				___currentLevel.Enemies = enemies;
				shyPrefab.enemyType.PowerLevel = 3f;
				shyPrefab.rarity = Config.spawnRarity;
				shyPrefab.enemyType.probabilityCurve = new AnimationCurve((Keyframe[])(object)new Keyframe[3]
				{
					new Keyframe(0f, Config.startEnemySpawnCurve),
					new Keyframe(0.5f, Config.midEnemySpawnCurve),
					new Keyframe(1f, Config.endEnemySpawnCurve)
				});
				shyPrefab.enemyType.MaxCount = Config.maxSpawnCount;
				shyPrefab.enemyType.isOutsideEnemy = Config.canSpawnOutside;
				if (Config.canSpawnOutside & (!Config.spawnOutsideHardPlanets || !nonoOutside.Contains(___currentLevel.sceneName)))
				{
					___currentLevel.OutsideEnemies.Add(shyPrefab);
					SelectableLevel val2 = ___currentLevel;
					val2.maxOutsideEnemyPowerCount += shyPrefab.enemyType.MaxCount * (int)shyPrefab.enemyType.PowerLevel;
				}
				___currentLevel.Enemies.Add(shyPrefab);
			}
			catch
			{
			}
		}
	}
}
namespace Scopophobia.NetcodePatcher
{
	[AttributeUsage(AttributeTargets.Module)]
	internal class NetcodePatchedAssemblyAttribute : Attribute
	{
	}
}

plugins/StrangerThingsMod.dll

Decompiled 2 years ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using LethalLib.Modules;
using Microsoft.CodeAnalysis;
using Unity.Netcode;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("StrangerThingsMod")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("A mod that adds stuff from Stranger Things, such as a new Demogoron enemy")]
[assembly: AssemblyFileVersion("0.0.31.0")]
[assembly: AssemblyInformationalVersion("0.0.31+ae62236394be7f66cf555222e16379a9b4ffe3ed")]
[assembly: AssemblyProduct("StrangerThingsMod")]
[assembly: AssemblyTitle("StrangerThingsMod")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.31.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 StrangerThingsMod
{
	public static class CarriedPlayerManager
	{
		public static PlayerControllerB CarriedPlayer { get; private set; }

		public static bool IsPlayerCarried(PlayerControllerB carriedPlayer)
		{
			return (Object)(object)CarriedPlayer == (Object)(object)carriedPlayer;
		}

		public static void SetCarriedPlayer(PlayerControllerB carriedPlayer)
		{
			CarriedPlayer = carriedPlayer;
		}

		public static void ClearCarriedPlayer()
		{
			CarriedPlayer = null;
		}
	}
	public class Config
	{
		public static ConfigEntry<int> DemogorgonSpawnWeight;

		public static ConfigEntry<bool> EnableFlickeringLights;

		public static ConfigEntry<string> version;

		public static void Load()
		{
			DemogorgonSpawnWeight = Plugin.config.Bind<int>("Enemies", "DemogorgonSpawnWeight", 10, "The weight of the Demogorgon spawning in the level. Higher values mean it will spawn more often.");
			EnableFlickeringLights = Plugin.config.Bind<bool>("General", "FlickeringLights", true, "Enable or disable flickering lights and sound when the Demogorgon is nearby.");
			version = Plugin.config.Bind<string>("Misc", "Version", "1.0.1", "Version of the mod config.");
		}
	}
	public class Content
	{
		public class CustomEnemy
		{
			public string name;

			public string enemyPath;

			public int rarity;

			public LevelTypes levelFlags;

			public SpawnType spawnType;

			public string infoKeyword;

			public string infoNode;

			public bool enabled = true;

			public CustomEnemy(string name, string enemyPath, int rarity, LevelTypes levelFlags, SpawnType spawnType, string infoKeyword, string infoNode)
			{
				//IL_0025: 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)
				//IL_002d: Unknown result type (might be due to invalid IL or missing references)
				//IL_002f: Unknown result type (might be due to invalid IL or missing references)
				this.name = name;
				this.enemyPath = enemyPath;
				this.rarity = rarity;
				this.levelFlags = levelFlags;
				this.spawnType = spawnType;
				this.infoKeyword = infoKeyword;
				this.infoNode = infoNode;
			}

			public static CustomEnemy Add(string name, string enemyPath, int rarity, LevelTypes levelFlags, SpawnType spawnType, string infoKeyword, string infoNode, bool enabled = true)
			{
				//IL_0004: Unknown result type (might be due to invalid IL or missing references)
				//IL_0005: Unknown result type (might be due to invalid IL or missing references)
				CustomEnemy customEnemy = new CustomEnemy(name, enemyPath, rarity, levelFlags, spawnType, infoKeyword, infoNode);
				customEnemy.enabled = enabled;
				return customEnemy;
			}
		}

		public static List<CustomEnemy> customEnemies;

		public static AssetBundle MainAssets;

		public static Dictionary<string, GameObject> Prefabs = new Dictionary<string, GameObject>();

		public static void TryLoadAssets()
		{
			if ((Object)(object)MainAssets == (Object)null)
			{
				MainAssets = AssetBundle.LoadFromFile(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "demogorgonenemy"));
				Plugin.logger.LogInfo((object)"Loaded asset bundle");
			}
		}

		public static AudioClip LoadAudioClip(string clipName)
		{
			if ((Object)(object)MainAssets == (Object)null)
			{
				Plugin.logger.LogWarning((object)"MainAssets is null, cannot load audio clip.");
				return null;
			}
			AudioClip val = MainAssets.LoadAsset<AudioClip>(clipName);
			if ((Object)(object)val == (Object)null)
			{
				Plugin.logger.LogWarning((object)("Failed to load audio clip: " + clipName));
			}
			return val;
		}

		public static void Load()
		{
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			TryLoadAssets();
			customEnemies = new List<CustomEnemy> { CustomEnemy.Add("Demogorgon", "Assets/Demogorgon/Demogorgon.asset", Config.DemogorgonSpawnWeight.Value, (LevelTypes)(-1), (SpawnType)0, null, "DemogorgonTN") };
			foreach (CustomEnemy customEnemy in customEnemies)
			{
				if (customEnemy.enabled)
				{
					EnemyType val = MainAssets.LoadAsset<EnemyType>(customEnemy.enemyPath);
					TerminalNode val2 = MainAssets.LoadAsset<TerminalNode>(customEnemy.infoNode);
					TerminalKeyword val3 = null;
					if (customEnemy.infoKeyword != null)
					{
						val3 = MainAssets.LoadAsset<TerminalKeyword>(customEnemy.infoKeyword);
					}
					NetworkPrefabs.RegisterNetworkPrefab(val.enemyPrefab);
					Prefabs.Add(customEnemy.name, val.enemyPrefab);
					Enemies.RegisterEnemy(val, customEnemy.rarity, customEnemy.levelFlags, customEnemy.spawnType, val2, val3);
				}
			}
			Plugin.logger.LogInfo((object)"Loaded content");
		}
	}
	public class DemogorgonAI : EnemyAI
	{
		public enum DemogorgonState
		{
			Wandering,
			Chasing,
			CarryingPlayer,
			Fleeing
		}

		private Animator anim;

		private AudioSource audioSource;

		public AudioClip[] sounds;

		public AudioClip hitDemogorgonSFX;

		private AudioClip demogorgonSpawnSound;

		public AudioClip[] screamSounds;

		private float soundTimer;

		public AISearchRoutine roamMap;

		private PlayerControllerB closestSeenPlayer;

		private PlayerControllerB lastSeenPlayer;

		private bool playerIsInLOS;

		private bool isSwitchingToWandering = false;

		private bool isCarryingPlayer = false;

		private PlayerControllerB carriedPlayer = null;

		public Transform carryPoint;

		private Coroutine damageCoroutine;

		private float pickupCooldownTimer = 0f;

		private bool isFleeing = false;

		private float fleeCooldownTimer = 0f;

		private ManualLogSource myLogSource;

		private bool hasStartedChasing = false;

		public AudioClip[] stepSounds;

		private Vector3 lastStepPosition;

		private float stepDistance = 2f;

		private Random enemyRandom;

		public override void Start()
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			((EnemyAI)this).Start();
			myLogSource = Logger.CreateLogSource("Demogorgon AI");
			myLogSource.LogInfo((object)"Demogorgon Spawned");
			anim = ((Component)this).GetComponent<Animator>();
			audioSource = ((Component)this).GetComponent<AudioSource>();
			lastStepPosition = ((Component)this).transform.position;
			stepSounds = (AudioClip[])(object)new AudioClip[5];
			for (int i = 0; i < 5; i++)
			{
				stepSounds[i] = Content.LoadAudioClip("Footstep" + (i + 1));
			}
			demogorgonSpawnSound = Content.LoadAudioClip("DemogorgonSpawn");
			audioSource.PlayOneShot(demogorgonSpawnSound);
			if (Config.EnableFlickeringLights.Value)
			{
				LightTriggerScript[] array = Object.FindObjectsOfType<LightTriggerScript>();
				LightTriggerScript[] array2 = array;
				foreach (LightTriggerScript lightTriggerScript in array2)
				{
					lightTriggerScript.AddDemogorgon(((Component)this).gameObject);
				}
			}
			enemyRandom = new Random(StartOfRound.Instance.randomMapSeed + base.thisEnemyIndex);
			base.currentBehaviourStateIndex = 0;
			InitializeDemogorgon();
		}

		public void InitializeDemogorgon()
		{
			base.enemyHP = 6;
			soundTimer = 0f;
			isCarryingPlayer = false;
			carriedPlayer = null;
			fleeCooldownTimer = 0f;
			pickupCooldownTimer = 0f;
			base.agent.speed = 4.5f;
			hasStartedChasing = false;
			isFleeing = false;
			isSwitchingToWandering = false;
			closestSeenPlayer = null;
			lastSeenPlayer = null;
			playerIsInLOS = false;
			CarriedPlayerManager.ClearCarriedPlayer();
			base.currentBehaviourStateIndex = 0;
			anim.SetBool("IsWalking", false);
			anim.SetBool("IsRunning", false);
			anim.SetBool("IsCloseRunning", false);
			anim.SetBool("IsCarrying", false);
		}

		public override void Update()
		{
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: 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)
			((EnemyAI)this).Update();
			if (!base.isEnemyDead && !StartOfRound.Instance.allPlayersDead)
			{
				soundTimer += Time.deltaTime;
				if (soundTimer >= 5f)
				{
					PlayRandomSound();
					soundTimer = 0f;
				}
				if (pickupCooldownTimer > 0f)
				{
					pickupCooldownTimer -= Time.deltaTime;
				}
				if (fleeCooldownTimer > 0f)
				{
					fleeCooldownTimer -= Time.deltaTime;
				}
				if (isCarryingPlayer && (Object)(object)carriedPlayer != (Object)null)
				{
					RunAway();
					UpdateCarriedPlayerPositionServerRpc(carryPoint.position, carryPoint.rotation);
					carriedPlayer.ResetFallGravity();
				}
				if (Vector3.Distance(((Component)this).transform.position, lastStepPosition) > stepDistance)
				{
					OnStep();
					lastStepPosition = ((Component)this).transform.position;
				}
				if (base.stunNormalizedTimer > 0f)
				{
					base.agent.speed = 0f;
					ReleasePlayerServerRpc();
				}
			}
		}

		private void OnStep()
		{
			AudioClip val = stepSounds[enemyRandom.Next(0, stepSounds.Length)];
			audioSource.PlayOneShot(val, 0.4f);
		}

		public override void DoAIInterval()
		{
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0268: Unknown result type (might be due to invalid IL or missing references)
			((EnemyAI)this).DoAIInterval();
			if (base.isEnemyDead || StartOfRound.Instance.allPlayersDead)
			{
				return;
			}
			PlayerControllerB val = null;
			switch (base.currentBehaviourStateIndex)
			{
			case 0:
				base.agent.speed = 4.5f;
				DoAnimationsServerRPC(isWalking: true, isRunning: false, isCloseRunning: false, isCarrying: false);
				if (!roamMap.inProgress && !isCarryingPlayer && !base.isEnemyDead && !isFleeing)
				{
					((EnemyAI)this).StartSearch(((Component)this).transform.position, roamMap);
					myLogSource.LogInfo((object)"Starting search...");
				}
				val = ((EnemyAI)this).CheckLineOfSightForPlayer(140f, 25, 6);
				playerIsInLOS = Object.op_Implicit((Object)(object)val);
				if (playerIsInLOS && !val.isPlayerDead && !isCarryingPlayer && !base.isEnemyDead && (Object)(object)CarriedPlayerManager.CarriedPlayer != (Object)(object)val)
				{
					((EnemyAI)this).ChangeOwnershipOfEnemy(val.actualClientId);
					((EnemyAI)this).SwitchToBehaviourClientRpc(1);
				}
				break;
			case 1:
				if (roamMap.inProgress)
				{
					((EnemyAI)this).StopSearch(roamMap, true);
				}
				closestSeenPlayer = ((EnemyAI)this).CheckLineOfSightForClosestPlayer(140f, 25, 6, 0f);
				if ((Object)(object)closestSeenPlayer != (Object)null)
				{
					lastSeenPlayer = closestSeenPlayer;
				}
				playerIsInLOS = Object.op_Implicit((Object)(object)closestSeenPlayer);
				if (playerIsInLOS && !closestSeenPlayer.isPlayerDead && !isCarryingPlayer && !base.isEnemyDead && (Object)(object)CarriedPlayerManager.CarriedPlayer != (Object)(object)closestSeenPlayer)
				{
					base.agent.speed = 7f;
					if (!hasStartedChasing)
					{
						int num = enemyRandom.Next(0, screamSounds.Length);
						audioSource.PlayOneShot(screamSounds[num]);
						WalkieTalkie.TransmitOneShotAudio(audioSource, screamSounds[num], 1f);
						hasStartedChasing = true;
					}
					if ((Object)(object)closestSeenPlayer != (Object)null)
					{
						((EnemyAI)this).SetDestinationToPosition(((Component)closestSeenPlayer).transform.position, false);
					}
					myLogSource.LogInfo((object)("Chasing player! " + ((Object)closestSeenPlayer).name));
					DoAnimationsServerRPC(isWalking: false, isRunning: false, isCloseRunning: true, isCarrying: false);
					isSwitchingToWandering = false;
				}
				else
				{
					if ((Object)(object)lastSeenPlayer != (Object)null)
					{
						((EnemyAI)this).SetDestinationToPosition(((Component)lastSeenPlayer).transform.position, false);
					}
					if (!isSwitchingToWandering)
					{
						myLogSource.LogInfo((object)"Lost sight of player, loosing interest...");
						((MonoBehaviour)this).StartCoroutine(SwitchToWanderingIfLostPlayer(5f));
						isSwitchingToWandering = true;
					}
				}
				break;
			case 2:
				base.agent.speed = 5f;
				if ((Object)(object)carriedPlayer == (Object)null || carriedPlayer.isPlayerDead || base.isEnemyDead)
				{
					myLogSource.LogInfo((object)"Player is dead or enemy is dead or carriedPlayer is null, releasing player...");
					ReleasePlayerServerRpc();
				}
				break;
			case 3:
				if (fleeCooldownTimer <= 0f)
				{
					isFleeing = false;
				}
				if (isFleeing)
				{
					RunAway();
				}
				else
				{
					((EnemyAI)this).SwitchToBehaviourClientRpc(0);
				}
				break;
			default:
				myLogSource.LogWarning((object)"Demogorgon state not found!");
				break;
			}
		}

		public override void OnCollideWithPlayer(Collider other)
		{
			((EnemyAI)this).OnCollideWithPlayer(other);
			if (!base.isEnemyDead && !isCarryingPlayer)
			{
				PlayerControllerB component = ((Component)other).gameObject.GetComponent<PlayerControllerB>();
				if (pickupCooldownTimer <= 0f && !isCarryingPlayer && !component.isPlayerDead && (Object)(object)CarriedPlayerManager.CarriedPlayer != (Object)(object)component)
				{
					myLogSource.LogInfo((object)("Picking up player! " + ((Object)component).name));
					GrabPlayerServerRpc(component.playerClientId);
					((EnemyAI)this).SwitchToBehaviourClientRpc(2);
				}
			}
		}

		private IEnumerator SwitchToWanderingIfLostPlayer(float delay)
		{
			yield return (object)new WaitForSeconds(delay);
			if (isSwitchingToWandering)
			{
				((EnemyAI)this).SwitchToBehaviourClientRpc(0);
				myLogSource.LogInfo((object)"Switching to wandering...");
			}
		}

		[ServerRpc(RequireOwnership = false)]
		public void DoAnimationsServerRPC(bool isWalking, bool isRunning, bool isCloseRunning, bool isCarrying)
		{
			SetAnimationState(isWalking, isRunning, isCloseRunning, isCarrying);
			DoAnimationsClientRPC(isWalking, isRunning, isCloseRunning, isCarrying);
		}

		[ClientRpc]
		public void DoAnimationsClientRPC(bool isWalking, bool isRunning, bool isCloseRunning, bool isCarrying)
		{
			SetAnimationState(isWalking, isRunning, isCloseRunning, isCarrying);
		}

		private void SetAnimationState(bool isWalking, bool isRunning, bool isCloseRunning, bool isCarrying)
		{
			anim.SetBool("IsWalking", isWalking);
			anim.SetBool("IsRunning", isRunning);
			anim.SetBool("IsCloseRunning", isCloseRunning);
			anim.SetBool("IsCarrying", isCarrying);
		}

		[ServerRpc(RequireOwnership = false)]
		public void GrabPlayerServerRpc(ulong playerId)
		{
			PlayerControllerB val = StartOfRound.Instance.allPlayerScripts[playerId];
			carriedPlayer = val;
			GrabPlayerClientRpc(playerId);
		}

		[ClientRpc]
		public void GrabPlayerClientRpc(ulong playerId)
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			PlayerControllerB val = StartOfRound.Instance.allPlayerScripts[playerId];
			if ((Object)(object)val != (Object)null)
			{
				isCarryingPlayer = true;
				carriedPlayer = val;
				CarriedPlayerManager.SetCarriedPlayer(val);
				MovementActions movement = val.playerActions.Movement;
				((MovementActions)(ref movement)).Move.Disable();
				movement = val.playerActions.Movement;
				((MovementActions)(ref movement)).Jump.Disable();
				movement = val.playerActions.Movement;
				((MovementActions)(ref movement)).Sprint.Disable();
				movement = val.playerActions.Movement;
				((MovementActions)(ref movement)).Crouch.Disable();
				DoAnimationsServerRPC(isWalking: false, isRunning: false, isCloseRunning: false, isCarrying: true);
				damageCoroutine = ((MonoBehaviour)this).StartCoroutine(DamagePlayerOverTime());
				((Component)val).transform.position = carryPoint.position;
				((Component)val).transform.rotation = carryPoint.rotation;
				val.ResetFallGravity();
			}
		}

		[ServerRpc(RequireOwnership = false)]
		public void ReleasePlayerServerRpc()
		{
			ReleasePlayer();
			ReleasePlayerClientRpc();
		}

		[ClientRpc]
		public void ReleasePlayerClientRpc()
		{
			ReleasePlayer();
		}

		private void ReleasePlayer()
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			if (isCarryingPlayer && (Object)(object)carriedPlayer != (Object)null)
			{
				((Component)carriedPlayer).transform.parent = null;
				MovementActions movement = carriedPlayer.playerActions.Movement;
				((MovementActions)(ref movement)).Move.Enable();
				movement = carriedPlayer.playerActions.Movement;
				((MovementActions)(ref movement)).Jump.Enable();
				movement = carriedPlayer.playerActions.Movement;
				((MovementActions)(ref movement)).Sprint.Enable();
				movement = carriedPlayer.playerActions.Movement;
				((MovementActions)(ref movement)).Crouch.Enable();
				carriedPlayer.takingFallDamage = true;
				DoAnimationsServerRPC(isWalking: true, isRunning: false, isCloseRunning: false, isCarrying: false);
				((MonoBehaviour)this).StopCoroutine(damageCoroutine);
				isCarryingPlayer = false;
				CarriedPlayerManager.ClearCarriedPlayer();
				pickupCooldownTimer = 5f;
				isFleeing = true;
				fleeCooldownTimer = 5f;
				carriedPlayer = null;
				((EnemyAI)this).SwitchToBehaviourClientRpc(3);
			}
		}

		[ServerRpc(RequireOwnership = false)]
		public void UpdateCarriedPlayerPositionServerRpc(Vector3 position, Quaternion rotation)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: 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)
			((Component)carriedPlayer).transform.position = position;
			((Component)carriedPlayer).transform.rotation = rotation;
			UpdateCarriedPlayerPositionClientRpc(position, rotation);
		}

		[ClientRpc]
		public void UpdateCarriedPlayerPositionClientRpc(Vector3 position, Quaternion rotation)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			((Component)carriedPlayer).transform.position = position;
			((Component)carriedPlayer).transform.rotation = rotation;
		}

		private void RunAway()
		{
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			if (!base.isEnemyDead && !base.agent.hasPath && !base.agent.pathPending && !(fleeCooldownTimer > 0f) && base.agent.isOnNavMesh)
			{
				Transform val = ((EnemyAI)this).ChooseFarthestNodeFromPosition(((Component)this).transform.position, true, 0, false);
				if ((Object)(object)val != (Object)null)
				{
					base.targetNode = val;
					((EnemyAI)this).SetDestinationToPosition(base.targetNode.position, false);
				}
			}
		}

		private IEnumerator DamagePlayerOverTime()
		{
			while (isCarryingPlayer)
			{
				yield return (object)new WaitForSeconds(1f);
				if ((Object)(object)carriedPlayer != (Object)null)
				{
					carriedPlayer.DamagePlayer(15, true, true, (CauseOfDeath)0, 0, false, default(Vector3));
				}
			}
		}

		private void PlayRandomSound()
		{
			if (sounds.Length != 0)
			{
				AudioClip val = sounds[Random.Range(0, sounds.Length)];
				audioSource.PlayOneShot(val);
			}
		}

		public override void HitEnemy(int force = 1, PlayerControllerB playerWhoHit = null, bool playHitSFX = false)
		{
			((EnemyAI)this).HitEnemy(force, playerWhoHit, playHitSFX);
			if (!base.isEnemyDead)
			{
				base.creatureSFX.PlayOneShot(hitDemogorgonSFX, 1f);
				WalkieTalkie.TransmitOneShotAudio(base.creatureSFX, hitDemogorgonSFX, 1f);
				base.enemyHP -= force;
				if (isCarryingPlayer)
				{
					ReleasePlayerServerRpc();
				}
				if (((NetworkBehaviour)this).IsOwner && base.enemyHP <= 0 && !base.isEnemyDead)
				{
					((EnemyAI)this).KillEnemyOnOwnerClient(false);
				}
			}
		}
	}
	[HarmonyPatch(typeof(RoundManager))]
	internal class LightColliderSpawnerPatch
	{
		public static List<GameObject> eligibleLights = new List<GameObject>();

		[HarmonyPatch("FinishGeneratingLevel")]
		[HarmonyPostfix]
		public static void FinishGeneratingLevelPostfix(RoundManager __instance)
		{
			if (!Config.EnableFlickeringLights.Value)
			{
				return;
			}
			Plugin.logger.LogInfo((object)"Adding colliders to lights");
			eligibleLights.Clear();
			Light[] array = Object.FindObjectsOfType<Light>();
			Light[] array2 = array;
			foreach (Light val in array2)
			{
				Transform parent = ((Component)val).transform.parent;
				if ((Object)(object)parent != (Object)null && (((Object)parent).name.StartsWith("HangingLight") || ((Object)parent).name.StartsWith("MansionWallLamp") || ((Object)parent).name.StartsWith("Chandelier")))
				{
					eligibleLights.Add(((Component)val).gameObject);
					LightTriggerScript lightTriggerScript = ((Component)val).gameObject.AddComponent<LightTriggerScript>();
					lightTriggerScript.Init(val);
				}
			}
		}
	}
	public class LightTriggerScript : MonoBehaviour
	{
		private Light lightComponent;

		private AudioSource audioSource;

		private AudioClip[] lightFlickerSounds;

		private List<GameObject> demogorgons = new List<GameObject>();

		private bool isFlickering = false;

		private bool hasExited = true;

		public Vector3 spawnPosition = ((Component)Object.FindAnyObjectByType<PlayerControllerB>()).transform.position;

		public void Init(Light light)
		{
			lightComponent = light;
			audioSource = ((Component)this).gameObject.AddComponent<AudioSource>();
			audioSource.spatialBlend = 1f;
			lightFlickerSounds = (AudioClip[])(object)new AudioClip[4]
			{
				Content.LoadAudioClip("BreakerLever1"),
				Content.LoadAudioClip("BreakerLever2"),
				Content.LoadAudioClip("BreakerLever3"),
				Content.LoadAudioClip("FlashlightFlicker")
			};
		}

		public void AddDemogorgon(GameObject demogorgon)
		{
			demogorgons.Add(demogorgon);
			Debug.Log((object)("Demogorgon added: " + (object)demogorgon));
		}

		private void Update()
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			foreach (GameObject demogorgon in demogorgons)
			{
				if ((Object)(object)demogorgon == (Object)null)
				{
					continue;
				}
				float num = Vector3.Distance(((Component)this).transform.position, demogorgon.transform.position);
				if (num < 5f)
				{
					if (!isFlickering && hasExited)
					{
						Debug.Log((object)"Starting FlickerLight coroutine");
						((MonoBehaviour)this).StartCoroutine(FlickerLight());
						break;
					}
				}
				else
				{
					hasExited = true;
				}
			}
		}

		private IEnumerator FlickerLight()
		{
			Debug.Log((object)"In FlickerLight coroutine");
			isFlickering = true;
			hasExited = false;
			int flickerCount = Random.Range(1, 5);
			for (int i = 0; i < flickerCount; i++)
			{
				audioSource.PlayOneShot(lightFlickerSounds[Random.Range(0, lightFlickerSounds.Length)]);
				((Behaviour)lightComponent).enabled = !((Behaviour)lightComponent).enabled;
				yield return (object)new WaitForSeconds(Random.Range(0.08f, 0.3f));
			}
			((Behaviour)lightComponent).enabled = true;
			isFlickering = false;
		}
	}
	[HarmonyPatch]
	public class Patches
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(StartOfRound), "StartGame")]
		public static void ResetAI()
		{
			DemogorgonAI demogorgonAI = Object.FindObjectOfType<DemogorgonAI>();
			if ((Object)(object)demogorgonAI != (Object)null)
			{
				demogorgonAI.InitializeDemogorgon();
			}
		}
	}
	[BepInPlugin("scoliosis.strangerthingsmod", "StrangerThingsMod", "0.0.31")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		public const string ModGUID = "scoliosis.strangerthingsmod";

		public const string ModName = "StrangerThingsMod";

		public const string ModVersion = "0.0.31";

		public static ManualLogSource logger;

		public static ConfigFile config;

		private void Awake()
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Expected O, but got Unknown
			logger = ((BaseUnityPlugin)this).Logger;
			config = ((BaseUnityPlugin)this).Config;
			Config.Load();
			Content.Load();
			Harmony val = new Harmony("scoliosis.strangerthingsmod");
			val.PatchAll();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Loaded Stranger Things Mod");
			Type[] types = Assembly.GetExecutingAssembly().GetTypes();
			Type[] array = types;
			foreach (Type type in array)
			{
				MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic);
				MethodInfo[] array2 = methods;
				foreach (MethodInfo methodInfo in array2)
				{
					object[] customAttributes = methodInfo.GetCustomAttributes(typeof(RuntimeInitializeOnLoadMethodAttribute), inherit: false);
					if (customAttributes.Length != 0)
					{
						methodInfo.Invoke(null, null);
					}
				}
			}
		}
	}
	public class Utilities
	{
		public static void SpawnDemogorgon(Vector3 spawningPosition)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			string text = "Demogorgon";
			if (Content.Prefabs.ContainsKey(text))
			{
				Quaternion identity = Quaternion.identity;
				Plugin.logger.LogInfo((object)("Spawning " + text + " at light"));
				GameObject val = Object.Instantiate<GameObject>(Content.Prefabs[text], spawningPosition, identity);
				val.GetComponent<NetworkObject>().Spawn(false);
			}
			else
			{
				Plugin.logger.LogWarning((object)("Prefab " + text + " not found!"));
			}
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "StrangerThingsMod";

		public const string PLUGIN_NAME = "StrangerThingsMod";

		public const string PLUGIN_VERSION = "0.0.31";
	}
}

plugins/TheFiend.dll

Decompiled 2 years ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using GameNetcodeStuff;
using LethalLib.Modules;
using TheFiend;
using TheFiend.NetcodePatcher;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.Audio;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = "")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: AssemblyCompany("TheFiend")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Your mod description.")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("TheFiend")]
[assembly: AssemblyTitle("TheFiend")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: NetcodePatchedAssembly]
internal class <Module>
{
	static <Module>()
	{
		NetworkVariableSerializationTypes.InitializeSerializer_UnmanagedByMemcpy<bool>();
		NetworkVariableSerializationTypes.InitializeEqualityChecker_UnmanagedIEquatable<bool>();
	}
}
public class TheFiendAI : EnemyAI
{
	public NetworkVariable<int> StateOfMind;

	public NetworkVariable<int> Funky = new NetworkVariable<int>(1, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0);

	private Animator animator;

	public GameObject Main;

	public GameObject Neck;

	public GameObject Spine;

	public GameObject LeftHand;

	public GameObject RightHand;

	public MeshRenderer MapDot;

	public SkinnedMeshRenderer skinnedMesh;

	private float OldYScale;

	public Random enemyRandom;

	public AudioClip[] audioClips;

	public AudioClip StepClip;

	private AudioSource AS;

	private AudioSource AS2;

	private Vector3 FavSpot;

	private bool ResetNode;

	private bool EatingPlayer;

	public NetworkVariable<bool> Seeking;

	public NetworkVariable<bool> Invis;

	public NetworkVariable<bool> RageMode;

	public NetworkVariable<bool> GlobalCD;

	public NetworkVariable<bool> StandingMode = new NetworkVariable<bool>(false, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0);

	public NetworkVariable<bool> LungApparatusWillRage = new NetworkVariable<bool>(global::TheFiend.TheFiend.WillRageAfterApparatus.Value, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0);

	public Quaternion OldR;

	public bool Step;

	private Vector3 LastPos;

	private Vector3 Node;

	private int LightTriggerTimes;

	private NavMeshPath path;

	private GameObject Head;

	private GameObject breakerBox;

	private RoundManager roundManager;

	public TimeOfDay timeOfDay;

	private GameObject LungApparatus;

	private Vector3 LungApparatusPosition;

	public ParticleSystem PS;

	public GameObject TargetLook;

	public void Awake()
	{
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Expected O, but got Unknown
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_0049: Unknown result type (might be due to invalid IL or missing references)
		//IL_004e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_0104: Unknown result type (might be due to invalid IL or missing references)
		//IL_0109: Unknown result type (might be due to invalid IL or missing references)
		path = new NavMeshPath();
		FavSpot = ((Component)this).transform.position;
		Head = ((Component)Neck.transform.Find("mixamorig:Head")).gameObject;
		OldR = Neck.transform.localRotation;
		animator = ((Component)this).GetComponent<Animator>();
		animator.Play("Idle");
		AS = ((Component)this).GetComponent<AudioSource>();
		AS2 = Spine.GetComponent<AudioSource>();
		try
		{
			breakerBox = ((Component)Object.FindObjectOfType<BreakerBox>()).gameObject;
		}
		catch
		{
			breakerBox = null;
		}
		roundManager = Object.FindObjectOfType<RoundManager>();
		timeOfDay = Object.FindObjectOfType<TimeOfDay>();
		((Renderer)MapDot).material.color = Color.red;
		LungApparatus = GameObject.Find("LungApparatus(Clone)");
		if (Object.op_Implicit((Object)(object)LungApparatus))
		{
			LungApparatusPosition = LungApparatus.transform.position;
		}
		AudioMixerGroup outputAudioMixerGroup = SoundManager.Instance.diageticMixer.FindMatchingGroups("SFX")[0];
		AS.outputAudioMixerGroup = outputAudioMixerGroup;
	}

	public override void Start()
	{
		//IL_0014: Unknown result type (might be due to invalid IL or missing references)
		//IL_0077: Unknown result type (might be due to invalid IL or missing references)
		//IL_007d: Invalid comparison between Unknown and I4
		((EnemyAI)this).Start();
		OldYScale = Main.transform.position.y;
		enemyRandom = new Random(StartOfRound.Instance.randomMapSeed + base.thisEnemyIndex);
		AS.clip = audioClips[0];
		AS.loop = true;
		AS.Play();
		if ((int)roundManager.currentLevel.currentWeather == 5)
		{
			PS.Play();
			((Component)PS).gameObject.GetComponent<AudioSource>().Play();
			Funky.Value = 3;
		}
	}

	public void FixedUpdate()
	{
		if (Step && !Invis.Value)
		{
			AS2.pitch = Random.Range(0.6f, 1f);
			AS2.PlayOneShot(StepClip);
		}
	}

	public void LateUpdate()
	{
		//IL_0043: 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 ((Object)(object)TargetLook != (Object)null)
		{
			Neck.transform.LookAt(TargetLook.transform, Vector3.up);
		}
		else
		{
			Neck.transform.localRotation = OldR;
		}
	}

	public override void DoAIInterval()
	{
		//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
		//IL_0204: Unknown result type (might be due to invalid IL or missing references)
		//IL_0214: Unknown result type (might be due to invalid IL or missing references)
		//IL_0219: Unknown result type (might be due to invalid IL or missing references)
		//IL_0246: Unknown result type (might be due to invalid IL or missing references)
		//IL_0252: Unknown result type (might be due to invalid IL or missing references)
		//IL_0387: Unknown result type (might be due to invalid IL or missing references)
		//IL_0393: Unknown result type (might be due to invalid IL or missing references)
		//IL_028d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0299: Unknown result type (might be due to invalid IL or missing references)
		//IL_042c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0441: Unknown result type (might be due to invalid IL or missing references)
		//IL_07d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_07da: Unknown result type (might be due to invalid IL or missing references)
		//IL_091c: Unknown result type (might be due to invalid IL or missing references)
		//IL_07ec: Unknown result type (might be due to invalid IL or missing references)
		//IL_0510: Unknown result type (might be due to invalid IL or missing references)
		//IL_0967: Unknown result type (might be due to invalid IL or missing references)
		//IL_096d: Unknown result type (might be due to invalid IL or missing references)
		//IL_070f: Unknown result type (might be due to invalid IL or missing references)
		//IL_099d: Unknown result type (might be due to invalid IL or missing references)
		//IL_075d: Unknown result type (might be due to invalid IL or missing references)
		((EnemyAI)this).DoAIInterval();
		if (timeOfDay.hour >= 15)
		{
			Funky.Value = 2;
		}
		if (Seeking.Value)
		{
			AS.volume = 0f;
		}
		else if (StateOfMind.Value != 3)
		{
			AS.volume = global::TheFiend.TheFiend.Volume.Value;
		}
		if (Invis.Value)
		{
			((Renderer)skinnedMesh).enabled = false;
		}
		else
		{
			((Renderer)skinnedMesh).enabled = true;
		}
		if (Random.Range(1, 10000) == 1)
		{
			TeleportServerRpc();
		}
		if (Random.Range(1, 10000 / Funky.Value) == 1 && StateOfMind.Value == 3)
		{
			HideOnCellingServerRpc();
		}
		if (Random.Range(1, 10000 / Funky.Value) == 1 && !Seeking.Value)
		{
			ToggleSeekingServerRpc();
		}
		if (!GlobalCD.Value)
		{
			if (StateOfMind.Value < 3)
			{
				StateOfMind.Value = 0;
			}
			if (Object.op_Implicit((Object)(object)breakerBox) && !Seeking.Value)
			{
				GameObject gameObject = ((Component)breakerBox.transform.Find("Mesh")).gameObject;
				if (Vector3.Distance(Main.transform.position, gameObject.transform.position) <= 5f)
				{
					RaycastHit val = default(RaycastHit);
					if (Physics.Raycast(Neck.transform.position, gameObject.transform.position - Neck.transform.position, ref val, float.PositiveInfinity, ~LayerMask.GetMask(new string[1] { "Enmies" })) && Vector3.Distance(((RaycastHit)(ref val)).point, gameObject.transform.position) < 2f)
					{
						StateOfMind.Value = 4;
						TargetLook = gameObject;
						if (Vector3.Distance(Main.transform.position, gameObject.transform.position) <= 2f)
						{
							BreakerBoxBreakServerRpc();
						}
					}
					else
					{
						StateOfMind.Value = 0;
					}
				}
			}
			if (((EnemyAI)this).TargetClosestPlayer(100f, false, 70f))
			{
				TargetLook = ((Component)base.targetPlayer).gameObject;
				if (Object.op_Implicit((Object)(object)base.targetPlayer.currentlyGrabbingObject) && ((Object)((Component)base.targetPlayer.currentlyGrabbingObject).gameObject).name.Contains("FlashlightItem"))
				{
					GameObject gameObject2 = ((Component)((Component)base.targetPlayer.currentlyGrabbingObject).gameObject.transform.Find("Light")).gameObject;
					Light component = gameObject2.GetComponent<Light>();
					if (((Behaviour)component).enabled && Vector3.Distance(Head.transform.position, gameObject2.transform.position) <= 2.5f)
					{
						FearedServerRpc(TempRage: false, uselight: true);
						LightTriggerTimes++;
					}
				}
			}
			if (StateOfMind.Value == 3 && !GlobalCD.Value && !Seeking.Value && ((EnemyAI)this).TargetClosestPlayer(100f, false, 70f))
			{
				TargetLook = ((Component)base.targetPlayer).gameObject;
				if (Vector3.Distance(((Component)this).transform.position, ((Component)base.targetPlayer).gameObject.transform.position) <= 4f)
				{
					HideOnCellingServerRpc();
				}
			}
			if (!EatingPlayer && StateOfMind.Value <= 2 && !GlobalCD.Value && !StandingMode.Value)
			{
				if (((EnemyAI)this).TargetClosestPlayer(100f, false, 70f))
				{
					TargetLook = ((Component)base.targetPlayer).gameObject;
					ResetNode = true;
					if (base.agent.remainingDistance > 10f && !RageMode.Value)
					{
						OldYScale = Main.transform.position.y;
						if (!Seeking.Value)
						{
							StateOfMind.Value = 1;
							base.agent.speed = 3 + (Funky.Value - 1);
							animator.Play("Walk");
							if (CheckDoor())
							{
								if (Random.Range(1, 100) == 1 && StateOfMind.Value != 3)
								{
									HideOnCellingServerRpc();
								}
							}
							else if (Random.Range(1, 1000) == 1 && StateOfMind.Value != 3)
							{
								HideOnCellingServerRpc();
							}
						}
						else
						{
							base.agent.speed = 1f;
							animator.Play("Seeking");
							BreakDoorServerRpc();
						}
						if (Random.Range(1, global::TheFiend.TheFiend.FlickerRngChance.Value) == 1)
						{
							roundManager.FlickerLights(true, true);
						}
					}
					else if (!Seeking.Value)
					{
						StateOfMind.Value = 2;
						if ((Object)(object)((EnemyAI)this).CheckLineOfSightForPlayer(45f, 60, -1) != (Object)null)
						{
							base.targetPlayer.JumpToFearLevel(0.9f, true);
						}
						if (!RageMode.Value)
						{
							base.agent.speed = 9 * Funky.Value;
						}
						else
						{
							base.agent.speed = 20 * Funky.Value;
						}
						animator.Play("Run");
						BreakDoorServerRpc();
					}
					((EnemyAI)this).SetDestinationToPosition(((Component)base.targetPlayer).transform.position, false);
					if (Seeking.Value)
					{
						PlayerControllerB[] array = Object.FindObjectsOfType(typeof(PlayerControllerB)) as PlayerControllerB[];
						foreach (PlayerControllerB val2 in array)
						{
							if (val2.HasLineOfSightToPosition(Neck.transform.position, 45f, 60, -1f))
							{
								ToggleSeekingServerRpc();
								FearedServerRpc(TempRage: true);
								break;
							}
						}
					}
				}
				else
				{
					base.agent.speed = 3f;
					if (ResetNode)
					{
						WonderVectorServerRpc(60f);
						ResetNode = false;
					}
					if (Node != Vector3.zero)
					{
						((EnemyAI)this).SetDestinationToPosition(Node, false);
					}
					else
					{
						ResetNode = true;
					}
					if (base.agent.remainingDistance == 0f)
					{
						ResetNode = true;
					}
					if (Random.Range(1, 100) == 1)
					{
						ResetNode = true;
					}
					TargetLook = null;
				}
				if (!GlobalCD.Value)
				{
					if (base.agent.remainingDistance == 0f && StateOfMind.Value == 0 && !RageMode.Value)
					{
						animator.Play("Idle");
					}
					else if (!Seeking.Value && StateOfMind.Value == 1)
					{
						animator.Play("Walk");
					}
				}
			}
			if (StateOfMind.Value == 4 && Object.op_Implicit((Object)(object)TargetLook))
			{
				animator.Play("Walk");
				((EnemyAI)this).SetDestinationToPosition(TargetLook.transform.position, false);
			}
			if ((Object)(object)LungApparatus != (Object)null && LungApparatusWillRage.Value && !Invis.Value && LungApparatus.transform.position != LungApparatusPosition)
			{
				((Component)LungApparatus.transform.Find("Point Light")).gameObject.GetComponent<Light>().color = Color.red;
				((GrabbableObject)LungApparatus.GetComponent<LungProp>()).scrapValue = 300;
				LungApparatus = null;
				((MonoBehaviour)this).StartCoroutine(Rage());
			}
		}
		((EnemyAI)this).SyncPositionToClients();
	}

	[ServerRpc]
	public void ToggleSeekingServerRpc()
	{
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Invalid comparison between Unknown and I4
		//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00dc: Invalid comparison between Unknown and I4
		//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c2: 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_0084: Invalid comparison between Unknown and I4
		NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
		if (networkManager == null || !networkManager.IsListening)
		{
			return;
		}
		if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
		{
			if (((NetworkBehaviour)this).OwnerClientId != networkManager.LocalClientId)
			{
				if ((int)networkManager.LogLevel <= 1)
				{
					Debug.LogError((object)"Only the owner can invoke a ServerRpc that requires ownership!");
				}
				return;
			}
			ServerRpcParams val = default(ServerRpcParams);
			FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(2185458962u, val, (RpcDelivery)0);
			((NetworkBehaviour)this).__endSendServerRpc(ref val2, 2185458962u, val, (RpcDelivery)0);
		}
		if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost))
		{
			Seeking.Value = !Seeking.Value;
		}
	}

	private void OnTriggerEnter(Collider collision)
	{
		//IL_0058: Unknown result type (might be due to invalid IL or missing references)
		//IL_0068: 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)
		if (Object.op_Implicit((Object)(object)((Component)collision).gameObject.GetComponent<PlayerControllerB>()) && StateOfMind.Value != 3 && !GlobalCD.Value && !Invis.Value && !EatingPlayer && Vector3.Distance(((Component)this).transform.position, ((Component)collision).gameObject.transform.position) < 4f)
		{
			GrabServerRpc(NetworkBehaviourReference.op_Implicit((NetworkBehaviour)(object)((Component)collision).gameObject.GetComponent<PlayerControllerB>()));
		}
	}

	[ServerRpc(RequireOwnership = false)]
	public void SceamServerRpc()
	{
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Invalid comparison between Unknown and I4
		//IL_008c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0096: Invalid comparison between Unknown and I4
		//IL_005f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0068: Unknown result type (might be due to invalid IL or missing references)
		//IL_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_007c: Unknown result type (might be due to invalid IL or missing references)
		NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
		if (networkManager != null && networkManager.IsListening)
		{
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
			{
				ServerRpcParams val = default(ServerRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(2166844155u, val, (RpcDelivery)0);
				((NetworkBehaviour)this).__endSendServerRpc(ref val2, 2166844155u, val, (RpcDelivery)0);
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost))
			{
				AS.Stop();
				AS.clip = audioClips[Random.Range(1, 2)];
				AS.loop = false;
				AS.Play();
				SceamClientRpc();
			}
		}
	}

	[ClientRpc]
	public void SceamClientRpc()
	{
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Invalid comparison between Unknown and I4
		//IL_008c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0096: Invalid comparison between Unknown and I4
		//IL_005f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0068: Unknown result type (might be due to invalid IL or missing references)
		//IL_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_007c: Unknown result type (might be due to invalid IL or missing references)
		NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
		if (networkManager != null && networkManager.IsListening)
		{
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
			{
				ClientRpcParams val = default(ClientRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(3334696286u, val, (RpcDelivery)0);
				((NetworkBehaviour)this).__endSendClientRpc(ref val2, 3334696286u, val, (RpcDelivery)0);
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
			{
				AS.Stop();
				AS.clip = audioClips[Random.Range(1, 2)];
				AS.loop = false;
				AS.Play();
			}
		}
	}

	[ServerRpc(RequireOwnership = false)]
	public void IdleSoundServerRpc()
	{
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Invalid comparison between Unknown and I4
		//IL_008c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0096: Invalid comparison between Unknown and I4
		//IL_005f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0068: Unknown result type (might be due to invalid IL or missing references)
		//IL_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_007c: Unknown result type (might be due to invalid IL or missing references)
		NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
		if (networkManager != null && networkManager.IsListening)
		{
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
			{
				ServerRpcParams val = default(ServerRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(579005519u, val, (RpcDelivery)0);
				((NetworkBehaviour)this).__endSendServerRpc(ref val2, 579005519u, val, (RpcDelivery)0);
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost))
			{
				AS.Stop();
				AS.clip = audioClips[0];
				AS.loop = true;
				AS.Play();
				IdleSoundClientRpc();
			}
		}
	}

	[ClientRpc]
	public void IdleSoundClientRpc()
	{
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Invalid comparison between Unknown and I4
		//IL_008c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0096: Invalid comparison between Unknown and I4
		//IL_005f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0068: Unknown result type (might be due to invalid IL or missing references)
		//IL_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_007c: Unknown result type (might be due to invalid IL or missing references)
		NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
		if (networkManager != null && networkManager.IsListening)
		{
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
			{
				ClientRpcParams val = default(ClientRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(469331619u, val, (RpcDelivery)0);
				((NetworkBehaviour)this).__endSendClientRpc(ref val2, 469331619u, val, (RpcDelivery)0);
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
			{
				AS.Stop();
				AS.clip = audioClips[0];
				AS.loop = true;
				AS.Play();
			}
		}
	}

	[ServerRpc(RequireOwnership = false)]
	public void GrabServerRpc(NetworkBehaviourReference PlayerControllerBRef)
	{
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Invalid comparison between Unknown and I4
		//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b1: Invalid comparison between Unknown and I4
		//IL_005f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0068: Unknown result type (might be due to invalid IL or missing references)
		//IL_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_007d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0083: Unknown result type (might be due to invalid IL or missing references)
		//IL_0097: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
		NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
		if (networkManager != null && networkManager.IsListening)
		{
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
			{
				ServerRpcParams val = default(ServerRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(2819942690u, val, (RpcDelivery)0);
				((FastBufferWriter)(ref val2)).WriteValueSafe<NetworkBehaviourReference>(ref PlayerControllerBRef, default(ForNetworkSerializable));
				((NetworkBehaviour)this).__endSendServerRpc(ref val2, 2819942690u, val, (RpcDelivery)0);
			}
			PlayerControllerB val3 = default(PlayerControllerB);
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost) && ((NetworkBehaviourReference)(ref PlayerControllerBRef)).TryGet<PlayerControllerB>(ref val3, (NetworkManager)null))
			{
				GrabClientRpc(NetworkObjectReference.op_Implicit(((Component)val3).gameObject));
			}
		}
	}

	[ClientRpc]
	public void GrabClientRpc(NetworkObjectReference networkObject)
	{
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Invalid comparison between Unknown and I4
		//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b1: Invalid comparison between Unknown and I4
		//IL_005f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0068: Unknown result type (might be due to invalid IL or missing references)
		//IL_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_007d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0083: Unknown result type (might be due to invalid IL or missing references)
		//IL_0097: Unknown result type (might be due to invalid IL or missing references)
		NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
		if (networkManager != null && networkManager.IsListening)
		{
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
			{
				ClientRpcParams val = default(ClientRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(2797167683u, val, (RpcDelivery)0);
				((FastBufferWriter)(ref val2)).WriteValueSafe<NetworkObjectReference>(ref networkObject, default(ForNetworkSerializable));
				((NetworkBehaviour)this).__endSendClientRpc(ref val2, 2797167683u, val, (RpcDelivery)0);
			}
			NetworkObject val3 = default(NetworkObject);
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost) && ((NetworkObjectReference)(ref networkObject)).TryGet(ref val3, (NetworkManager)null))
			{
				((MonoBehaviour)this).StartCoroutine(Grabbing(((Component)val3).gameObject));
			}
		}
	}

	public IEnumerator Grabbing(GameObject Player)
	{
		if (!EatingPlayer && Object.op_Implicit((Object)(object)Player))
		{
			EatingPlayer = true;
			TargetLook = null;
			base.agent.speed = 0f;
			((EnemyAI)this).SetDestinationToPosition(((Component)base.agent).transform.position, false);
			PlayerControllerB PCB = Player.GetComponent<PlayerControllerB>();
			float oldspeed = PCB.movementSpeed;
			PCB.movementSpeed = 0f;
			animator.Play("Grab");
			((Component)this).transform.LookAt(Player.transform.position, Vector3.up);
			((MonoBehaviour)this).StartCoroutine(RotatePlayerToMe(PCB));
			SceamServerRpc();
			yield return (object)new WaitForSeconds(1.7f);
			PCB.KillPlayer(Main.transform.forward * 15f, true, (CauseOfDeath)5, 1);
			if (((NetworkBehaviour)PCB).IsOwner)
			{
				PCB.movementSpeed = oldspeed;
			}
			yield return (object)new WaitForSeconds(1f);
			IdleSoundServerRpc();
			animator.Play("Idle");
			yield return (object)new WaitForSeconds(3f);
			yield return (object)new WaitForSeconds(2f);
			RageMode.Value = false;
			if (Random.Range(1, 30) == 1)
			{
				HideOnCellingServerRpc();
			}
			EatingPlayer = false;
		}
	}

	private IEnumerator RotatePlayerToMe(PlayerControllerB PCB)
	{
		if (Object.op_Implicit((Object)(object)PCB))
		{
			Vector3 Position = ((Component)this).transform.position - ((Component)PCB).gameObject.transform.position;
			while (PCB.health != 0)
			{
				PlayerSmoothLookAt(Position, PCB);
				yield return null;
			}
		}
	}

	private void PlayerSmoothLookAt(Vector3 newDirection, PlayerControllerB PCB)
	{
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		((Component)PCB).gameObject.transform.rotation = Quaternion.Lerp(((Component)PCB).gameObject.transform.rotation, Quaternion.LookRotation(newDirection), Time.deltaTime * 5f);
	}

	[ServerRpc(RequireOwnership = false)]
	public void HideOnCellingServerRpc()
	{
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Invalid comparison between Unknown and I4
		//IL_008c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0096: Invalid comparison between Unknown and I4
		//IL_005f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0068: Unknown result type (might be due to invalid IL or missing references)
		//IL_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_007c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0107: Unknown result type (might be due to invalid IL or missing references)
		//IL_010c: Unknown result type (might be due to invalid IL or missing references)
		//IL_011d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0137: Unknown result type (might be due to invalid IL or missing references)
		//IL_0142: Unknown result type (might be due to invalid IL or missing references)
		//IL_0147: Unknown result type (might be due to invalid IL or missing references)
		//IL_019e: Unknown result type (might be due to invalid IL or missing references)
		NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
		if (networkManager == null || !networkManager.IsListening)
		{
			return;
		}
		if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
		{
			ServerRpcParams val = default(ServerRpcParams);
			FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(862535042u, val, (RpcDelivery)0);
			((NetworkBehaviour)this).__endSendServerRpc(ref val2, 862535042u, val, (RpcDelivery)0);
		}
		if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 || (!networkManager.IsServer && !networkManager.IsHost))
		{
			return;
		}
		if (StateOfMind.Value != 3)
		{
			if (StateOfMind.Value <= 3)
			{
				StateOfMind.Value = 3;
				LastPos = Main.transform.position;
				OldYScale = Main.transform.position.y;
				RaycastHit val3 = default(RaycastHit);
				Physics.Raycast(Main.transform.position, ((Component)this).transform.TransformDirection(Vector3.up), ref val3, float.PositiveInfinity, ~LayerMask.GetMask(new string[1] { "Enmies" }));
				animator.Play("Hide");
				AS.Stop();
				base.agent.speed = 0f;
				SetYLevelClientRpc(((RaycastHit)(ref val3)).point.y);
				((Renderer)MapDot).enabled = false;
			}
		}
		else if (!StandingMode.Value)
		{
			((MonoBehaviour)this).StartCoroutine(Stand());
		}
	}

	[ClientRpc]
	public void SetYLevelClientRpc(float y)
	{
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Invalid comparison between Unknown and I4
		//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b1: Invalid comparison between Unknown and I4
		//IL_005f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0068: Unknown result type (might be due to invalid IL or missing references)
		//IL_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_007d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0083: Unknown result type (might be due to invalid IL or missing references)
		//IL_0097: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
		//IL_0103: Unknown result type (might be due to invalid IL or missing references)
		//IL_010d: Unknown result type (might be due to invalid IL or missing references)
		NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
		if (networkManager != null && networkManager.IsListening)
		{
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
			{
				ClientRpcParams val = default(ClientRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(3597756483u, val, (RpcDelivery)0);
				((FastBufferWriter)(ref val2)).WriteValueSafe<float>(ref y, default(ForPrimitives));
				((NetworkBehaviour)this).__endSendClientRpc(ref val2, 3597756483u, val, (RpcDelivery)0);
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
			{
				Main.transform.position = new Vector3(Main.transform.position.x, y, Main.transform.position.z);
			}
		}
	}

	public IEnumerator Stand()
	{
		StandingMode.Value = true;
		((Renderer)MapDot).enabled = true;
		Rigidbody rig = Main.AddComponent<Rigidbody>();
		rig.detectCollisions = false;
		while (Vector3.Distance(Main.transform.position, LastPos) > 1.5f)
		{
			yield return null;
		}
		Object.Destroy((Object)(object)rig);
		animator.Play("UnHide");
		yield return (object)new WaitForSeconds(0.2f);
		SetYLevelClientRpc(OldYScale);
		animator.Play("Idle");
		SceamServerRpc();
		yield return (object)new WaitForSeconds(2f);
		IdleSoundServerRpc();
		BreakDoorServerRpc();
		StateOfMind.Value = 1;
		StandingMode.Value = false;
	}

	[ServerRpc]
	public void BreakDoorServerRpc()
	{
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Invalid comparison between Unknown and I4
		//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00dc: Invalid comparison between Unknown and I4
		//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c2: 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_0084: Invalid comparison between Unknown and I4
		//IL_0164: Unknown result type (might be due to invalid IL or missing references)
		//IL_016f: Unknown result type (might be due to invalid IL or missing references)
		//IL_018c: Unknown result type (might be due to invalid IL or missing references)
		//IL_019c: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
		NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
		if (networkManager == null || !networkManager.IsListening)
		{
			return;
		}
		if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
		{
			if (((NetworkBehaviour)this).OwnerClientId != networkManager.LocalClientId)
			{
				if ((int)networkManager.LogLevel <= 1)
				{
					Debug.LogError((object)"Only the owner can invoke a ServerRpc that requires ownership!");
				}
				return;
			}
			ServerRpcParams val = default(ServerRpcParams);
			FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(2228961150u, val, (RpcDelivery)0);
			((NetworkBehaviour)this).__endSendServerRpc(ref val2, 2228961150u, val, (RpcDelivery)0);
		}
		if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 || (!networkManager.IsServer && !networkManager.IsHost))
		{
			return;
		}
		DoorLock[] array = Object.FindObjectsOfType(typeof(DoorLock)) as DoorLock[];
		foreach (DoorLock val3 in array)
		{
			GameObject gameObject = ((Component)((Component)((Component)((Component)val3).transform.parent).transform.parent).transform.parent).gameObject;
			if (!Object.op_Implicit((Object)(object)gameObject.GetComponent<Rigidbody>()) && Vector3.Distance(((Component)this).transform.position, gameObject.transform.position) <= 4f)
			{
				NetworkObjectReference netObjRef = NetworkObjectReference.op_Implicit(gameObject);
				Vector3 val4 = ((Component)base.targetPlayer).transform.position - ((Component)this).transform.position;
				BashDoorClientRpc(netObjRef, ((Vector3)(ref val4)).normalized * 20f);
			}
		}
	}

	[ClientRpc]
	public void BashDoorClientRpc(NetworkObjectReference netObjRef, Vector3 Position)
	{
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Invalid comparison between Unknown and I4
		//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00be: Invalid comparison between Unknown and I4
		//IL_005f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0068: Unknown result type (might be due to invalid IL or missing references)
		//IL_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_007d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0083: 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_014d: Unknown result type (might be due to invalid IL or missing references)
		NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
		if (networkManager != null && networkManager.IsListening)
		{
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
			{
				ClientRpcParams val = default(ClientRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(2581177773u, val, (RpcDelivery)0);
				((FastBufferWriter)(ref val2)).WriteValueSafe<NetworkObjectReference>(ref netObjRef, default(ForNetworkSerializable));
				((FastBufferWriter)(ref val2)).WriteValueSafe(ref Position);
				((NetworkBehaviour)this).__endSendClientRpc(ref val2, 2581177773u, val, (RpcDelivery)0);
			}
			NetworkObject val3 = default(NetworkObject);
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost) && ((NetworkObjectReference)(ref netObjRef)).TryGet(ref val3, (NetworkManager)null))
			{
				GameObject gameObject = ((Component)val3).gameObject;
				Rigidbody val4 = gameObject.AddComponent<Rigidbody>();
				AudioSource val5 = gameObject.AddComponent<AudioSource>();
				val5.spatialBlend = 1f;
				val5.maxDistance = 60f;
				val5.rolloffMode = (AudioRolloffMode)1;
				val5.volume = 3f;
				((MonoBehaviour)this).StartCoroutine(TurnOffC(val4, 0.12f));
				val4.AddForce(Position, (ForceMode)1);
				val5.PlayOneShot(audioClips[3]);
			}
		}
	}

	public bool CheckDoor()
	{
		//IL_0041: Unknown result type (might be due to invalid IL or missing references)
		//IL_004c: Unknown result type (might be due to invalid IL or missing references)
		DoorLock[] array = Object.FindObjectsOfType(typeof(DoorLock)) as DoorLock[];
		foreach (DoorLock val in array)
		{
			GameObject gameObject = ((Component)((Component)((Component)val).transform.parent).transform.parent).gameObject;
			if (Vector3.Distance(((Component)this).transform.position, gameObject.transform.position) <= 4f)
			{
				return true;
			}
		}
		return false;
	}

	private IEnumerator TurnOffC(Rigidbody rigidbody, float time)
	{
		rigidbody.detectCollisions = false;
		yield return (object)new WaitForSeconds(time);
		rigidbody.detectCollisions = true;
		Object.Destroy((Object)(object)((Component)rigidbody).gameObject, 5f);
	}

	[ServerRpc(RequireOwnership = false)]
	public void FearedServerRpc(bool TempRage, bool uselight = false)
	{
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Invalid comparison between Unknown and I4
		//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cc: Invalid comparison between Unknown and I4
		//IL_005f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0068: Unknown result type (might be due to invalid IL or missing references)
		//IL_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_007d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0083: Unknown result type (might be due to invalid IL or missing references)
		//IL_0098: Unknown result type (might be due to invalid IL or missing references)
		//IL_009e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
		NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
		if (networkManager == null || !networkManager.IsListening)
		{
			return;
		}
		if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
		{
			ServerRpcParams val = default(ServerRpcParams);
			FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(3886079065u, val, (RpcDelivery)0);
			((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref TempRage, default(ForPrimitives));
			((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref uselight, default(ForPrimitives));
			((NetworkBehaviour)this).__endSendServerRpc(ref val2, 3886079065u, val, (RpcDelivery)0);
		}
		if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost) && !EatingPlayer && !StandingMode.Value)
		{
			GlobalCD.Value = true;
			FearedClientRpc();
			((MonoBehaviour)this).StartCoroutine(CD(5f));
			float tempRage = 3f;
			if (uselight)
			{
				tempRage = LightTriggerTimes * 2;
			}
			if (TempRage)
			{
				((MonoBehaviour)this).StartCoroutine(SetTempRage(tempRage));
			}
		}
	}

	public IEnumerator Rage()
	{
		GlobalCD.Value = true;
		yield return (object)new WaitForSeconds(0.2f);
		animator.Play("Rage");
		PlayerControllerB[] array = Object.FindObjectsOfType(typeof(PlayerControllerB)) as PlayerControllerB[];
		foreach (PlayerControllerB player in array)
		{
			player.JumpToFearLevel(0.9f, true);
		}
		AS.maxDistance = 500f;
		AS.Stop();
		AS.clip = audioClips[5];
		AS.loop = false;
		AS.Play();
		yield return (object)new WaitForSeconds(9f);
		ToggleRageServerRpc(TheRageValue: true);
		AS.maxDistance = 30f;
		GlobalCD.Value = false;
		yield return (object)new WaitForSeconds(20f);
		ToggleRageServerRpc(TheRageValue: false);
	}

	[ServerRpc(RequireOwnership = false)]
	public void ToggleRageServerRpc(bool TheRageValue)
	{
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Invalid comparison between Unknown and I4
		//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b1: Invalid comparison between Unknown and I4
		//IL_005f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0068: Unknown result type (might be due to invalid IL or missing references)
		//IL_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_007d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0083: Unknown result type (might be due to invalid IL or missing references)
		//IL_0097: Unknown result type (might be due to invalid IL or missing references)
		NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
		if (networkManager != null && networkManager.IsListening)
		{
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
			{
				ServerRpcParams val = default(ServerRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(1019923705u, val, (RpcDelivery)0);
				((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref TheRageValue, default(ForPrimitives));
				((NetworkBehaviour)this).__endSendServerRpc(ref val2, 1019923705u, val, (RpcDelivery)0);
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost))
			{
				RageMode.Value = TheRageValue;
			}
		}
	}

	[ServerRpc(RequireOwnership = false)]
	public void TeleportServerRpc()
	{
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Invalid comparison between Unknown and I4
		//IL_008c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0096: Invalid comparison between Unknown and I4
		//IL_005f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0068: Unknown result type (might be due to invalid IL or missing references)
		//IL_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_007c: Unknown result type (might be due to invalid IL or missing references)
		//IL_015a: Unknown result type (might be due to invalid IL or missing references)
		NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
		if (networkManager == null || !networkManager.IsListening)
		{
			return;
		}
		if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
		{
			ServerRpcParams val = default(ServerRpcParams);
			FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(1623300671u, val, (RpcDelivery)0);
			((NetworkBehaviour)this).__endSendServerRpc(ref val2, 1623300671u, val, (RpcDelivery)0);
		}
		if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 || (!networkManager.IsServer && !networkManager.IsHost) || Invis.Value)
		{
			return;
		}
		Invis.Value = true;
		List<PlayerControllerB> list = new List<PlayerControllerB>();
		PlayerControllerB[] array = Object.FindObjectsOfType(typeof(PlayerControllerB)) as PlayerControllerB[];
		foreach (PlayerControllerB val3 in array)
		{
			if (val3.isInsideFactory)
			{
				list.Add(val3);
			}
		}
		if (list.Count > 0)
		{
			((Component)this).transform.position = ((Component)list[Random.Range(1, list.Count)]).gameObject.transform.position;
		}
		GlobalCD.Value = true;
		((MonoBehaviour)this).StartCoroutine(CD(25f, UnInvis: true));
	}

	[ClientRpc]
	public void FearedClientRpc()
	{
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Invalid comparison between Unknown and I4
		//IL_008c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0096: Invalid comparison between Unknown and I4
		//IL_005f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0068: Unknown result type (might be due to invalid IL or missing references)
		//IL_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_007c: Unknown result type (might be due to invalid IL or missing references)
		NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
		if (networkManager != null && networkManager.IsListening)
		{
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
			{
				ClientRpcParams val = default(ClientRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(3221369379u, val, (RpcDelivery)0);
				((NetworkBehaviour)this).__endSendClientRpc(ref val2, 3221369379u, val, (RpcDelivery)0);
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
			{
				animator.Play("CoverFace");
				base.agent.speed = 0f;
				AS.Stop();
				AS.clip = audioClips[4];
				AS.loop = false;
				AS.Play();
			}
		}
	}

	private IEnumerator CD(float time, bool UnInvis = false)
	{
		base.agent.speed = 0f;
		yield return (object)new WaitForSeconds(time);
		GlobalCD.Value = false;
		if (UnInvis)
		{
			Invis.Value = false;
		}
	}

	private IEnumerator StateMindCD(float time, int typenow)
	{
		yield return (object)new WaitForSeconds(time);
		StateOfMind.Value = typenow;
	}

	private IEnumerator SetTempRage(float time)
	{
		ToggleRageServerRpc(TheRageValue: true);
		yield return (object)new WaitForSeconds(time);
		ToggleRageServerRpc(TheRageValue: false);
	}

	[ServerRpc(RequireOwnership = false)]
	public void WonderVectorServerRpc(float Range)
	{
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Invalid comparison between Unknown and I4
		//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b1: Invalid comparison between Unknown and I4
		//IL_005f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0068: Unknown result type (might be due to invalid IL or missing references)
		//IL_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_007d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0083: Unknown result type (might be due to invalid IL or missing references)
		//IL_0097: Unknown result type (might be due to invalid IL or missing references)
		//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
		//IL_0101: Unknown result type (might be due to invalid IL or missing references)
		//IL_0108: Unknown result type (might be due to invalid IL or missing references)
		//IL_0122: Unknown result type (might be due to invalid IL or missing references)
		//IL_0127: Unknown result type (might be due to invalid IL or missing references)
		//IL_0119: Unknown result type (might be due to invalid IL or missing references)
		//IL_011a: Unknown result type (might be due to invalid IL or missing references)
		NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
		if (networkManager == null || !networkManager.IsListening)
		{
			return;
		}
		if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
		{
			ServerRpcParams val = default(ServerRpcParams);
			FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(2540260648u, val, (RpcDelivery)0);
			((FastBufferWriter)(ref val2)).WriteValueSafe<float>(ref Range, default(ForPrimitives));
			((NetworkBehaviour)this).__endSendServerRpc(ref val2, 2540260648u, val, (RpcDelivery)0);
		}
		if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost))
		{
			Vector3 val3 = ((Component)this).transform.position + new Vector3(Random.Range(0f - Range, Range), 0f, Random.Range(0f - Range, Range));
			if (base.agent.CalculatePath(val3, path))
			{
				Node = val3;
			}
			else
			{
				Node = Vector3.zero;
			}
		}
	}

	[ServerRpc]
	public void BreakerBoxBreakServerRpc()
	{
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Invalid comparison between Unknown and I4
		//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00dc: Invalid comparison between Unknown and I4
		//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c2: 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_0084: Invalid comparison between Unknown and I4
		//IL_0121: Unknown result type (might be due to invalid IL or missing references)
		NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
		if (networkManager == null || !networkManager.IsListening)
		{
			return;
		}
		if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
		{
			if (((NetworkBehaviour)this).OwnerClientId != networkManager.LocalClientId)
			{
				if ((int)networkManager.LogLevel <= 1)
				{
					Debug.LogError((object)"Only the owner can invoke a ServerRpc that requires ownership!");
				}
				return;
			}
			ServerRpcParams val = default(ServerRpcParams);
			FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(180009697u, val, (RpcDelivery)0);
			((NetworkBehaviour)this).__endSendServerRpc(ref val2, 180009697u, val, (RpcDelivery)0);
		}
		if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost) && !Object.op_Implicit((Object)(object)breakerBox.GetComponent<Rigidbody>()))
		{
			BreakerBoxBreakClientRpc(NetworkObjectReference.op_Implicit(breakerBox));
		}
	}

	[ClientRpc]
	public void BreakerBoxBreakClientRpc(NetworkObjectReference networkObjectReference)
	{
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Invalid comparison between Unknown and I4
		//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b1: Invalid comparison between Unknown and I4
		//IL_005f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0068: Unknown result type (might be due to invalid IL or missing references)
		//IL_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_007d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0083: Unknown result type (might be due to invalid IL or missing references)
		//IL_0097: Unknown result type (might be due to invalid IL or missing references)
		//IL_0140: Unknown result type (might be due to invalid IL or missing references)
		//IL_014b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0150: Unknown result type (might be due to invalid IL or missing references)
		//IL_0155: Unknown result type (might be due to invalid IL or missing references)
		//IL_0159: Unknown result type (might be due to invalid IL or missing references)
		//IL_0163: Unknown result type (might be due to invalid IL or missing references)
		NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
		if (networkManager != null && networkManager.IsListening)
		{
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
			{
				ClientRpcParams val = default(ClientRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(4033774285u, val, (RpcDelivery)0);
				((FastBufferWriter)(ref val2)).WriteValueSafe<NetworkObjectReference>(ref networkObjectReference, default(ForNetworkSerializable));
				((NetworkBehaviour)this).__endSendClientRpc(ref val2, 4033774285u, val, (RpcDelivery)0);
			}
			NetworkObject val3 = default(NetworkObject);
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost) && ((NetworkObjectReference)(ref networkObjectReference)).TryGet(ref val3, (NetworkManager)null))
			{
				GameObject gameObject = ((Component)val3).gameObject;
				((Component)((Component)gameObject.transform.Find("Mesh")).transform.Find("PowerBoxDoor")).gameObject.AddComponent<Rigidbody>();
				Rigidbody val4 = gameObject.AddComponent<Rigidbody>();
				((MonoBehaviour)this).StartCoroutine(TurnOffC(val4, 0.1f));
				Vector3 val5 = Neck.transform.position - ((Component)this).transform.position;
				val4.AddForce(((Vector3)(ref val5)).normalized * 15f, (ForceMode)1);
				gameObject.GetComponent<AudioSource>().PlayOneShot(audioClips[3]);
				Object.Destroy((Object)(object)gameObject, 5f);
				gameObject = null;
				roundManager.PowerSwitchOffClientRpc();
				((MonoBehaviour)this).StartCoroutine(StateMindCD(1f, 0));
				animator.Play("Grab");
			}
		}
	}

	protected override void __initializeVariables()
	{
		if (StateOfMind == null)
		{
			throw new Exception("TheFiendAI.StateOfMind cannot be null. All NetworkVariableBase instances must be initialized.");
		}
		((NetworkVariableBase)StateOfMind).Initialize((NetworkBehaviour)(object)this);
		((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)StateOfMind, "StateOfMind");
		((NetworkBehaviour)this).NetworkVariableFields.Add((NetworkVariableBase)(object)StateOfMind);
		if (Funky == null)
		{
			throw new Exception("TheFiendAI.Funky cannot be null. All NetworkVariableBase instances must be initialized.");
		}
		((NetworkVariableBase)Funky).Initialize((NetworkBehaviour)(object)this);
		((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)Funky, "Funky");
		((NetworkBehaviour)this).NetworkVariableFields.Add((NetworkVariableBase)(object)Funky);
		if (Seeking == null)
		{
			throw new Exception("TheFiendAI.Seeking cannot be null. All NetworkVariableBase instances must be initialized.");
		}
		((NetworkVariableBase)Seeking).Initialize((NetworkBehaviour)(object)this);
		((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)Seeking, "Seeking");
		((NetworkBehaviour)this).NetworkVariableFields.Add((NetworkVariableBase)(object)Seeking);
		if (Invis == null)
		{
			throw new Exception("TheFiendAI.Invis cannot be null. All NetworkVariableBase instances must be initialized.");
		}
		((NetworkVariableBase)Invis).Initialize((NetworkBehaviour)(object)this);
		((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)Invis, "Invis");
		((NetworkBehaviour)this).NetworkVariableFields.Add((NetworkVariableBase)(object)Invis);
		if (RageMode == null)
		{
			throw new Exception("TheFiendAI.RageMode cannot be null. All NetworkVariableBase instances must be initialized.");
		}
		((NetworkVariableBase)RageMode).Initialize((NetworkBehaviour)(object)this);
		((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)RageMode, "RageMode");
		((NetworkBehaviour)this).NetworkVariableFields.Add((NetworkVariableBase)(object)RageMode);
		if (GlobalCD == null)
		{
			throw new Exception("TheFiendAI.GlobalCD cannot be null. All NetworkVariableBase instances must be initialized.");
		}
		((NetworkVariableBase)GlobalCD).Initialize((NetworkBehaviour)(object)this);
		((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)GlobalCD, "GlobalCD");
		((NetworkBehaviour)this).NetworkVariableFields.Add((NetworkVariableBase)(object)GlobalCD);
		if (StandingMode == null)
		{
			throw new Exception("TheFiendAI.StandingMode cannot be null. All NetworkVariableBase instances must be initialized.");
		}
		((NetworkVariableBase)StandingMode).Initialize((NetworkBehaviour)(object)this);
		((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)StandingMode, "StandingMode");
		((NetworkBehaviour)this).NetworkVariableFields.Add((NetworkVariableBase)(object)StandingMode);
		if (LungApparatusWillRage == null)
		{
			throw new Exception("TheFiendAI.LungApparatusWillRage cannot be null. All NetworkVariableBase instances must be initialized.");
		}
		((NetworkVariableBase)LungApparatusWillRage).Initialize((NetworkBehaviour)(object)this);
		((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)LungApparatusWillRage, "LungApparatusWillRage");
		((NetworkBehaviour)this).NetworkVariableFields.Add((NetworkVariableBase)(object)LungApparatusWillRage);
		((EnemyAI)this).__initializeVariables();
	}

	[RuntimeInitializeOnLoadMethod]
	internal static void InitializeRPCS_TheFiendAI()
	{
		//IL_0011: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Expected O, but got Unknown
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: Expected O, but got Unknown
		//IL_0047: Unknown result type (might be due to invalid IL or missing references)
		//IL_0051: Expected O, but got Unknown
		//IL_0062: Unknown result type (might be due to invalid IL or missing references)
		//IL_006c: Expected O, but got Unknown
		//IL_007d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0087: Expected O, but got Unknown
		//IL_0098: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a2: Expected O, but got Unknown
		//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bd: Expected O, but got Unknown
		//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d8: Expected O, but got Unknown
		//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f3: Expected O, but got Unknown
		//IL_0104: Unknown result type (might be due to invalid IL or missing references)
		//IL_010e: Expected O, but got Unknown
		//IL_011f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0129: Expected O, but got Unknown
		//IL_013a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0144: Expected O, but got Unknown
		//IL_0155: Unknown result type (might be due to invalid IL or missing references)
		//IL_015f: Expected O, but got Unknown
		//IL_0170: Unknown result type (might be due to invalid IL or missing references)
		//IL_017a: Expected O, but got Unknown
		//IL_018b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0195: Expected O, but got Unknown
		//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b0: Expected O, but got Unknown
		//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cb: Expected O, but got Unknown
		//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e6: Expected O, but got Unknown
		NetworkManager.__rpc_func_table.Add(2185458962u, new RpcReceiveHandler(__rpc_handler_2185458962));
		NetworkManager.__rpc_func_table.Add(2166844155u, new RpcReceiveHandler(__rpc_handler_2166844155));
		NetworkManager.__rpc_func_table.Add(3334696286u, new RpcReceiveHandler(__rpc_handler_3334696286));
		NetworkManager.__rpc_func_table.Add(579005519u, new RpcReceiveHandler(__rpc_handler_579005519));
		NetworkManager.__rpc_func_table.Add(469331619u, new RpcReceiveHandler(__rpc_handler_469331619));
		NetworkManager.__rpc_func_table.Add(2819942690u, new RpcReceiveHandler(__rpc_handler_2819942690));
		NetworkManager.__rpc_func_table.Add(2797167683u, new RpcReceiveHandler(__rpc_handler_2797167683));
		NetworkManager.__rpc_func_table.Add(862535042u, new RpcReceiveHandler(__rpc_handler_862535042));
		NetworkManager.__rpc_func_table.Add(3597756483u, new RpcReceiveHandler(__rpc_handler_3597756483));
		NetworkManager.__rpc_func_table.Add(2228961150u, new RpcReceiveHandler(__rpc_handler_2228961150));
		NetworkManager.__rpc_func_table.Add(2581177773u, new RpcReceiveHandler(__rpc_handler_2581177773));
		NetworkManager.__rpc_func_table.Add(3886079065u, new RpcReceiveHandler(__rpc_handler_3886079065));
		NetworkManager.__rpc_func_table.Add(1019923705u, new RpcReceiveHandler(__rpc_handler_1019923705));
		NetworkManager.__rpc_func_table.Add(1623300671u, new RpcReceiveHandler(__rpc_handler_1623300671));
		NetworkManager.__rpc_func_table.Add(3221369379u, new RpcReceiveHandler(__rpc_handler_3221369379));
		NetworkManager.__rpc_func_table.Add(2540260648u, new RpcReceiveHandler(__rpc_handler_2540260648));
		NetworkManager.__rpc_func_table.Add(180009697u, new RpcReceiveHandler(__rpc_handler_180009697));
		NetworkManager.__rpc_func_table.Add(4033774285u, new RpcReceiveHandler(__rpc_handler_4033774285));
	}

	private static void __rpc_handler_2185458962(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
	{
		//IL_0023: 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_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_0076: Unknown result type (might be due to invalid IL or missing references)
		//IL_008c: Unknown result type (might be due to invalid IL or missing references)
		//IL_004b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0055: Invalid comparison between Unknown and I4
		NetworkManager networkManager = target.NetworkManager;
		if (networkManager == null || !networkManager.IsListening)
		{
			return;
		}
		if (rpcParams.Server.Receive.SenderClientId != target.OwnerClientId)
		{
			if ((int)networkManager.LogLevel <= 1)
			{
				Debug.LogError((object)"Only the owner can invoke a ServerRpc that requires ownership!");
			}
		}
		else
		{
			target.__rpc_exec_stage = (__RpcExecStage)1;
			((TheFiendAI)(object)target).ToggleSeekingServerRpc();
			target.__rpc_exec_stage = (__RpcExecStage)0;
		}
	}

	private static void __rpc_handler_2166844155(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
	{
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		NetworkManager networkManager = target.NetworkManager;
		if (networkManager != null && networkManager.IsListening)
		{
			target.__rpc_exec_stage = (__RpcExecStage)1;
			((TheFiendAI)(object)target).SceamServerRpc();
			target.__rpc_exec_stage = (__RpcExecStage)0;
		}
	}

	private static void __rpc_handler_3334696286(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
	{
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		NetworkManager networkManager = target.NetworkManager;
		if (networkManager != null && networkManager.IsListening)
		{
			target.__rpc_exec_stage = (__RpcExecStage)2;
			((TheFiendAI)(object)target).SceamClientRpc();
			target.__rpc_exec_stage = (__RpcExecStage)0;
		}
	}

	private static void __rpc_handler_579005519(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
	{
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		NetworkManager networkManager = target.NetworkManager;
		if (networkManager != null && networkManager.IsListening)
		{
			target.__rpc_exec_stage = (__RpcExecStage)1;
			((TheFiendAI)(object)target).IdleSoundServerRpc();
			target.__rpc_exec_stage = (__RpcExecStage)0;
		}
	}

	private static void __rpc_handler_469331619(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
	{
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		NetworkManager networkManager = target.NetworkManager;
		if (networkManager != null && networkManager.IsListening)
		{
			target.__rpc_exec_stage = (__RpcExecStage)2;
			((TheFiendAI)(object)target).IdleSoundClientRpc();
			target.__rpc_exec_stage = (__RpcExecStage)0;
		}
	}

	private static void __rpc_handler_2819942690(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
	{
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: Unknown result type (might be due to invalid IL or missing references)
		//IL_004f: Unknown result type (might be due to invalid IL or missing references)
		//IL_005e: Unknown result type (might be due to invalid IL or missing references)
		NetworkManager networkManager = target.NetworkManager;
		if (networkManager != null && networkManager.IsListening)
		{
			NetworkBehaviourReference playerControllerBRef = default(NetworkBehaviourReference);
			((FastBufferReader)(ref reader)).ReadValueSafe<NetworkBehaviourReference>(ref playerControllerBRef, default(ForNetworkSerializable));
			target.__rpc_exec_stage = (__RpcExecStage)1;
			((TheFiendAI)(object)target).GrabServerRpc(playerControllerBRef);
			target.__rpc_exec_stage = (__RpcExecStage)0;
		}
	}

	private static void __rpc_handler_2797167683(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
	{
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: Unknown result type (might be due to invalid IL or missing references)
		//IL_004f: Unknown result type (might be due to invalid IL or missing references)
		//IL_005e: Unknown result type (might be due to invalid IL or missing references)
		NetworkManager networkManager = target.NetworkManager;
		if (networkManager != null && networkManager.IsListening)
		{
			NetworkObjectReference networkObject = default(NetworkObjectReference);
			((FastBufferReader)(ref reader)).ReadValueSafe<NetworkObjectReference>(ref networkObject, default(ForNetworkSerializable));
			target.__rpc_exec_stage = (__RpcExecStage)2;
			((TheFiendAI)(object)target).GrabClientRpc(networkObject);
			target.__rpc_exec_stage = (__RpcExecStage)0;
		}
	}

	private static void __rpc_handler_862535042(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
	{
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		NetworkManager networkManager = target.NetworkManager;
		if (networkManager != null && networkManager.IsListening)
		{
			target.__rpc_exec_stage = (__RpcExecStage)1;
			((TheFiendAI)(object)target).HideOnCellingServerRpc();
			target.__rpc_exec_stage = (__RpcExecStage)0;
		}
	}

	private static void __rpc_handler_3597756483(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
	{
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: Unknown result type (might be due to invalid IL or missing references)
		//IL_005e: Unknown result type (might be due to invalid IL or missing references)
		NetworkManager networkManager = target.NetworkManager;
		if (networkManager != null && networkManager.IsListening)
		{
			float yLevelClientRpc = default(float);
			((FastBufferReader)(ref reader)).ReadValueSafe<float>(ref yLevelClientRpc, default(ForPrimitives));
			target.__rpc_exec_stage = (__RpcExecStage)2;
			((TheFiendAI)(object)target).SetYLevelClientRpc(yLevelClientRpc);
			target.__rpc_exec_stage = (__RpcExecStage)0;
		}
	}

	private static void __rpc_handler_2228961150(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
	{
		//IL_0023: 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_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_0076: Unknown result type (might be due to invalid IL or missing references)
		//IL_008c: Unknown result type (might be due to invalid IL or missing references)
		//IL_004b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0055: Invalid comparison between Unknown and I4
		NetworkManager networkManager = target.NetworkManager;
		if (networkManager == null || !networkManager.IsListening)
		{
			return;
		}
		if (rpcParams.Server.Receive.SenderClientId != target.OwnerClientId)
		{
			if ((int)networkManager.LogLevel <= 1)
			{
				Debug.LogError((object)"Only the owner can invoke a ServerRpc that requires ownership!");
			}
		}
		else
		{
			target.__rpc_exec_stage = (__RpcExecStage)1;
			((TheFiendAI)(object)target).BreakDoorServerRpc();
			target.__rpc_exec_stage = (__RpcExecStage)0;
		}
	}

	private static void __rpc_handler_2581177773(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
	{
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_0051: Unknown result type (might be due to invalid IL or missing references)
		//IL_005c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0060: Unknown result type (might be due to invalid IL or missing references)
		//IL_006f: Unknown result type (might be due to invalid IL or missing references)
		NetworkManager networkManager = target.NetworkManager;
		if (networkManager != null && networkManager.IsListening)
		{
			NetworkObjectReference netObjRef = default(NetworkObjectReference);
			((FastBufferReader)(ref reader)).ReadValueSafe<NetworkObjectReference>(ref netObjRef, default(ForNetworkSerializable));
			Vector3 position = default(Vector3);
			((FastBufferReader)(ref reader)).ReadValueSafe(ref position);
			target.__rpc_exec_stage = (__RpcExecStage)2;
			((TheFiendAI)(object)target).BashDoorClientRpc(netObjRef, position);
			target.__rpc_exec_stage = (__RpcExecStage)0;
		}
	}

	private static void __rpc_handler_3886079065(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
	{
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_004a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0050: Unknown result type (might be due to invalid IL or missing references)
		//IL_005f: Unknown result type (might be due to invalid IL or missing references)
		//IL_007d: Unknown result type (might be due to invalid IL or missing references)
		NetworkManager networkManager = target.NetworkManager;
		if (networkManager != null && networkManager.IsListening)
		{
			bool tempRage = default(bool);
			((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref tempRage, default(ForPrimitives));
			bool uselight = default(bool);
			((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref uselight, default(ForPrimitives));
			target.__rpc_exec_stage = (__RpcExecStage)1;
			((TheFiendAI)(object)target).FearedServerRpc(tempRage, uselight);
			target.__rpc_exec_stage = (__RpcExecStage)0;
		}
	}

	private static void __rpc_handler_1019923705(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
	{
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: Unknown result type (might be due to invalid IL or missing references)
		//IL_005e: Unknown result type (might be due to invalid IL or missing references)
		NetworkManager networkManager = target.NetworkManager;
		if (networkManager != null && networkManager.IsListening)
		{
			bool theRageValue = default(bool);
			((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref theRageValue, default(ForPrimitives));
			target.__rpc_exec_stage = (__RpcExecStage)1;
			((TheFiendAI)(object)target).ToggleRageServerRpc(theRageValue);
			target.__rpc_exec_stage = (__RpcExecStage)0;
		}
	}

	private static void __rpc_handler_1623300671(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
	{
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		NetworkManager networkManager = target.NetworkManager;
		if (networkManager != null && networkManager.IsListening)
		{
			target.__rpc_exec_stage = (__RpcExecStage)1;
			((TheFiendAI)(object)target).TeleportServerRpc();
			target.__rpc_exec_stage = (__RpcExecStage)0;
		}
	}

	private static void __rpc_handler_3221369379(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
	{
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		NetworkManager networkManager = target.NetworkManager;
		if (networkManager != null && networkManager.IsListening)
		{
			target.__rpc_exec_stage = (__RpcExecStage)2;
			((TheFiendAI)(object)target).FearedClientRpc();
			target.__rpc_exec_stage = (__RpcExecStage)0;
		}
	}

	private static void __rpc_handler_2540260648(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
	{
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: Unknown result type (might be due to invalid IL or missing references)
		//IL_005e: Unknown result type (might be due to invalid IL or missing references)
		NetworkManager networkManager = target.NetworkManager;
		if (networkManager != null && networkManager.IsListening)
		{
			float range = default(float);
			((FastBufferReader)(ref reader)).ReadValueSafe<float>(ref range, default(ForPrimitives));
			target.__rpc_exec_stage = (__RpcExecStage)1;
			((TheFiendAI)(object)target).WonderVectorServerRpc(range);
			target.__rpc_exec_stage = (__RpcExecStage)0;
		}
	}

	private static void __rpc_handler_180009697(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
	{
		//IL_0023: 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_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_0076: Unknown result type (might be due to invalid IL or missing references)
		//IL_008c: Unknown result type (might be due to invalid IL or missing references)
		//IL_004b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0055: Invalid comparison between Unknown and I4
		NetworkManager networkManager = target.NetworkManager;
		if (networkManager == null || !networkManager.IsListening)
		{
			return;
		}
		if (rpcParams.Server.Receive.SenderClientId != target.OwnerClientId)
		{
			if ((int)networkManager.LogLevel <= 1)
			{
				Debug.LogError((object)"Only the owner can invoke a ServerRpc that requires ownership!");
			}
		}
		else
		{
			target.__rpc_exec_stage = (__RpcExecStage)1;
			((TheFiendAI)(object)target).BreakerBoxBreakServerRpc();
			target.__rpc_exec_stage = (__RpcExecStage)0;
		}
	}

	private static void __rpc_handler_4033774285(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
	{
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: Unknown result type (might be due to invalid IL or missing references)
		//IL_004f: Unknown result type (might be due to invalid IL or missing references)
		//IL_005e: Unknown result type (might be due to invalid IL or missing references)
		NetworkManager networkManager = target.NetworkManager;
		if (networkManager != null && networkManager.IsListening)
		{
			NetworkObjectReference networkObjectReference = default(NetworkObjectReference);
			((FastBufferReader)(ref reader)).ReadValueSafe<NetworkObjectReference>(ref networkObjectReference, default(ForNetworkSerializable));
			target.__rpc_exec_stage = (__RpcExecStage)2;
			((TheFiendAI)(object)target).BreakerBoxBreakClientRpc(networkObjectReference);
			target.__rpc_exec_stage = (__RpcExecStage)0;
		}
	}

	[MethodImpl(MethodImplOptions.NoInlining)]
	protected internal override string __getTypeName()
	{
		return "TheFiendAI";
	}
}
namespace TheFiend
{
	[BepInPlugin("com.RuthlessCompany", "The Fiend", "0.0.0")]
	public class TheFiend : BaseUnityPlugin
	{
		public static TheFiend instance;

		public static string RoleCompanyFolder = "Assets/TheFiend/";

		public static AssetBundle bundle;

		public static ConfigEntry<int> SpawnChance;

		public static ConfigEntry<LevelTypes> Moon;

		public static ConfigEntry<int> FlickerRngChance;

		public static ConfigEntry<bool> WillRageAfterApparatus;

		public static ConfigEntry<float> Volume;

		private void Awake()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Expected O, but got Unknown
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: 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
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Expected O, but got Unknown
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			ConfigFile val = new ConfigFile(Path.Combine(Paths.ConfigPath, "Fiend.cfg"), true);
			SpawnChance = val.Bind<int>("Fiend", "Spawn Weight", 30, new ConfigDescription("The Chance to spawn the fiend inside of the building", (AcceptableValueBase)null, Array.Empty<object>()));
			Moon = val.Bind<LevelTypes>("Fiend", "Moon", (LevelTypes)(-1), new ConfigDescription("What is the only moon it can spawn on. Only one VALUE at a time.", (AcceptableValueBase)null, Array.Empty<object>()));
			FlickerRngChance = val.Bind<int>("Fiend", "Flicker Chance", 1000, new ConfigDescription("This is a Random chance out of 1/1000 happening to a random player", (AcceptableValueBase)null, Array.Empty<object>()));
			WillRageAfterApparatus = val.Bind<bool>("Fiend", "Rage After Apparatus", true, new ConfigDescription("Trigger his rage mode if you remove the Apparatus.", (AcceptableValueBase)null, Array.Empty<object>()));
			Volume = val.Bind<float>("Fiend", "Volume", 1f, new ConfigDescription("Sounds as scream and idle sound, not step sounds", (AcceptableValueBase)null, Array.Empty<object>()));
			Type[] types = Assembly.GetExecutingAssembly().GetTypes();
			Type[] array = types;
			foreach (Type type in array)
			{
				MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic);
				MethodInfo[] array2 = methods;
				foreach (MethodInfo methodInfo in array2)
				{
					object[] customAttributes = methodInfo.GetCustomAttributes(typeof(RuntimeInitializeOnLoadMethodAttribute), inherit: false);
					if (customAttributes.Length != 0)
					{
						methodInfo.Invoke(null, null);
					}
				}
			}
			instance = this;
			bundle = AssetBundle.LoadFromFile(Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), "thefiend"));
			EnemyType val2 = bundle.LoadAsset<EnemyType>(RoleCompanyFolder + "TheFiend.asset");
			Enemies.RegisterEnemy(val2, SpawnChance.Value, Moon.Value, bundle.LoadAsset<TerminalNode>(RoleCompanyFolder + "TheFiendNode.asset"), bundle.LoadAsset<TerminalKeyword>(RoleCompanyFolder + "TheFiendKey.asset"));
			NetworkPrefabs.RegisterNetworkPrefab(val2.enemyPrefab);
			Utilities.FixMixerGroups(val2.enemyPrefab);
		}

		public void AddScrap(string Name, int Rare, LevelTypes level)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			Item val = bundle.LoadAsset<Item>(RoleCompanyFolder + Name + ".asset");
			NetworkPrefabs.RegisterNetworkPrefab(val.spawnPrefab);
			Utilities.FixMixerGroups(val.spawnPrefab);
			Items.RegisterScrap(val, Rare, level);
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "TheFiend";

		public const string PLUGIN_NAME = "TheFiend";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}
namespace TheFiend.NetcodePatcher
{
	[AttributeUsage(AttributeTargets.Module)]
	internal class NetcodePatchedAssemblyAttribute : Attribute
	{
	}
}

plugins/ThiccCoilHead.dll

Decompiled 2 years ago
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using ThiccCoilHead.Patches;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.1", FrameworkDisplayName = ".NET Framework 4.7.1")]
[assembly: AssemblyVersion("0.0.0.0")]
namespace ThiccCoilHead
{
	[BepInPlugin("ThiccCoilHead", "ThiccCoilHead", "1.2.2")]
	public class Plugin : BaseUnityPlugin
	{
		internal static ManualLogSource Log;

		public static GameObject Visuals;

		public static AudioClip Audio;

		private void Awake()
		{
			Log = ((BaseUnityPlugin)this).Logger;
			Log.LogInfo((object)"Plugin ThiccCoilHead is loaded!");
			Harmony.CreateAndPatchAll(typeof(SpringManPatch), (string)null);
			AssetBundle val = AssetBundle.LoadFromFile(Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), "ThiccCoilHead.bundle"));
			Visuals = val.LoadAsset<GameObject>("assets/prefabs/ThiccCoilHead.prefab");
			if ((Object)(object)Visuals == (Object)null)
			{
				Debug.LogError((object)"could not loadThiccCoilHead assetbundle");
			}
			Renderer[] componentsInChildren = Visuals.GetComponentsInChildren<Renderer>(true);
			Renderer[] array = componentsInChildren;
			foreach (Renderer val2 in array)
			{
				((Component)val2).gameObject.layer = LayerMask.NameToLayer("Enemies");
			}
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "ThiccCoilHead";

		public const string PLUGIN_NAME = "ThiccCoilHead";

		public const string PLUGIN_VERSION = "1.2.2";
	}
}
namespace ThiccCoilHead.Patches
{
	internal class SpringManPatch
	{
		[HarmonyPatch(typeof(EnemyAI), "Start")]
		[HarmonyPostfix]
		private static void StartPostfix(EnemyAI __instance)
		{
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			if (!(__instance is SpringManAI))
			{
				return;
			}
			Debug.Log((object)"ThiccCoilHead spawned");
			if ((Object)(object)Plugin.Visuals != (Object)null)
			{
				Transform val = ((Component)__instance).transform.Find("SpringManModel");
				SkinnedMeshRenderer val2 = (((Object)(object)val != (Object)null) ? ((Component)val.Find("Body")).GetComponent<SkinnedMeshRenderer>() : null);
				if ((Object)(object)val2 != (Object)null && ((Renderer)val2).enabled)
				{
					((Renderer)val2).enabled = false;
					MeshRenderer component = ((Component)val.Find("Head")).GetComponent<MeshRenderer>();
					Transform val3 = val.Find("AnimContainer").Find("metarig");
					((Renderer)component).enabled = false;
					GameObject val4 = Object.Instantiate<GameObject>(Plugin.Visuals);
					val4.transform.SetParent(val);
					val4.transform.localPosition = Vector3.zero;
					val4.transform.localRotation = Quaternion.identity;
					val4.transform.localScale = Vector3.one;
					Transform val5 = val4.transform.Find("Container/ThiccCoilMesh");
					Transform val6 = val4.transform.Find("Container/metarig");
					val6.SetParent(val3.parent, true);
					((Component)val6).transform.localScale = ((Component)val3).transform.localScale;
					((Component)val6).transform.localRotation = ((Component)val3).transform.localRotation;
					((Component)val6).transform.localPosition = ((Component)val3).transform.localPosition;
					SkinnedMeshRenderer component2 = ((Component)val5).GetComponent<SkinnedMeshRenderer>();
					component2.rootBone = val6;
					((Object)val3).name = "old-metarig";
				}
				else
				{
					Debug.LogError((object)"ThiccCoilHead could not find SkinnerMeshRenderer on original Coil Head (could also be disabled)");
				}
			}
			else
			{
				Debug.LogError((object)"ThiccCoilHead new Coil Head asset missing");
			}
		}
	}
}

plugins/TooManyEmotes.dll

Decompiled 2 years ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using Dissonance.Integrations.Unity_NFGO;
using GameNetcodeStuff;
using HarmonyLib;
using LCVR.Player;
using LethalCompanyInputUtils.Api;
using MoreCompany.Cosmetics;
using TMPro;
using TooManyEmotes.Audio;
using TooManyEmotes.Compatibility;
using TooManyEmotes.Config;
using TooManyEmotes.Input;
using TooManyEmotes.Networking;
using TooManyEmotes.Patches;
using TooManyEmotes.Props;
using TooManyEmotes.UI;
using Unity.Collections;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.Animations.Rigging;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.Experimental.Rendering;
using UnityEngine.InputSystem;
using UnityEngine.Rendering;
using UnityEngine.Rendering.HighDefinition;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("TooManyEmotes")]
[assembly: AssemblyDescription("Mod made by flipf17")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("TooManyEmotes")]
[assembly: AssemblyCopyright("Copyright ©  2023")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("d6950625-e3a1-4896-a183-87110491bf18")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: InternalsVisibleTo("TooManyEmotesScrap")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace TooManyEmotes
{
	[HarmonyPatch]
	public static class AdditionalEmoteData
	{
		public static void SetAdditionalEmoteData()
		{
		}

		public static void SetAdditionalPropData()
		{
			if (EmotesManager.allUnlockableEmotesDict != null)
			{
				AssignPropToEmote("jug_prop", "jug_band.jug");
				AssignPropToEmote("guitar_prop", "jug_band.guitar");
				AssignPropToEmote("banjo_prop", "jug_band.banjo");
				AssignPropToEmote("fiddle_prop", "jug_band.fiddle");
				AssignPropToEmote("sexy_saxophone.sexy_sax.prop", "sexy_saxophone.sexy_sax");
				AssignPropToEmote("sexy_saxophone.epic_sax.prop", "sexy_saxophone.epic_sax");
				AssignPropToEmote("trombone.prop", "sad_trombone");
				AssignPropToEmote("old_chair.prop", "ma-ya-hi");
				AssignPropToEmote("baseball_bat.prop", "miracle_trickshot");
				AssignPropToEmote("dumbbell.prop", "pumping_iron");
				AssignPropToEmote("paddle.prop", "paddle_royale");
				AssignPropToEmote("gamepad.prop", "controller_crew");
			}
		}

		public static void SetAdditionalMusicData()
		{
			if (EmotesManager.allUnlockableEmotesDict != null)
			{
				SetEmoteDoesNotUseBoombox("hand_signals");
				SetEmoteDoesNotUseBoombox("red_card");
				SetEmoteDoesNotUseBoombox("sexy_saxophone.sexy_sax");
				SetEmoteDoesNotUseBoombox("sexy_saxophone.epic_sax");
				SetEmoteDoesNotUseBoombox("jug_band.jug");
				SetEmoteDoesNotUseBoombox("jug_band.guitar");
				SetEmoteDoesNotUseBoombox("jug_band.banjo");
				SetEmoteDoesNotUseBoombox("jug_band.fiddle");
				SetEmoteDoesNotUseBoombox("sad_trombone");
				SetEmoteDoesNotUseBoombox("snake_summoner");
				SetEmoteDoesNotUseBoombox("miracle_trickshot");
				SetEmoteDoesNotUseBoombox("junk_food");
				SetEmoteDoesNotUseBoombox("pumping_iron");
				SetEmoteDoesNotUseBoombox("paddle_royale");
				AssignMusicToEmote("jug_band.jug", "jug_band.jug");
				AssignMusicToEmote("jug_band.guitar", "jug_band.guitar");
				AssignMusicToEmote("jug_band.banjo", "jug_band.banjo");
				AssignMusicToEmote("jug_band.fiddle", "jug_band.fiddle");
			}
		}

		public static void AssignPropToEmote(string propName, string emoteName)
		{
			if (!EmotePropManager.emotePropsDataDict.TryGetValue(propName, out var _))
			{
				CustomLogging.LogWarning("Failed to assign prop: " + propName + " to emote. Prop does not exist!");
				return;
			}
			if (!EmotesManager.allUnlockableEmotesDict.TryGetValue(emoteName, out var value2))
			{
				CustomLogging.LogWarning("Failed to assign prop: " + propName + " to emote: " + emoteName + ". Emote does not exist!");
				return;
			}
			if (!EmotePropManager.emotePropsDataDict.TryGetValue(propName, out var value3))
			{
				CustomLogging.LogWarning("Failed to assign prop: " + propName + " to emote: " + emoteName + ". Prop data does not exist for: " + propName);
				return;
			}
			if (value2.propNamesInEmote == null)
			{
				value2.propNamesInEmote = new List<string>();
			}
			value2.propNamesInEmote.Add(propName);
			if (value3.parentEmotes == null)
			{
				value3.parentEmotes = new List<UnlockableEmote>();
			}
			if (!value3.parentEmotes.Contains(value2))
			{
				value3.parentEmotes.Add(value2);
			}
		}

		public static void SetEmoteDoesNotUseBoombox(string emoteName)
		{
			if (EmotesManager.allUnlockableEmotesDict.TryGetValue(emoteName, out var value))
			{
				value.isBoomboxAudio = false;
			}
		}

		public static void SetCanMoveWhileEmoting(string emoteName)
		{
			if (EmotesManager.allUnlockableEmotesDict.TryGetValue(emoteName, out var value))
			{
				value.canMoveWhileEmoting = true;
			}
		}

		public static void AssignMusicToEmote(string emoteName, string audioName, string audioLoopName = "")
		{
			if (EmotesManager.allUnlockableEmotesDict.TryGetValue(emoteName, out var value) && AudioManager.AudioExists(audioName))
			{
				value.overrideAudioClipName = audioName;
				value.overrideAudioLoopClipName = audioLoopName;
			}
		}
	}
	public static class BoneMapper
	{
		public static Dictionary<Transform, Transform> CreateBoneMap(Transform sourceSkeleton, Transform targetSkeleton, List<string> sourceBoneNames, List<string> targetBoneNames = null)
		{
			if ((Object)(object)sourceSkeleton == (Object)null || (Object)(object)targetSkeleton == (Object)null || sourceBoneNames == null)
			{
				return null;
			}
			if (targetBoneNames == null)
			{
				targetBoneNames = sourceBoneNames;
			}
			if (sourceBoneNames.Count != targetBoneNames.Count)
			{
				CustomLogging.LogError("Attempted to map humanoid skeleton, but passed two sets of bone names with differing sizes.");
				return null;
			}
			int count = sourceBoneNames.Count;
			Transform[] array = (Transform[])(object)new Transform[count];
			Transform[] array2 = (Transform[])(object)new Transform[count];
			FindBones(sourceSkeleton, sourceBoneNames, array);
			FindBones(targetSkeleton, targetBoneNames, array2);
			Dictionary<Transform, Transform> dictionary = new Dictionary<Transform, Transform>();
			for (int i = 0; i < count; i++)
			{
				if ((Object)(object)array[i] != (Object)null && !dictionary.ContainsKey(array[i]))
				{
					dictionary.Add(array[i], array2[i]);
				}
			}
			return dictionary;
		}

		private static void FindBones(Transform bone, List<string> boneNames, Transform[] boneArray)
		{
			if ((Object)(object)((Component)bone).GetComponent<Rig>() != (Object)null || ((Object)bone).name == "ScavengerModelArmsOnly")
			{
				return;
			}
			if (boneNames.Contains(((Object)bone).name))
			{
				int num = boneNames.IndexOf(((Object)bone).name);
				if (!((Object)(object)boneArray[num] != (Object)null))
				{
					boneArray[num] = bone;
				}
			}
			for (int i = 0; i < bone.childCount; i++)
			{
				FindBones(bone.GetChild(i), boneNames, boneArray);
			}
		}
	}
	internal static class CustomLogging
	{
		private static ManualLogSource logger;

		public static void InitLogger()
		{
			try
			{
				logger = Logger.CreateLogSource($"{((BaseUnityPlugin)Plugin.instance).Info.Metadata.Name}-{((BaseUnityPlugin)Plugin.instance).Info.Metadata.Version}");
			}
			catch
			{
				logger = Plugin.defaultLogger;
			}
		}

		public static void Log(string message)
		{
			logger.LogInfo((object)message);
		}

		public static void LogError(string message)
		{
			logger.LogError((object)message);
		}

		public static void LogWarning(string message)
		{
			logger.LogWarning((object)message);
		}

		public static void LogVerbose(string message)
		{
			if (ConfigSettings.verboseLogs.Value)
			{
				logger.LogInfo((object)("[VERBOSE] " + message));
			}
		}

		public static void LogErrorVerbose(string message)
		{
			if (ConfigSettings.verboseLogs.Value)
			{
				logger.LogError((object)("[VERBOSE] " + message));
			}
		}

		public static void LogWarningVerbose(string message)
		{
			if (ConfigSettings.verboseLogs.Value)
			{
				logger.LogWarning((object)("[VERBOSE] " + message));
			}
		}

		public static bool Assert(bool condition, string failMessage)
		{
			if (!condition)
			{
				LogWarning(failMessage);
			}
			return condition;
		}
	}
	public class OnAnimatorIKHandler : MonoBehaviour
	{
		private EmoteController emoteController;

		private Animator animator;

		private void Awake()
		{
			animator = ((Component)this).GetComponent<Animator>();
			if ((Object)(object)animator == (Object)null)
			{
				CustomLogging.LogWarning("OnIKHandler must be attached to a gameobject with an animator component.");
			}
		}

		public void SetParentEmoteController(EmoteController emoteController)
		{
			this.emoteController = emoteController;
		}

		protected void OnAnimatorIK(int layerIndex)
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)emoteController) && emoteController.initialized && emoteController.IsPerformingCustomEmote())
			{
				if (Object.op_Implicit((Object)(object)emoteController.ikLeftHand) && emoteController.ikLeftHand.localPosition != Vector3.zero)
				{
					animator.SetIKPositionWeight((AvatarIKGoal)2, 0.65f);
					animator.SetIKRotationWeight((AvatarIKGoal)2, 0.65f);
					animator.SetIKPosition((AvatarIKGoal)2, emoteController.ikLeftHand.position);
					animator.SetIKRotation((AvatarIKGoal)2, emoteController.ikLeftHand.rotation);
				}
				if (Object.op_Implicit((Object)(object)emoteController.ikRightHand) && emoteController.ikRightHand.localPosition != Vector3.zero)
				{
					animator.SetIKPositionWeight((AvatarIKGoal)3, 0.65f);
					animator.SetIKRotationWeight((AvatarIKGoal)3, 0.65f);
					animator.SetIKPosition((AvatarIKGoal)3, emoteController.ikRightHand.position);
					animator.SetIKRotation((AvatarIKGoal)3, emoteController.ikRightHand.rotation);
				}
				if (Object.op_Implicit((Object)(object)emoteController.ikHead) && emoteController.ikHead.localPosition != Vector3.zero)
				{
					animator.SetLookAtWeight(1f, 0.25f, 0.5f);
					animator.SetLookAtPosition(emoteController.ikHead.position);
				}
			}
		}
	}
	[HarmonyPatch]
	public class EmoteSyncGroup
	{
		public static int currentEmoteSyncId = 0;

		public static Dictionary<int, EmoteSyncGroup> allEmoteSyncGroups = new Dictionary<int, EmoteSyncGroup>();

		public int syncId = -1;

		public List<EmoteController> syncGroup;

		public Dictionary<UnlockableEmote, EmoteController> leadEmoteControllerByEmote = new Dictionary<UnlockableEmote, EmoteController>();

		public Dictionary<UnlockableEmote, EmoteAudioSource> currentEmoteAudioSources;

		public float timeStartedEmote;

		public UnlockableEmote performingEmote;

		public bool useAudio = true;

		public EmoteAudioPlayer currentAudioPlayer;

		public EmoteController leadEmoteController => (syncGroup != null && syncGroup.Count > 0) ? syncGroup[0] : null;

		public EmoteAudioSource leadEmoteAudioSource
		{
			get
			{
				if (currentEmoteAudioSources != null && currentEmoteAudioSources.Count > 0)
				{
					foreach (EmoteController item in syncGroup)
					{
						if ((Object)(object)item?.personalEmoteAudioSource != (Object)null && currentEmoteAudioSources.ContainsValue(item.personalEmoteAudioSource))
						{
							return item.personalEmoteAudioSource;
						}
					}
				}
				return null;
			}
		}

		[HarmonyPatch(typeof(StartOfRound), "Awake")]
		[HarmonyPrefix]
		public static void Init()
		{
			currentEmoteSyncId = 0;
			allEmoteSyncGroups?.Clear();
		}

		public static EmoteSyncGroup CreateEmoteSyncGroup(EmoteController emoteController, bool useAudio = true)
		{
			return new EmoteSyncGroup(emoteController, useAudio);
		}

		public EmoteSyncGroup(EmoteController emoteController, bool useAudio = true)
		{
			syncGroup = new List<EmoteController> { emoteController };
			syncId = currentEmoteSyncId++;
			performingEmote = emoteController.performingEmote;
			leadEmoteControllerByEmote.Add(performingEmote, emoteController);
			this.useAudio = useAudio;
			if (useAudio && performingEmote.hasAudio)
			{
				if (!performingEmote.isBoomboxAudio)
				{
					currentEmoteAudioSources = new Dictionary<UnlockableEmote, EmoteAudioSource>();
					if ((Object)(object)emoteController.personalEmoteAudioSource == (Object)null)
					{
						CustomLogging.LogError("Attempted to perform emote with personal audio source, which is null.");
						this.useAudio = false;
					}
					else
					{
						currentEmoteAudioSources[performingEmote] = emoteController.personalEmoteAudioSource;
						emoteController.personalEmoteAudioSource.SyncWithEmoteControllerAudio(emoteController);
						emoteController.personalEmoteAudioSource.AddToEmoteSyncGroup(this);
					}
				}
				else
				{
					EmoteAudioPlayer nearestEmoteAudioPlayer = EmoteAudioPlayerManager.GetNearestEmoteAudioPlayer(((Component)emoteController).transform);
					if ((Object)(object)nearestEmoteAudioPlayer != (Object)null && nearestEmoteAudioPlayer.CanPlayMusic())
					{
						AssignExternalAudioPlayer(nearestEmoteAudioPlayer);
					}
					else
					{
						CustomLogging.LogWarning("Performing emote with no music. No available boomboxes found nearby. Don't worry. Everything will be okay.");
					}
				}
				UpdateAudioVolume();
			}
			allEmoteSyncGroups[syncId] = this;
			timeStartedEmote = Time.time;
		}

		public void AddToEmoteSyncGroup(EmoteController emoteController)
		{
			if (syncGroup == null || syncGroup.Contains(emoteController))
			{
				return;
			}
			syncGroup.Add(emoteController);
			if (!leadEmoteControllerByEmote.ContainsKey(emoteController.performingEmote) || (Object)(object)leadEmoteControllerByEmote[emoteController.performingEmote] == (Object)null)
			{
				leadEmoteControllerByEmote[emoteController.performingEmote] = emoteController;
			}
			if (!useAudio || !performingEmote.hasAudio)
			{
				return;
			}
			if (!performingEmote.isBoomboxAudio)
			{
				if (currentEmoteAudioSources != null && (!currentEmoteAudioSources.ContainsKey(emoteController.performingEmote) || (Object)(object)currentEmoteAudioSources[emoteController.performingEmote] == (Object)null))
				{
					currentEmoteAudioSources[emoteController.performingEmote] = emoteController.personalEmoteAudioSource;
					emoteController.personalEmoteAudioSource.SyncWithEmoteSyncGroup(this, emoteController);
					emoteController.personalEmoteAudioSource.AddToEmoteSyncGroup(this);
				}
			}
			else if ((Object)(object)currentAudioPlayer == (Object)null)
			{
				EmoteAudioPlayer nearestEmoteAudioPlayer = EmoteAudioPlayerManager.GetNearestEmoteAudioPlayer(((Component)emoteController).transform);
				if ((Object)(object)nearestEmoteAudioPlayer != (Object)null && nearestEmoteAudioPlayer.CanPlayMusic())
				{
					AssignExternalAudioPlayer(nearestEmoteAudioPlayer);
				}
			}
			UpdateAudioVolume();
		}

		public void RemoveFromEmoteSyncGroup(EmoteController emoteController)
		{
			if (syncGroup == null)
			{
				return;
			}
			syncGroup.Remove(emoteController);
			if (syncGroup.Count <= 0)
			{
				DestroyEmoteSyncGroup();
				return;
			}
			if (leadEmoteControllerByEmote.ContainsValue(emoteController))
			{
				UnlockableEmote key = leadEmoteControllerByEmote.FirstOrDefault((KeyValuePair<UnlockableEmote, EmoteController> x) => (Object)(object)x.Value == (Object)(object)emoteController).Key;
				leadEmoteControllerByEmote.Remove(key);
				foreach (EmoteController item in syncGroup)
				{
					if ((Object)(object)item == (Object)null || item.performingEmote == null || item.performingEmote != key)
					{
						continue;
					}
					leadEmoteControllerByEmote[key] = item;
					break;
				}
			}
			if (currentEmoteAudioSources == null)
			{
				return;
			}
			if (currentEmoteAudioSources.ContainsValue(emoteController.personalEmoteAudioSource))
			{
				emoteController.personalEmoteAudioSource.StopAudio();
				emoteController.personalEmoteAudioSource.RemoveFromEmoteSyncGroup();
				UnlockableEmote key2 = currentEmoteAudioSources.FirstOrDefault((KeyValuePair<UnlockableEmote, EmoteAudioSource> x) => (Object)(object)x.Value == (Object)(object)emoteController.personalEmoteAudioSource).Key;
				currentEmoteAudioSources.Remove(key2);
				if (useAudio && key2.hasAudio && !key2.isBoomboxAudio)
				{
					foreach (EmoteController item2 in syncGroup)
					{
						if (!((Object)(object)item2 == (Object)null) && item2.performingEmote != null && !((Object)(object)item2 == (Object)(object)emoteController))
						{
							EmoteAudioSource personalEmoteAudioSource = item2.personalEmoteAudioSource;
							if (item2.performingEmote == key2 && (Object)(object)personalEmoteAudioSource != (Object)null && personalEmoteAudioSource.CanPlayMusic())
							{
								currentEmoteAudioSources[key2] = personalEmoteAudioSource;
								personalEmoteAudioSource.SyncWithEmoteControllerAudio(item2);
								break;
							}
						}
					}
				}
			}
			UpdateAudioVolume();
		}

		public void DestroyEmoteSyncGroup()
		{
			CustomLogging.Log("Cleaning up emote sync group with id: " + syncId);
			if (currentEmoteAudioSources != null)
			{
				foreach (EmoteAudioSource value in currentEmoteAudioSources.Values)
				{
					if ((Object)(object)value != (Object)null)
					{
						value.StopAudio();
						value.RemoveFromEmoteSyncGroup();
					}
				}
				currentEmoteAudioSources = null;
			}
			if ((Object)(object)currentAudioPlayer != (Object)null)
			{
				currentAudioPlayer.StopAudio();
				currentAudioPlayer.RemoveFromEmoteSyncGroup();
			}
			allEmoteSyncGroups.Remove(syncId);
			syncGroup = null;
			syncId = -1;
		}

		public void UpdateAudioVolume()
		{
			if (currentEmoteAudioSources != null)
			{
				foreach (EmoteAudioSource value in currentEmoteAudioSources.Values)
				{
					if ((Object)(object)value != (Object)null)
					{
						value.UpdateVolume();
					}
				}
			}
			if ((Object)(object)currentAudioPlayer != (Object)null)
			{
				currentAudioPlayer.UpdateVolume();
			}
		}

		public void AssignExternalAudioPlayer(EmoteAudioPlayer audioPlayer)
		{
			if ((Object)(object)currentAudioPlayer != (Object)null)
			{
				currentAudioPlayer.StopAudio();
				currentAudioPlayer.RemoveFromEmoteSyncGroup();
				currentAudioPlayer = null;
			}
			if (useAudio && performingEmote.hasAudio && performingEmote.isBoomboxAudio)
			{
				currentAudioPlayer = audioPlayer;
				if ((Object)(object)currentAudioPlayer != (Object)null)
				{
					currentAudioPlayer.SyncWithEmoteControllerAudio(leadEmoteController);
					currentAudioPlayer.AddToEmoteSyncGroup(this);
					currentAudioPlayer.UpdateVolume();
				}
			}
		}
	}
	internal static class HelperTools
	{
		public static NetworkManager networkManager => NetworkManager.Singleton;

		public static bool isClient => networkManager.IsClient;

		public static bool isServer => networkManager.IsServer;

		public static bool isHost => networkManager.IsHost;

		public static PlayerControllerB localPlayerController => StartOfRound.Instance?.localPlayerController;

		public static QuickMenuManager quickMenuManager => localPlayerController?.quickMenuManager;

		public static TextMeshProUGUI[] controlTipLines => HUDManager.Instance?.controlTipLines;

		public static List<Item> allItems => StartOfRound.Instance?.allItemsList?.itemsList;

		public static SelectableLevel[] selectableLevels => StartOfRound.Instance?.levels;

		public static string currentSaveFileName => GameNetworkManager.Instance?.currentSaveFileName;

		public static int groupCredits => ((Object)(object)TerminalPatcher.terminalInstance != (Object)null) ? groupCredits : (-1);

		public static int currentEmoteCredits => TerminalPatcher.currentEmoteCredits;

		public static EmoteControllerPlayer emoteControllerLocal => EmoteControllerPlayer.emoteControllerLocal;

		public static bool TryGetPlayerByClientId(ulong clientId, out PlayerControllerB playerController)
		{
			playerController = null;
			PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts;
			foreach (PlayerControllerB val in allPlayerScripts)
			{
				if (val.actualClientId == clientId)
				{
					playerController = val;
					break;
				}
			}
			return (Object)(object)playerController != (Object)null;
		}

		public static bool TryGetPlayerByUsername(string username, out PlayerControllerB playerController)
		{
			playerController = null;
			PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts;
			foreach (PlayerControllerB val in allPlayerScripts)
			{
				if (val.playerUsername == username)
				{
					playerController = val;
					break;
				}
			}
			return (Object)(object)playerController != (Object)null;
		}

		public static EmoteController GetEmoteControllerById(ulong id)
		{
			foreach (EmoteController value in EmoteController.allEmoteControllers.Values)
			{
				if (value.emoteControllerId == id)
				{
					return value;
				}
			}
			return null;
		}
	}
	[HarmonyPatch]
	public class EmoteControllerMaskedEnemy : EmoteController
	{
		public static Dictionary<MaskedPlayerEnemy, EmoteControllerMaskedEnemy> allMaskedEnemyEmoteControllers = new Dictionary<MaskedPlayerEnemy, EmoteControllerMaskedEnemy>();

		public MaskedPlayerEnemy maskedEnemy;

		public int emoteCount = 0;

		public bool stoppedAndStaring = false;

		public bool behaviour1 = false;

		public Vector3 emotedAtPosition;

		public int id => (int)((NetworkBehaviour)maskedEnemy).NetworkObjectId;

		public float stopAndStareTimer
		{
			get
			{
				return (float)Traverse.Create((object)maskedEnemy).Field("stopAndStareTimer").GetValue();
			}
			set
			{
				Traverse.Create((object)maskedEnemy).Field("stopAndStareTimer").SetValue((object)value);
			}
		}

		public NavMeshAgent agent => ((EnemyAI)maskedEnemy).agent;

		public PlayerControllerB lookingAtPlayer
		{
			get
			{
				Transform stareAtTransform = maskedEnemy.stareAtTransform;
				return (stareAtTransform != null) ? ((Component)stareAtTransform).GetComponentInParent<PlayerControllerB>() : null;
			}
		}

		public bool inKillAnimation => (bool)Traverse.Create((object)maskedEnemy).Field("inKillAnimation").GetValue();

		public bool handsOut => (bool)Traverse.Create((object)maskedEnemy).Field("handsOut").GetValue();

		public float localSpeed
		{
			get
			{
				//IL_001b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0020: Unknown result type (might be due to invalid IL or missing references)
				Vector3 val = (Vector3)Traverse.Create((object)maskedEnemy).Field("agentLocalVelocity").GetValue();
				return ((Vector3)(ref val)).magnitude;
			}
		}

		public bool isMoving => animator.GetBool("IsMoving");

		public override void Initialize(string sourceRootBoneName = "metarig")
		{
			base.Initialize();
			if (initialized)
			{
				maskedEnemy = ((Component)this).GetComponentInParent<MaskedPlayerEnemy>();
				if ((Object)(object)maskedEnemy == (Object)null)
				{
					CustomLogging.LogError("Failed to find MaskedPlayerEnemy component in parent of EmoteControllerMaskedEnemy.");
				}
				else
				{
					allMaskedEnemyEmoteControllers.Add(maskedEnemy, this);
				}
			}
		}

		protected override void OnDestroy()
		{
			base.OnDestroy();
			allMaskedEnemyEmoteControllers?.Remove(maskedEnemy);
		}

		protected override bool CheckIfShouldStopEmoting()
		{
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			if (!isPerformingEmote)
			{
				return false;
			}
			if (base.CheckIfShouldStopEmoting())
			{
				return true;
			}
			return ((EnemyAI)maskedEnemy).isEnemyDead || (NetworkManager.Singleton.IsServer && (agent.speed > 0f || stopAndStareTimer <= 0f)) || (!NetworkManager.Singleton.IsServer && Vector3.Distance(emotedAtPosition, ((Component)maskedEnemy).transform.position) > 0.01f) || inKillAnimation;
		}

		public override bool IsPerformingCustomEmote()
		{
			return base.IsPerformingCustomEmote();
		}

		public override bool CanPerformEmote()
		{
			return base.CanPerformEmote() && (Object)(object)lookingAtPlayer != (Object)null && (!NetworkManager.Singleton.IsServer || stopAndStareTimer >= 2f) && !inKillAnimation && ((NetworkManager.Singleton.IsServer && agent.speed == 0f) || (!NetworkManager.Singleton.IsServer && !isMoving)) && !((EnemyAI)maskedEnemy).isEnemyDead;
		}

		public override bool PerformEmote(UnlockableEmote emote, int overrideEmoteId = -1, bool doNotTriggerAudio = false)
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			bool result = base.PerformEmote(emote, overrideEmoteId, doNotTriggerAudio);
			if (isPerformingEmote)
			{
				emoteCount++;
				emotedAtPosition = ((Component)maskedEnemy).transform.position;
			}
			return result;
		}

		public override void StopPerformingEmote()
		{
			base.StopPerformingEmote();
			stoppedAndStaring = false;
		}

		protected override void CreateBoneMap()
		{
			boneMap = BoneMapper.CreateBoneMap(humanoidSkeleton, metarig, EmoteControllerPlayer.sourceBoneNames);
		}

		protected override ulong GetEmoteControllerId()
		{
			return ((Object)(object)maskedEnemy != (Object)null) ? ((NetworkBehaviour)maskedEnemy).NetworkObjectId : 0;
		}

		protected override string GetEmoteControllerName()
		{
			return ((Object)(object)maskedEnemy != (Object)null) ? ((Object)maskedEnemy).name : base.GetEmoteControllerName();
		}
	}
	[DefaultExecutionOrder(-2)]
	public class EmoteControllerPlayer : EmoteController
	{
		public static Dictionary<PlayerControllerB, EmoteControllerPlayer> allPlayerEmoteControllers = new Dictionary<PlayerControllerB, EmoteControllerPlayer>();

		public PlayerControllerB playerController;

		public Animator originalAnimator;

		private Dictionary<Transform, Transform> boneMapLocalPlayerArms;

		internal Transform humanoidHead;

		private Transform cameraContainerTarget;

		private Transform cameraContainerLerp;

		public static List<string> sourceBoneNames = new List<string>
		{
			"spine", "spine.001", "spine.002", "spine.003", "spine.004", "shoulder.L", "arm.L_upper", "arm.L_lower", "hand.L", "finger1.L",
			"finger1.L.001", "finger2.L", "finger2.L.001", "finger3.L", "finger3.L.001", "finger4.L", "finger4.L.001", "finger5.L", "finger5.L.001", "shoulder.R",
			"arm.R_upper", "arm.R_lower", "hand.R", "finger1.R", "finger1.R.001", "finger2.R", "finger2.R.001", "finger3.R", "finger3.R.001", "finger4.R",
			"finger4.R.001", "finger5.R", "finger5.R.001", "thigh.L", "shin.L", "foot.L", "heel.02.L", "toe.L", "thigh.R", "shin.R",
			"foot.R", "heel.02.R", "toe.R"
		};

		public GrabbablePropObject sourceGrabbableEmoteProp;

		public static EmoteControllerPlayer emoteControllerLocal => ((Object)(object)HelperTools.localPlayerController != (Object)null && allPlayerEmoteControllers.ContainsKey(HelperTools.localPlayerController)) ? allPlayerEmoteControllers[HelperTools.localPlayerController] : null;

		public bool isLocalPlayer => (Object)(object)playerController == (Object)(object)StartOfRound.Instance?.localPlayerController;

		public ulong clientId => playerController.actualClientId;

		public ulong playerId => playerController.playerClientId;

		public ulong steamId => playerController.playerSteamId;

		public string username => playerController.playerUsername;

		public float timeSinceStartingEmote
		{
			get
			{
				return (float)Traverse.Create((object)playerController).Field("timeSinceStartingEmote").GetValue();
			}
			set
			{
				Traverse.Create((object)playerController).Field("timeSinceStartingEmote").SetValue((object)value);
			}
		}

		public override void Initialize(string sourceRootBoneName = "metarig")
		{
			base.Initialize();
			if (initialized)
			{
				originalAnimator = ((Component)metarig).GetComponentInChildren<Animator>();
				playerController = ((Component)this).GetComponentInParent<PlayerControllerB>();
				if ((Object)(object)playerController == (Object)null)
				{
					CustomLogging.LogError("Failed to find PlayerControllerB component in parent of EmoteControllerPlayer.");
				}
				else
				{
					allPlayerEmoteControllers.Add(playerController, this);
				}
			}
		}

		protected override void Start()
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: 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_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			base.Start();
			if (initialized)
			{
				Transform val = FindChildRecursive("spine.004", metarig);
				if ((Object)(object)val != (Object)null)
				{
					cameraContainerTarget = new GameObject("CameraContainer_Target").transform;
					cameraContainerTarget.SetParent(val);
					cameraContainerTarget.localPosition = new Vector3(0f, 0.22f, 0f);
					cameraContainerTarget.localEulerAngles = new Vector3(-3f, 0f, 0f);
					cameraContainerLerp = new GameObject("CameraContainer_Lerp").transform;
					cameraContainerLerp.SetParent(humanoidSkeleton);
					cameraContainerLerp.SetLocalPositionAndRotation(Vector3.zero, Quaternion.identity);
				}
				humanoidHead = FindChildRecursive("head", humanoidSkeleton);
				if (!Object.op_Implicit((Object)(object)humanoidHead))
				{
					CustomLogging.LogError("Failed to find Head on: " + base.emoteControllerName);
				}
			}
		}

		protected override void OnDestroy()
		{
			base.OnDestroy();
			allPlayerEmoteControllers?.Remove(playerController);
		}

		protected override void Update()
		{
			if (initialized && !((Object)(object)playerController == (Object)null) && (!((Object)(object)playerController == (Object)(object)HelperTools.localPlayerController) || (!ConfigSettings.disableEmotesForSelf.Value && !LCVR_Compat.LoadedAndEnabled)))
			{
				base.Update();
			}
		}

		protected override void LateUpdate()
		{
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			if (!initialized || (Object)(object)playerController == (Object)null || ((Object)(object)playerController == (Object)(object)HelperTools.localPlayerController && (ConfigSettings.disableEmotesForSelf.Value || LCVR_Compat.LoadedAndEnabled)))
			{
				return;
			}
			bool flag = isPerformingEmote;
			base.LateUpdate();
			if (flag && !isPerformingEmote && playerController.performingEmote)
			{
				playerController.performingEmote = false;
				originalAnimator.SetInteger("emoteNumber", 0);
				AnimatorStateInfo currentAnimatorStateInfo = originalAnimator.GetCurrentAnimatorStateInfo(0);
				animator.Play(((AnimatorStateInfo)(ref currentAnimatorStateInfo)).fullPathHash, 0, 0f);
				if (isLocalPlayer)
				{
					timeSinceStartingEmote = 0f;
					playerController.StopPerformingEmoteServerRpc();
				}
			}
		}

		protected override void TranslateAnimation()
		{
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0209: Unknown result type (might be due to invalid IL or missing references)
			//IL_0222: Unknown result type (might be due to invalid IL or missing references)
			if (!initialized || !isPerformingEmote || (Object)(object)playerController == (Object)null)
			{
				return;
			}
			base.TranslateAnimation();
			if (Object.op_Implicit((Object)(object)humanoidHead) && Object.op_Implicit((Object)(object)cameraContainerLerp) && Object.op_Implicit((Object)(object)cameraContainerTarget))
			{
				cameraContainerLerp.position = Vector3.Lerp(cameraContainerLerp.position, cameraContainerTarget.position, 25f * Time.deltaTime);
				cameraContainerLerp.rotation = Quaternion.Lerp(cameraContainerLerp.rotation, cameraContainerTarget.rotation, 25f * Time.deltaTime);
				if (!isLocalPlayer || !ThirdPersonEmoteController.firstPersonEmotesEnabled || !ThirdPersonEmoteController.isMovingWhileEmoting)
				{
					playerController.cameraContainerTransform.position = cameraContainerLerp.position;
					playerController.cameraContainerTransform.rotation = cameraContainerLerp.rotation;
				}
				if (isLocalPlayer)
				{
					playerController.localVisor.position = playerController.localVisorTargetPoint.position;
					playerController.localVisor.rotation = playerController.localVisorTargetPoint.rotation;
				}
			}
			if (!isLocalPlayer)
			{
				return;
			}
			playerController.playerModelArmsMetarig.rotation = playerController.localArmsRotationTarget.rotation;
			if (boneMapLocalPlayerArms == null)
			{
				return;
			}
			foreach (KeyValuePair<Transform, Transform> boneMapLocalPlayerArm in boneMapLocalPlayerArms)
			{
				Transform key = boneMapLocalPlayerArm.Key;
				Transform value = boneMapLocalPlayerArm.Value;
				if (!((Object)(object)key == (Object)null) && !((Object)(object)value == (Object)null))
				{
					((Component)value).transform.position = ((Component)key).transform.position;
					((Component)value).transform.rotation = ((Component)key).transform.rotation;
				}
			}
		}

		protected override bool CheckIfShouldStopEmoting()
		{
			if ((Object)(object)playerController == (Object)null || !isPerformingEmote)
			{
				return false;
			}
			if (base.CheckIfShouldStopEmoting() || !playerController.performingEmote || performingEmote == null)
			{
				return true;
			}
			GrabbableObject val = playerController.ItemSlots[playerController.currentItemSlot];
			if ((Object)(object)sourceGrabbableEmoteProp != (Object)null && (Object)(object)sourceGrabbableEmoteProp != (Object)(object)val)
			{
				return true;
			}
			return false;
		}

		public override bool IsPerformingCustomEmote()
		{
			return base.IsPerformingCustomEmote();
		}

		public bool TryPerformingEmoteLocal(UnlockableEmote emote, int overrideEmoteId = -1, GrabbablePropObject sourcePropObject = null)
		{
			if (!initialized || ConfigSettings.disableEmotesForSelf.Value || LCVR_Compat.LoadedAndEnabled)
			{
				return false;
			}
			if (!isLocalPlayer)
			{
				CustomLogging.LogWarning("Cannot run TryPerformEmoteLocal on a character who does not belong to the local player. This is not allowed.");
				return false;
			}
			CustomLogging.Log("Attempting to perform emote on local player.");
			if (!CanPerformEmote())
			{
				return false;
			}
			if (overrideEmoteId >= 0 && (emote.emoteSyncGroup == null || emote.emoteSyncGroup.Count <= 1 || overrideEmoteId < 0 || overrideEmoteId >= emote.emoteSyncGroup.Count))
			{
				overrideEmoteId = -1;
			}
			if (emote.emoteSyncGroup != null && emote.emoteSyncGroup.Count > 1)
			{
				if (emote.randomEmote)
				{
					if (overrideEmoteId < 0)
					{
						overrideEmoteId = Random.Range(0, emote.emoteSyncGroup.Count);
					}
				}
				else
				{
					emote = emote.emoteSyncGroup[0];
				}
			}
			if (overrideEmoteId >= 0 && emote.emoteSyncGroup != null && overrideEmoteId < emote.emoteSyncGroup.Count)
			{
				emote = emote.emoteSyncGroup[overrideEmoteId];
			}
			else
			{
				overrideEmoteId = -1;
			}
			EmoteController emoteController = null;
			if (isPerformingEmote && performingEmote.IsEmoteInEmoteGroup(emote) && (!performingEmote.randomEmote || performingEmote.loopable))
			{
				if (performingEmote.emoteSyncGroup != null && performingEmote.emoteSyncGroup.Count > 1)
				{
					overrideEmoteId = (performingEmote.emoteSyncGroup.IndexOf(performingEmote) + 1) % performingEmote.emoteSyncGroup.Count;
					if (performingEmote.emoteSyncGroup[overrideEmoteId] != null)
					{
						emote = performingEmote.emoteSyncGroup[overrideEmoteId];
					}
				}
				if (emoteSyncGroup?.syncGroup != null && emoteSyncGroup.syncGroup.Count > 1)
				{
					if (emoteSyncGroup.syncGroup.Count > 1 && (performingEmote?.emoteSyncGroup == null || performingEmote.emoteSyncGroup.Count <= 1))
					{
						return true;
					}
					foreach (EmoteController item in emoteSyncGroup.syncGroup)
					{
						if ((Object)(object)item != (Object)(object)this)
						{
							emoteController = item;
							break;
						}
					}
				}
			}
			if ((Object)(object)emoteController != (Object)null)
			{
				return TrySyncingEmoteWithEmoteController(emoteController, overrideEmoteId);
			}
			bool result = ((!((Object)(object)sourcePropObject != (Object)null) || !((Object)(object)sourcePropObject == (Object)(object)HelperTools.localPlayerController.ItemSlots[HelperTools.localPlayerController.currentItemSlot])) ? PerformEmote(emote, overrideEmoteId, AudioManager.emoteOnlyMode) : PerformEmote(emote, sourcePropObject, overrideEmoteId, AudioManager.emoteOnlyMode));
			playerController.StartPerformingEmoteServerRpc();
			SyncPerformingEmoteManager.SendPerformingEmoteUpdateToServer(emote, AudioManager.emoteOnlyMode);
			timeSinceStartingEmote = 0f;
			playerController.performingEmote = true;
			return result;
		}

		public bool TrySyncingEmoteWithEmoteController(EmoteController emoteController, int overrideEmoteId = -1)
		{
			if (!initialized || (Object)(object)emoteController == (Object)null || ConfigSettings.disableEmotesForSelf.Value || LCVR_Compat.LoadedAndEnabled)
			{
				return false;
			}
			if (!isLocalPlayer)
			{
				CustomLogging.LogWarning("Cannot run TrySyncingEmoteWithEmoteController on a character who does not belong to the local player. This is not allowed.");
				return false;
			}
			CustomLogging.Log("Attempting to sync emote for player: " + ((Object)playerController).name + " with emote controller with id: " + emoteController.emoteControllerId);
			if (!CanPerformEmote() || !emoteController.IsPerformingCustomEmote())
			{
				return false;
			}
			if (overrideEmoteId >= 0 && (emoteController.performingEmote?.emoteSyncGroup == null || overrideEmoteId >= emoteController.performingEmote.emoteSyncGroup.Count || emoteController.performingEmote.emoteSyncGroup[overrideEmoteId] == null))
			{
				overrideEmoteId = -1;
			}
			SyncWithEmoteController(emoteController, overrideEmoteId);
			if (performingEmote != null)
			{
				if (performingEmote.inEmoteSyncGroup)
				{
					overrideEmoteId = performingEmote.emoteSyncGroup.IndexOf(performingEmote);
				}
				playerController.StartPerformingEmoteServerRpc();
				SyncPerformingEmoteManager.SendSyncEmoteUpdateToServer(emoteController, overrideEmoteId);
				timeSinceStartingEmote = 0f;
				playerController.performingEmote = true;
				return true;
			}
			return false;
		}

		public override bool CanPerformEmote()
		{
			if (!isLocalPlayer)
			{
				return true;
			}
			if (!initialized || ConfigSettings.disableEmotesForSelf.Value || LCVR_Compat.LoadedAndEnabled)
			{
				return false;
			}
			bool flag = base.CanPerformEmote();
			MethodInfo method = ((object)playerController).GetType().GetMethod("CheckConditionsForEmote", BindingFlags.Instance | BindingFlags.NonPublic);
			flag &= (bool)method.Invoke(playerController, new object[0]);
			bool flag2 = (Object)(object)playerController.inAnimationWithEnemy == (Object)null && (!isLocalPlayer || !CentipedePatcher.IsCentipedeLatchedOntoLocalPlayer());
			return flag && flag2;
		}

		[HarmonyPatch(typeof(PlayerControllerB), "SwitchToItemSlot")]
		[HarmonyPostfix]
		private static void OnSwapItem(int slot, PlayerControllerB __instance)
		{
			if (allPlayerEmoteControllers.TryGetValue(__instance, out var value) && value.IsPerformingCustomEmote())
			{
				GrabbableObject val = __instance.ItemSlots[slot];
				if ((Object)(object)value.sourceGrabbableEmoteProp != (Object)null && (Object)(object)value.sourceGrabbableEmoteProp != (Object)(object)val)
				{
					value.StopPerformingEmote();
				}
				else if ((Object)(object)val != (Object)null && val is GrabbablePropObject)
				{
					val.EnableItemMeshes(false);
				}
			}
		}

		public bool PerformEmote(UnlockableEmote emote, GrabbablePropObject sourcePropObject, int overrideEmoteId = -1, bool doNotTriggerAudio = false)
		{
			if ((Object)(object)sourcePropObject != (Object)null && (Object)(object)sourcePropObject == (Object)(object)playerController.ItemSlots[playerController.currentItemSlot])
			{
				sourceGrabbableEmoteProp = sourcePropObject;
			}
			bool result = PerformEmote(emote, overrideEmoteId, doNotTriggerAudio);
			if (isPerformingEmote)
			{
				if (!isLocalPlayer && SyncManager.isSynced && ConfigSync.instance.syncPersistentUnlocksGlobal && !SessionManager.unlockedEmotesByPlayer.TryGetValue(playerController.playerUsername, out var value) && !value.Contains(performingEmote))
				{
					SessionManager.UnlockEmoteLocal(emote.emoteId, purchased: false, playerController.playerUsername);
				}
			}
			else
			{
				StopPerformingEmote();
			}
			return result;
		}

		public override bool PerformEmote(UnlockableEmote emote, int overrideEmoteId = -1, bool doNotTriggerAudio = false)
		{
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)playerController == (Object)null || (isLocalPlayer && (ConfigSettings.disableEmotesForSelf.Value || LCVR_Compat.LoadedAndEnabled)))
			{
				return false;
			}
			bool result = base.PerformEmote(emote, overrideEmoteId, doNotTriggerAudio);
			if (isPerformingEmote)
			{
				cameraContainerLerp.SetPositionAndRotation(cameraContainerTarget.position, cameraContainerTarget.rotation);
				playerController.performingEmote = true;
				if (!isLocalPlayer)
				{
					originalAnimator.SetInteger("emoteNumber", 0);
				}
				GrabbablePropObject grabbablePropObject = playerController.ItemSlots[playerController.currentItemSlot] as GrabbablePropObject;
				if (Object.op_Implicit((Object)(object)grabbablePropObject))
				{
					((GrabbableObject)grabbablePropObject).EnableItemMeshes(false);
				}
				if (isLocalPlayer)
				{
					ThirdPersonEmoteController.OnStartCustomEmoteLocal();
				}
			}
			return result;
		}

		public override bool SyncWithEmoteController(EmoteController emoteController, int overrideEmoteId = -1)
		{
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)playerController == (Object)null || (isLocalPlayer && (ConfigSettings.disableEmotesForSelf.Value || LCVR_Compat.LoadedAndEnabled)))
			{
				return false;
			}
			bool result = base.SyncWithEmoteController(emoteController, overrideEmoteId);
			if (isPerformingEmote)
			{
				cameraContainerLerp.SetPositionAndRotation(cameraContainerTarget.position, cameraContainerTarget.rotation);
				playerController.performingEmote = true;
				if (!isLocalPlayer)
				{
					originalAnimator.SetInteger("emoteNumber", 0);
				}
				else
				{
					ThirdPersonEmoteController.OnStartCustomEmoteLocal();
					playerController.StartPerformingEmoteServerRpc();
				}
			}
			return result;
		}

		public override void StopPerformingEmote()
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)playerController == (Object)null || (isLocalPlayer && ConfigSettings.disableEmotesForSelf.Value))
			{
				return;
			}
			base.StopPerformingEmote();
			cameraContainerLerp.SetPositionAndRotation(cameraContainerTarget.position, cameraContainerTarget.rotation);
			((Component)playerController.gameplayCamera).transform.SetLocalPositionAndRotation(Vector3.zero, Quaternion.identity);
			GrabbablePropObject grabbablePropObject = playerController.ItemSlots[playerController.currentItemSlot] as GrabbablePropObject;
			if (Object.op_Implicit((Object)(object)grabbablePropObject))
			{
				((GrabbableObject)grabbablePropObject).EnableItemMeshes(true);
			}
			if ((Object)(object)sourceGrabbableEmoteProp != (Object)null)
			{
				if (sourceGrabbableEmoteProp.isPerformingEmote)
				{
					sourceGrabbableEmoteProp.StopEmote();
				}
				sourceGrabbableEmoteProp = null;
			}
			playerController.playerBodyAnimator.SetInteger("emote_number", 0);
			playerController.performingEmote = false;
			playerController.playerBodyAnimator.Update(0f);
			if (isLocalPlayer)
			{
				ThirdPersonEmoteController.OnStopCustomEmoteLocal();
				playerController.StopPerformingEmoteServerRpc();
			}
		}

		public override void ResetPerformingEmote()
		{
			if ((Object)(object)playerController == (Object)null || (isLocalPlayer && ConfigSettings.disableEmotesForSelf.Value))
			{
				return;
			}
			base.ResetPerformingEmote();
			if ((Object)(object)sourceGrabbableEmoteProp != (Object)null)
			{
				if (sourceGrabbableEmoteProp.isPerformingEmote)
				{
					sourceGrabbableEmoteProp.StopEmote();
				}
				sourceGrabbableEmoteProp = null;
			}
		}

		protected override void CreateBoneMap()
		{
			boneMap = BoneMapper.CreateBoneMap(humanoidSkeleton, metarig, sourceBoneNames);
			List<string> list = new List<string>
			{
				"arm.L_upper", "arm.L_lower", "hand.L", "finger1.L", "finger1.L.001", "finger2.L", "finger2.L.001", "finger3.L", "finger3.L.001", "finger4.L",
				"finger4.L.001", "finger5.L", "finger5.L.001", "arm.R_upper", "arm.R_lower", "hand.R", "finger1.R", "finger1.R.001", "finger2.R", "finger2.R.001",
				"finger3.R", "finger3.R.001", "finger4.R", "finger4.R.001", "finger5.R", "finger5.R.001"
			};
			boneMapLocalPlayerArms = BoneMapper.CreateBoneMap(humanoidSkeleton, playerController.localArmsTransform, list);
		}

		protected override ulong GetEmoteControllerId()
		{
			return ((Object)(object)playerController != (Object)null) ? ((NetworkBehaviour)playerController).NetworkObjectId : 0;
		}

		protected override string GetEmoteControllerName()
		{
			return ((Object)(object)playerController != (Object)null) ? playerController.playerUsername : base.GetEmoteControllerName();
		}
	}
	[HarmonyPatch]
	[DefaultExecutionOrder(-2)]
	public class EmoteController : MonoBehaviour
	{
		public static Dictionary<GameObject, EmoteController> allEmoteControllers = new Dictionary<GameObject, EmoteController>();

		public bool initialized = false;

		public Transform metarig;

		public Transform humanoidSkeleton;

		public Animator animator;

		public AnimatorOverrideController animatorController;

		public bool isPerformingEmote = false;

		public UnlockableEmote performingEmote;

		protected Dictionary<Transform, Transform> boneMap;

		public List<Transform> groundContactPoints = new List<Transform>();

		public Transform propsParent;

		public List<PropObject> emotingProps = new List<PropObject>();

		public Transform ikLeftHand;

		public Transform ikRightHand;

		public Transform ikLeftFoot;

		public Transform ikRightFoot;

		public Transform ikHead;

		public EmoteSyncGroup emoteSyncGroup;

		public EmoteAudioSource personalEmoteAudioSource;

		public ulong emoteControllerId => GetEmoteControllerId();

		public string emoteControllerName => GetEmoteControllerName();

		public float currentAnimationTimeNormalized
		{
			get
			{
				//IL_0008: Unknown result type (might be due to invalid IL or missing references)
				//IL_000d: Unknown result type (might be due to invalid IL or missing references)
				AnimatorStateInfo currentAnimatorStateInfo = animator.GetCurrentAnimatorStateInfo(0);
				return ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).normalizedTime;
			}
		}

		public float currentAnimationTime
		{
			get
			{
				AnimationClip currentAnimationClip = GetCurrentAnimationClip();
				return ((Object)(object)currentAnimationClip != (Object)null) ? (currentAnimationClip.length * (currentAnimationTimeNormalized % 1f)) : 0f;
			}
		}

		public int currentStateHash
		{
			get
			{
				//IL_0008: Unknown result type (might be due to invalid IL or missing references)
				//IL_000d: Unknown result type (might be due to invalid IL or missing references)
				AnimatorStateInfo currentAnimatorStateInfo = animator.GetCurrentAnimatorStateInfo(0);
				return ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).shortNameHash;
			}
		}

		public bool isLooping
		{
			get
			{
				return animator.GetBool("loop");
			}
			set
			{
				animator.SetBool("loop", value);
			}
		}

		public bool isAnimatorInLoopingState
		{
			get
			{
				//IL_0008: Unknown result type (might be due to invalid IL or missing references)
				//IL_000d: Unknown result type (might be due to invalid IL or missing references)
				AnimatorStateInfo currentAnimatorStateInfo = animator.GetCurrentAnimatorStateInfo(0);
				return ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).IsName("emote_loop");
			}
		}

		public bool isSimpleEmoteController => ((object)this).GetType() == typeof(EmoteController);

		public int emoteSyncId => (emoteSyncGroup != null) ? emoteSyncGroup.syncId : (-1);

		protected virtual void Awake()
		{
			if (!initialized)
			{
				Initialize();
			}
		}

		public virtual void Initialize(string sourceRootBoneName = "metarig")
		{
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Expected O, but got Unknown
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Expected O, but got Unknown
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_01df: Unknown result type (might be due to invalid IL or missing references)
			//IL_0206: Unknown result type (might be due to invalid IL or missing references)
			//IL_020b: Unknown result type (might be due to invalid IL or missing references)
			//IL_021c: Unknown result type (might be due to invalid IL or missing references)
			if (initialized || (Object)(object)Plugin.humanoidSkeletonPrefab == (Object)null || (Object)(object)Plugin.humanoidAnimatorController == (Object)null || (Object)(object)Plugin.humanoidAvatar == (Object)null)
			{
				return;
			}
			try
			{
				metarig = FindChildRecursive(sourceRootBoneName, ((Component)this).transform);
				humanoidSkeleton = Object.Instantiate<GameObject>(Plugin.humanoidSkeletonPrefab, metarig.parent).transform;
				((Object)humanoidSkeleton).name = "HumanoidSkeleton";
				humanoidSkeleton.SetSiblingIndex(metarig.GetSiblingIndex() + 1);
				animator = ((Component)humanoidSkeleton).GetComponent<Animator>();
				OnAnimatorIKHandler onAnimatorIKHandler = ((Component)animator).gameObject.AddComponent<OnAnimatorIKHandler>();
				onAnimatorIKHandler.SetParentEmoteController(this);
				animatorController = new AnimatorOverrideController(Plugin.humanoidAnimatorController);
				animator.runtimeAnimatorController = (RuntimeAnimatorController)(object)animatorController;
				humanoidSkeleton.SetLocalPositionAndRotation(metarig.localPosition + Vector3.down * 0.025f, Quaternion.identity);
				humanoidSkeleton.localScale = metarig.localScale;
				if (!isSimpleEmoteController)
				{
					allEmoteControllers.Add(((Component)this).gameObject, this);
					GameObject val = new GameObject("PersonalEmoteAudioSource");
					val.transform.SetParent(humanoidSkeleton);
					val.transform.SetLocalPositionAndRotation(Vector3.zero, Quaternion.identity);
					val.transform.localScale = Vector3.one;
					personalEmoteAudioSource = val.AddComponent<EmoteAudioSource>();
				}
				if ((Object)(object)propsParent == (Object)null)
				{
					propsParent = ((Component)this).transform.Find("EmoteProps");
					if ((Object)(object)propsParent == (Object)null)
					{
						propsParent = new GameObject("EmoteProps").transform;
						propsParent.SetParent(humanoidSkeleton);
						propsParent.SetLocalPositionAndRotation(Vector3.zero, Quaternion.identity);
						propsParent.localScale = Vector3.one;
					}
				}
				initialized = true;
			}
			catch (Exception ex)
			{
				Debug.LogError((object)("Failed to initialize EmoteController. Error: " + ex));
			}
		}

		protected virtual void Start()
		{
			if (!initialized)
			{
				return;
			}
			if (boneMap == null)
			{
				if (!isSimpleEmoteController)
				{
					CreateBoneMap();
				}
				else
				{
					Debug.LogWarning((object)"Using the base emote controller. Remember that when doing this, the bonemap will need to be built manually.");
				}
			}
			FindIkBones();
		}

		protected virtual void OnEnable()
		{
		}

		protected virtual void OnDisable()
		{
			if (isPerformingEmote)
			{
				StopPerformingEmote();
			}
		}

		protected virtual void OnDestroy()
		{
			if (isPerformingEmote)
			{
				StopPerformingEmote();
			}
			allEmoteControllers?.Remove(((Component)this).gameObject);
			if (SyncPerformingEmoteManager.doNotTriggerAudioDict.ContainsKey(this))
			{
				SyncPerformingEmoteManager.doNotTriggerAudioDict.Remove(this);
			}
		}

		protected virtual void Update()
		{
			if (initialized)
			{
			}
		}

		protected virtual void LateUpdate()
		{
			if (initialized)
			{
				if (isPerformingEmote && CheckIfShouldStopEmoting())
				{
					StopPerformingEmote();
				}
				if (!((Object)(object)animator == (Object)null) && !((Object)(object)animatorController == (Object)null) && boneMap != null && isPerformingEmote)
				{
					TranslateAnimation();
				}
			}
		}

		protected virtual void TranslateAnimation()
		{
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			if (performingEmote == null || boneMap == null || boneMap.Count <= 0)
			{
				return;
			}
			foreach (KeyValuePair<Transform, Transform> item in boneMap)
			{
				Transform key = item.Key;
				Transform value = item.Value;
				if (!((Object)(object)key == (Object)null) && !((Object)(object)value == (Object)null))
				{
					((Component)value).transform.position = ((Component)key).transform.position;
					((Component)value).transform.rotation = ((Component)key).transform.rotation;
				}
			}
		}

		protected virtual bool CheckIfShouldStopEmoting()
		{
			if (isPerformingEmote)
			{
				return performingEmote == null || (!performingEmote.loopable && !performingEmote.isPose && currentAnimationTimeNormalized >= 1f);
			}
			return false;
		}

		protected virtual void CorrectVerticalPosition()
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			if (groundContactPoints == null)
			{
				return;
			}
			float num = 0f;
			foreach (Transform groundContactPoint in groundContactPoints)
			{
				num = Mathf.Min(num, ((Component)groundContactPoint).transform.position.y - metarig.position.y);
			}
			if (num < 0f)
			{
				metarig.position = new Vector3(metarig.position.x, metarig.position.y - num, metarig.position.z);
			}
		}

		public virtual bool IsPerformingCustomEmote()
		{
			return isPerformingEmote && performingEmote != null;
		}

		public virtual bool CanPerformEmote()
		{
			return initialized && (Object)(object)animator != (Object)null && ((Behaviour)animator).enabled;
		}

		public virtual bool PerformEmote(UnlockableEmote emote, int overrideEmoteId = -1, bool doNotTriggerAudio = false)
		{
			if (!initialized || !CanPerformEmote())
			{
				return false;
			}
			if (!isSimpleEmoteController)
			{
				CustomLogging.Log("[" + emoteControllerName + "] Performing emote: " + emote.emoteName);
			}
			if (isPerformingEmote)
			{
				ResetPerformingEmote();
			}
			if (emote.emoteSyncGroup != null)
			{
				if (overrideEmoteId >= 0 && overrideEmoteId < emote.emoteSyncGroup.Count && emote.emoteSyncGroup[overrideEmoteId] != null)
				{
					emote = emote.emoteSyncGroup[overrideEmoteId];
				}
				else if (emote.randomEmote)
				{
					int index = Random.Range(0, emote.emoteSyncGroup.Count);
					UnlockableEmote unlockableEmote = emote.emoteSyncGroup[index];
					if (unlockableEmote != null)
					{
						emote = unlockableEmote;
					}
				}
			}
			animatorController["emote"] = emote.animationClip;
			if ((Object)(object)emote.transitionsToClip != (Object)null)
			{
				animatorController["emote_loop"] = emote.transitionsToClip;
			}
			animator.SetBool("loop", (Object)(object)emote.transitionsToClip != (Object)null);
			animator.Play("emote", 0, 0f);
			animator.Update(0f);
			performingEmote = emote;
			isPerformingEmote = true;
			PerformEmoteProps();
			if (!isSimpleEmoteController)
			{
				CreateEmoteSyncGroup(doNotTriggerAudio);
			}
			DiscoBallPatcher.OnPerformEmote(this);
			return true;
		}

		public virtual bool SyncWithEmoteController(EmoteController emoteController, int overrideEmoteId = -1)
		{
			if (!initialized || !CanPerformEmote() || (Object)(object)emoteController == (Object)null || !emoteController.IsPerformingCustomEmote())
			{
				return false;
			}
			if (!isSimpleEmoteController)
			{
				CustomLogging.Log("[" + emoteControllerName + "] Attempting to sync with emote controller: " + ((Object)emoteController).name + " Emote: " + emoteController.performingEmote.emoteName + " PlayEmoteAtTimeNormalized: " + emoteController.currentAnimationTimeNormalized % 1f);
			}
			if (isPerformingEmote)
			{
				ResetPerformingEmote();
			}
			EmoteSyncGroup emoteSyncGroup = emoteController.emoteSyncGroup;
			if (emoteSyncGroup == null)
			{
				CustomLogging.LogWarning("[" + emoteControllerName + "] Attempted to sync with emote controller who is not a part of an emote sync group. Continuing anyways.");
			}
			UnlockableEmote unlockableEmote = emoteController.performingEmote;
			if (unlockableEmote.emoteSyncGroup != null)
			{
				if (overrideEmoteId >= 0 && overrideEmoteId < unlockableEmote.emoteSyncGroup.Count && unlockableEmote.emoteSyncGroup[overrideEmoteId] != null)
				{
					unlockableEmote = unlockableEmote.emoteSyncGroup[overrideEmoteId];
				}
				else if (unlockableEmote.randomEmote)
				{
					if (unlockableEmote.hasAudio && !unlockableEmote.isBoomboxAudio)
					{
						unlockableEmote = emoteController.performingEmote;
					}
					else
					{
						int index = Random.Range(0, unlockableEmote.emoteSyncGroup.Count);
						UnlockableEmote unlockableEmote2 = unlockableEmote.emoteSyncGroup[index];
						if (unlockableEmote2 != null)
						{
							unlockableEmote = unlockableEmote2;
						}
					}
				}
				else
				{
					bool flag = false;
					foreach (UnlockableEmote item in unlockableEmote.emoteSyncGroup)
					{
						if (!emoteSyncGroup.leadEmoteControllerByEmote.ContainsKey(item) || (Object)(object)emoteSyncGroup.leadEmoteControllerByEmote[unlockableEmote] == (Object)null)
						{
							unlockableEmote = item;
							flag = true;
							break;
						}
					}
					if (!flag)
					{
						int num = unlockableEmote.emoteSyncGroup.IndexOf(unlockableEmote);
						if (num >= 0)
						{
							num = (num + 1) % unlockableEmote.emoteSyncGroup.Count;
							unlockableEmote = unlockableEmote.emoteSyncGroup[num];
						}
					}
				}
			}
			AnimationClip currentAnimationClip = emoteController.GetCurrentAnimationClip();
			if (!unlockableEmote.ClipIsInEmote(currentAnimationClip))
			{
				CustomLogging.LogError("[" + emoteControllerName + "] Attempted to sync with emote controller whose animation clip is not a part of their performing emote? Emote: " + emoteController.performingEmote?.ToString() + " AnimationClip: " + ((Object)currentAnimationClip).name);
				return false;
			}
			animatorController["emote"] = unlockableEmote.animationClip;
			if ((Object)(object)unlockableEmote.transitionsToClip != (Object)null)
			{
				animatorController["emote_loop"] = unlockableEmote.transitionsToClip;
			}
			float num2 = emoteController.currentAnimationTimeNormalized % 1f;
			animator.SetBool("loop", (Object)(object)unlockableEmote.transitionsToClip != (Object)null);
			animator.Play(((Object)(object)currentAnimationClip == (Object)(object)unlockableEmote.transitionsToClip) ? "emote_loop" : "emote", 0, num2);
			animator.Update(0f);
			performingEmote = unlockableEmote;
			isPerformingEmote = true;
			PerformEmoteProps();
			if (!isSimpleEmoteController && emoteController.emoteSyncGroup != null)
			{
				AddToEmoteSyncGroup(emoteController.emoteSyncGroup);
			}
			DiscoBallPatcher.OnPerformEmote(this);
			return true;
		}

		protected void PerformEmoteProps()
		{
			if ((Object)(object)propsParent != (Object)null && performingEmote.propNamesInEmote != null)
			{
				LoadEmoteProps();
			}
			if (emotingProps == null)
			{
				return;
			}
			foreach (PropObject emotingProp in emotingProps)
			{
				emotingProp.SyncWithEmoteController(this);
			}
		}

		protected void LoadEmoteProps()
		{
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			if (performingEmote.propNamesInEmote == null)
			{
				return;
			}
			UnloadEmoteProps();
			foreach (string item in performingEmote.propNamesInEmote)
			{
				PropObject propObject = EmotePropManager.LoadEmoteProp(item);
				propObject.SetPropLayer(6);
				emotingProps.Add(propObject);
				((Component)propObject).transform.SetParent(propsParent);
				((Component)propObject).transform.localPosition = Vector3.zero;
				((Component)propObject).transform.localRotation = Quaternion.identity;
			}
		}

		protected void UnloadEmoteProps()
		{
			if (emotingProps == null)
			{
				return;
			}
			foreach (PropObject emotingProp in emotingProps)
			{
				((Component)emotingProp).transform.SetParent(EmotePropManager.propPoolParent);
				emotingProp.active = false;
			}
			emotingProps.Clear();
		}

		public virtual void StopPerformingEmote()
		{
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			if (initialized)
			{
				isPerformingEmote = false;
				if (!isSimpleEmoteController)
				{
					CustomLogging.Log(string.Format("[" + emoteControllerName + "] Stopping emote."));
				}
				animatorController["emote"] = null;
				animatorController["emote_loop"] = null;
				RemoveFromEmoteSyncGroup();
				UnloadEmoteProps();
				if ((Object)(object)ikLeftHand != (Object)null)
				{
					ikLeftHand.localPosition = Vector3.zero;
				}
				if ((Object)(object)ikRightHand != (Object)null)
				{
					ikRightHand.localPosition = Vector3.zero;
				}
				if ((Object)(object)ikLeftFoot != (Object)null)
				{
					ikLeftFoot.localPosition = Vector3.zero;
				}
				if ((Object)(object)ikRightFoot != (Object)null)
				{
					ikRightFoot.localPosition = Vector3.zero;
				}
				if ((Object)(object)ikHead != (Object)null)
				{
					ikHead.localPosition = Vector3.zero;
				}
				DiscoBallPatcher.OnStopPerformingEmote(this);
			}
		}

		public virtual void ResetPerformingEmote()
		{
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: 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_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			if (initialized)
			{
				isPerformingEmote = false;
				animatorController["emote"] = null;
				animatorController["emote_loop"] = null;
				RemoveFromEmoteSyncGroup();
				UnloadEmoteProps();
				if ((Object)(object)ikLeftHand != (Object)null)
				{
					ikLeftHand.localPosition = Vector3.zero;
				}
				if ((Object)(object)ikRightHand != (Object)null)
				{
					ikRightHand.localPosition = Vector3.zero;
				}
				if ((Object)(object)ikLeftFoot != (Object)null)
				{
					ikLeftFoot.localPosition = Vector3.zero;
				}
				if ((Object)(object)ikRightFoot != (Object)null)
				{
					ikRightFoot.localPosition = Vector3.zero;
				}
				if ((Object)(object)ikHead != (Object)null)
				{
					ikHead.localPosition = Vector3.zero;
				}
			}
		}

		public AnimationClip GetCurrentAnimationClip()
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			if (!IsPerformingCustomEmote())
			{
				return null;
			}
			if (!animator.GetBool("loop"))
			{
				return animatorController["emote"];
			}
			AnimatorStateInfo currentAnimatorStateInfo = animator.GetCurrentAnimatorStateInfo(0);
			return animatorController[((AnimatorStateInfo)(ref currentAnimatorStateInfo)).IsName("emote_loop") ? "emote_loop" : "emote"];
		}

		protected virtual void CreateBoneMap()
		{
		}

		public void CreateBoneMap(List<string> sourceBoneNames, List<string> targetBoneNames = null)
		{
			boneMap = BoneMapper.CreateBoneMap(humanoidSkeleton, metarig, sourceBoneNames, targetBoneNames);
		}

		protected virtual void FindIkBones()
		{
			Transform val = FindChildRecursive("root_ik");
			if ((Object)(object)val == (Object)null)
			{
				CustomLogging.LogError("Failed to find root ik bone called \"root_ik\" in humanoid skeleton: " + emoteControllerName);
				return;
			}
			ikLeftHand = val.Find("hand_ik_l");
			ikRightHand = val.Find("hand_ik_r");
			ikLeftFoot = val.Find("foot_ik_l");
			ikRightFoot = val.Find("foot_ik_r");
			ikHead = val.Find("head_ik");
		}

		protected virtual Transform FindChildRecursive(string objectName, Transform root = null)
		{
			if ((Object)(object)root == (Object)null)
			{
				root = humanoidSkeleton;
			}
			if (((Object)root).name == objectName)
			{
				return root;
			}
			for (int i = 0; i < root.childCount; i++)
			{
				Transform child = root.GetChild(i);
				Transform val = FindChildRecursive(objectName, child);
				if ((Object)(object)val != (Object)null)
				{
					return val;
				}
			}
			return null;
		}

		protected virtual ulong GetEmoteControllerId()
		{
			return 0uL;
		}

		protected virtual string GetEmoteControllerName()
		{
			return ((Object)this).name;
		}

		protected void CreateEmoteSyncGroup(bool doNotTriggerAudio = false)
		{
			emoteSyncGroup = EmoteSyncGroup.CreateEmoteSyncGroup(this, !doNotTriggerAudio);
		}

		protected void AddToEmoteSyncGroup(EmoteSyncGroup emoteSyncGroup)
		{
			CustomLogging.Log("Adding to emote sync group with id: " + emoteSyncGroup.syncId);
			emoteSyncGroup.AddToEmoteSyncGroup(this);
			this.emoteSyncGroup = emoteSyncGroup;
		}

		protected void RemoveFromEmoteSyncGroup()
		{
			if (emoteSyncGroup != null)
			{
				emoteSyncGroup.RemoveFromEmoteSyncGroup(this);
			}
			emoteSyncGroup = null;
		}
	}
	[HarmonyPatch]
	public static class EmotesManager
	{
		public static List<UnlockableEmote> allUnlockableEmotes;

		public static Dictionary<string, UnlockableEmote> allUnlockableEmotesDict;

		public static List<UnlockableEmote> complementaryEmotes;

		internal static List<UnlockableEmote> complementaryEmotesDefault;

		public static List<string> allFavoriteEmotes;

		public static List<UnlockableEmote> allEmotesTier0;

		public static List<UnlockableEmote> allEmotesTier1;

		public static List<UnlockableEmote> allEmotesTier2;

		public static List<UnlockableEmote> allEmotesTier3;

		public static void BuildEmotesList()
		{
			allUnlockableEmotes = new List<UnlockableEmote>();
			allUnlockableEmotesDict = new Dictionary<string, UnlockableEmote>();
			complementaryEmotesDefault = new List<UnlockableEmote>();
			allFavoriteEmotes = new List<string>();
			allEmotesTier0 = new List<UnlockableEmote>();
			allEmotesTier1 = new List<UnlockableEmote>();
			allEmotesTier2 = new List<UnlockableEmote>();
			allEmotesTier3 = new List<UnlockableEmote>();
			Dictionary<string, List<UnlockableEmote>> dictionary = new Dictionary<string, List<UnlockableEmote>>();
			for (int i = 0; i < Plugin.customAnimationClips.Count; i++)
			{
				AnimationClip val = Plugin.customAnimationClips[i];
				UnlockableEmote unlockableEmote = new UnlockableEmote
				{
					emoteId = i,
					emoteName = ((Object)val).name,
					displayName = "",
					animationClip = val,
					rarity = 0
				};
				unlockableEmote.rarity = (Plugin.animationClipsTier1.Contains(val) ? 1 : (Plugin.animationClipsTier2.Contains(val) ? 2 : (Plugin.animationClipsTier3.Contains(val) ? 3 : 0)));
				if (Plugin.complementaryAnimationClips.Contains(val))
				{
					unlockableEmote.complementary = true;
				}
				if (unlockableEmote.emoteName.Contains("_start") && !unlockableEmote.emoteName.Contains("_start_"))
				{
					string key = unlockableEmote.emoteName.Replace("_start", "_loop");
					AnimationClip val2 = Plugin.customAnimationClipsLoopDict[key];
					if ((Object)(object)val2 != (Object)null)
					{
						unlockableEmote.transitionsToClip = val2;
						unlockableEmote.emoteName = unlockableEmote.emoteName.Replace("_start", "");
						((Object)unlockableEmote.animationClip).name = unlockableEmote.emoteName + "_start";
						((Object)unlockableEmote.transitionsToClip).name = unlockableEmote.emoteName + "_loop";
					}
				}
				else if (unlockableEmote.emoteName.Contains("_pose"))
				{
					unlockableEmote.isPose = true;
					unlockableEmote.emoteName = unlockableEmote.emoteName.Replace("_pose", "");
					((Object)unlockableEmote.animationClip).name = unlockableEmote.emoteName;
				}
				if (unlockableEmote.emoteName.Contains("."))
				{
					string[] array = unlockableEmote.emoteName.Split(new char[1] { '.' });
					if (array.Length != 0 && array[0].Length > 0)
					{
						if (array.Length > 3)
						{
							CustomLogging.LogError("Error parsing emote name: " + unlockableEmote.emoteName + ". Correct format: \"emote_group.optional_arg.emote_name\"");
							continue;
						}
						unlockableEmote.emoteSyncGroupName = array[0];
						unlockableEmote.emoteName = unlockableEmote.emoteSyncGroupName + "." + array[^1];
						unlockableEmote.displayName = unlockableEmote.emoteSyncGroupName;
						if ((Object)(object)unlockableEmote.transitionsToClip == (Object)null)
						{
							((Object)unlockableEmote.animationClip).name = unlockableEmote.emoteName;
						}
						else
						{
							((Object)unlockableEmote.animationClip).name = unlockableEmote.emoteName + "_start";
							((Object)unlockableEmote.transitionsToClip).name = unlockableEmote.emoteName + "_loop";
						}
						if (!dictionary.TryGetValue(unlockableEmote.emoteSyncGroupName, out unlockableEmote.emoteSyncGroup))
						{
							unlockableEmote.emoteSyncGroup = new List<UnlockableEmote>();
							dictionary.Add(unlockableEmote.emoteSyncGroupName, unlockableEmote.emoteSyncGroup);
						}
						if (array.Length == 3 && array[1].ToLower().Contains("layer_"))
						{
							((Object)val).name = ((Object)val).name.Replace("." + array[1], "");
							if ((Object)(object)unlockableEmote.transitionsToClip != (Object)null)
							{
								((Object)unlockableEmote.transitionsToClip).name = ((Object)unlockableEmote.transitionsToClip).name.Replace("." + array[1], "");
							}
							if (!int.TryParse(array[1].Substring(6), out var result))
							{
								CustomLogging.LogError("Failed to parse emote layer number in arg: " + array[1] + ". Emote will not be added.");
								continue;
							}
							unlockableEmote.purchasable = result == 0;
							while (unlockableEmote.emoteSyncGroup.Count <= result)
							{
								unlockableEmote.emoteSyncGroup.Add(null);
							}
							unlockableEmote.emoteSyncGroup[result] = unlockableEmote;
						}
						else
						{
							unlockableEmote.emoteSyncGroup.Add(unlockableEmote);
							unlockableEmote.purchasable = unlockableEmote.emoteSyncGroup.Count == 1;
							if (array.Length == 3 && array[1].ToLower() == "random")
							{
								unlockableEmote.randomEmote = true;
								((Object)val).name = ((Object)val).name.Replace("." + array[1], "");
								if ((Object)(object)unlockableEmote.transitionsToClip != (Object)null)
								{
									((Object)unlockableEmote.transitionsToClip).name = ((Object)unlockableEmote.transitionsToClip).name.Replace("." + array[1], "");
								}
							}
						}
					}
				}
				if (unlockableEmote.emoteName.Contains("_start") && !unlockableEmote.emoteName.Contains("_start_"))
				{
					string key2 = unlockableEmote.emoteName.Replace("_start", "_loop");
					AnimationClip val3 = Plugin.customAnimationClipsLoopDict[key2];
					if ((Object)(object)val3 != (Object)null)
					{
						unlockableEmote.transitionsToClip = val3;
						unlockableEmote.emoteName = unlockableEmote.emoteName.Replace("_start", "");
						((Object)unlockableEmote.animationClip).name = unlockableEmote.emoteName + "_start";
						((Object)unlockableEmote.transitionsToClip).name = unlockableEmote.emoteName + "_loop";
					}
				}
				else if (unlockableEmote.emoteName.Contains("_pose"))
				{
					unlockableEmote.isPose = true;
					unlockableEmote.emoteName = unlockableEmote.emoteName.Replace("_pose", "");
					((Object)unlockableEmote.animationClip).name = unlockableEmote.emoteName;
				}
				if ((!((Object)(object)unlockableEmote.transitionsToClip != (Object)null) && !((Motion)unlockableEmote.animationClip).isLooping && !unlockableEmote.isPose && unlockableEmote.emoteSyncGroup == null) || true)
				{
					unlockableEmote.canSyncEmote = true;
				}
				if (unlockableEmote.displayName == "")
				{
					unlockableEmote.displayName = unlockableEmote.emoteName;
				}
				unlockableEmote.displayName = unlockableEmote.displayName.Replace('_', ' ').Trim(new char[1] { ' ' });
				unlockableEmote.displayName = char.ToUpper(unlockableEmote.displayName[0]) + unlockableEmote.displayName.Substring(1).ToLower();
				if (!allUnlockableEmotes.Contains(unlockableEmote))
				{
					allUnlockableEmotes.Add(unlockableEmote);
					allUnlockableEmotesDict.Add(unlockableEmote.emoteName, unlockableEmote);
				}
				if (Plugin.complementaryAnimationClips.Contains(val) && unlockableEmote.purchasable)
				{
					unlockableEmote.complementary = true;
					complementaryEmotesDefault.Add(unlockableEmote);
				}
			}
			allUnlockableEmotes = allUnlockableEmotes.OrderBy((UnlockableEmote item) => item.emoteName).ToList();
			int num = 0;
			foreach (UnlockableEmote allUnlockableEmote in allUnlockableEmotes)
			{
				allUnlockableEmote.emoteId = num++;
				if (!allUnlockableEmote.complementary)
				{
					if (allUnlockableEmote.rarity == 0)
					{
						allEmotesTier0.Add(allUnlockableEmote);
					}
					else if (allUnlockableEmote.rarity == 1)
					{
						allEmotesTier1.Add(allUnlockableEmote);
					}
					else if (allUnlockableEmote.rarity == 2)
					{
						allEmotesTier2.Add(allUnlockableEmote);
					}
					else if (allUnlockableEmote.rarity == 3)
					{
						allEmotesTier3.Add(allUnlockableEmote);
					}
				}
			}
			complementaryEmotes = new List<UnlockableEmote>(complementaryEmotesDefault);
			SaveManager.LoadFavoritedEmotes();
		}
	}
	[HarmonyPatch]
	public static class SessionManager
	{
		public static List<UnlockableEmote> unlockedEmotes = new List<UnlockableEmote>();

		public static List<UnlockableEmote> unlockedEmotesTier0 = new List<UnlockableEmote>();

		public static List<UnlockableEmote> unlockedEmotesTier1 = new List<UnlockableEmote>();

		public static List<UnlockableEmote> unlockedEmotesTier2 = new List<UnlockableEmote>();

		public static List<UnlockableEmote> unlockedEmotesTier3 = new List<UnlockableEmote>();

		internal static List<UnlockableEmote> emotesUnlockedThisSession = new List<UnlockableEmote>();

		public static Dictionary<string, List<UnlockableEmote>> unlockedEmotesByPlayer = new Dictionary<string, List<UnlockableEmote>>();

		public static List<UnlockableEmote> unlockedFavoriteEmotes = new List<UnlockableEmote>();

		public static string localPlayerUsername => GameNetworkManager.Instance?.username;

		[HarmonyPatch(typeof(StartOfRound), "Awake")]
		[HarmonyPrefix]
		private static void ResetGameValues()
		{
			EmoteController.allEmoteControllers?.Clear();
			EmoteControllerPlayer.allPlayerEmoteControllers?.Clear();
			EmoteControllerMaskedEnemy.allMaskedEnemyEmoteControllers?.Clear();
			EmoteAudioSource.allEmoteAudioSources?.Clear();
			EmotesManager.complementaryEmotes = new List<UnlockableEmote>(EmotesManager.complementaryEmotesDefault);
		}

		[HarmonyPatch(typeof(PlayerControllerB), "ConnectClientToPlayerObject")]
		[HarmonyPostfix]
		private static void OnHostConnected(PlayerControllerB __instance)
		{
			if (!HelperTools.isServer)
			{
				return;
			}
			if (!unlockedEmotesByPlayer.ContainsKey(HelperTools.localPlayerController.playerUsername))
			{
				unlockedEmotesByPlayer.Add(HelperTools.localPlayerController.playerUsername, unlockedEmotes);
				TerminalPatcher.currentEmoteCreditsByPlayer.Add(HelperTools.localPlayerController.playerUsername, TerminalPatcher.currentEmoteCredits);
				return;
			}
			foreach (UnlockableEmote item in unlockedEmotesByPlayer[HelperTools.localPlayerController.playerUsername])
			{
				if (!IsEmoteUnlocked(item))
				{
					unlockedEmotes.Add(item);
				}
			}
			unlockedEmotesByPlayer[HelperTools.localPlayerController.playerUsername] = unlockedEmotes;
			TerminalPatcher.currentEmoteCreditsByPlayer[HelperTools.localPlayerController.playerUsername] = TerminalPatcher.currentEmoteCredits;
		}

		[HarmonyPatch(typeof(StartOfRound), "Start")]
		[HarmonyPostfix]
		private static void OnServerStart(StartOfRound __instance)
		{
			if (HelperTools.isServer)
			{
			}
			SyncManager.RotateEmoteSelectionServer(TerminalPatcher.emoteStoreSeed);
		}

		[HarmonyPatch(typeof(StartOfRound), "StartGame")]
		[HarmonyPostfix]
		private static void ResetOverrideSeedFlag(StartOfRound __instance)
		{
			__instance.overrideRandomSeed = false;
		}

		[HarmonyPatch(typeof(StartOfRound), "ResetShip")]
		[HarmonyPostfix]
		private static void ResetEmotesOnShipReset(StartOfRound __instance)
		{
			if (!ConfigSync.instance.syncUnlockEverything)
			{
				ResetProgressLocal();
			}
			if (HelperTools.isServer)
			{
				SyncManager.RotateEmoteSelectionServer();
			}
		}

		public static void ResetProgressLocal(bool forceResetAll = false)
		{
			CustomLogging.Log("Resetting progress.");
			if (!ConfigSync.instance.syncPersistentUnlocks || forceResetAll)
			{
				ResetEmotesLocal();
			}
			if (!ConfigSync.instance.syncPersistentEmoteCredits || forceResetAll)
			{
				TerminalPatcher.currentEmoteCredits = ConfigSync.instance.syncStartingEmoteCredits;
				List<string> list = new List<string>(TerminalPatcher.currentEmoteCreditsByPlayer.Keys);
				foreach (string item in list)
				{
					TerminalPatcher.currentEmoteCreditsByPlayer[item] = ConfigSync.instance.syncStartingEmoteCredits;
				}
			}
			TerminalPatcher.emoteStoreSeed = 0;
		}

		[HarmonyPatch(typeof(StartOfRound), "SyncShipUnlockablesServerRpc")]
		[HarmonyPostfix]
		private static void SyncUnlockedEmotesWithClients(StartOfRound __instance)
		{
			if (!HelperTools.isServer || ConfigSync.instance.syncUnlockEverything || ConfigSync.instance.syncPersistentUnlocksGlobal)
			{
				return;
			}
			if (ConfigSync.instance.syncShareEverything)
			{
				CustomLogging.Log("Syncing unlocked emotes with clients.");
				SyncManager.SendOnUnlockEmoteUpdateMulti(TerminalPatcher.currentEmoteCredits);
				return;
			}
			HashSet<ulong> hashSet = new HashSet<ulong>();
			PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts;
			foreach (PlayerControllerB val in allPlayerScripts)
			{
				if (val.actualClientId != 0L && val.playerSteamId != 0)
				{
					hashSet.Add(val.actualClientId);
				}
			}
			foreach (ulong item in hashSet)
			{
				SyncManager.ServerSendSyncToClient(item);
			}
		}

		public static bool IsEmoteUnlocked(string emoteName, string playerUsername = "")
		{
			if (EmotesManager.allUnlockableEmotesDict.TryGetValue(emoteName, out var value))
			{
				return IsEmoteUnlocked(value, playerUsername);
			}
			return false;
		}

		public static bool IsEmoteUnlocked(UnlockableEmote emote, string playerUsername = "")
		{
			if (emote == null)
			{
				return false;
			}
			List<UnlockableEmote> value = unlockedEmotes;
			if (playerUsername != "" && !unlockedEmotesByPlayer.TryGetValue(playerUsername, out value))
			{
				return false;
			}
			if (emote.emoteSyncGroup != null && emote.emoteSyncGroup.Count > 0)
			{
				foreach (UnlockableEmote item in emote.emoteSyncGroup)
				{
					if (value.Contains(item))
					{
						return true;
					}
				}
			}
			return value.Contains(emote);
		}

		public static List<UnlockableEmote> GetUnlockedEmotes(PlayerControllerB playerController)
		{
			return GetUnlockedEmotes(((Object)(object)playerController != (Object)null) ? playerController.playerUsername : "");
		}

		public static List<UnlockableEmote> GetUnlockedEmotes(string playerUsername)
		{
			if (unlockedEmotesByPlayer.TryGetValue(playerUsername, out var value))
			{
				return value;
			}
			return null;
		}

		public static void UnlockEmotesLocal(IEnumerable<UnlockableEmote> emotes, bool purchased = false, string playerUsername = "")
		{
			foreach (UnlockableEmote emote in emotes)
			{
				UnlockEmoteLocal(emote, purchased, playerUsername);
			}
		}

		public static void UnlockEmoteLocal(int emoteId, bool purchased = false, string playerUsername = "")
		{
			UnlockEmoteLocal((emoteId >= 0 && emoteId < EmotesManager.allUnlockableEmotes.Count) ? EmotesManager.allUnlockableEmotes[emoteId] : null, purchased, playerUsername);
		}

		public static void UnlockEmoteLocal(UnlockableEmote emote, bool purchased = false, string playerUsername = "")
		{
			if (emote == null || (emote.requiresHeldProp && ConfigSync.instance.syncRemoveGrabbableEmotesPartyPooperMode))
			{
				return;
			}
			List<UnlockableEmote> list = unlockedEmotes;
			if (playerUsername != "" && playerUsername != localPlayerUsername)
			{
				if (!unlockedEmotesByPlayer.TryGetValue(playerUsername, out var value) && !ConfigSync.instance.syncShareEverything)
				{
					return;
				}
				if (value != null)
				{
					list = value;
				}
			}
			if (IsEmoteUnlocked(emote, playerUsername))
			{
				return;
			}
			if (emote.emoteSyncGroup != null)
			{
				foreach (UnlockableEmote item in emote.emoteSyncGroup)
				{
					if (list.Contains(item))
					{
						return;
					}
				}
			}
			if (!list.Contains(emote))
			{
				list.Add(emote);
			}
			if (list != unlockedEmotes)
			{
				return;
			}
			if (!emote.complementary)
			{
				if (emote.rarity == 3 && !unlockedEmotesTier3.Contains(emote))
				{
					unlockedEmotesTier3.Add(emote);
				}
				else if (emote.rarity == 2 && !unlockedEmotesTier2.Contains(emote))
				{
					unlockedEmotesTier2.Add(emote);
				}
				else if (emote.rarity == 1 && !unlockedEmotesTier1.Contains(emote))
				{
					unlockedEmotesTier1.Add(emote);
				}
				else if (emote.rarity == 0 && !unlockedEmotesTier0.Contains(emote))
				{
					unlockedEmotesTier0.Add(emote);
				}
			}
			if (EmotesManager.allFavoriteEmotes.Contains(emote.emoteName) && !unlockedFavoriteEmotes.Contains(emote))
			{
				unlockedFavoriteEmotes.Add(emote);
			}
			if (ConfigSync.instance.syncPersistentUnlocksGlobal && purchased && !emotesUnlockedThisSession.Contains(emote))
			{
				emotesUnlockedThisSession.Add(emote);
			}
		}

		public static void RemoveEmoteLocal(UnlockableEmote emote)
		{
			unlockedEmotes.Remove(emote);
			unlockedEmotesTier0.Remove(emote);
			unlockedEmotesTier1.Remove(emote);
			unlockedEmotesTier2.Remove(emote);
			unlockedEmotesTier3.Remove(emote);
			unlockedFavoriteEmotes.Remove(emote);
			emotesUnlockedThisSession.Remove(emote);
			foreach (List<UnlockableEmote> value in unlockedEmotesByPlayer.Values)
			{
				value.Remove(emote);
			}
		}

		public static void ResetEmotesLocal()
		{
			CustomLogging.Log("Resetting unlocked emotes.");
			unlockedEmotes.Clear();
			unlockedEmotesTier0.Clear();
			unlockedEmotesTier1.Clear();
			unlockedEmotesTier2.Clear();
			unlockedEmotesTier3.Clear();
			emotesUnlockedThisSession.Clear();
			unlockedEmotesByPlayer.Clear();
			PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts;
			foreach (PlayerControllerB val in allPlayerScripts)
			{
				if (val.playerSteamId != 0)
				{
					unlockedEmotesByPlayer.Add(val.playerUsername, ((Object)(object)val == (Object)(object)HelperTools.localPlayerController || ConfigSync.instance.syncShareEverything) ? unlockedEmotes : new List<UnlockableEmote>());
				}
			}
			UnlockEmotesLocal(ConfigSync.instance.syncUnlockEverything ? EmotesManager.allUnlockableEmotes : EmotesManager.complementaryEmotes);
			UpdateUnlockedFavoriteEmotes();
		}

		public static void UpdateUnlockedFavoriteEmotes()
		{
			unlockedFavoriteEmotes?.Clear();
			if (EmotesManager.allFavoriteEmotes == null || EmotesManager.allUnlockableEmotesDict == null || unlockedFavoriteEmotes == null)
			{
				return;
			}
			foreach (string allFavoriteEmote in EmotesManager.allFavoriteEmotes)
			{
				if (EmotesManager.allUnlockableEmotesDict.TryGetValue(allFavoriteEmote, out var value))
				{
					if (value.emoteSyncGroup != null && value.emoteSyncGroup.Count > 0)
					{
						value = value.emoteSyncGroup[0];
					}
					if (IsEmoteUnlocked(value))
					{
						unlockedFavoriteEmotes.Add(value);
					}
				}
			}
		}
	}
	public class UnlockableEmote
	{
		public int emoteId;

		public string emoteName;

		public string displayName = "";

		public AnimationClip animationClip;

		public AnimationClip transitionsToClip = null;

		public bool purchasable = true;

		public bool requiresHeldProp = false;

		public GameObject requiredHeldPropPrefab = null;

		public bool complementary = false;

		public bool isPose = false;

		public bool canMoveWhileEmoting = false;

		private bool _isBoomboxAudio = true;

		public string overrideAudioClipName = "";

		public string overrideAudioLoopClipName = "";

		public string emoteSyncGroupName = "";

		public List<UnlockableEmote> emoteSyncGroup;

		public bool randomEmote = false;

		public List<string> propNamesInEmote;

		public bool canSyncEmote = false;

		public int rarity = 0;

		public static string[] rarityColorCodes = new string[4]
		{
			ConfigSettings.emoteNameColorTier0.Value,
			ConfigSettings.emoteNameColorTier1.Value,
			ConfigSettings.emoteNameColorTier2.Value,
			ConfigSettings.emoteNameColorTier3.Value
		};

		public string displayNameColorCoded => $"<color={nameColor}>{displayName}</color>";

		public bool humanoidAnimation => ((Motion)animationClip).isHumanMotion;

		public bool loopable => ((Motion)animationClip).isLooping || ((Object)(object)transitionsToClip != (Object)null && ((Motion)transitionsToClip).isLooping);

		public bool hasAudio => audioClipName != "" || audioLoopClipName != "";

		public bool isBoomboxAudio
		{
			get
			{
				return _isBoomboxAudio && !ConfigSettings.disableBoomboxRequirement.Value;
			}
			set
			{
				_isBoomboxAudio = value;
			}
		}

		public string audioClipName => ((Object)(object)animationClip != (Object)null && AudioManager.AudioExists(((Object)animationClip).name)) ? ((Object)animationClip).name : ((overrideAudioClipName != "" && AudioManager.AudioExists(overrideAudioClipName)) ? overrideAudioClipName : "");

		public string audioLoopClipName => ((Object)(object)transitionsToClip != (Object)null && AudioManager.AudioExists(((Object)transitionsToClip).name)) ? ((Object)transitionsToClip).name : ((overrideAudioLoopClipName != "" && AudioManager.AudioExists(overrideAudioLoopClipName)) ? overrideAudioLoopClipName : "");

		public bool inEmoteSyncGroup => emoteSyncGroup != null && !randomEmote;

		public bool favorite => EmotesManager.allFavoriteEmotes.Contains(emoteName);

		public string rarityText
		{
			get
			{
				if (rarity == 0)
				{
					return "Common";
				}
				if (rarity == 1)
				{
					return "Rare";
				}
				if (rarity == 2)
				{
					return "Epic";
				}
				if (rarity == 3)
				{
					return "Legendary";
				}
				return "Invalid";
			}
		}

		public int price
		{
			get
			{
				int num = -1;
				if (complementary)
				{
					num = 0;
				}
				else if (rarity == 0)
				{
					num = ConfigSync.instance.syncBasePriceEmoteTier0;
				}
				else if (rarity == 1)
				{
					num = ConfigSync.instance.syncBasePriceEmoteTier1;
				}
				else if (rarity == 2)
				{
					num = ConfigSync.instance.syncBasePriceEmoteTier2;
				}
				else if (rarity == 3)
				{
					num = ConfigSync.instance.syncBasePriceEmoteTier3;
				}
				return (int)Mathf.Max((float)num * ConfigSync.instance.syncPriceMultiplierEmotesStore, 0f);
			}
		}

		public string nameColor => rarityColorCodes[rarity];

		public bool IsEmoteInEmoteGroup(UnlockableEmote emote)
		{
			return this == emote || (emoteSyncGroup != null && emoteSyncGroup.Contains(emote));
		}

		public bool ClipIsInEmote(AnimationClip clip)
		{
			if ((Object)(object)clip == (Object)null)
			{
				return false;
			}
			if ((Object)(object)clip == (Object)(object)animationClip || (Object)(object)clip == (Object)(object)transitionsToClip)
			{
				return true;
			}
			if (emoteSyncGroup != null)
			{
				foreach (UnlockableEmote item in emoteSyncGroup)
				{
					if ((Object)(object)clip == (Object)(object)item.animationClip || (Object)(object)clip == (Object)(object)item.transitionsToClip)
					{
						return true;
					}
				}
			}
			return false;
		}

		public AudioClip LoadAudioClip()
		{
			if (hasAudio && audioClipName.Length > 0)
			{
				return AudioManager.LoadAudioClip(audioClipName);
			}
			return null;
		}

		public AudioClip LoadAudioLoopClip()
		{
			if (hasAudio && (Object)(object)transitionsToClip != (Object)null && audioLoopClipName.Length > 0)
			{
				return AudioManager.LoadAudioClip(audioLoopClipName);
			}
			return null;
		}
	}
	[HarmonyPatch]
	public static class SaveManager
	{
		public static string TooManyEmotesSaveFileName = "TooManyEmotes_LocalSaveData";

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

		[HarmonyPatch(typeof(PlayerControllerB), "ConnectClientToPlayerObject")]
		[HarmonyPrefix]
		private static void CheckIfShouldResetLocalSettings()
		{
			if (ConfigSettings.resetGloballyUnlockedEmotes)
			{
				ResetGloballyUnlockedEmotes();
			}
			if (ConfigSettings.resetFavoriteEmotes)
			{
				ResetFavoritedEmotes();
			}
			ConfigSettings.resetGloballyUnlockedEmotes = false;
			ConfigSettings.resetFavoriteEmotes = false;
		}

		[HarmonyPatch(typeof(GameNetworkManager), "SaveGameValues")]
		[HarmonyPostfix]
		private static void SaveUnlockedEmotes(GameNetworkManager __instance)
		{
			if (!__instance.isHostingGame || !StartOfRound.Instance.inShipPhase)
			{
				return;
			}
			CustomLogging.Log("Saving game values.");
			try
			{
				HashSet<string> hashSet;
				try
				{
					hashSet = new HashSet<string>(ES3.Load<string[]>("TooManyEmotes.UnlockedEmotes.PlayersList", HelperTools.currentSaveFileName, new string[0]));
				}
				catch (Exception ex)
				{
					CustomLogging.LogErrorVerbose("Error loading previous users list. Deleting key: TooManyEmotes.UnlockedEmotes.PlayersList from file: " + HelperTools.currentSaveFileName);
					CustomLogging.LogErrorVerbose(ex.ToString());
					ES3.DeleteKey("TooManyEmotes.UnlockedEmotes.PlayersList", HelperTools.currentSaveFileName);
					hashSet = new HashSet<string>();
				}
				foreach (string key in SessionManager.unlockedEmotesByPlayer.Keys)
				{
					hashSet.Add(key);
				}
				ES3.Save<string[]>("TooManyEmotes.UnlockedEmotes.PlayersList", hashSet.ToArray(), HelperTools.currentSaveFileName);
				foreach (string item in hashSet)
				{
					if (!ConfigSync.instance.syncPersistentUnlocksGlobal)
					{
						if (!SessionManager.unlockedEmotesByPlayer.ContainsKey(item))
						{
							continue;
						}
						if (SessionManager.unlockedEmotesByPlayer.TryGetValue(item, out var value))
						{
							CustomLogging.Log("Saving " + value.Count + " unlocked emotes for player: " + item);
							string[] array = new string[value.Count];
							for (int i = 0; i < value.Count; i++)
							{
								array[i] = value[i].emoteName;
							}
							if (value == SessionManager.unlockedEmotes)
							{
								ES3.Save<string[]>("TooManyEmotes.UnlockedEmotes", array, HelperTools.currentSaveFileName);
							}
							else
							{
								ES3.Save<string[]>("TooManyEmotes.UnlockedEmotes.Player_" + item, array, HelperTools.currentSaveFileName);
							}
						}
					}
					if (TerminalPatcher.currentEmoteCreditsByPlayer.ContainsKey(item))
					{
						CustomLogging.Log("Saving " + TerminalPatcher.currentEmoteCreditsByPlayer[item] + " emote credits for player: " + item);
						string text = "TooManyEmotes.CurrentEmoteCredits" + (ConfigSync.instance.syncPersistentUnlocks ? ".Persistent" : "");
						if ((Object)(object)HelperTools.localPlayerController != (Object)null && HelperTools.localPlayerController.playerSteamId != 0L && item == HelperTools.localPlayerController.playerUsername)
						{
							ES3.Save<int>(text, TerminalPatcher.currentEmoteCredits, __instance.currentSaveFileName);
						}
						else
						{
							ES3.Save<int>(text + ".Player_" + item, TerminalPatcher.currentEmoteCreditsByPlayer[item], __instance.currentSaveFileName);
						}
					}
				}
				ES3.Save<int>("TooManyEmotes.EmoteStoreSeed", TerminalPatcher.emoteStoreSeed, __instance.currentSaveFileName);
				CustomLogging.Log("Saved Seed: " + TerminalPatcher.emoteStoreSeed);
			}
			catch (Exception ex2)
			{
				CustomLogging.LogError("Error while trying to save TooManyEmotes values when disconnecting as host.");
				CustomLogging.LogError(ex2.ToString());
			}
		}

		[HarmonyPatch(typeof(StartOfRound), "LoadUnlockables")]
		[HarmonyPostfix]
		private static void LoadUnlockedEmotes(StartOfRound __instance)
		{
			if (!GameNetworkManager.Instance.isHostingGame)
			{
				return;
			}
			CustomLogging.Log("Loading game values.");
			try
			{
				if (!ConfigSync.instance.syncPersistentUnlocksGlobal)
				{
					SessionManager.ResetEmotesLocal();
					string[] array = ES3.Load<string[]>("TooManyEmotes.UnlockedEmotes", HelperTools.currentSaveFileName, new string[0]);
					string[] array2 = array;
					foreach (string key in array2)
					{
						if (EmotesManager.allUnlockableEmotesDict.TryGetValue(key, out var value))
						{
							SessionManager.UnlockEmoteLocal(value);
						}
					}
				}
				string text = "TooManyEmotes.CurrentEmoteCredits" + (ConfigSync.instance.syncPersistentUnlocks ? ".Persistent" : "");
				TerminalPatcher.currentEmoteCredits = ES3.Load<int>(text, HelperTools.currentSaveFileName, ConfigSync.instance.syncStartingEmoteCredits);
				string[] array3 = ES3.Load<string[]>("TooManyEmotes.UnlockedEmotes.PlayersList", HelperTools.currentSaveFileName, new string[0]);
				string[] array4 = array3;
				foreach (string text2 in array4)
				{
					if ((Object)(object)HelperTools.localPlayerController != (Object)null && HelperTools.localPlayerController.playerSteamId != 0L && text2 == HelperTools.localPlayerController.playerUsername)
					{
						continue;
					}
					if (!SessionManager.unlockedEmotesByPlayer.ContainsKey(text2))
					{
						SessionManager.unlockedEmotesByPlayer.Add(text2, new List<UnlockableEmote>());
					}
					text = "TooManyEmotes.UnlockedEmotes.Player_" + text2;
					if (!ConfigSync.instance.syncPersistentUnlocksGlobal)
					{
						string[] array5 = ES3.Load<string[]>(text, HelperTools.currentSaveFileName, new string[0]);
						CustomLogging.Log("Loading " + array5.Length + " unlocked emotes for player: " + text2);
						string[] array6 = array5;
						foreach (string key2 in array6)
						{
							if (EmotesManager.allUnlockableEmotesDict.TryGetValue(key2, out var value2))
							{
								SessionManager.UnlockEmoteLocal(value2, purchased: false, text2);
							}
						}
					}
					text = "TooManyEmotes.CurrentEmoteCredits.Player_" + text2;
					if (ConfigSync.instance.syncPersistentUnlocks)
					{
						text = text.Replace("CurrentEmoteCredits", "CurrentEmoteCredits.Persistent");
					}
					int value3 = ES3.Load<int>(text, HelperTools.currentSaveFileName, ConfigSync.instance.syncStartingEmoteCredits);
					CustomLogging.Log("Loading " + value3 + " emote credits for player: " + text2);
					TerminalPatcher.currentEmoteCreditsByPlayer[text2] = value3;
				}
				TerminalPatcher.emoteStoreSeed = ES3.Load<int>("TooManyEmotes.EmoteStoreSeed", HelperTools.currentSaveFileName, 0);
				CustomLogging.Log("Loaded Seed: " + TerminalPatcher.emoteStoreSeed);
			}
			catch (Exception ex)
			{
				CustomLogging.LogError("Error while trying to load TooManyEmotes values: " + ex);
			}
		}

		[HarmonyPatch(typeof(GameNetworkManager), "ResetSavedGameValues")]
		[HarmonyPrefix]
		private static void ResetUnlockedEmotesList(GameNetworkManager __instance)
		{
			if (!__instance.isHostingGame || (Object)(object)StartOfRound.Instance == (Object)null || SessionManager.unlockedEmotes == null)
			{
				return;
			}
			CustomLogging.Log("Resetting saved game values.");
			if (!ConfigSync.instance.syncPersistentUnlocks)
			{
				ES3.DeleteKey("TooManyEmotes.UnlockedEmotes", __instance.currentSaveFileName);
				ES3.DeleteKey("TooManyEmotes.CurrentEmoteCredits.Persistent", __instance.currentSaveFileName);
			}
			ES3.DeleteKey("TooManyEmotes.CurrentEmoteCredits", __instance.currentSaveFileName);
			ES3.DeleteKey("TooManyEmotes.EmoteStoreSeed", __instance.currentSaveFileName);
			HashSet<string> hashSet = new HashSet<string>(ES3.Load<string[]>("TooManyEmotes.UnlockedEmotes.PlayersList", __instance.currentSaveFileName, new string[0]));
			foreach (string key in SessionManager.unlockedEmotesByPlayer.Keys)
			{
				hashSet.Add(key);
			}
			foreach (string item in hashSet)
			{
				if (!ConfigSync.instance.syncPersistentUnlocks)
				{
					ES3.DeleteKey("TooManyEmotes.UnlockedEmotes.Player_" + item, __instance.currentSaveFileName);
					ES3.DeleteKey("TooManyEmotes.CurrentEmoteCredits.Persistent.Player_" + item, __instance.currentSaveFileName);
				}
				ES3.DeleteKey("TooManyEmotes.CurrentEmoteCredits.Player_" + item, __instance.currentSaveFileName);
			}
			SessionManager.ResetProgressLocal();
		}

		[HarmonyPatch(typeof(GameNetworkManager), "SaveLocalPlayerValues")]
		[HarmonyPrefix]
		private static void SaveLocalPlayerValues()
		{
			if (!HelperTools.isClient || !SyncManager.isSynced || ConfigSync.instance == null || !ConfigSync.instance.syncPersistentUnlocksGlobal || globallyUnlockedEmoteNames == null || SessionManager.emotesUnlockedThisSession == null)
			{
				return;
			}
			try
			{
				foreach (UnlockableEmote item in SessionManager.emotesUnlockedThisSession)
				{
					if (item != null && !item.complementary && !item.requiresHeldProp && !globallyUnlockedEmoteNames.Cont

plugins/YippeeMod.dll

Decompiled 2 years ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using YippeeMod.Patches;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("YippeeMod")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("YippeeMod")]
[assembly: AssemblyTitle("YippeeMod")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
}
namespace YippeeMod
{
	[BepInPlugin("sunnobunno.YippeeMod", "Yippee tbh mod", "1.2.4")]
	public class YippeeModBase : BaseUnityPlugin
	{
		private const string modGUID = "sunnobunno.YippeeMod";

		private const string modName = "Yippee tbh mod";

		private const string modVersion = "1.2.4";

		private readonly Harmony harmony = new Harmony("sunnobunno.YippeeMod");

		private static YippeeModBase? Instance;

		internal ManualLogSource? mls;

		internal static AudioClip[]? newSFX;

		private void Awake()
		{
			if ((Object)(object)Instance == (Object)null)
			{
				Instance = this;
			}
			mls = Logger.CreateLogSource("sunnobunno.YippeeMod");
			mls.LogInfo((object)"sunnobunno.YippeeMod is loading.");
			string location = ((BaseUnityPlugin)Instance).Info.Location;
			string text = "YippeeMod.dll";
			string text2 = location.TrimEnd(text.ToCharArray());
			string text3 = text2 + "yippeesound";
			AssetBundle val = AssetBundle.LoadFromFile(text3);
			if ((Object)(object)val == (Object)null)
			{
				mls.LogError((object)"Failed to load audio assets!");
				return;
			}
			newSFX = val.LoadAssetWithSubAssets<AudioClip>("assets/yippee-tbh.mp3");
			harmony.PatchAll(typeof(HoarderBugPatch));
			mls.LogInfo((object)"sunnobunno.YippeeMod is loaded. Yippee!!!");
		}
	}
}
namespace YippeeMod.Patches
{
	[HarmonyPatch(typeof(HoarderBugAI))]
	internal class HoarderBugPatch
	{
		[HarmonyPatch("Start")]
		[HarmonyPostfix]
		public static void hoarderBugAudioPatch(ref AudioClip[] ___chitterSFX)
		{
			AudioClip[] newSFX = YippeeModBase.newSFX;
			___chitterSFX = newSFX;
		}
	}
}