Decompiled source of Squirts Modification Collection v1.0.2

BepInEx/plugins/CoilHeadStare.dll

Decompiled a month ago
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using TDP.CoilHeadStare.Patch;
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("CoilHeadStare")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("CoilHeadStare")]
[assembly: AssemblyCopyright("Copyright ©  2023")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("9d96f0c2-6393-4d02-99d7-34538a0dad5c")]
[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 TDP.CoilHeadStare
{
	[BepInPlugin("TDP.CoilHeadStare", "CoilHeadStare", "1.1.0")]
	public class ModBase : BaseUnityPlugin
	{
		private const string modGUID = "TDP.CoilHeadStare";

		private const string modName = "CoilHeadStare";

		private const string modVersion = "1.1.0";

		private Harmony harmony;

		internal static ModBase instance;

		internal ManualLogSource mls;

		public static ConfigEntry<float> config_timeUntilStare;

		public static ConfigEntry<float> config_maxStareDistance;

		public static ConfigEntry<float> config_turnHeadSpeed;

		public static ConfigEntry<bool> config_shovelReact;

		private void Awake()
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			if ((Object)(object)instance == (Object)null)
			{
				instance = this;
			}
			else
			{
				Object.Destroy((Object)(object)this);
			}
			ConfigFile();
			harmony = new Harmony("TDP.CoilHeadStare");
			harmony.PatchAll(typeof(CoilHeadPatch));
			mls = Logger.CreateLogSource("TDP.CoilHeadStare");
			mls.LogInfo((object)string.Format("{0} {1} loaded. (TUS={2}, MSD={3}, HTS={4}, SR={5})", "CoilHeadStare", "1.1.0", Stare.timeUntilStare, Stare.maxStareDistance, Stare.turnHeadSpeed, CoilHeadPatch.shovelReact));
		}

		private void ConfigFile()
		{
			config_timeUntilStare = ((BaseUnityPlugin)this).Config.Bind<float>("CoilHeadStare", "Time Until Stare", 8f, "Time between moving and looking at closest player (in seconds)");
			config_maxStareDistance = ((BaseUnityPlugin)this).Config.Bind<float>("CoilHeadStare", "Max Stare Distance", 6f, "Coilhead will only stare at players closer than this (for reference: coilhead's height is ca. 4)");
			config_turnHeadSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("CoilHeadStare", "Head Turn Speed", 0.3f, "The speed at which the head turns towards the player");
			config_shovelReact = ((BaseUnityPlugin)this).Config.Bind<bool>("CoilHeadStare", "Head Bounce on Shovel Hit", true, "Should the coilhead spring recoil when hit with a shovel (or with anything else)");
			Stare.timeUntilStare = config_timeUntilStare.Value;
			Stare.maxStareDistance = config_maxStareDistance.Value;
			Stare.turnHeadSpeed = config_turnHeadSpeed.Value;
			CoilHeadPatch.shovelReact = config_shovelReact.Value;
		}
	}
}
namespace TDP.CoilHeadStare.Patch
{
	internal class CoilHeadPatch
	{
		public static bool shovelReact;

		[HarmonyPatch(typeof(EnemyAI), "Start")]
		[HarmonyPostfix]
		[HarmonyPriority(200)]
		private static void StartPostFix(EnemyAI __instance)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Expected O, but got Unknown
			if (__instance is SpringManAI)
			{
				Debug.Log((object)"CoilHead found. Adding stare script.");
				Stare stare = ((Component)__instance).gameObject.AddComponent<Stare>();
				stare.Initialize((SpringManAI)__instance);
			}
		}

		[HarmonyPatch(typeof(EnemyAI), "HitEnemy")]
		[HarmonyPrefix]
		public static void HitEnemyPreFix(EnemyAI __instance)
		{
			if (__instance is SpringManAI)
			{
				if ((Object)(object)__instance == (Object)null)
				{
					ModBase.instance.mls.LogError((object)"On player hit Coil Head: Coil Head instance is missing.");
				}
				else if ((Object)(object)__instance.creatureAnimator == (Object)null)
				{
					ModBase.instance.mls.LogError((object)"On player hit Coil Head: Coil Head animator is missing.");
				}
				else if (__instance.creatureAnimator.parameters.All((AnimatorControllerParameter x) => x.name == "springBoing"))
				{
					ModBase.instance.mls.LogError((object)"On player hit Coil Head: Coil Head animatorcontroller is missing the parameter \"springBoing\".");
				}
				else if (shovelReact)
				{
					__instance.creatureAnimator.SetTrigger("springBoing");
				}
			}
		}
	}
	public class Stare : MonoBehaviour
	{
		private SpringManAI coilHeadInstance;

		public static float timeUntilStare;

		public static float maxStareDistance;

		public static float turnHeadSpeed;

		public static bool keepRunningOnDeath;

		public const string headParentBone = "springBone.002";

		private Transform head;

		private float timeSinceMoving;

		private bool isTurningHead;

		private PlayerControllerB stareTarget;

		public void Initialize(SpringManAI instance)
		{
			Debug.Log((object)"Initializing Stare on Coil Head.");
			coilHeadInstance = instance;
			if ((Object)(object)coilHeadInstance == (Object)null)
			{
				ModBase.instance.mls.LogError((object)"Coil Head instance missing. Harmony Patch failed?");
			}
			List<Transform> list = FindChildren(((Component)coilHeadInstance).transform, "springBone.002");
			if (list == null)
			{
				ModBase.instance.mls.LogError((object)"Search for head parent returned null. This should not be possible, something went wrong.");
			}
			else if (list.Count > 0)
			{
				if (list.Last().childCount > 0)
				{
					head = list.Last().GetChild(list.Last().childCount - 1);
				}
				else
				{
					ModBase.instance.mls.LogWarning((object)"Found head parent (springBone.002), but it has no child transforms. (Likely due to an incompatible reskin mod)");
				}
			}
			else
			{
				ModBase.instance.mls.LogError((object)"Could not find head parent bone. Possibly missing or renamed? Head must be parented to \"springBone.002\".");
			}
			if ((Object)(object)head == (Object)null)
			{
				ModBase.instance.mls.LogError((object)"Could not find head transform. Destroying script. (Coil Head should be unaffected by this)");
				Object.Destroy((Object)(object)this);
			}
			else
			{
				ModBase.instance.mls.LogInfo((object)("Found head transform: " + ((Object)head).name));
			}
		}

		private List<Transform> FindChildren(Transform parent, string name)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			List<Transform> list = new List<Transform>();
			foreach (Transform item in parent)
			{
				Transform val = item;
				if (((Object)val).name == name)
				{
					list.Add(val);
				}
				else
				{
					list.AddRange(FindChildren(val, name));
				}
			}
			return list;
		}

		private void Start()
		{
			if ((Object)(object)head != (Object)null)
			{
				ModBase.instance.mls.LogInfo((object)"Stare initialization successful. Note: If a reskin is being used and the head does not turn, it is most likely incompatible.");
			}
			else
			{
				ModBase.instance.mls.LogWarning((object)"Stare initialization unsuccessful. An error has probably occurred.");
			}
		}

		private void Update()
		{
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: 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_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: 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)(object)coilHeadInstance == (Object)null || (((EnemyAI)coilHeadInstance).isEnemyDead && !keepRunningOnDeath))
			{
				isTurningHead = false;
				stareTarget = null;
				return;
			}
			if ((Object)(object)head == (Object)null)
			{
				ModBase.instance.mls.LogError((object)"Head transform missing. Destroying script.");
				Object.Destroy((Object)(object)this);
				return;
			}
			if (!isTurningHead)
			{
				stareTarget = ((EnemyAI)coilHeadInstance).GetClosestPlayer(false, false, false);
			}
			if (!((Object)(object)stareTarget == (Object)null))
			{
				Vector3 val = ((Component)stareTarget.gameplayCamera).transform.position - head.position;
				float num = Vector3.Distance(head.position, ((Component)((EnemyAI)coilHeadInstance).GetClosestPlayer(false, false, false)).transform.position);
				if ((double)((EnemyAI)coilHeadInstance).creatureAnimator.GetFloat("walkSpeed") > 0.01 || num > maxStareDistance || Vector3.Angle(head.forward, val) < 5f)
				{
					timeSinceMoving = 0f;
				}
				else
				{
					timeSinceMoving += Time.deltaTime;
				}
				if (timeSinceMoving > timeUntilStare)
				{
					isTurningHead = true;
				}
				else
				{
					isTurningHead = false;
				}
				if (isTurningHead)
				{
					head.forward = Vector3.RotateTowards(head.forward, val, turnHeadSpeed * Time.deltaTime, 0f);
				}
			}
		}
	}
}

BepInEx/plugins/CoilheadStareUASoundRedux.dll

Decompiled a month ago
using System;
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.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using LCSoundTool;
using Microsoft.CodeAnalysis;
using TDP.CoilHeadStare.Patch;
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("CoilheadStareUASoundRedux")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("A template for Lethal Company")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+62d1b1ea45c1ba9ac3e7d26a450ccb981c25a03d")]
[assembly: AssemblyProduct("CoilheadStareUASoundRedux")]
[assembly: AssemblyTitle("CoilheadStareUASoundRedux")]
[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.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace CoilheadStareUASoundRedux
{
	[BepInPlugin("CoilheadStareUASoundRedux", "CoilheadStareUASoundRedux", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		private readonly Harmony _harmony = new Harmony("CoilheadStareUASoundRedux");

		public AudioClip audioClip;

		public static Plugin Instance { get; set; }

		public static ManualLogSource Log => ((BaseUnityPlugin)Instance).Logger;

		public Plugin()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			Instance = this;
		}

		private void Awake()
		{
			audioClip = SoundTool.GetAudioClip(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), "zelensky.wav");
			Log.LogInfo((object)"Applying patches...");
			ApplyPluginPatch();
			Log.LogInfo((object)"Patches applied");
		}

		private void ApplyPluginPatch()
		{
			_harmony.PatchAll(typeof(CoilHeadStarePatch));
		}
	}
	[HarmonyPatch(typeof(Stare))]
	public class CoilHeadStarePatch
	{
		[HarmonyPatch("Update")]
		[HarmonyPostfix]
		private static void UpdatePlaySound(PlayerControllerB ___stareTarget, bool ___isTurningHead, SpringManAI ___coilHeadInstance)
		{
			if (___isTurningHead && (Object)(object)___stareTarget != (Object)null && (Object)(object)___coilHeadInstance != (Object)null && !((EnemyAI)___coilHeadInstance).creatureVoice.isPlaying)
			{
				((EnemyAI)___coilHeadInstance).creatureVoice.clip = Plugin.Instance.audioClip;
				((EnemyAI)___coilHeadInstance).creatureVoice.Play();
			}
			else if (!___isTurningHead && (Object)(object)___coilHeadInstance != (Object)null && ((EnemyAI)___coilHeadInstance).creatureVoice.isPlaying)
			{
				((EnemyAI)___coilHeadInstance).creatureVoice.Stop();
			}
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "CoilheadStareUASoundRedux";

		public const string PLUGIN_NAME = "CoilheadStareUASoundRedux";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}

BepInEx/plugins/GetItOffMe.dll

Decompiled a month ago
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
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("GetItOffMe")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("GetItOffMe")]
[assembly: AssemblyCopyright("Copyright ©  2024")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("7705f351-3382-4868-84c6-766b9dc54f7c")]
[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 GetItOffMe
{
	[BepInPlugin("GetItOffMe", "GetItOffMe", "1.0.0")]
	internal class GetItOffMeBase : BaseUnityPlugin
	{
		public static PluginLogger logger = new PluginLogger();

		private static GetItOffMeBase Instance;

		private static ConfigEntry<bool> LoggingEnabled;

		private static ConfigEntry<bool> ConfigMechanicEnabled;

		private static ConfigEntry<float> ConfigCentipedeRemovalChance;

		private static ConfigEntry<bool> ConfigCustomIntervalEnabled;

		private static ConfigEntry<float> ConfigRemovalInterval;

		private static ConfigEntry<bool> ConfigSuffocationEnabled;

		private static ConfigEntry<bool> ConfigCustomHurtChance;

		private static ConfigEntry<float> ConfigSuffocationHurtChance;

		private static ConfigEntry<int> ConfigSuffocationDamage;

		private static ConfigEntry<bool> ConfigCentipedeCanDie;

		private static ConfigEntry<float> ConfigCentipedeDeathChance;

		public static bool MechanicEnabled;

		public static float CentipedeRemovalChance;

		public static bool CustomIntervalEnabled;

		public static float RemovalInterval;

		public static bool SuffocationEnabled;

		public static bool CustomHurtChance;

		public static float SuffocationHurtChance;

		public static int SuffocationDamage;

		public static bool CentipedeCanDie;

		public static float CentipedeDeathChance;

		private void Awake()
		{
			if ((Object)(object)Instance == (Object)null)
			{
				Instance = this;
			}
			BindConfig();
			Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "GetItOffMe");
			SetValues();
			logger.LogInfo("Plugin has been awoken!");
		}

		private void BindConfig()
		{
			ConfigCentipedeCanDie = ((BaseUnityPlugin)this).Config.Bind<bool>("Removal Settings", "Can Die", true, "Whether or not the snare flea has a chance of dying after you get it off your head.");
			ConfigCentipedeDeathChance = ((BaseUnityPlugin)this).Config.Bind<float>("Removal Settings", "Death Chance", 0.2f, "The chance in percentage of which the snare flea can die after getting removed from player heads.");
			ConfigSuffocationEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Suffocation Settings", "Enabled", true, (ConfigDescription)null);
			ConfigCustomHurtChance = ((BaseUnityPlugin)this).Config.Bind<bool>("Suffocation Settings", "Custom Hurt Chance", true, (ConfigDescription)null);
			ConfigSuffocationHurtChance = ((BaseUnityPlugin)this).Config.Bind<float>("Suffocation Settings", "Suffocation Hurt Chance", 0.35f, "The chance in percentage of which the snare flea will damage you.");
			ConfigSuffocationDamage = ((BaseUnityPlugin)this).Config.Bind<int>("Suffocation Settings", "Damage", 10, (ConfigDescription)null);
			ConfigMechanicEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Disable the mechanics of the mod if it conflicts with other mods.");
			ConfigCentipedeRemovalChance = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Removal Chance", 0.25f, "The success rate of players getting rid of snare fleas clinging on their head.");
			ConfigCustomIntervalEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Custom Interval", true, (ConfigDescription)null);
			ConfigRemovalInterval = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Removal Interval", 1f, "The amount of seconds it'll take before player either gets hurt, or before snare flea gets removed");
			LoggingEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Debugging", "Logging", true, (ConfigDescription)null);
		}

		private void SetValues()
		{
			logger.EnableLogging(LoggingEnabled.Value);
			MechanicEnabled = ConfigMechanicEnabled.Value;
			CentipedeRemovalChance = ConfigCentipedeRemovalChance.Value;
			CustomIntervalEnabled = ConfigCustomIntervalEnabled.Value;
			RemovalInterval = ConfigRemovalInterval.Value;
			SuffocationEnabled = ConfigSuffocationEnabled.Value;
			CustomHurtChance = ConfigCustomHurtChance.Value;
			SuffocationHurtChance = ConfigSuffocationHurtChance.Value;
			SuffocationDamage = ConfigSuffocationDamage.Value;
			CentipedeCanDie = ConfigCentipedeCanDie.Value;
			CentipedeDeathChance = ConfigCentipedeDeathChance.Value;
		}
	}
	public class PluginInfo
	{
		public const string PLUGIN_GUID = "GetItOffMe";

		public const string PLUGIN_NAME = "GetItOffMe";

		public const string PLUGIN_VERSION = "1.0.0";
	}
	public class PluginLogger
	{
		private static ManualLogSource mls = Logger.CreateLogSource("GetItOffMe");

		private static bool ShouldLog = true;

		public void EnableLogging(bool enabled)
		{
			ShouldLog = enabled;
		}

		public void LogInfo(object data)
		{
			if (ShouldLog)
			{
				mls.LogInfo(data);
			}
		}

		public void LogError(object data)
		{
			if (ShouldLog)
			{
				mls.LogError(data);
			}
		}
	}
}
namespace GetItOffMe.Patches
{
	[HarmonyPatch(typeof(CentipedeAI))]
	internal class CentipedeAIPatch
	{
		private static FieldInfo DamagePlayerInterval = typeof(CentipedeAI).GetField("damagePlayerInterval", BindingFlags.Instance | BindingFlags.NonPublic);

		[HarmonyPatch("Start")]
		[HarmonyPrefix]
		public static void Prefix(CentipedeAI __instance)
		{
			if (GetItOffMeBase.MechanicEnabled && (Object)(object)((Component)__instance).GetComponent<CentipedeRemover>() == (Object)null)
			{
				((Component)__instance).gameObject.AddComponent<CentipedeRemover>();
				GetItOffMeBase.logger.LogInfo("Patched the Snare flea with the Centipede Removal Mechanic.");
			}
		}

		[HarmonyPatch("DamagePlayerOnIntervals")]
		[HarmonyPostfix]
		public static void DamagePlayerOnIntervals_Postfix(ref CentipedeAI __instance)
		{
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: 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: Unknown result type (might be due to invalid IL or missing references)
			if (!GetItOffMeBase.SuffocationEnabled)
			{
				GetItOffMeBase.logger.LogInfo("Suffocation is disabled. Damage is not going through.");
				return;
			}
			float num = (float)DamagePlayerInterval.GetValue(__instance);
			if (num <= 0f)
			{
				if (Random.value <= GetItOffMeBase.SuffocationHurtChance && GetItOffMeBase.CustomHurtChance)
				{
					__instance.clingingToPlayer.DamagePlayer(GetItOffMeBase.SuffocationDamage, true, true, (CauseOfDeath)5, 0, false, default(Vector3));
					GetItOffMeBase.logger.LogInfo($"Player took {GetItOffMeBase.SuffocationDamage} damage.");
				}
				else
				{
					__instance.clingingToPlayer.DamagePlayer(GetItOffMeBase.SuffocationDamage, true, true, (CauseOfDeath)5, 0, false, default(Vector3));
					GetItOffMeBase.logger.LogInfo($"Player took {GetItOffMeBase.SuffocationDamage} damage.");
				}
				DamagePlayerInterval.SetValue(__instance, 2);
			}
		}
	}
	public class CentipedeRemover : MonoBehaviour
	{
		private CentipedeAI centipede;

		public bool IsClingingToPlayer;

		private void Start()
		{
			centipede = ((Component)this).GetComponent<CentipedeAI>();
			float num = (GetItOffMeBase.CustomIntervalEnabled ? GetItOffMeBase.RemovalInterval : 1f);
			((MonoBehaviour)this).InvokeRepeating("AttemptCentipedeRemoval", num, num);
		}

		private void Update()
		{
			if ((Object)(object)centipede != (Object)null)
			{
				IsClingingToPlayer = (((Object)(object)centipede.clingingToPlayer != (Object)null) ? true : false);
			}
		}

		private void AttemptCentipedeRemoval()
		{
			if ((Object)(object)centipede == (Object)null || !IsClingingToPlayer)
			{
				return;
			}
			if (Random.value <= GetItOffMeBase.CentipedeRemovalChance)
			{
				IsClingingToPlayer = false;
				centipede.StopClingingClientRpc(false);
				centipede.StopClingingServerRpc(false);
				if (GetItOffMeBase.CentipedeCanDie && Random.value <= GetItOffMeBase.CentipedeDeathChance)
				{
					((EnemyAI)centipede).KillEnemy(true);
					GetItOffMeBase.logger.LogInfo("Player yoinked off the snare flea too hard, causing the snare flea to die.");
				}
				((MonoBehaviour)this).CancelInvoke("AttemptCentipedeRemoval");
				GetItOffMeBase.logger.LogInfo("Stopped Calling AttemptCentipedeRemoval because snare flea has already been removed.");
			}
			else
			{
				GetItOffMeBase.logger.LogInfo("Player was unsuccessful in getting the snare flea off their head.");
			}
			GetItOffMeBase.logger.LogInfo($"Hurt Chance -> {GetItOffMeBase.SuffocationHurtChance}({GetItOffMeBase.SuffocationEnabled}) <-> Death Chance -> {GetItOffMeBase.CentipedeDeathChance}({GetItOffMeBase.CentipedeCanDie})");
		}
	}
}

BepInEx/plugins/GokuBracken.dll

Decompiled a month 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.Configuration;
using BepInEx.Logging;
using GokuBracken.Core;
using GokuBracken.Patches;
using GokuBracken.Scripts;
using HarmonyLib;
using UnityEngine;
using UnityEngine.Video;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("GokuBracken")]
[assembly: AssemblyDescription("A mod for Lethal Company that replaces the bracken's model with a model of Goku from the Tenkaichi games")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Vulf")]
[assembly: AssemblyProduct("GokuBracken")]
[assembly: AssemblyCopyright("Copyright ©  2024")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("50feedfa-5dd6-4358-936e-87945c1a8cae")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("1.5.9.0")]
namespace GokuBracken.Scripts
{
	public class GokuController : MonoBehaviour
	{
		private FlowermanAI FlowermanAI { get; set; }

		private int Variant { get; set; }

		private int[] VariantWeights { get; set; }

		private string VariantName => Variant switch
		{
			0 => "Base Goku", 
			1 => "SSJ Goku", 
			2 => "God Goku", 
			3 => "SSB Goku", 
			_ => "Unknown", 
		};

		private string VariantAssetName => Variant switch
		{
			0 => "baseGokuUnlitPrefab", 
			1 => "ssjGokuPrefab", 
			2 => "godGokuPrefab", 
			3 => "ssbGokuPrefab", 
			_ => "Unknown", 
		};

		private Aura VariantAura => Variant switch
		{
			0 => new Aura(Color.white, Color.black, Color.white, Color.white), 
			1 => new Aura(Color32.op_Implicit(new Color32(byte.MaxValue, (byte)142, (byte)0, byte.MaxValue)), Color32.op_Implicit(new Color32(byte.MaxValue, (byte)216, (byte)0, byte.MaxValue)), Color32.op_Implicit(new Color32(byte.MaxValue, (byte)142, (byte)0, byte.MaxValue)), Color32.op_Implicit(new Color32(byte.MaxValue, (byte)142, (byte)0, byte.MaxValue))), 
			2 => new Aura(Color32.op_Implicit(new Color32(byte.MaxValue, (byte)76, (byte)0, byte.MaxValue)), Color32.op_Implicit(new Color32(byte.MaxValue, (byte)76, (byte)0, byte.MaxValue)), Color32.op_Implicit(new Color32(byte.MaxValue, (byte)0, (byte)0, byte.MaxValue)), Color32.op_Implicit(new Color32(byte.MaxValue, (byte)58, (byte)0, byte.MaxValue))), 
			3 => new Aura(Color32.op_Implicit(new Color32((byte)0, (byte)132, byte.MaxValue, byte.MaxValue)), Color32.op_Implicit(new Color32((byte)85, (byte)172, byte.MaxValue, byte.MaxValue)), Color32.op_Implicit(new Color32((byte)0, (byte)137, byte.MaxValue, byte.MaxValue)), Color32.op_Implicit(new Color32((byte)66, (byte)172, byte.MaxValue, byte.MaxValue))), 
			_ => default(Aura), 
		};

		private GameObject BaseGokuObject { get; set; }

		private GameObject SecondaryGokuObject { get; set; }

		private GameObject GokuEyesObject { get; set; }

		private GameObject AuraObject { get; set; }

		private bool IsAttacking { get; set; }

		private bool IsDead { get; set; }

		private void Start()
		{
			FlowermanAI = ((Component)this).GetComponent<FlowermanAI>();
			VariantWeights = new int[4] { 50, 30, 15, 5 };
			int seed = StartOfRound.Instance.randomMapSeed + Mathf.RoundToInt(StartOfRound.Instance.timeSinceRoundStarted / 10f) * 10;
			SelectGokuVariant(seed);
			HideFlowermanModel();
			CreateGokuModels();
			ReplaceFlowermanSFX();
			UpdateScanNodeData();
			CreateAura();
		}

		private void Update()
		{
			//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_0017: 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)
			Quaternion rotation = ((Component)StartOfRound.Instance.localPlayerController).transform.rotation;
			float num = ((Quaternion)(ref rotation)).eulerAngles.y - 180f;
			AuraObject.transform.rotation = Quaternion.Euler(0f, num, 0f);
			if (((EnemyAI)FlowermanAI).movingTowardsTargetPlayer && !IsAttacking)
			{
				EnterAttackState();
			}
			if (!((EnemyAI)FlowermanAI).movingTowardsTargetPlayer && IsAttacking)
			{
				ExitAttackState();
			}
			if (((EnemyAI)FlowermanAI).isEnemyDead && !IsDead)
			{
				KillGoku();
			}
		}

		private void HideFlowermanModel()
		{
			Renderer[] componentsInChildren = ((Component)((Component)FlowermanAI).transform.Find("FlowermanModel")).GetComponentsInChildren<Renderer>();
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				componentsInChildren[i].enabled = false;
			}
		}

		private void CreateGokuModels()
		{
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			GameObject asset = Assets.GetAsset<GameObject>("baseGokuPrefab");
			BaseGokuObject = Object.Instantiate<GameObject>(asset, ((Component)this).gameObject.transform);
			((Object)BaseGokuObject).name = "Base Goku";
			GameObject asset2 = Assets.GetAsset<GameObject>(VariantAssetName);
			SecondaryGokuObject = Object.Instantiate<GameObject>(asset2, ((Component)this).gameObject.transform);
			((Object)SecondaryGokuObject).name = VariantName;
			SecondaryGokuObject.SetActive(false);
			GameObject asset3 = Assets.GetAsset<GameObject>("gokuEyesPrefab");
			GokuEyesObject = Object.Instantiate<GameObject>(asset3, ((Component)this).gameObject.transform);
			GokuEyesObject.transform.localPosition = new Vector3(0f, 2.7f, 0f);
			((Object)GokuEyesObject).name = "GokuEyes";
		}

		private void ReplaceFlowermanSFX()
		{
			if (ConfigManager.UseMusic.Value)
			{
				FlowermanAI.creatureAngerVoice.clip = Assets.GetAsset<AudioClip>("aggressiveSFX");
			}
			if (ConfigManager.UseVoicelines.Value)
			{
				FlowermanAI.crackNeckSFX = Assets.GetAsset<AudioClip>("baseGokuKillSFX");
				FlowermanAI.crackNeckAudio.clip = Assets.GetAsset<AudioClip>("baseGokuKillSFX");
			}
		}

		private void UpdateScanNodeData()
		{
			((Component)FlowermanAI).GetComponentInChildren<ScanNodeProperties>().headerText = "Son Goku";
		}

		private void CreateAura()
		{
			//IL_004c: 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_006c: 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_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: 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_0115: Unknown result type (might be due to invalid IL or missing references)
			GameObject asset = Assets.GetAsset<GameObject>("auraPrefab");
			AuraObject = Object.Instantiate<GameObject>(asset, SecondaryGokuObject.transform);
			((Object)AuraObject).name = "Aura";
			MainModule main = ((Component)AuraObject.transform.Find("Outer")).GetComponent<ParticleSystem>().main;
			MainModule main2 = ((Component)AuraObject.transform.Find("Inner")).GetComponent<ParticleSystem>().main;
			MainModule main3 = ((Component)AuraObject.transform.Find("Inner Burst")).GetComponent<ParticleSystem>().main;
			MainModule main4 = ((Component)AuraObject.transform.Find("Bottom")).GetComponent<ParticleSystem>().main;
			((MainModule)(ref main)).startColor = MinMaxGradient.op_Implicit(VariantAura.OuterColor);
			((MainModule)(ref main2)).startColor = MinMaxGradient.op_Implicit(VariantAura.InnerColor);
			((MainModule)(ref main3)).startColor = MinMaxGradient.op_Implicit(VariantAura.InnerBurstColor);
			((MainModule)(ref main4)).startColor = MinMaxGradient.op_Implicit(VariantAura.BottomColor);
		}

		private void EnterAttackState()
		{
			BaseGokuObject.SetActive(false);
			SecondaryGokuObject.SetActive(true);
			IsAttacking = true;
		}

		private void ExitAttackState()
		{
			BaseGokuObject.SetActive(true);
			SecondaryGokuObject.SetActive(false);
			IsAttacking = false;
		}

		private void KillGoku()
		{
			//IL_003f: 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_0047: 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_0061: 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_006e: Unknown result type (might be due to invalid IL or missing references)
			GokuEyesObject.SetActive(false);
			BaseGokuObject.SetActive(true);
			SecondaryGokuObject.SetActive(false);
			Transform transform = BaseGokuObject.transform;
			Quaternion rotation = BaseGokuObject.transform.rotation;
			float y = ((Quaternion)(ref rotation)).eulerAngles.y;
			rotation = BaseGokuObject.transform.rotation;
			transform.rotation = Quaternion.Euler(-90f, y, ((Quaternion)(ref rotation)).eulerAngles.z);
			if (ConfigManager.UseDeathSound.Value)
			{
				Object.Destroy((Object)(object)Object.Instantiate<GameObject>(Assets.GetAsset<GameObject>("soundContainerPrefab"), BaseGokuObject.transform), 40f);
			}
			IsDead = true;
		}

		private void SelectGokuVariant(int seed)
		{
			Random random = new Random(seed);
			if (VariantWeights.Length == 0)
			{
				Variant = 0;
				return;
			}
			int num = 0;
			for (int i = 0; i < VariantWeights.Length; i++)
			{
				num += VariantWeights[i];
			}
			int num2 = random.Next(0, num);
			for (int j = 0; j < VariantWeights.Length; j++)
			{
				if (num2 < VariantWeights[j])
				{
					Variant = j;
					return;
				}
				num2 -= VariantWeights[j];
			}
			Variant = 0;
		}
	}
	public struct Aura
	{
		public Color OuterColor { get; set; }

		public Color InnerColor { get; set; }

		public Color InnerBurstColor { get; set; }

		public Color BottomColor { get; set; }

		public Aura(Color outerColor, Color innerColor, Color innerBurstColor, Color bottomColor)
		{
			//IL_0001: 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_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)
			OuterColor = outerColor;
			InnerColor = innerColor;
			InnerBurstColor = innerBurstColor;
			BottomColor = bottomColor;
		}
	}
}
namespace GokuBracken.Patches
{
	[HarmonyPatch]
	internal class EnemyPatches
	{
		[HarmonyPatch(typeof(FlowermanAI), "Start")]
		[HarmonyPostfix]
		public static void CreateGokuModel(FlowermanAI __instance)
		{
			((Component)__instance).gameObject.AddComponent<GokuController>();
		}
	}
	[HarmonyPatch]
	internal class RoundManagementPatches
	{
		private static Transform CardObject { get; set; }

		[HarmonyPatch(typeof(RoundManager), "GenerateNewLevelClientRpc")]
		[HarmonyPostfix]
		public static void GameStart(RoundManager __instance, int randomSeed, int levelID)
		{
			//IL_003e: 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_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			if (levelID == 0)
			{
				if ((Object)(object)CardObject == (Object)null)
				{
					CardObject = Object.Instantiate<GameObject>(Assets.GetAsset<GameObject>("cardsPrefab")).transform;
				}
				CardObject.position = new Vector3(-37f, 0.94f, -40.84f);
				CardObject.rotation = Quaternion.Euler(new Vector3(0f, 196f, 0f));
				CardObject.localScale = new Vector3(0.15f, 0.15f, 0.15f);
			}
		}

		[HarmonyPatch(typeof(StartOfRound), "EndOfGame")]
		[HarmonyPostfix]
		public static void GameEnd(StartOfRound __instance)
		{
			if ((Object)(object)CardObject != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)CardObject).gameObject);
			}
		}
	}
	[HarmonyPatch]
	internal class TerminalPatches
	{
		[HarmonyPatch(typeof(Terminal), "Start")]
		[HarmonyPostfix]
		public static void EditTerminal(Terminal __instance)
		{
			int index = __instance.enemyFiles.FindIndex((TerminalNode e) => ((Object)e).name == "BrackenFile");
			int num = __instance.terminalNodes.allKeywords.ToList().FindIndex((TerminalKeyword e) => ((Object)e).name == "Bracken");
			__instance.enemyFiles[index].creatureName = "Son Goku";
			__instance.enemyFiles[index].displayText = "Hey, you!\nI think it's about time I got a chance to fight.\n";
			__instance.enemyFiles[index].displayVideo = Assets.GetAsset<VideoClip>("gokuLogVideo");
			__instance.terminalNodes.allKeywords[num].word = "goku";
		}
	}
}
namespace GokuBracken.Core
{
	internal static class Assets
	{
		public static AssetBundle AssetBundle { get; private set; }

		private static Dictionary<string, Object> AssetList { get; set; }

		private static string AssemblyName => Assembly.GetExecutingAssembly().FullName.Split(new char[1] { ',' })[0];

		public static void PopulateAssets()
		{
			if ((Object)(object)AssetBundle != (Object)null)
			{
				Logger.LogWarning("Attempted to load the asset bundle but the bundle was not null!");
				return;
			}
			string name = AssemblyName + ".Bundle.gokubracken";
			using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(name))
			{
				AssetBundle = AssetBundle.LoadFromStream(stream);
			}
			if ((Object)(object)AssetBundle == (Object)null)
			{
				Logger.LogError("Asset bundle at " + AssemblyName + ".gokubracken failed to load!");
			}
			AssetList = new Dictionary<string, Object>();
			Object[] array = AssetBundle.LoadAllAssets();
			foreach (Object val in array)
			{
				AssetList.Add(val.name, val);
			}
		}

		public static T GetAsset<T>(string name) where T : Object
		{
			if (!AssetList.TryGetValue(name, out var value))
			{
				Logger.LogError("Attempted to load asset of name " + name + " but no asset of that name exists!");
				return default(T);
			}
			T val = (T)(object)((value is T) ? value : null);
			if ((Object)(object)val == (Object)null)
			{
				Logger.LogError("Attempted to load an asset of type " + typeof(T).Name + " but asset of name " + name + " does not match this type!");
				return default(T);
			}
			return val;
		}
	}
	internal static class ConfigManager
	{
		public static ConfigEntry<bool> UseSkinVariants { get; private set; }

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

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

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

		private static ConfigFile Config => GokuBrackenBase.ModConfig;

		public static void InitializeConfig()
		{
			UseSkinVariants = Config.Bind<bool>("Skin Variants", "Use Skin Variants", true, "Controls whether or not to give Goku the chance to spawn as a different form");
			UseVoicelines = Config.Bind<bool>("Sound", "Use Goku Voicelines", true, "Controls whether or not to replace the bracken's kill sound with Goku voicelines");
			UseMusic = Config.Bind<bool>("Sound", "Use UI Music", true, "Controls whether or not to replace the bracken's agressive sound with the Ultra Instinct theme");
			UseDeathSound = Config.Bind<bool>("Sound", "Use Death Sound", true, "Controls whether or not to play a sound on the bracken's death");
		}
	}
	internal static class Logger
	{
		public static void LogInfo(object message)
		{
			GokuBrackenBase.LogSource.LogInfo(message);
		}

		public static void LogWarning(object message)
		{
			GokuBrackenBase.LogSource.LogWarning(message);
		}

		public static void LogError(object message)
		{
			GokuBrackenBase.LogSource.LogError(message);
		}
	}
	[BepInPlugin("Vulf.GokuBracken", "Goku Bracken", "1.5.8")]
	public class GokuBrackenBase : BaseUnityPlugin
	{
		private static GokuBrackenBase _instance;

		private readonly Harmony Harmony = new Harmony("Vulf.GokuBracken");

		internal static GokuBrackenBase Instance
		{
			get
			{
				return _instance;
			}
			set
			{
				if ((Object)(object)_instance == (Object)null)
				{
					_instance = value;
				}
				else
				{
					Object.Destroy((Object)(object)value);
				}
			}
		}

		public static ManualLogSource LogSource => ((BaseUnityPlugin)Instance).Logger;

		public static ConfigFile ModConfig => ((BaseUnityPlugin)Instance).Config;

		private void Awake()
		{
			Instance = this;
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Initializing config...");
			ConfigManager.InitializeConfig();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Loading asset bundle...");
			Assets.PopulateAssets();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Hey it's me! Goku!");
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Your files look pretty strong! I'm gonna patch them!");
			Harmony.PatchAll(typeof(GokuBrackenBase));
			Harmony.PatchAll(typeof(EnemyPatches));
			Harmony.PatchAll(typeof(TerminalPatches));
			Harmony.PatchAll(typeof(RoundManagementPatches));
		}
	}
	internal static class PluginInfo
	{
		public const string GUID = "Vulf.GokuBracken";

		public const string NAME = "Goku Bracken";

		public const string VERSION = "1.5.8";

		public const string ASSET_BUNDLE_NAME = "gokubracken";
	}
}

BepInEx/plugins/KarmaForBeingAnnoying_UPDATED.dll

Decompiled a month ago
using System;
using System.Collections;
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.Configuration;
using GameNetcodeStuff;
using HarmonyLib;
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(".NETFramework,Version=v4.6", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("KarmaForBeingAnnoying_UPDATED")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Updated version of the mod \"KarmaForBeingAnnoying\"")]
[assembly: AssemblyFileVersion("1.1.0.0")]
[assembly: AssemblyInformationalVersion("1.1.0")]
[assembly: AssemblyProduct("KarmaForBeingAnnoying_UPDATED")]
[assembly: AssemblyTitle("KarmaForBeingAnnoying_UPDATED")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.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 KarmaForBeingAnnoying_UPDATED
{
	[BepInPlugin("KarmaForBeingAnnoying_UPDATED", "KarmaForBeingAnnoying_UPDATED", "1.1.0")]
	public class Main : BaseUnityPlugin
	{
		private readonly Harmony harmony = new Harmony("KarmaForBeingAnnoying_UPDATED");

		private static Main Instance;

		internal static ConfigEntry<bool> AnnoyingItemSetting;

		internal static ConfigEntry<float> ProbabilitySetting;

		internal static ConfigEntry<float> ProbabilityRemoteSetting;

		internal static ConfigEntry<float> ProbabilityAirhornSetting;

		internal static ConfigEntry<float> ProbabilityClownhornSetting;

		internal static ConfigEntry<float> ProbabilityCashRegisterSetting;

		internal static ConfigEntry<float> ProbabilityHairDryerSetting;

		internal static ConfigEntry<float> DelaySetting;

		internal static ConfigEntry<float> KillRangeSetting;

		internal static ConfigEntry<float> DamageRangeSetting;

		internal static ConfigEntry<bool> RemoteSetting;

		private void Awake()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			if ((Object)Instance == (Object)null)
			{
				Instance = this;
			}
			SetCFG();
			harmony.PatchAll(typeof(Patches));
		}

		private static void SetCFG()
		{
			AnnoyingItemSetting = ((BaseUnityPlugin)Instance).Config.Bind<bool>("KarmaForBeingAnnoying Settings", "ON OFF switch", true, "Turns functionality on or off");
			ProbabilitySetting = ((BaseUnityPlugin)Instance).Config.Bind<float>("Probability Settings", "General Probability", 0.1f, "Set probability of exploding");
			ProbabilityRemoteSetting = ((BaseUnityPlugin)Instance).Config.Bind<float>("Probability Settings", "Remote Probability", 0.1f, "Set probability of exploding when using Remote");
			ProbabilityAirhornSetting = ((BaseUnityPlugin)Instance).Config.Bind<float>("Probability Settings", "Airhorn Probability", 0.1f, "Set probability of exploding when using Airhorn");
			ProbabilityClownhornSetting = ((BaseUnityPlugin)Instance).Config.Bind<float>("Probability Settings", "Clownhorn Probability", 0.1f, "Set probability of exploding when using Clownhorn");
			ProbabilityCashRegisterSetting = ((BaseUnityPlugin)Instance).Config.Bind<float>("Probability Settings", "Cashregister Probability", 0.1f, "Set probability of exploding when using Cashregister");
			ProbabilityHairDryerSetting = ((BaseUnityPlugin)Instance).Config.Bind<float>("Probability Settings", "Hairdryer Probability", 0.1f, "Set probability of exploding when using Hairdryer");
			DelaySetting = ((BaseUnityPlugin)Instance).Config.Bind<float>("Delay Settings", "General Delay", 0.5f, "Set delay of explosion");
			KillRangeSetting = ((BaseUnityPlugin)Instance).Config.Bind<float>("Kill Range Settings", "General Kill Range", 10f, "Set kill range of explosion");
			DamageRangeSetting = ((BaseUnityPlugin)Instance).Config.Bind<float>("Damage Range Settings", "General Damage Range", 1f, "Set damage range of explosion");
			RemoteSetting = ((BaseUnityPlugin)Instance).Config.Bind<bool>("KarmaForBeingAnnoying Settings", "UseOnRemote", true, "Defines if Remote sets off explosion based on params");
		}
	}
	public class Patches
	{
		private static IEnumerator DelayedExplosion(Vector3 position, bool effect, float killrange, float damagerange, float delay)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			yield return (object)new WaitForSeconds(delay);
			Landmine.SpawnExplosion(position, effect, killrange, damagerange, 50, 0f, (GameObject)null, false);
		}

		[HarmonyPatch(typeof(NoisemakerProp), "ItemActivate")]
		[HarmonyPostfix]
		private static void NoiseMakerPropItemActivatePatch(ref PlayerControllerB ___playerHeldBy, ref NoisemakerProp __instance)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Expected O, but got Unknown
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			NetworkBehaviour val = (NetworkBehaviour)___playerHeldBy;
			if ((Main.AnnoyingItemSetting.Value && val.IsOwner && ___playerHeldBy.isPlayerControlled && (!val.IsServer || ___playerHeldBy.isHostPlayerObject)) || ___playerHeldBy.isTestingPlayer)
			{
				float value = Main.ProbabilitySetting.Value;
				switch (((Object)__instance).name.Replace("(Clone)", "").ToLower())
				{
				case "airhorn":
					value = Main.ProbabilityAirhornSetting.Value;
					break;
				case "clownhorn":
					value = Main.ProbabilityClownhornSetting.Value;
					break;
				case "cashregisteritem":
					value = Main.ProbabilityCashRegisterSetting.Value;
					break;
				case "hairdryer":
					value = Main.ProbabilityHairDryerSetting.Value;
					break;
				}
				if (Random.value < value)
				{
					((MonoBehaviour)__instance).StartCoroutine(DelayedExplosion(((Component)val).transform.position, effect: true, Main.KillRangeSetting.Value, Main.DamageRangeSetting.Value, Main.DelaySetting.Value));
				}
			}
		}

		[HarmonyPatch(typeof(RemoteProp), "ItemActivate")]
		[HarmonyPostfix]
		private static void RemotePropPatch(ref PlayerControllerB ___playerHeldBy, ref RemoteProp __instance)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Expected O, but got Unknown
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			NetworkBehaviour val = (NetworkBehaviour)__instance;
			if (((Main.RemoteSetting.Value && val.IsOwner && ___playerHeldBy.isPlayerControlled && (!val.IsServer || ___playerHeldBy.isHostPlayerObject)) || ___playerHeldBy.isTestingPlayer) && Random.value < Main.ProbabilityRemoteSetting.Value)
			{
				((MonoBehaviour)__instance).StartCoroutine(DelayedExplosion(((Component)val).transform.position, effect: true, Main.KillRangeSetting.Value, Main.DamageRangeSetting.Value, Main.DelaySetting.Value));
			}
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "KarmaForBeingAnnoying_UPDATED";

		public const string PLUGIN_NAME = "KarmaForBeingAnnoying_UPDATED";

		public const string PLUGIN_VERSION = "1.1.0";
	}
}

BepInEx/plugins/Luxciano32.OiiaCat.dll

Decompiled a month ago
#define DEBUG
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 LethalLib.Modules;
using Luxciano32.OiiaCat.NetcodePatcher;
using Microsoft.CodeAnalysis;
using OiiaCat.Configuration;
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("Luxciano32.OiiaCat")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.3.0.0")]
[assembly: AssemblyInformationalVersion("1.3.0+5423e585c5e70ffadcb418a21b853eaf3f6d357b")]
[assembly: AssemblyProduct("OiiaCat")]
[assembly: AssemblyTitle("Luxciano32.OiiaCat")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.3.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 OiiaCat
{
	internal class OiiaCatAI : EnemyAI
	{
		private enum State
		{
			SearchingForPlayer,
			StickingInFrontOfPlayer
		}

		private enum SingingAnimations
		{
			singing2spin,
			singing2spinfast,
			singin3spin,
			singin3spinfast,
			singing4spin,
			singing4spinfast
		}

		public Transform turnCompass = null;

		public Transform attackArea = null;

		private float timeSinceHittingLocalPlayer;

		private float timeSinceNewRandPos;

		private Vector3 positionRandomness;

		private Vector3 StalkPos;

		private Random enemyRandom = null;

		private bool isDeadAnimationDone;

		public List<AudioClip> audioClips = null;

		public List<AudioClip> audioClipsFart = null;

		private int lastPlayedAudioClipIndex = -1;

		private int waitBeforeNextSong = 3;

		private float[] hitTimes = new float[3];

		private int hitIndex = 0;

		private float minTimeBetweenHits = 1f;

		private float maxTimeBetweenHits = 3f;

		public AudioClip audioClipDead = null;

		private List<string> lowValueItems = new List<string> { "Flashlight", "Key", "Lockpicker", "box", "Shovel", "Extension ladder", "Walkie-talkie", "TZP-Inhalant" };

		private List<string> midValueItems = new List<string> { "Boombox", "Pro-flashlight", "Stun grenade", "Zap gun", "Belt bag", "Spray paint", "Weed killer" };

		private List<string> highValueItems = new List<string> { "Jetpack", "Shotgun", "Kitchen knife", "Binoculars" };

		private List<string> lowValuescraps = new List<string>
		{
			"Rubber Ducky", "Brush", "Metal sheet", "Gift", "Dust pan", "Cookie mold pan", "Plastic cup", "Yield sign", "Pill bottle", "Flask",
			"Steering wheel", "Toy cube", "Mug", "Plastic fish", "Jar of pickles", "Garbage lid", "Bottles"
		};

		private List<string> midValuescraps = new List<string>
		{
			"Candy", "Apparatus", "Remote", "Big bolt", "Stop sign", "Toothpaste", "Red soda", "Homemade flashbang", "Easter egg", "Tragedy",
			"Comedy", "Tea kettle", "Chemical jug", "Zed Dog", "Control pad", "Large axle", "Magic 7 ball", "Hive", "V-type engine", "Whoopie cushion",
			"Soccer ball", "Magnifying glass", "Airhorn", "Clown horn", "Toy robot"
		};

		private List<string> highValuescraps = new List<string>
		{
			"Laser pointer", "Old phone", "Clock", "Bell", "Perfume bottle", "Ring", "Toy train", "Teeth", "Fancy lamp", "Painting",
			"Toilet paper", "Hairdryer", "Cash register", "Gold bar"
		};

		private List<string> lowDangerEnemies = new List<string> { "HoarderBug", "Centipede", "Blob", "CaveDweller" };

		private List<string> midDangerEnemies = new List<string> { "SandSpider", "Puffer", "SpringMan", "MaskedPlayerEnemy", "Butler" };

		private List<string> highDangerEnemies = new List<string> { "Flowerman", "Crawler", "DressGirl", "Nutcracker", "ClaySurgeon", "Jester" };

		[Conditional("DEBUG")]
		private void LogIfDebugBuild(string text)
		{
			Plugin.Logger.LogInfo((object)text);
		}

		public override void Start()
		{
			//IL_0041: 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)
			((EnemyAI)this).Start();
			LogIfDebugBuild("Oiia Cat Spawned");
			timeSinceHittingLocalPlayer = 0f;
			PlaySong();
			timeSinceNewRandPos = 0f;
			positionRandomness = new Vector3(0f, 0f, 0f);
			enemyRandom = new Random(StartOfRound.Instance.randomMapSeed + base.thisEnemyIndex);
			isDeadAnimationDone = false;
			base.currentBehaviourStateIndex = 0;
		}

		public override void Update()
		{
			//IL_00b3: 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_00da: 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_00fe: Unknown result type (might be due to invalid IL or missing references)
			((EnemyAI)this).Update();
			if (base.isEnemyDead)
			{
				if (!isDeadAnimationDone)
				{
					LogIfDebugBuild("Stopping enemy voice with janky code.");
					isDeadAnimationDone = true;
					base.creatureVoice.Stop();
					base.creatureVoice.PlayOneShot(base.dieSFX);
				}
				return;
			}
			timeSinceHittingLocalPlayer += Time.deltaTime;
			timeSinceNewRandPos += Time.deltaTime;
			int currentBehaviourStateIndex = base.currentBehaviourStateIndex;
			if ((Object)(object)base.targetPlayer != (Object)null && currentBehaviourStateIndex == 1)
			{
				turnCompass.LookAt(((Component)base.targetPlayer.gameplayCamera).transform.position);
				((Component)this).transform.rotation = Quaternion.Lerp(((Component)this).transform.rotation, Quaternion.Euler(new Vector3(0f, turnCompass.eulerAngles.y, 0f)), 4f * Time.deltaTime);
			}
			if (base.stunNormalizedTimer > 0f)
			{
				base.agent.speed = 0f;
			}
		}

		public override void DoAIInterval()
		{
			((EnemyAI)this).DoAIInterval();
			if (base.isEnemyDead || StartOfRound.Instance.allPlayersDead)
			{
				return;
			}
			switch (base.currentBehaviourStateIndex)
			{
			case 0:
				base.agent.speed = 3f;
				if (FoundClosestPlayerInRange(25f, 3f))
				{
					LogIfDebugBuild("Start Target Player");
					((EnemyAI)this).StopSearch(base.currentSearch, true);
					((EnemyAI)this).SwitchToBehaviourClientRpc(1);
				}
				break;
			case 1:
				base.agent.speed = 5f;
				StickingInFrontOfPlayer();
				break;
			default:
				LogIfDebugBuild("This Behavior State doesn't exist!");
				break;
			}
		}

		private bool FoundClosestPlayerInRange(float range, float senseRange)
		{
			//IL_004e: 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)
			((EnemyAI)this).TargetClosestPlayer(1.5f, true, 70f);
			if ((Object)(object)base.targetPlayer == (Object)null)
			{
				((EnemyAI)this).TargetClosestPlayer(1.5f, false, 70f);
				range = senseRange;
			}
			return (Object)(object)base.targetPlayer != (Object)null && Vector3.Distance(((Component)this).transform.position, ((Component)base.targetPlayer).transform.position) < range;
		}

		private bool TargetClosestPlayerInAnyCase()
		{
			//IL_001f: 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)
			base.mostOptimalDistance = 2000f;
			base.targetPlayer = null;
			for (int i = 0; i < StartOfRound.Instance.connectedPlayersAmount + 1; i++)
			{
				base.tempDist = Vector3.Distance(((Component)this).transform.position, ((Component)StartOfRound.Instance.allPlayerScripts[i]).transform.position);
				if (base.tempDist < base.mostOptimalDistance)
				{
					base.mostOptimalDistance = base.tempDist;
					base.targetPlayer = StartOfRound.Instance.allPlayerScripts[i];
				}
			}
			if ((Object)(object)base.targetPlayer == (Object)null)
			{
				return false;
			}
			return true;
		}

		private void StickingInFrontOfPlayer()
		{
			//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)
			//IL_007f: 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_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			if (!((Object)(object)base.targetPlayer == (Object)null) && ((NetworkBehaviour)this).IsOwner && timeSinceNewRandPos > 0.7f)
			{
				timeSinceNewRandPos = 0f;
				positionRandomness = new Vector3((float)enemyRandom.Next(-2, 2), 0f, (float)enemyRandom.Next(-2, 2));
				StalkPos = ((Component)base.targetPlayer).transform.position - Vector3.Scale(new Vector3(-5f, 0f, -5f), ((Component)base.targetPlayer).transform.forward) + positionRandomness;
			}
		}

		public override void HitEnemy(int force = 1, PlayerControllerB? playerWhoHit = null, bool playHitSFX = false, int hitID = -1)
		{
			if (isDeadAnimationDone)
			{
				return;
			}
			float time = Time.time;
			hitTimes[hitIndex] = time;
			if (hitIndex == 2)
			{
				float num = hitTimes[2] - hitTimes[1];
				if (num <= maxTimeBetweenHits)
				{
					((MonoBehaviour)this).StopCoroutine(StopAnimationWhenAudioEnds());
					LogIfDebugBuild("Tres golpes consecutivos recibidos, el tercero está dentro del tiempo permitido desde el segundo");
					base.creatureVoice.Stop();
					base.creatureVoice.clip = audioClipDead;
					base.creatureVoice.Play();
					isDeadAnimationDone = true;
					base.creatureAnimator.SetTrigger("singingForItem");
					((MonoBehaviour)this).StopCoroutine(StopAnimationItem());
					((MonoBehaviour)this).StartCoroutine(StopAnimationItem());
					return;
				}
			}
			LogIfDebugBuild($"El enemigo recibio el golpe N° {hitIndex + 1} de 3");
			hitIndex = (hitIndex + 1) % hitTimes.Length;
			PlaySong();
			if (!base.isEnemyDead)
			{
			}
		}

		[ClientRpc]
		public void DoAnimationClientRpc(string animationName)
		{
			//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)((NetworkBehaviour)this).__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
			{
				ClientRpcParams val = default(ClientRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(1844099280u, val, (RpcDelivery)0);
				bool flag = animationName != null;
				((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref flag, default(ForPrimitives));
				if (flag)
				{
					((FastBufferWriter)(ref val2)).WriteValueSafe(animationName, false);
				}
				((NetworkBehaviour)this).__endSendClientRpc(ref val2, 1844099280u, val, (RpcDelivery)0);
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
			{
				LogIfDebugBuild("Animation: " + animationName);
				base.creatureAnimator.SetTrigger(animationName);
			}
		}

		public void NextSinginAnimation()
		{
			LogIfDebugBuild("Next singing animation");
			string trigger = GetRandomEnumValue((SingingAnimations[])Enum.GetValues(typeof(SingingAnimations))).ToString();
			base.creatureAnimator.SetTrigger(trigger);
		}

		public static T GetRandomEnumValue<T>(T[] EnumValues) where T : Enum
		{
			int num = Random.Range(0, EnumValues.Length);
			return EnumValues[num];
		}

		public void PlaySong()
		{
			((MonoBehaviour)this).StopCoroutine(StopAnimationWhenAudioEnds());
			AudioClip randomAudioClip = GetRandomAudioClip();
			if (!((Object)(object)randomAudioClip == (Object)null))
			{
				base.creatureVoice.clip = randomAudioClip;
				base.creatureVoice.Play();
				base.creatureAnimator.SetTrigger("animationIdle");
				((MonoBehaviour)this).StartCoroutine(StopAnimationWhenAudioEnds());
			}
		}

		private AudioClip? GetRandomAudioClip()
		{
			if (audioClips == null || audioClips.Count == 0)
			{
				LogIfDebugBuild("La lista de AudioClips está vacía o es nula.");
				return null;
			}
			int num;
			do
			{
				num = Random.Range(0, audioClips.Count);
			}
			while (num == lastPlayedAudioClipIndex && audioClips.Count > 1);
			lastPlayedAudioClipIndex = num;
			return audioClips[num];
		}

		private IEnumerator StopAnimationWhenAudioEnds()
		{
			while (base.creatureVoice.isPlaying)
			{
				yield return null;
			}
			base.creatureAnimator.SetTrigger("backToIdle");
			yield return (object)new WaitForSeconds((float)waitBeforeNextSong);
			PlaySong();
		}

		private IEnumerator StopAnimationItem()
		{
			yield return (object)new WaitForSeconds(base.creatureVoice.clip.length);
			Random randomNumber = new Random();
			int randomIndex = randomNumber.Next(100);
			if (randomIndex <= 30)
			{
				TriggerExplosionFromAnimation();
			}
			else if (randomIndex > 30 && randomIndex <= 55)
			{
				SpawnScrap();
			}
			else if (randomIndex > 55 && randomIndex <= 75)
			{
				SpawnItems();
			}
			else if (randomIndex > 75 && randomIndex <= 90)
			{
				SpawnEnemy();
			}
			else
			{
				SpawnFartSound();
			}
			base.creatureAnimator.SetTrigger("animationExit");
		}

		public void SpawnItems()
		{
			//IL_00d8: 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_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				LogIfDebugBuild("Spawning items");
				List<string> list = new List<string>();
				Random random = new Random();
				int num = random.Next(100);
				list = ((num <= 50) ? lowValueItems : ((num <= 50 || num > 80) ? highValueItems : midValueItems));
				Random random2 = new Random();
				int index = random2.Next(list.Count);
				string randomItemName = list[index];
				Item val = StartOfRound.Instance.allItemsList.itemsList.Find((Item item) => item.itemName == randomItemName);
				try
				{
					LogIfDebugBuild("Instatiating item: " + val.itemName);
					GrabbableObject component = Object.Instantiate<GameObject>(val.spawnPrefab, new Vector3(((Component)this).transform.position.x, ((Component)this).transform.position.y, ((Component)this).transform.position.z), Quaternion.identity).GetComponent<GrabbableObject>();
					((NetworkBehaviour)component).NetworkObject.Spawn(false);
				}
				catch (Exception ex)
				{
					LogIfDebugBuild("Error al instanciar el item: " + ex.Message + "\n" + ex.StackTrace);
				}
			}
			catch (Exception ex2)
			{
				LogIfDebugBuild("Error al instanciar los items: " + ex2.Message + "\n" + ex2.StackTrace);
			}
		}

		public void SpawnScrap()
		{
			//IL_00d8: 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_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				LogIfDebugBuild("Spawning scrap");
				List<string> list = new List<string>();
				Random random = new Random();
				int num = random.Next(100);
				list = ((num <= 50) ? lowValuescraps : ((num <= 50 || num > 80) ? highValuescraps : midValuescraps));
				Random random2 = new Random();
				int index = random2.Next(list.Count);
				string randomScrapName = list[index];
				Item val = StartOfRound.Instance.allItemsList.itemsList.Find((Item item) => item.itemName == randomScrapName);
				try
				{
					LogIfDebugBuild("Instatiating scrap: " + val.itemName);
					GrabbableObject component = Object.Instantiate<GameObject>(val.spawnPrefab, new Vector3(((Component)this).transform.position.x, ((Component)this).transform.position.y, ((Component)this).transform.position.z), Quaternion.identity).GetComponent<GrabbableObject>();
					int minValue = val.minValue;
					int maxValue = val.maxValue;
					Random random3 = new Random();
					int scrapValue = random3.Next(minValue, maxValue);
					component.SetScrapValue(scrapValue);
					((NetworkBehaviour)component).NetworkObject.Spawn(false);
				}
				catch (Exception ex)
				{
					LogIfDebugBuild("Error al instanciar el item: " + ex.Message + "\n" + ex.StackTrace);
				}
			}
			catch (Exception ex2)
			{
				LogIfDebugBuild("Error al instanciar los items: " + ex2.Message + "\n" + ex2.StackTrace);
			}
		}

		public void TriggerExplosionFromAnimation()
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				CreateExplosion(((Component)this).transform.position, spawnExplosionEffect: true, 50, 0f, 4.3f, 15, (CauseOfDeath)3);
				Destroy();
			}
			catch (Exception ex)
			{
				LogIfDebugBuild("Error al crear la explosión: " + ex.Message + "\n" + ex.StackTrace);
			}
		}

		public void CreateExplosion(Vector3? explosionPosition = null, bool spawnExplosionEffect = false, int damage = 20, float minDamageRange = 0f, float maxDamageRange = 1f, int enemyHitForce = 6, CauseOfDeath causeOfDeath = 3, PlayerControllerB attacker = null)
		{
			//IL_0028: 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_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: 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_0109: 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_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0326: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: 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)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: 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_035b: 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_01f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fe: 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_02d5: Unknown result type (might be due to invalid IL or missing references)
			LogIfDebugBuild("Spawning explosion}");
			Vector3 val = (Vector3)(((??)explosionPosition) ?? ((Component)this).transform.position);
			Transform val2 = null;
			if ((Object)(object)RoundManager.Instance != (Object)null && (Object)(object)RoundManager.Instance.mapPropsContainer != (Object)null && (Object)(object)RoundManager.Instance.mapPropsContainer.transform != (Object)null)
			{
				val2 = RoundManager.Instance.mapPropsContainer.transform;
			}
			if (spawnExplosionEffect)
			{
				Object.Instantiate<GameObject>(StartOfRound.Instance.explosionPrefab, val, Quaternion.Euler(-90f, 0f, 0f), val2).SetActive(true);
			}
			float num = Vector3.Distance(((Component)GameNetworkManager.Instance.localPlayerController).transform.position, val);
			if (num < 14f)
			{
				HUDManager.Instance.ShakeCamera((ScreenShakeType)1);
			}
			else if (num < 25f)
			{
				HUDManager.Instance.ShakeCamera((ScreenShakeType)0);
			}
			Collider[] array = Physics.OverlapSphere(val, maxDamageRange, 2621448, (QueryTriggerInteraction)2);
			PlayerControllerB val3 = null;
			for (int i = 0; i < array.Length; i++)
			{
				float num2 = Vector3.Distance(val, ((Component)array[i]).transform.position);
				if (num2 > 4f && Physics.Linecast(val, ((Component)array[i]).transform.position + Vector3.up * 0.3f, 256, (QueryTriggerInteraction)1))
				{
					continue;
				}
				if (((Component)array[i]).gameObject.layer == 3)
				{
					LogIfDebugBuild("Damaging player: " + ((Object)((Component)array[i]).gameObject).name);
					val3 = ((Component)array[i]).gameObject.GetComponent<PlayerControllerB>();
					if ((Object)(object)val3 != (Object)null)
					{
						float num3 = Mathf.Clamp01((maxDamageRange - minDamageRange) / (num2 - minDamageRange));
						val3.DamagePlayer((int)((float)damage * num3), true, true, causeOfDeath, 0, false, default(Vector3));
					}
				}
				else if (((Component)array[i]).gameObject.layer == 21)
				{
					Landmine componentInChildren = ((Component)array[i]).gameObject.GetComponentInChildren<Landmine>();
					if ((Object)(object)componentInChildren != (Object)null && !componentInChildren.hasExploded && num2 < 6f)
					{
						LogIfDebugBuild("Setting off other mine");
					}
				}
				else if (((Component)array[i]).gameObject.layer == 19)
				{
					EnemyAICollisionDetect componentInChildren2 = ((Component)array[i]).gameObject.GetComponentInChildren<EnemyAICollisionDetect>();
					if ((Object)(object)componentInChildren2 != (Object)null && ((NetworkBehaviour)componentInChildren2.mainScript).IsOwner && num2 < 4.5f)
					{
						componentInChildren2.mainScript.HitEnemyOnLocalClient(enemyHitForce, default(Vector3), attacker, false, -1);
					}
				}
			}
			int num4 = ~LayerMask.GetMask(new string[1] { "Room" });
			num4 = ~LayerMask.GetMask(new string[1] { "Colliders" });
			array = Physics.OverlapSphere(val, 10f, num4);
			for (int j = 0; j < array.Length; j++)
			{
				Rigidbody component = ((Component)array[j]).GetComponent<Rigidbody>();
				if ((Object)(object)component != (Object)null)
				{
					component.AddExplosionForce(70f, val, 10f);
				}
			}
		}

		public void SpawnEnemy()
		{
			//IL_0122: 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_0142: 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_0159: Unknown result type (might be due to invalid IL or missing references)
			LogIfDebugBuild("Spawning enemy");
			List<string> list = new List<string>();
			Random random = new Random();
			int num = random.Next(100);
			list = ((num <= 80) ? lowDangerEnemies : ((num <= 80 || num > 92) ? highDangerEnemies : midDangerEnemies));
			Random random2 = new Random();
			int index = random2.Next(list.Count);
			string randomEnemyName = list[index];
			while (!RoundManager.Instance.currentLevel.Enemies.Exists((SpawnableEnemyWithRarity e) => ((Object)e.enemyType).name == randomEnemyName))
			{
				index = random2.Next(list.Count);
				randomEnemyName = list[index];
			}
			try
			{
				EnemyType enemyType = RoundManager.Instance.currentLevel.Enemies.Find((SpawnableEnemyWithRarity e) => ((Object)e.enemyType).name == randomEnemyName).enemyType;
				RoundManager.Instance.SpawnEnemyGameObject(new Vector3(((Component)this).transform.position.x, ((Component)this).transform.position.y, ((Component)this).transform.position.z), 0f, -1, enemyType);
			}
			catch (Exception ex)
			{
				LogIfDebugBuild("Error: " + ex.Message);
				SpawnScrap();
			}
		}

		public void SpawnFartSound()
		{
			Random random = new Random();
			int index = random.Next(audioClipsFart.Count);
			AudioClip val = audioClipsFart[index];
			base.creatureVoice.PlayOneShot(val, 2.5f);
			int num = random.Next(100);
			if (num <= 40)
			{
				HUDManager.Instance.ShakeCamera((ScreenShakeType)0);
			}
			else if (num > 40 && num <= 60)
			{
				HUDManager.Instance.ShakeCamera((ScreenShakeType)1);
			}
		}

		public void Destroy()
		{
			Object.Destroy((Object)(object)((Component)this).gameObject);
		}

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

		[RuntimeInitializeOnLoadMethod]
		internal static void InitializeRPCS_OiiaCatAI()
		{
			//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(1844099280u, new RpcReceiveHandler(__rpc_handler_1844099280));
		}

		private static void __rpc_handler_1844099280(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 animationName = null;
				if (flag)
				{
					((FastBufferReader)(ref reader)).ReadValueSafe(ref animationName, false);
				}
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((OiiaCatAI)(object)target).DoAnimationClientRpc(animationName);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		protected internal override string __getTypeName()
		{
			return "OiiaCatAI";
		}
	}
	[BepInPlugin("Luxciano32.OiiaCat", "OiiaCat", "1.3.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		internal static ManualLogSource Logger;

		public static AssetBundle? ModAssets;

		internal static PluginConfig BoundConfig { get; private set; }

		private void Awake()
		{
			Logger = ((BaseUnityPlugin)this).Logger;
			BoundConfig = new PluginConfig(((BaseUnityPlugin)this).Config);
			InitializeNetworkBehaviours();
			string path = "oiiacatassets";
			ModAssets = AssetBundle.LoadFromFile(Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), path));
			if ((Object)(object)ModAssets == (Object)null)
			{
				Logger.LogError((object)"Failed to load custom assets.");
				return;
			}
			EnemyType val = ModAssets.LoadAsset<EnemyType>("OiiaCat");
			TerminalNode val2 = ModAssets.LoadAsset<TerminalNode>("OiiaCatTN");
			TerminalKeyword val3 = ModAssets.LoadAsset<TerminalKeyword>("OiiaCatTK");
			NetworkPrefabs.RegisterNetworkPrefab(val.enemyPrefab);
			Enemies.RegisterEnemy(val, 70, (LevelTypes)(-1), val2, val3);
			Logger.LogInfo((object)"Plugin Luxciano32.OiiaCat is loaded!");
		}

		private static void InitializeNetworkBehaviours()
		{
			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 class PluginInfo
	{
		public const string PLUGIN_GUID = "Luxciano32.OiiaCat";

		public const string PLUGIN_NAME = "OiiaCat";

		public const string PLUGIN_VERSION = "1.3.0";
	}
}
namespace OiiaCat.Configuration
{
	public class PluginConfig
	{
		public ConfigEntry<int> SpawnWeight;

		public PluginConfig(ConfigFile cfg)
		{
			SpawnWeight = cfg.Bind<int>("General", "Spawn weight", 20, "The spawn chance weight for OiiaCat, relative to other existing enemies.\nGoes up from 0, lower is more rare, 100 and up is very common.");
			ClearUnusedEntries(cfg);
		}

		private void ClearUnusedEntries(ConfigFile cfg)
		{
			PropertyInfo property = ((object)cfg).GetType().GetProperty("OrphanedEntries", BindingFlags.Instance | BindingFlags.NonPublic);
			Dictionary<ConfigDefinition, string> dictionary = (Dictionary<ConfigDefinition, string>)property.GetValue(cfg, null);
			dictionary.Clear();
			cfg.Save();
		}
	}
}
namespace Luxciano32.OiiaCat.NetcodePatcher
{
	[AttributeUsage(AttributeTargets.Module)]
	internal class NetcodePatchedAssemblyAttribute : Attribute
	{
	}
}

BepInEx/plugins/PeterHead.dll

Decompiled a month ago
using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
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("PeterHead")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("PeterHead")]
[assembly: AssemblyCopyright("Copyright ©  2024")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("bad7520b-d6ab-49ba-9521-27aba032cdc5")]
[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 PeterHead
{
	[BepInPlugin("KadenBiel.PeterHead", "PeterHead", "1.0.2")]
	public class PeterHeadBase : BaseUnityPlugin
	{
		private const string modGUID = "KadenBiel.PeterHead";

		private const string modName = "PeterHead";

		private const string modVersion = "1.0.2";

		private readonly Harmony harmony = new Harmony("KadenBiel.PeterHead");

		private static PeterHeadBase Instance;

		public static ManualLogSource mls;

		public static AssetBundle PeterAssets;

		public static GameObject PeterPrefab;

		public static AudioClip Walk;

		public static AudioClip Hit;

		public static AudioClip Laugh0;

		public static AudioClip Laugh1;

		public static AudioClip Laugh2;

		public static string modDir;

		private void Awake()
		{
			if ((Object)(object)Instance == (Object)null)
			{
				Instance = this;
			}
			modDir = ((BaseUnityPlugin)this).Info.Location;
			mls = Logger.CreateLogSource("KadenBiel.PeterHead");
			LoadAssets();
			mls.LogInfo((object)"PeterHead is awake");
			Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), (string)null);
		}

		private static void LoadAssets()
		{
			try
			{
				PeterAssets = AssetBundle.LoadFromFile(Path.Combine(Path.GetDirectoryName(modDir), "peterhead"));
			}
			catch (Exception ex)
			{
				mls.LogError((object)("AssetBundle failed to load -- " + ex.Message));
				return;
			}
			try
			{
				PeterPrefab = PeterAssets.LoadAsset<GameObject>("PeterHead.prefab");
				Walk = PeterAssets.LoadAsset<AudioClip>("PeterWalk.ogg");
				Hit = PeterAssets.LoadAsset<AudioClip>("PeterKill.ogg");
				Laugh0 = PeterAssets.LoadAsset<AudioClip>("PeterLaugh.ogg");
				Laugh1 = PeterAssets.LoadAsset<AudioClip>("PeterLaugh0.ogg");
				Laugh2 = PeterAssets.LoadAsset<AudioClip>("PeterLaugh1.ogg");
				mls.LogInfo((object)"Peter Assets Loaded");
			}
			catch (Exception ex2)
			{
				mls.LogError((object)("Failed to load assets -- " + ex2.Message));
			}
		}
	}
}
namespace PeterHead.Patchers
{
	[HarmonyPatch]
	internal class CoilPatch
	{
		[HarmonyPatch(typeof(SpringManAI), "Update")]
		[HarmonyPostfix]
		private static void addController(SpringManAI __instance)
		{
			if ((Object)(object)((Component)__instance).gameObject.GetComponent<PeterController>() == (Object)null)
			{
				PeterHeadBase.mls.LogInfo((object)"Instantiating Peter");
				((Component)__instance).gameObject.AddComponent<PeterController>();
			}
		}
	}
	internal class PeterController : MonoBehaviour
	{
		private static GameObject Peter;

		private SpringManAI SpringAI { get; set; }

		private Vector3 prevPosition { get; set; }

		private void LoadAudio()
		{
			SpringAI.springNoises = (AudioClip[])(object)new AudioClip[3]
			{
				PeterHeadBase.Laugh0,
				PeterHeadBase.Laugh1,
				PeterHeadBase.Laugh2
			};
			PeterHeadBase.mls.LogInfo((object)"Audio Replaced");
		}

		private void HideSpringModel()
		{
			try
			{
				PeterHeadBase.mls.LogInfo((object)"Attempting to find spring man mesh");
				for (int i = 0; i < ((Component)SpringAI).transform.childCount - 1; i++)
				{
					PeterHeadBase.mls.LogInfo((object)("Index: " + i + " Name: " + ((Object)((Component)SpringAI).transform.GetChild(i)).name));
				}
				Renderer[] componentsInChildren = ((Component)((Component)SpringAI).transform.Find("SpringManModel")).GetComponentsInChildren<Renderer>();
				for (int j = 0; j < componentsInChildren.Length; j++)
				{
					componentsInChildren[j].enabled = false;
				}
				PeterHeadBase.mls.LogInfo((object)"Spring Man Hidden");
			}
			catch (Exception ex)
			{
				PeterHeadBase.mls.LogError((object)("Failed to find Spring Man Model: " + ex.Message));
			}
		}

		private void EnablePeter()
		{
			try
			{
				MeshRenderer[] componentsInChildren = Peter.GetComponentsInChildren<MeshRenderer>();
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					((Renderer)componentsInChildren[i]).enabled = true;
				}
				PeterHeadBase.mls.LogInfo((object)"Peter Enabled");
			}
			catch (Exception ex)
			{
				PeterHeadBase.mls.LogError((object)("Failed to find Peter Model: " + ex.Message));
			}
		}

		private void Start()
		{
			//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)
			PeterHeadBase.mls.LogInfo((object)"Peter Started");
			SpringAI = ((Component)this).GetComponent<SpringManAI>();
			Peter = Object.Instantiate<GameObject>(PeterHeadBase.PeterPrefab, ((Component)SpringAI).transform.position, Quaternion.identity, ((Component)SpringAI).transform);
			LoadAudio();
			HideSpringModel();
			EnablePeter();
		}

		private void Update()
		{
			//IL_0064: 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_009a: Unknown result type (might be due to invalid IL or missing references)
			if (((EnemyAI)SpringAI).movingTowardsTargetPlayer && !((EnemyAI)SpringAI).creatureSFX.isPlaying)
			{
				((EnemyAI)SpringAI).creatureSFX.clip = PeterHeadBase.Hit;
				((EnemyAI)SpringAI).creatureSFX.Play();
			}
			if (((EnemyAI)SpringAI).creatureSFX.isPlaying && prevPosition == ((Component)this).transform.position)
			{
				((EnemyAI)SpringAI).creatureSFX.Stop();
			}
			prevPosition = ((Component)this).transform.position;
		}
	}
}

BepInEx/plugins/PizzaTowerEscapeMusic.dll

Decompiled a month ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
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.Threading.Tasks;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using PizzaTowerEscapeMusic.Scripting;
using PizzaTowerEscapeMusic.Scripting.Conditions;
using PizzaTowerEscapeMusic.Scripting.ScriptEvents;
using UnityEngine;
using UnityEngine.Networking;

[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("PizzaTowerEscapeMusic")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Plays music from Pizza Tower when the early ship leave alert appears")]
[assembly: AssemblyFileVersion("2.4.0.0")]
[assembly: AssemblyInformationalVersion("2.4.0")]
[assembly: AssemblyProduct("PizzaTowerEscapeMusic")]
[assembly: AssemblyTitle("PizzaTowerEscapeMusic")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.4.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 PizzaTowerEscapeMusic
{
	public class Configuration
	{
		private readonly ConfigFile config;

		internal ConfigEntry<float> volumeMaster;

		internal ConfigEntry<string> scriptingScripts;

		public Configuration(ConfigFile config)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Expected O, but got Unknown
			this.config = config;
			scriptingScripts = config.Bind<string>("Scripting", "Scripts", "Default", new ConfigDescription("The names of the JSON script files that will be loaded (Separated by commas, do not put a space after the commas)", (AcceptableValueBase)null, Array.Empty<object>()));
			volumeMaster = config.Bind<float>("Volume", "Master", 0.5f, new ConfigDescription("The volume of the music as a whole, all volumes are scaled by this value", (AcceptableValueBase)null, Array.Empty<object>()));
			RemoveObsoleteEntries();
		}

		private void RemoveObsoleteEntry(string section, string key)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			ConfigDefinition val = new ConfigDefinition(section, key);
			config.Bind<string>(val, "", (ConfigDescription)null);
			config.Remove(val);
		}

		private void ReplaceObsoleteEntry<T>(string section, string key, ConfigEntry<T> replacement)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			ConfigDefinition val = new ConfigDefinition(section, key);
			ConfigEntry<T> val2 = config.Bind<T>(val, (T)((ConfigEntryBase)replacement).DefaultValue, (ConfigDescription)null);
			if (!EqualityComparer<T>.Default.Equals(val2.Value, (T)((ConfigEntryBase)replacement).DefaultValue))
			{
				replacement.Value = val2.Value;
			}
			config.Remove(val);
		}

		private void RemoveObsoleteEntries()
		{
			RemoveObsoleteEntry("Volume", "InsideFacility");
			RemoveObsoleteEntry("Volume", "OutsideFacility");
			RemoveObsoleteEntry("Volume", "InsideShip");
			RemoveObsoleteEntry("Volume", "CrouchingScale");
			RemoveObsoleteEntry("Music", "InsideFacility");
			RemoveObsoleteEntry("Music", "OutsideFacility");
			RemoveObsoleteEntry("Music", "HeavyWeather");
			ReplaceObsoleteEntry<string>("Scripting", "Script", scriptingScripts);
			config.Save();
		}
	}
	internal static class CustomManager
	{
		public static string GetFilePath(string path, string fallbackPath)
		{
			string[] directories = Directory.GetDirectories(Paths.PluginPath);
			for (int i = 0; i < directories.Length; i++)
			{
				string text = directories[i] + "/BGN-PizzaTowerEscapeMusic/" + path;
				if (File.Exists(text))
				{
					return text;
				}
			}
			string text2 = Paths.PluginPath + "/BGN-PizzaTowerEscapeMusic_Custom/" + path;
			if (File.Exists(text2))
			{
				return text2;
			}
			return Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + "/" + fallbackPath;
		}
	}
	public class GameEventListener : MonoBehaviour
	{
		private ManualLogSource logger;

		public Action OnFrameUpdate = delegate
		{
		};

		public Action OnSoundManagerCreated = delegate
		{
		};

		public Action OnSoundManagerDestroyed = delegate
		{
		};

		public Action OnDungeonDoneGenerating = delegate
		{
		};

		public Action OnShipLanded = delegate
		{
		};

		public Action OnShipTakeOff = delegate
		{
		};

		public Action OnShipReturnToOrbit = delegate
		{
		};

		public Action OnShipLeavingAlertCalled = delegate
		{
		};

		public Action OnPlayerDamaged = delegate
		{
		};

		public Action OnPlayerDeath = delegate
		{
		};

		public Action OnPlayerEnteredFacility = delegate
		{
		};

		public Action OnPlayerExitedFacility = delegate
		{
		};

		public Action OnPlayerEnteredShip = delegate
		{
		};

		public Action OnPlayerExitedShip = delegate
		{
		};

		public Action OnApparatusTaken = delegate
		{
		};

		public Action<SelectableLevel?> OnCurrentMoonChanged = delegate
		{
		};

		private readonly Dictionary<string, object?> previousValues = new Dictionary<string, object>();

		private static LungProp? dockedApparatus;

		private void Awake()
		{
			logger = Logger.CreateLogSource("PizzaTowerEscapeMusic GameEventListener");
			OnShipLanded = (Action)Delegate.Combine(OnShipLanded, new Action(FindDockedApparatus));
		}

		private void FindDockedApparatus()
		{
			logger.LogDebug((object)"Checking for docked Apparatus...");
			LungProp[] array = Object.FindObjectsOfType<LungProp>();
			foreach (LungProp val in array)
			{
				if (val.isLungDocked)
				{
					logger.LogDebug((object)"Found docked Apparatus");
					dockedApparatus = val;
					return;
				}
			}
			logger.LogDebug((object)"Could not find docked Apparatus");
		}

		public static bool IsApparatusDocked()
		{
			return (Object)(object)dockedApparatus != (Object)null;
		}

		private void Update()
		{
			if ((Object)(object)SoundManager.Instance != (Object)null)
			{
				OnFrameUpdate();
			}
			CheckSoundManager();
			CheckDungeonDoneGenerating();
			CheckShipLanded();
			CheckShipReturnToOrbit();
			CheckShipLeavingAlertCalled();
			CheckPlayerDamaged();
			CheckPlayerDeath();
			CheckPlayerInsideFacility();
			CheckPlayerInsideShip();
			CheckApparatusTaken();
			CheckCurrentMoonChanged();
		}

		private T? UpdateCached<T>(string key, T? currentValue, T? defaultValue)
		{
			if (!previousValues.TryGetValue(key, out object value))
			{
				value = defaultValue;
			}
			previousValues[key] = currentValue;
			return (T)value;
		}

		private void CheckSoundManager()
		{
			bool flag = (Object)(object)SoundManager.Instance != (Object)null;
			if (UpdateCached("SoundManager", flag, defaultValue: false) != flag)
			{
				if (flag)
				{
					logger.LogDebug((object)"Sound Manager created");
					OnSoundManagerCreated();
				}
				else
				{
					logger.LogDebug((object)"Sound Manager destroyed");
					OnSoundManagerDestroyed();
				}
			}
		}

		private void CheckDungeonDoneGenerating()
		{
			bool flag = (Object)(object)RoundManager.Instance != (Object)null && RoundManager.Instance.dungeonCompletedGenerating;
			bool flag2 = UpdateCached("DungeonDoneGenerating", flag, defaultValue: false);
			if (flag != flag2 && flag)
			{
				logger.LogDebug((object)"Dungeon done generating");
				OnDungeonDoneGenerating();
			}
		}

		private void CheckShipLanded()
		{
			bool flag = (Object)(object)StartOfRound.Instance != (Object)null && StartOfRound.Instance.shipHasLanded;
			bool flag2 = UpdateCached("ShipLanded", flag, defaultValue: true);
			if (flag != flag2 && !((Object)(object)StartOfRound.Instance == (Object)null))
			{
				if (flag)
				{
					logger.LogDebug((object)"Ship has landed");
					OnShipLanded();
				}
				else
				{
					logger.LogDebug((object)"Ship has taken off");
					OnShipTakeOff();
				}
			}
		}

		private void CheckShipReturnToOrbit()
		{
			bool flag = (Object)(object)StartOfRound.Instance == (Object)null || (!StartOfRound.Instance.shipHasLanded && !StartOfRound.Instance.shipIsLeaving);
			bool flag2 = UpdateCached("ShipReturnToOrbit", flag, defaultValue: true);
			if (flag != flag2 && flag)
			{
				logger.LogDebug((object)"Ship returned to orbit");
				OnShipReturnToOrbit();
			}
		}

		private void CheckShipLeavingAlertCalled()
		{
			bool flag = (Object)(object)TimeOfDay.Instance != (Object)null && TimeOfDay.Instance.shipLeavingAlertCalled;
			bool flag2 = UpdateCached("ShipLeavingAlertCalled", flag, defaultValue: false);
			if (flag != flag2 && flag)
			{
				logger.LogDebug((object)"Ship leaving alert called");
				OnShipLeavingAlertCalled();
			}
		}

		private void CheckPlayerDamaged()
		{
			if (!((Object)(object)GameNetworkManager.Instance == (Object)null) && !((Object)(object)GameNetworkManager.Instance.localPlayerController == (Object)null))
			{
				int health = GameNetworkManager.Instance.localPlayerController.health;
				int num = UpdateCached("PlayerDamaged", health, 100);
				if (health < num)
				{
					logger.LogDebug((object)$"Player took damage (Health: {GameNetworkManager.Instance.localPlayerController.health})");
					OnPlayerDamaged();
				}
			}
		}

		private void CheckPlayerDeath()
		{
			bool flag = (Object)(object)GameNetworkManager.Instance != (Object)null && (Object)(object)GameNetworkManager.Instance.localPlayerController != (Object)null && GameNetworkManager.Instance.localPlayerController.isPlayerDead;
			bool flag2 = UpdateCached("PlayerDeath", flag, defaultValue: false);
			if (flag != flag2 && flag)
			{
				logger.LogDebug((object)"Player has died");
				OnPlayerDeath();
			}
		}

		private void CheckPlayerInsideFacility()
		{
			bool flag = (Object)(object)GameNetworkManager.Instance != (Object)null && (Object)(object)GameNetworkManager.Instance.localPlayerController != (Object)null && GameNetworkManager.Instance.localPlayerController.isInsideFactory;
			bool flag2 = UpdateCached("PlayerInsideFacility", flag, defaultValue: false);
			if (flag != flag2)
			{
				if (flag)
				{
					logger.LogDebug((object)"Player entered facility");
					OnPlayerEnteredFacility();
				}
				else
				{
					logger.LogDebug((object)"Player exited facility");
					OnPlayerExitedFacility();
				}
			}
		}

		private void CheckPlayerInsideShip()
		{
			bool flag = (Object)(object)GameNetworkManager.Instance != (Object)null && (Object)(object)GameNetworkManager.Instance.localPlayerController != (Object)null && GameNetworkManager.Instance.localPlayerController.isInHangarShipRoom;
			bool flag2 = UpdateCached("PlayerInsideShip", flag, defaultValue: false);
			if (flag != flag2)
			{
				if (flag)
				{
					logger.LogDebug((object)"Player entered ship");
					OnPlayerEnteredShip();
				}
				else
				{
					logger.LogDebug((object)"Player exited ship");
					OnPlayerExitedShip();
				}
			}
		}

		private void CheckApparatusTaken()
		{
			bool flag = (Object)(object)dockedApparatus != (Object)null && !dockedApparatus.isLungDocked;
			bool flag2 = UpdateCached("ApparatusTaken", flag, defaultValue: false);
			if (flag != flag2 && flag)
			{
				dockedApparatus = null;
				logger.LogDebug((object)"Apparatus was taken");
				OnApparatusTaken();
			}
		}

		private void CheckCurrentMoonChanged()
		{
			SelectableLevel val = TimeOfDay.Instance?.currentLevel;
			SelectableLevel val2 = UpdateCached<SelectableLevel>("CurrentMoon", val, null);
			if (!((Object)(object)val == (Object)(object)val2))
			{
				logger.LogDebug((object)("Level has changed to " + val?.PlanetName));
				OnCurrentMoonChanged(val);
			}
		}
	}
	public class MusicManager : MonoBehaviour
	{
		private class MusicInstance
		{
			public Script script;

			public ScriptEvent_PlayMusic musicEvent;

			public AudioSource audioSource;

			public Script.VolumeGroup volumeGroup;

			private bool isStopping;

			private float volume;

			public float FadeSpeed { get; private set; }

			public MusicInstance(Script script, ScriptEvent_PlayMusic musicEvent, AudioSource audioSource, AudioClip? musicClip)
			{
				this.script = script;
				this.musicEvent = musicEvent;
				this.audioSource = audioSource;
				audioSource.clip = musicClip;
				audioSource.loop = musicEvent.loop;
				audioSource.Play();
				musicInstances.Add(this);
				if (musicEvent.tag != null)
				{
					if (!musicInstancesByTag.TryGetValue(musicEvent.tag, out List<MusicInstance> value))
					{
						value = new List<MusicInstance>(1);
						musicInstancesByTag.Add(musicEvent.tag, value);
					}
					value.Add(this);
				}
				volumeGroup = script.TryGetVolumeGroupOrDefault(musicEvent.tag);
				volume = volumeGroup.GetVolume(script);
			}

			public void Update(float deltaTime)
			{
				float num = (isStopping ? 0f : volumeGroup.GetVolume(script));
				float num2 = (isStopping ? volumeGroup.stoppingVolumeLerpSpeed : volumeGroup.volumeLerpSpeed);
				volume = Mathf.Lerp(volume, num, num2 * deltaTime);
				audioSource.volume = volume * PizzaTowerEscapeMusicManager.Configuration.volumeMaster.Value;
				if (!audioSource.isPlaying || (isStopping && audioSource.volume < 0.005f))
				{
					StopCompletely();
				}
			}

			public void FadeStop()
			{
				if (!isStopping)
				{
					isStopping = true;
					FadeSpeed = volumeGroup.stoppingVolumeLerpSpeed;
				}
			}

			public void StopCompletely()
			{
				audioSource.Stop();
				audioSourcePool.Push(audioSource);
				musicInstances.Remove(this);
				if (musicEvent.tag != null && musicInstancesByTag.TryGetValue(musicEvent.tag, out List<MusicInstance> value))
				{
					value.Remove(this);
				}
			}
		}

		private ManualLogSource logger;

		private static readonly List<MusicInstance> musicInstances = new List<MusicInstance>();

		private static readonly Dictionary<string, List<MusicInstance>> musicInstancesByTag = new Dictionary<string, List<MusicInstance>>();

		private static readonly Stack<AudioSource> audioSourcePool = new Stack<AudioSource>();

		private readonly Dictionary<string, AudioClip> loadedMusic = new Dictionary<string, AudioClip>();

		private void Awake()
		{
			logger = Logger.CreateLogSource("PizzaTowerEscapeMusic MusicManager");
		}

		private void Update()
		{
			if ((Object)(object)StartOfRound.Instance == (Object)null)
			{
				return;
			}
			for (int num = musicInstances.Count - 1; num >= 0; num--)
			{
				musicInstances[num].Update(Time.deltaTime);
			}
			bool flag = false;
			foreach (MusicInstance musicInstance in musicInstances)
			{
				if (musicInstance.musicEvent.silenceGameMusic)
				{
					flag = true;
					break;
				}
			}
			if (flag)
			{
				if (SoundManager.Instance.playingOutsideMusic && GetIsMusicPlaying())
				{
					SoundManager.Instance.playingOutsideMusic = false;
					logger.LogInfo((object)"Silenced the outside music because alternate music is playing");
				}
				if (TimeOfDay.Instance.TimeOfDayMusic.isPlaying && GetIsMusicPlaying())
				{
					TimeOfDay.Instance.TimeOfDayMusic.Stop();
					logger.LogInfo((object)"Silenced the time of day music because alternate music is playing");
				}
			}
		}

		public bool GetIsMusicPlaying(string? tag = null)
		{
			if (tag == null)
			{
				return musicInstances.Count > 0;
			}
			if (musicInstancesByTag.TryGetValue(tag, out List<MusicInstance> value))
			{
				logger.LogDebug((object)$"GetIsMusicPlaying says there's {value.Count} music instance(s) with the tag \"{tag}\"");
				return value.Count > 0;
			}
			logger.LogDebug((object)("GetIsMusicPlaying says there was no music instance list for tag \"" + tag + "\""));
			return false;
		}

		public void PlayMusic(Script script, ScriptEvent_PlayMusic musicEvent)
		{
			logger.LogDebug((object)("PlayMusic called\nTag:                         " + musicEvent.tag + $"\nOverlap handling:            {musicEvent.overlapHandling}" + $"\nAny music playing?:          {GetIsMusicPlaying()}" + $"\nAny music playing with tag?: {GetIsMusicPlaying(musicEvent.tag)}"));
			if (musicEvent.overlapHandling == ScriptEvent_PlayMusic.OverlapHandling.IgnoreAll && GetIsMusicPlaying())
			{
				logger.LogDebug((object)"PlayMusic canceled because other music was playing");
				return;
			}
			if (musicEvent.overlapHandling == ScriptEvent_PlayMusic.OverlapHandling.IgnoreTag && GetIsMusicPlaying(musicEvent.tag))
			{
				logger.LogDebug((object)("PlayMusic canceled because other music with the tag \"" + musicEvent.tag + "\" was playing"));
				return;
			}
			switch (musicEvent.overlapHandling)
			{
			case ScriptEvent_PlayMusic.OverlapHandling.OverrideAll:
				StopMusic();
				break;
			case ScriptEvent_PlayMusic.OverlapHandling.OverrideTag:
				StopMusic(musicEvent.tag);
				break;
			case ScriptEvent_PlayMusic.OverlapHandling.OverrideFadeAll:
				FadeStopMusic();
				break;
			case ScriptEvent_PlayMusic.OverlapHandling.OverrideFadeTag:
				FadeStopMusic(musicEvent.tag);
				break;
			}
			string text = musicEvent.musicNames[Random.Range(0, musicEvent.musicNames.Length)];
			loadedMusic.TryGetValue(text, out AudioClip value);
			if ((Object)(object)value != (Object)null)
			{
				new MusicInstance(script, musicEvent, GetAudioSource(), value);
				logger.LogInfo((object)("Playing music (" + text + ")"));
			}
			else
			{
				logger.LogWarning((object)("Music (" + text + ") is null, cannot play. Maybe it wasn't loaded correctly?"));
			}
		}

		public void StopMusic(string? targetTag = null)
		{
			foreach (MusicInstance item in new List<MusicInstance>(musicInstances))
			{
				if (targetTag == null || !(item.musicEvent.tag != targetTag))
				{
					item.StopCompletely();
				}
			}
		}

		public void FadeStopMusic(string? targetTag = null)
		{
			foreach (MusicInstance item in new List<MusicInstance>(musicInstances))
			{
				if (targetTag == null || !(item.musicEvent.tag != targetTag))
				{
					item.FadeStop();
				}
			}
		}

		private AudioSource GetAudioSource()
		{
			if (!audioSourcePool.TryPop(out AudioSource result))
			{
				return ((Component)this).gameObject.AddComponent<AudioSource>();
			}
			return result;
		}

		public async void LoadNecessaryMusicClips()
		{
			if (PizzaTowerEscapeMusicManager.ScriptManager.loadedScripts.Count == 0)
			{
				logger.LogError((object)"No scripts are loaded, cannot load their music!");
				return;
			}
			UnloadMusicClips();
			foreach (Script loadedScript in PizzaTowerEscapeMusicManager.ScriptManager.loadedScripts)
			{
				ScriptEvent[] scriptEvents = loadedScript.scriptEvents;
				for (int i = 0; i < scriptEvents.Length; i++)
				{
					if (!(scriptEvents[i] is ScriptEvent_PlayMusic scriptEvent_PlayMusic))
					{
						continue;
					}
					string[] musicNames = scriptEvent_PlayMusic.musicNames;
					foreach (string musicName in musicNames)
					{
						if (!loadedMusic.ContainsKey(musicName))
						{
							AudioClip val = await LoadMusicClip(musicName);
							if (!((Object)(object)val == (Object)null))
							{
								loadedMusic.Add(musicName, val);
							}
						}
					}
				}
			}
			logger.LogInfo((object)"Music clips done loading");
		}

		public void UnloadMusicClips()
		{
			foreach (AudioClip value in loadedMusic.Values)
			{
				value.UnloadAudioData();
			}
			loadedMusic.Clear();
			logger.LogInfo((object)"All music clips unloaded");
		}

		private async Task<AudioClip?> LoadMusicClip(string musicFileName)
		{
			InterpretMusicFileName(musicFileName, out AudioType audioType, out string finalFileName);
			string path = "file:///" + CustomManager.GetFilePath("Music/" + finalFileName, "DefaultMusic/" + finalFileName);
			UnityWebRequest request = UnityWebRequestMultimedia.GetAudioClip(path, audioType);
			try
			{
				request.SendWebRequest();
				while (!request.isDone)
				{
					await Task.Delay(50);
				}
				if ((int)request.result == 1)
				{
					logger.LogInfo((object)("Loaded music (" + musicFileName + ") from file"));
					AudioClip content = DownloadHandlerAudioClip.GetContent(request);
					((Object)content).name = musicFileName;
					return content;
				}
				logger.LogError((object)($"Failed to load music ({musicFileName}) from file as audio type {audioType}, if the file extension and the audio type do not match the file extension may not be supported." + "\n- Path: " + path + "\n- Error: " + request.error));
				return null;
			}
			finally
			{
				((IDisposable)request)?.Dispose();
			}
		}

		private void InterpretMusicFileName(string musicFileName, out AudioType audioType, out string finalFileName)
		{
			//IL_004e: 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_005c: Expected I4, but got Unknown
			//IL_0053: 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)
			if (!musicFileName.Contains('.'))
			{
				audioType = (AudioType)20;
				finalFileName = musicFileName + ".wav";
				return;
			}
			string text = musicFileName.Split('.').Last().ToLower();
			AudioType val = ((text == "ogg") ? ((AudioType)14) : ((!(text == "mp3")) ? ((AudioType)20) : ((AudioType)13)));
			audioType = (AudioType)(int)val;
			finalFileName = musicFileName;
		}
	}
	public class PizzaTowerEscapeMusicManager : MonoBehaviour
	{
		private GameEventListener gameEventListener;

		private ManualLogSource logger;

		public static Configuration Configuration { get; private set; }

		public static ScriptManager ScriptManager { get; private set; }

		public static MusicManager MusicManager { get; private set; }

		public void Initialise(ManualLogSource logger, ConfigFile config)
		{
			this.logger = logger;
			Configuration = new Configuration(config);
			MusicManager = ((Component)this).gameObject.AddComponent<MusicManager>();
			gameEventListener = ((Component)this).gameObject.AddComponent<GameEventListener>();
			GameEventListener obj = gameEventListener;
			obj.OnSoundManagerCreated = (Action)Delegate.Combine(obj.OnSoundManagerCreated, new Action(MusicManager.LoadNecessaryMusicClips));
			GameEventListener obj2 = gameEventListener;
			obj2.OnSoundManagerDestroyed = (Action)Delegate.Combine(obj2.OnSoundManagerDestroyed, (Action)delegate
			{
				MusicManager.StopMusic();
			});
			GameEventListener obj3 = gameEventListener;
			obj3.OnSoundManagerDestroyed = (Action)Delegate.Combine(obj3.OnSoundManagerDestroyed, new Action(MusicManager.UnloadMusicClips));
			ScriptManager = new ScriptManager(Configuration.scriptingScripts.Value.Split(','), gameEventListener);
			GameEventListener obj4 = gameEventListener;
			obj4.OnSoundManagerDestroyed = (Action)Delegate.Combine(obj4.OnSoundManagerDestroyed, new Action(ScriptManager.ClearAllScriptTimers));
			((Object)((Component)this).gameObject).hideFlags = (HideFlags)61;
			logger.LogInfo((object)"Plugin bgn.pizzatowerescapemusic is loaded!");
		}

		private void Update()
		{
			ScriptManager.UpdateAllScriptTimers(Time.deltaTime);
		}
	}
	[BepInPlugin("bgn.pizzatowerescapemusic", "PizzaTowerEscapeMusic", "2.4.0")]
	[BepInProcess("Lethal Company.exe")]
	public class Plugin : BaseUnityPlugin
	{
		public const string GUID = "bgn.pizzatowerescapemusic";

		private void Awake()
		{
			//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)
			GameObject val = new GameObject("PizzaTowerEscapeMusic Manager");
			val.AddComponent<PizzaTowerEscapeMusicManager>().Initialise(((BaseUnityPlugin)this).Logger, ((BaseUnityPlugin)this).Config);
			((Object)val).hideFlags = (HideFlags)61;
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "PizzaTowerEscapeMusic";

		public const string PLUGIN_NAME = "PizzaTowerEscapeMusic";

		public const string PLUGIN_VERSION = "2.4.0";
	}
}
namespace PizzaTowerEscapeMusic.Scripting
{
	public class Script
	{
		public class VolumeRule
		{
			public string comment = string.Empty;

			[JsonRequired]
			public float volume;

			public Condition? condition;
		}

		public class VolumeModifier
		{
			public string comment = string.Empty;

			[JsonRequired]
			public float volumeScale;

			public Condition? condition;
		}

		public class VolumeGroup
		{
			public string comment = string.Empty;

			public string tag = string.Empty;

			public float volumeLerpSpeed = 1f;

			public float stoppingVolumeLerpSpeed = 1f;

			public float masterVolume = 1f;

			public VolumeRule[] volumeRules = Array.Empty<VolumeRule>();

			public VolumeModifier[] volumeModifiers = Array.Empty<VolumeModifier>();

			public float GetVolume(Script script)
			{
				float num = 1f;
				VolumeRule[] array = volumeRules;
				foreach (VolumeRule volumeRule in array)
				{
					if (volumeRule.condition == null || volumeRule.condition.Check(script))
					{
						num = volumeRule.volume;
						break;
					}
				}
				VolumeModifier[] array2 = volumeModifiers;
				foreach (VolumeModifier volumeModifier in array2)
				{
					if (volumeModifier.condition == null || volumeModifier.condition.Check(script))
					{
						num *= volumeModifier.volumeScale;
					}
				}
				return num * masterVolume;
			}
		}

		public class Timer
		{
			public string name;

			public float time;

			public Timer(string name)
			{
				this.name = name;
			}
		}

		public string comment = string.Empty;

		public bool isAddon;

		public VolumeGroup[] volumeGroups = Array.Empty<VolumeGroup>();

		[JsonRequired]
		public ScriptEvent[] scriptEvents = Array.Empty<ScriptEvent>();

		[JsonIgnore]
		public readonly Dictionary<ScriptEvent.GameEventType, List<ScriptEvent>> loadedScriptEvents = new Dictionary<ScriptEvent.GameEventType, List<ScriptEvent>>();

		[JsonIgnore]
		public readonly Dictionary<string, VolumeGroup> loadedScriptVolumeGroups = new Dictionary<string, VolumeGroup>();

		[JsonIgnore]
		public readonly Dictionary<string, Timer> activeTimers = new Dictionary<string, Timer>();

		[JsonIgnore]
		public static VolumeGroup DefaultVolumeGroup { get; private set; } = new VolumeGroup();


		public void Initialise(ManualLogSource logger)
		{
			ScriptEvent[] array = scriptEvents;
			foreach (ScriptEvent scriptEvent in array)
			{
				if (!loadedScriptEvents.TryGetValue(scriptEvent.gameEventType, out List<ScriptEvent> value))
				{
					value = new List<ScriptEvent>(1);
					loadedScriptEvents.Add(scriptEvent.gameEventType, value);
				}
				value.Add(scriptEvent);
			}
			VolumeGroup[] array2 = volumeGroups;
			foreach (VolumeGroup volumeGroup in array2)
			{
				if (!loadedScriptVolumeGroups.TryAdd(volumeGroup.tag, volumeGroup))
				{
					logger.LogError((object)("Volume group tag \"" + volumeGroup.tag + "\" was already declared, you cannot have two volume groups with the same tag"));
				}
			}
		}

		public VolumeGroup TryGetVolumeGroupOrDefault(string? tag)
		{
			if (tag == null || !loadedScriptVolumeGroups.ContainsKey(tag))
			{
				return DefaultVolumeGroup;
			}
			return loadedScriptVolumeGroups[tag];
		}

		public bool TryGetVolumeGroup(string? tag, [NotNullWhen(true)] out VolumeGroup? volumeGroup)
		{
			if (tag == null || !loadedScriptVolumeGroups.ContainsKey(tag))
			{
				volumeGroup = null;
				return false;
			}
			volumeGroup = loadedScriptVolumeGroups[tag];
			return true;
		}

		public void UpdateTimers(float deltaTime)
		{
			foreach (Timer value in activeTimers.Values)
			{
				value.time += deltaTime;
			}
		}

		public void ClearTimers()
		{
			activeTimers.Clear();
		}

		internal void ClearTimer(string timerName)
		{
			activeTimers.Remove(timerName);
		}
	}
	public class ScriptManager
	{
		public readonly List<Script> loadedScripts = new List<Script>();

		public ManualLogSource Logger { get; private set; }

		public ScriptManager(string[] scriptNames, GameEventListener gameEventListener)
		{
			Logger = Logger.CreateLogSource("PizzaTowerEscapeMusic ScriptManager");
			Script script = new Script();
			loadedScripts.Add(script);
			foreach (string text in scriptNames)
			{
				Script script2 = DeserializeScript(text);
				if (script2 != null)
				{
					script2.Initialise(Logger);
					if (script2.isAddon)
					{
						List<Script.VolumeGroup> list = script.volumeGroups.ToList();
						list.AddRange(script2.volumeGroups);
						script.volumeGroups = list.ToArray();
						List<ScriptEvent> list2 = script.scriptEvents.ToList();
						list2.AddRange(script2.scriptEvents);
						script.scriptEvents = list2.ToArray();
					}
					else
					{
						loadedScripts.Add(script2);
					}
					if (script2.isAddon)
					{
						Logger.LogInfo((object)("Script (" + text + ") loaded as addon"));
					}
					else
					{
						Logger.LogInfo((object)("Script (" + text + ") loaded"));
					}
				}
			}
			script.Initialise(Logger);
			gameEventListener.OnFrameUpdate = (Action)Delegate.Combine(gameEventListener.OnFrameUpdate, (Action)delegate
			{
				CheckScriptEvents(ScriptEvent.GameEventType.FrameUpdated);
			});
			gameEventListener.OnShipLanded = (Action)Delegate.Combine(gameEventListener.OnShipLanded, (Action)delegate
			{
				CheckScriptEvents(ScriptEvent.GameEventType.ShipLanded);
			});
			gameEventListener.OnShipTakeOff = (Action)Delegate.Combine(gameEventListener.OnShipTakeOff, (Action)delegate
			{
				CheckScriptEvents(ScriptEvent.GameEventType.ShipTakeOff);
			});
			gameEventListener.OnShipLeavingAlertCalled = (Action)Delegate.Combine(gameEventListener.OnShipLeavingAlertCalled, (Action)delegate
			{
				CheckScriptEvents(ScriptEvent.GameEventType.ShipLeavingAlertCalled);
			});
			gameEventListener.OnPlayerDamaged = (Action)Delegate.Combine(gameEventListener.OnPlayerDamaged, (Action)delegate
			{
				CheckScriptEvents(ScriptEvent.GameEventType.PlayerDamaged);
			});
			gameEventListener.OnPlayerDeath = (Action)Delegate.Combine(gameEventListener.OnPlayerDeath, (Action)delegate
			{
				CheckScriptEvents(ScriptEvent.GameEventType.PlayerDied);
			});
			gameEventListener.OnPlayerEnteredFacility = (Action)Delegate.Combine(gameEventListener.OnPlayerEnteredFacility, (Action)delegate
			{
				CheckScriptEvents(ScriptEvent.GameEventType.PlayerEnteredFacility);
			});
			gameEventListener.OnPlayerExitedFacility = (Action)Delegate.Combine(gameEventListener.OnPlayerExitedFacility, (Action)delegate
			{
				CheckScriptEvents(ScriptEvent.GameEventType.PlayerExitedFacility);
			});
			gameEventListener.OnPlayerEnteredShip = (Action)Delegate.Combine(gameEventListener.OnPlayerEnteredShip, (Action)delegate
			{
				CheckScriptEvents(ScriptEvent.GameEventType.PlayerEnteredShip);
			});
			gameEventListener.OnPlayerExitedShip = (Action)Delegate.Combine(gameEventListener.OnPlayerExitedShip, (Action)delegate
			{
				CheckScriptEvents(ScriptEvent.GameEventType.PlayerExitedShip);
			});
			gameEventListener.OnApparatusTaken = (Action)Delegate.Combine(gameEventListener.OnApparatusTaken, (Action)delegate
			{
				CheckScriptEvents(ScriptEvent.GameEventType.ApparatusTaken);
			});
			gameEventListener.OnCurrentMoonChanged = (Action<SelectableLevel>)Delegate.Combine(gameEventListener.OnCurrentMoonChanged, (Action<SelectableLevel>)delegate
			{
				CheckScriptEvents(ScriptEvent.GameEventType.CurrentMoonChanged);
			});
			Logger.LogInfo((object)"Done loading scripts");
		}

		private void CheckScriptEvents(ScriptEvent.GameEventType eventType)
		{
			foreach (Script loadedScript in loadedScripts)
			{
				if (!loadedScript.loadedScriptEvents.TryGetValue(eventType, out List<ScriptEvent> value))
				{
					continue;
				}
				foreach (ScriptEvent item in value)
				{
					if (item.CheckConditions(loadedScript))
					{
						Logger.LogDebug((object)("Conditions for a script event have been met!\n Script Event Type: " + item.scriptEventType + $"\n   Game Event Type: {item.gameEventType}" + "\n           Comment: " + item.comment));
						item.Run(loadedScript);
					}
				}
			}
		}

		private Script? DeserializeScript(string name)
		{
			string filePath = CustomManager.GetFilePath("Scripts/" + name + ".json", "DefaultScripts/" + name + ".json");
			if (!File.Exists(filePath))
			{
				Logger.LogError((object)("Script \"" + name + "\" does not exist! Make sure you spelt it right the config, and make sure its file extension is \".json\""));
				return null;
			}
			string text = File.ReadAllText(filePath);
			try
			{
				return JsonConvert.DeserializeObject<Script>(text);
			}
			catch (Exception ex)
			{
				Logger.LogError((object)("Failed to deserialize script \"" + name + "\":\n" + ex.Message));
				return null;
			}
		}

		public void UpdateAllScriptTimers(float deltaTime)
		{
			foreach (Script loadedScript in loadedScripts)
			{
				loadedScript.UpdateTimers(deltaTime);
			}
		}

		public void ClearAllScriptTimers()
		{
			foreach (Script loadedScript in loadedScripts)
			{
				loadedScript.ClearTimers();
			}
		}
	}
}
namespace PizzaTowerEscapeMusic.Scripting.ScriptEvents
{
	public class ScriptEventConverter : JsonConverter<ScriptEvent>
	{
		public override bool CanWrite => false;

		public override ScriptEvent ReadJson(JsonReader reader, Type objectType, ScriptEvent? existingValue, bool hasExistingValue, JsonSerializer serializer)
		{
			JObject val = JObject.Load(reader);
			JToken val2 = default(JToken);
			if (!val.TryGetValue("scriptEventType", ref val2))
			{
				throw new Exception("scriptEventType type is null!");
			}
			ScriptEvent scriptEvent = Extensions.Value<string>((IEnumerable<JToken>)val2) switch
			{
				"PlayMusic" => new ScriptEvent_PlayMusic(), 
				"StopMusic" => new ScriptEvent_StopMusic(), 
				"ResetTimers" => new ScriptEvent_ResetTimers(), 
				"SetVolumeGroupMasterVolume" => new ScriptEvent_SetVolumeGroupMasterVolume(), 
				_ => throw new Exception($"Condition type \"{val2}\" does not exist"), 
			};
			serializer.Populate(((JToken)val).CreateReader(), (object)scriptEvent);
			return scriptEvent;
		}

		public override void WriteJson(JsonWriter writer, ScriptEvent? value, JsonSerializer serializer)
		{
			throw new NotImplementedException();
		}
	}
	[JsonConverter(typeof(ScriptEventConverter))]
	public abstract class ScriptEvent
	{
		public enum GameEventType
		{
			FrameUpdated,
			ShipLanded,
			ShipTakeOff,
			ShipLeavingAlertCalled,
			PlayerDamaged,
			PlayerDied,
			PlayerEnteredFacility,
			PlayerExitedFacility,
			PlayerEnteredShip,
			PlayerExitedShip,
			ApparatusTaken,
			CurrentMoonChanged
		}

		public string comment = string.Empty;

		[JsonRequired]
		public string scriptEventType = string.Empty;

		[JsonRequired]
		public GameEventType gameEventType;

		public Condition[] conditions = Array.Empty<Condition>();

		public bool CheckConditions(Script script)
		{
			Script script2 = script;
			return !conditions.Any((Condition c) => !c.Check(script2));
		}

		public abstract void Run(Script script);
	}
	public class ScriptEvent_PlayMusic : ScriptEvent
	{
		public enum OverlapHandling
		{
			IgnoreAll,
			IgnoreTag,
			OverrideAll,
			OverrideTag,
			OverrideFadeAll,
			OverrideFadeTag,
			Overlap
		}

		public bool loop;

		public bool silenceGameMusic = true;

		[JsonRequired]
		public OverlapHandling overlapHandling;

		public string? tag;

		[JsonRequired]
		public string[] musicNames = Array.Empty<string>();

		public override void Run(Script script)
		{
			if (musicNames.Length != 0)
			{
				PizzaTowerEscapeMusicManager.MusicManager.PlayMusic(script, this);
			}
		}
	}
	public class ScriptEvent_StopMusic : ScriptEvent
	{
		public string[]? targetTags;

		public bool instant;

		public override void Run(Script script)
		{
			if (targetTags != null)
			{
				string[] array = targetTags;
				foreach (string targetTag in array)
				{
					if (instant)
					{
						PizzaTowerEscapeMusicManager.MusicManager.StopMusic(targetTag);
					}
					else
					{
						PizzaTowerEscapeMusicManager.MusicManager.FadeStopMusic(targetTag);
					}
				}
			}
			else if (instant)
			{
				PizzaTowerEscapeMusicManager.MusicManager.StopMusic();
			}
			else
			{
				PizzaTowerEscapeMusicManager.MusicManager.FadeStopMusic();
			}
		}
	}
	public class ScriptEvent_ResetTimers : ScriptEvent
	{
		public string[]? targetTimerNames;

		public override void Run(Script script)
		{
			if (targetTimerNames == null)
			{
				script.ClearTimers();
				return;
			}
			string[] array = targetTimerNames;
			foreach (string timerName in array)
			{
				script.ClearTimer(timerName);
			}
		}
	}
	public class ScriptEvent_SetVolumeGroupMasterVolume : ScriptEvent
	{
		public string[] targetTags = Array.Empty<string>();

		[JsonRequired]
		public float masterVolume;

		public override void Run(Script script)
		{
			if (targetTags.Length == 0)
			{
				Script.DefaultVolumeGroup.masterVolume = masterVolume;
				return;
			}
			string[] array = targetTags;
			foreach (string text in array)
			{
				if (!script.loadedScriptVolumeGroups.TryGetValue(text, out Script.VolumeGroup value))
				{
					PizzaTowerEscapeMusicManager.ScriptManager.Logger.LogError((object)("Script Event SetVolumeGroupMasterVolume was called for volume group with tag \"" + text + "\", but there is no volume group of that tag"));
				}
				else
				{
					value.masterVolume = masterVolume;
				}
			}
		}
	}
}
namespace PizzaTowerEscapeMusic.Scripting.Conditions
{
	public class ConditionConverter : JsonConverter<Condition>
	{
		public override bool CanWrite => false;

		public override Condition ReadJson(JsonReader reader, Type objectType, Condition? existingValue, bool hasExistingValue, JsonSerializer serializer)
		{
			JObject val = JObject.Load(reader);
			JToken val2 = default(JToken);
			if (!val.TryGetValue("conditionType", ref val2))
			{
				throw new Exception("Condition type is null!");
			}
			Condition condition = Extensions.Value<string>((IEnumerable<JToken>)val2) switch
			{
				"And" => new Condition_And(), 
				"Or" => new Condition_Or(), 
				"Not" => new Condition_Not(), 
				"Weather" => new Condition_Weather(), 
				"PlayerLocation" => new Condition_PlayerLocation(), 
				"PlayerAlive" => new Condition_PlayerAlive(), 
				"PlayerHealth" => new Condition_PlayerHealth(), 
				"PlayerCrouching" => new Condition_PlayerCrouching(), 
				"PlayerInsanity" => new Condition_PlayerInsanity(), 
				"ShipLanded" => new Condition_ShipLanded(), 
				"ShipLeavingAlertCalled" => new Condition_ShipLeavingAlertCalled(), 
				"MusicWithTagPlaying" => new Condition_MusicWithTagPlaying(), 
				"CurrentMoon" => new Condition_CurrentMoon(), 
				"Timer" => new Condition_Timer(), 
				"Random" => new Condition_Random(), 
				"ApparatusDocked" => new Condition_ApparatusDocked(), 
				"TimeOfDay" => new Condition_TimeOfDay(), 
				_ => throw new Exception($"Condition type \"{val2}\" does not exist"), 
			};
			serializer.Populate(((JToken)val).CreateReader(), (object)condition);
			return condition;
		}

		public override void WriteJson(JsonWriter writer, Condition? value, JsonSerializer serializer)
		{
			throw new NotImplementedException();
		}
	}
	[JsonConverter(typeof(ConditionConverter))]
	public abstract class Condition
	{
		[JsonRequired]
		public string conditionType = string.Empty;

		public abstract bool Check(Script script);
	}
	public abstract class ConditionComparableNumber : Condition
	{
		public enum ComparisonType
		{
			Equals,
			NotEquals,
			GreaterThan,
			LessThan,
			GreaterThanOrEquals,
			LessThanOrEquals
		}

		[JsonRequired]
		public ComparisonType comparisonType;
	}
	public class Condition_And : Condition
	{
		[JsonRequired]
		public Condition[] conditions = Array.Empty<Condition>();

		public override bool Check(Script script)
		{
			Script script2 = script;
			return !conditions.Any((Condition c) => !c.Check(script2));
		}
	}
	public class Condition_Or : Condition
	{
		[JsonRequired]
		public Condition[] conditions = Array.Empty<Condition>();

		public override bool Check(Script script)
		{
			Script script2 = script;
			return conditions.Any((Condition c) => c.Check(script2));
		}
	}
	public class Condition_Not : Condition
	{
		[JsonRequired]
		public Condition? condition;

		public override bool Check(Script script)
		{
			if (condition == null)
			{
				return true;
			}
			return !condition.Check(script);
		}
	}
	public class Condition_Weather : Condition
	{
		[JsonRequired]
		public LevelWeatherType weather;

		public override bool Check(Script script)
		{
			//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)
			if ((Object)(object)TimeOfDay.Instance == (Object)null)
			{
				return false;
			}
			return TimeOfDay.Instance.currentLevelWeather == weather;
		}
	}
	public class Condition_PlayerLocation : Condition
	{
		public enum Location
		{
			Ship,
			Facility
		}

		[JsonRequired]
		public Location location;

		public override bool Check(Script script)
		{
			if ((Object)(object)GameNetworkManager.Instance == (Object)null)
			{
				return false;
			}
			if ((Object)(object)GameNetworkManager.Instance.localPlayerController == (Object)null)
			{
				return false;
			}
			return location switch
			{
				Location.Ship => GameNetworkManager.Instance.localPlayerController.isInHangarShipRoom, 
				Location.Facility => GameNetworkManager.Instance.localPlayerController.isInsideFactory, 
				_ => false, 
			};
		}
	}
	public class Condition_PlayerAlive : Condition
	{
		public override bool Check(Script script)
		{
			if ((Object)(object)GameNetworkManager.Instance == (Object)null)
			{
				return false;
			}
			if ((Object)(object)GameNetworkManager.Instance.localPlayerController == (Object)null)
			{
				return false;
			}
			return !GameNetworkManager.Instance.localPlayerController.isPlayerDead;
		}
	}
	public class Condition_PlayerHealth : ConditionComparableNumber
	{
		[JsonRequired]
		public int value;

		public override bool Check(Script script)
		{
			if ((Object)(object)GameNetworkManager.Instance == (Object)null)
			{
				return false;
			}
			if ((Object)(object)GameNetworkManager.Instance.localPlayerController == (Object)null)
			{
				return false;
			}
			int health = GameNetworkManager.Instance.localPlayerController.health;
			return comparisonType switch
			{
				ComparisonType.Equals => health == value, 
				ComparisonType.NotEquals => health != value, 
				ComparisonType.GreaterThan => health > value, 
				ComparisonType.LessThan => health < value, 
				ComparisonType.GreaterThanOrEquals => health >= value, 
				ComparisonType.LessThanOrEquals => health <= value, 
				_ => false, 
			};
		}
	}
	public class Condition_PlayerCrouching : Condition
	{
		public override bool Check(Script script)
		{
			if ((Object)(object)GameNetworkManager.Instance == (Object)null)
			{
				return false;
			}
			if ((Object)(object)GameNetworkManager.Instance.localPlayerController == (Object)null)
			{
				return false;
			}
			return GameNetworkManager.Instance.localPlayerController.isCrouching;
		}
	}
	public class Condition_PlayerInsanity : ConditionComparableNumber
	{
		[JsonRequired]
		public float level;

		public override bool Check(Script script)
		{
			if ((Object)(object)GameNetworkManager.Instance == (Object)null)
			{
				return false;
			}
			if ((Object)(object)GameNetworkManager.Instance.localPlayerController == (Object)null)
			{
				return false;
			}
			float num = GameNetworkManager.Instance.localPlayerController.insanityLevel / GameNetworkManager.Instance.localPlayerController.maxInsanityLevel;
			return comparisonType switch
			{
				ComparisonType.Equals => level == num, 
				ComparisonType.NotEquals => level != num, 
				ComparisonType.GreaterThan => level > num, 
				ComparisonType.LessThan => level < num, 
				ComparisonType.GreaterThanOrEquals => level >= num, 
				ComparisonType.LessThanOrEquals => level <= num, 
				_ => false, 
			};
		}
	}
	public class Condition_ShipLanded : Condition
	{
		public override bool Check(Script script)
		{
			if ((Object)(object)StartOfRound.Instance == (Object)null)
			{
				return false;
			}
			return StartOfRound.Instance.shipHasLanded;
		}
	}
	public class Condition_ShipLeavingAlertCalled : Condition
	{
		public override bool Check(Script script)
		{
			if ((Object)(object)TimeOfDay.Instance == (Object)null)
			{
				return false;
			}
			return TimeOfDay.Instance.shipLeavingAlertCalled;
		}
	}
	public class Condition_MusicWithTagPlaying : Condition
	{
		[JsonRequired]
		public string tag = string.Empty;

		public override bool Check(Script script)
		{
			return PizzaTowerEscapeMusicManager.MusicManager.GetIsMusicPlaying(tag);
		}
	}
	public class Condition_CurrentMoon : Condition
	{
		private static readonly Dictionary<string, int> moonNameToId = new Dictionary<string, int>();

		[JsonRequired]
		public string moonName = string.Empty;

		private bool isDisabled;

		public override bool Check(Script script)
		{
			if ((Object)(object)TimeOfDay.Instance == (Object)null)
			{
				return false;
			}
			if ((Object)(object)StartOfRound.Instance == (Object)null)
			{
				return false;
			}
			if (isDisabled)
			{
				return false;
			}
			if (!moonNameToId.TryGetValue(moonName, out var value))
			{
				SelectableLevel[] levels = StartOfRound.Instance.levels;
				foreach (SelectableLevel val in levels)
				{
					moonNameToId.TryAdd(val.PlanetName, val.levelID);
				}
				if (!moonNameToId.TryGetValue(moonName, out value))
				{
					PizzaTowerEscapeMusicManager.ScriptManager.Logger.LogError((object)("From CurrentMoon condition: Found no existing level with the name \"" + moonName + "\""));
					isDisabled = true;
					return false;
				}
			}
			return TimeOfDay.Instance.currentLevel.levelID == value;
		}
	}
	public class Condition_Timer : Condition
	{
		[JsonRequired]
		public string timerName = string.Empty;

		[JsonRequired]
		public float timeGoal;

		public bool resetsTimer = true;

		public override bool Check(Script script)
		{
			if (!script.activeTimers.TryGetValue(timerName, out Script.Timer value))
			{
				value = new Script.Timer(timerName);
				script.activeTimers.Add(timerName, value);
			}
			if (value.time >= timeGoal)
			{
				if (resetsTimer)
				{
					value.time = 0f;
				}
				return true;
			}
			return false;
		}
	}
	public class Condition_Random : Condition
	{
		[JsonRequired]
		public float chance;

		public override bool Check(Script script)
		{
			return Random.Range(0f, 1f) <= chance;
		}
	}
	public class Condition_ApparatusDocked : Condition
	{
		public override bool Check(Script script)
		{
			return GameEventListener.IsApparatusDocked();
		}
	}
	public class Condition_TimeOfDay : ConditionComparableNumber
	{
		[JsonRequired]
		public float time;

		public override bool Check(Script script)
		{
			if ((Object)(object)TimeOfDay.Instance == (Object)null)
			{
				return false;
			}
			float num = TimeOfDay.Instance.currentDayTime / TimeOfDay.Instance.totalTime;
			return comparisonType switch
			{
				ComparisonType.Equals => num == time, 
				ComparisonType.NotEquals => num != time, 
				ComparisonType.GreaterThan => num > time, 
				ComparisonType.LessThan => num < time, 
				ComparisonType.GreaterThanOrEquals => num >= time, 
				ComparisonType.LessThanOrEquals => num <= time, 
				_ => false, 
			};
		}
	}
}

BepInEx/plugins/WeirdMods.OIIA.dll

Decompiled a month 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 BepInEx.Logging;
using HarmonyLib;
using LethalLib.Modules;
using LobbyCompatibility.Attributes;
using Microsoft.CodeAnalysis;
using OIIA.Scripts;
using Unity.Netcode;
using UnityEngine;
using WeirdMods.OIIA.NetcodePatcher;

[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("WeirdMods.OIIA")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+7f04e269862c177673bcf8e7ec94b3c04992d6f9")]
[assembly: AssemblyProduct("OIIA")]
[assembly: AssemblyTitle("WeirdMods.OIIA")]
[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 OIIA
{
	[BepInPlugin("WeirdMods.OIIA", "OIIA", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[LobbyCompatibility(/*Could not decode attribute arguments.*/)]
	public class OIIA : BaseUnityPlugin
	{
		public static ContentLoader ContentLoader = null;

		private static readonly string ASSETS_PATH = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "OIIA");

		public List<AudioClip> OIIAClips = new List<AudioClip>();

		public static OIIA Instance { get; private set; } = null;


		internal static ManualLogSource Logger { get; private set; } = null;


		internal static Harmony? Harmony { get; set; }

		public static AssetBundle MainAssetBundle { get; private set; } = null;


		private void Awake()
		{
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Expected O, but got Unknown
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Expected O, but got Unknown
			Logger = ((BaseUnityPlugin)this).Logger;
			Instance = this;
			MainAssetBundle = AssetBundle.LoadFromFile(Path.Combine(ASSETS_PATH, "oiiaasset"));
			ContentLoader = new ContentLoader(((BaseUnityPlugin)Instance).Info, MainAssetBundle, (Action<CustomContent, GameObject>)delegate
			{
			});
			ContentLoader.Register((CustomContent)new ScrapItem("OIIA_CAT", "Assets/OIIA/OIIACat.asset", 6, (LevelTypes)(-1), (string[])null, (Action<Item>)delegate(Item item)
			{
				OIIACatScript oIIACatScript = item.spawnPrefab.AddComponent<OIIACatScript>();
				((GrabbableObject)oIIACatScript).itemProperties = item;
			}));
			for (int i = 1; i <= 6; i++)
			{
				OIIAClips.Add(MainAssetBundle.LoadAsset<AudioClip>($"Assets/OIIA/Sounds/OIIA_{i}.wav"));
				OIIAClips.Last().LoadAudioData();
			}
			Patch();
			NetcodePatcher();
			Logger.LogInfo((object)"WeirdMods.OIIA v1.0.0 has loaded!");
		}

		internal static void Patch()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			if (Harmony == null)
			{
				Harmony = new Harmony("WeirdMods.OIIA");
			}
			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!");
		}

		private static void NetcodePatcher()
		{
			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 class MyPluginInfo
	{
		public const string PLUGIN_GUID = "WeirdMods.OIIA";

		public const string PLUGIN_NAME = "OIIA";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}
namespace OIIA.Scripts
{
	internal class OIIACatScript : PhysicsProp
	{
		private Animator _animator;

		private AudioSource _audio;

		private const float BaseAnimSpeed = 0.3f;

		private const float MaxSpeedMultiplier = 3f;

		private void Awake()
		{
			//IL_001c: 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_003b: 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)
			((GrabbableObject)this).grabbable = true;
			((GrabbableObject)this).itemProperties.positionOffset = new Vector3(-0.35f, 0.3f, 0.1f);
			((GrabbableObject)this).itemProperties.rotationOffset = new Vector3(-90f, 28f, -90f);
			_animator = ((Component)this).GetComponentInChildren<Animator>();
			_audio = ((Component)((Component)this).transform.Find("Cat/OIIAAudio")).gameObject.GetComponent<AudioSource>();
		}

		public override void ItemActivate(bool used, bool buttonDown = true)
		{
			SetSpinningServerRpc(buttonDown, Random.Range(1f, 3f));
		}

		[ServerRpc(RequireOwnership = false)]
		private void SetSpinningServerRpc(bool spinning, float speed)
		{
			//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)
			{
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
				{
					ServerRpcParams val = default(ServerRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(954555982u, val, (RpcDelivery)0);
					((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref spinning, default(ForPrimitives));
					((FastBufferWriter)(ref val2)).WriteValueSafe<float>(ref speed, default(ForPrimitives));
					((NetworkBehaviour)this).__endSendServerRpc(ref val2, 954555982u, val, (RpcDelivery)0);
				}
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost))
				{
					SetSpinningClientRpc(spinning, speed);
				}
			}
		}

		[ClientRpc]
		private void SetSpinningClientRpc(bool spinning, float speed)
		{
			//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 != 2 && (networkManager.IsServer || networkManager.IsHost))
			{
				ClientRpcParams val = default(ClientRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(4062488745u, val, (RpcDelivery)0);
				((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref spinning, default(ForPrimitives));
				((FastBufferWriter)(ref val2)).WriteValueSafe<float>(ref speed, default(ForPrimitives));
				((NetworkBehaviour)this).__endSendClientRpc(ref val2, 4062488745u, val, (RpcDelivery)0);
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
			{
				_animator.SetBool("Spinning", spinning);
				_animator.SetFloat("Speed", 0.3f * speed);
				float num = 3f / (float)OIIA.Instance.OIIAClips.Count;
				int index = Math.Min((int)Math.Floor(speed / num), OIIA.Instance.OIIAClips.Count - 1);
				_audio.clip = OIIA.Instance.OIIAClips[index];
				if (spinning)
				{
					_audio.Play();
				}
				else
				{
					_audio.Stop();
				}
			}
		}

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

		[RuntimeInitializeOnLoadMethod]
		internal static void InitializeRPCS_OIIACatScript()
		{
			//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(954555982u, new RpcReceiveHandler(__rpc_handler_954555982));
			NetworkManager.__rpc_func_table.Add(4062488745u, new RpcReceiveHandler(__rpc_handler_4062488745));
		}

		private static void __rpc_handler_954555982(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 spinning = default(bool);
				((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref spinning, default(ForPrimitives));
				float speed = default(float);
				((FastBufferReader)(ref reader)).ReadValueSafe<float>(ref speed, default(ForPrimitives));
				target.__rpc_exec_stage = (__RpcExecStage)1;
				((OIIACatScript)(object)target).SetSpinningServerRpc(spinning, speed);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_4062488745(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 spinning = default(bool);
				((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref spinning, default(ForPrimitives));
				float speed = default(float);
				((FastBufferReader)(ref reader)).ReadValueSafe<float>(ref speed, default(ForPrimitives));
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((OIIACatScript)(object)target).SetSpinningClientRpc(spinning, speed);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		protected internal override string __getTypeName()
		{
			return "OIIACatScript";
		}
	}
}
namespace WeirdMods.OIIA.NetcodePatcher
{
	[AttributeUsage(AttributeTargets.Module)]
	internal class NetcodePatchedAssemblyAttribute : Attribute
	{
	}
}

BepInEx/plugins/GuaranteeApparatus/GuaranteeApparatus.dll

Decompiled a month ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using DunGen;
using DunGen.Graph;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Unity.Collections;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyVersion("0.0.0.0")]
[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 GuaranteeApparatus
{
	internal enum InteriorClassification
	{
		Vanilla,
		KnownCustom,
		UnknownCustom
	}
	internal sealed class ValidationContext
	{
		[CompilerGenerated]
		private sealed class <FindSceneObjects>d__39<T> : IEnumerable<T>, IEnumerable, IEnumerator<T>, IEnumerator, IDisposable where T : notnull, Component
		{
			private int <>1__state;

			private T <>2__current;

			private int <>l__initialThreadId;

			private T[] <allObjects>5__2;

			private int <i>5__3;

			T IEnumerator<T>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <FindSceneObjects>d__39(int <>1__state)
			{
				this.<>1__state = <>1__state;
				<>l__initialThreadId = Environment.CurrentManagedThreadId;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<allObjects>5__2 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0056: 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)
				int num = <>1__state;
				if (num != 0)
				{
					if (num != 1)
					{
						return false;
					}
					<>1__state = -1;
					goto IL_007c;
				}
				<>1__state = -1;
				<allObjects>5__2 = Resources.FindObjectsOfTypeAll<T>();
				<i>5__3 = 0;
				goto IL_008c;
				IL_007c:
				<i>5__3++;
				goto IL_008c;
				IL_008c:
				if (<i>5__3 < <allObjects>5__2.Length)
				{
					T val = <allObjects>5__2[<i>5__3];
					if (!((Object)(object)val == (Object)null))
					{
						Scene scene = ((Component)val).gameObject.scene;
						if (((Scene)(ref scene)).IsValid())
						{
							<>2__current = val;
							<>1__state = 1;
							return true;
						}
					}
					goto IL_007c;
				}
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}

			[DebuggerHidden]
			IEnumerator<T> IEnumerable<T>.GetEnumerator()
			{
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					return this;
				}
				return new <FindSceneObjects>d__39<T>(0);
			}

			[DebuggerHidden]
			IEnumerator IEnumerable.GetEnumerator()
			{
				return ((IEnumerable<T>)this).GetEnumerator();
			}
		}

		public RoundManager RoundManager { get; }

		public StartOfRound StartOfRound { get; }

		public Dungeon Dungeon { get; }

		public List<Tile> Tiles { get; }

		public Bounds DungeonBounds { get; }

		public LllContext LllContext { get; }

		public string FlowName { get; }

		public bool IsFactoryLike { get; }

		public InteriorClassification Classification { get; set; }

		public IKnownCustomInteriorRule? KnownRule { get; set; }

		public Vector3 EntrancePosition { get; set; }

		public Transform DungeonRootTransform => ((Component)Dungeon).transform;

		public ValidationContext(RoundManager roundManager, StartOfRound startOfRound, Dungeon dungeon, List<Tile> tiles, LllContext lllContext, string flowName, bool isFactoryLike)
		{
			//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)
			RoundManager = roundManager;
			StartOfRound = startOfRound;
			Dungeon = dungeon;
			Tiles = tiles;
			LllContext = lllContext;
			FlowName = flowName;
			IsFactoryLike = isFactoryLike;
			DungeonBounds = BuildDungeonBounds(tiles);
		}

		[IteratorStateMachine(typeof(<FindSceneObjects>d__39<>))]
		public IEnumerable<T> FindSceneObjects<T>() where T : Component
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <FindSceneObjects>d__39<T>(-2);
		}

		public T[] FindDungeonComponents<T>() where T : Component
		{
			return ((Component)DungeonRootTransform).GetComponentsInChildren<T>(true);
		}

		public Transform[] FindDungeonTransforms()
		{
			return ((Component)DungeonRootTransform).GetComponentsInChildren<Transform>(true);
		}

		public bool IsInDungeonHierarchy(Transform? transform)
		{
			if ((Object)(object)transform != (Object)null)
			{
				if (!((Object)(object)transform == (Object)(object)DungeonRootTransform))
				{
					return transform.IsChildOf(DungeonRootTransform);
				}
				return true;
			}
			return false;
		}

		public bool IsInDungeon(Vector3 position)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			Tile tile;
			Bounds containingBounds;
			return TryFindContainingTile(position, out tile, out containingBounds);
		}

		public bool TryFindContainingTile(Vector3 position, out Tile? tile, out Bounds containingBounds)
		{
			//IL_0013: 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_0022: 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_004f: 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_0032: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i < Tiles.Count; i++)
			{
				Tile val = Tiles[i];
				Bounds val2 = ExpandedBounds(GetTileBounds(val), 1.5f);
				if (((Bounds)(ref val2)).Contains(position))
				{
					tile = val;
					containingBounds = val2;
					return true;
				}
			}
			tile = null;
			containingBounds = default(Bounds);
			return false;
		}

		public Bounds GetTileBounds(Tile tile)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			return tile.Bounds;
		}

		public string GetRelativeDungeonPath(Transform transform)
		{
			return ApparatusValidator.GetRelativeTransformPath(transform, DungeonRootTransform);
		}

		public static Bounds ExpandedBounds(Bounds bounds, float padding)
		{
			//IL_0002: 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_000e: 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_0024: Unknown result type (might be due to invalid IL or missing references)
			return new Bounds(((Bounds)(ref bounds)).center, ((Bounds)(ref bounds)).size + Vector3.one * (padding * 2f));
		}

		private static Bounds BuildDungeonBounds(List<Tile> tiles)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			//IL_0012: 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_0049: Unknown result type (might be due to invalid IL or missing references)
			if (tiles.Count == 0)
			{
				return new Bounds(Vector3.zero, Vector3.zero);
			}
			Bounds bounds = tiles[0].Bounds;
			for (int i = 1; i < tiles.Count; i++)
			{
				((Bounds)(ref bounds)).Encapsulate(tiles[i].Bounds);
			}
			return bounds;
		}
	}
	internal readonly struct SpawnCandidate
	{
		public Vector3 Position { get; }

		public float DistanceFromEntrance { get; }

		public float TileVolume { get; }

		public float NormalizedDepth { get; }

		public bool PreferredUnusedAnchor { get; }

		public string StableKey { get; }

		public string RelativeDungeonPath { get; }

		public SpawnCandidate(Vector3 position, float distanceFromEntrance, float tileVolume, float normalizedDepth, bool preferredUnusedAnchor, string stableKey, string relativeDungeonPath)
		{
			//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)
			Position = position;
			DistanceFromEntrance = distanceFromEntrance;
			TileVolume = tileVolume;
			NormalizedDepth = normalizedDepth;
			PreferredUnusedAnchor = preferredUnusedAnchor;
			StableKey = stableKey;
			RelativeDungeonPath = relativeDungeonPath;
		}
	}
	internal readonly struct FallbackSpawnResult
	{
		public LungProp LungProp { get; }

		public Vector3 Position { get; }

		public string PlacementKey { get; }

		public string RelativeDungeonPath { get; }

		public FallbackSpawnResult(LungProp lungProp, Vector3 position, string placementKey, string relativeDungeonPath)
		{
			//IL_0008: 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)
			LungProp = lungProp;
			Position = position;
			PlacementKey = placementKey;
			RelativeDungeonPath = relativeDungeonPath;
		}
	}
	internal static class ApparatusValidator
	{
		private const string VanillaApparatusItemName = "Apparatus";

		private static readonly FieldInfo? NormalizedPathDepthField = AccessTools.Field(typeof(TilePlacementData), "normalizedPathDepth");

		public static void Evaluate(RoundManager roundManager)
		{
			//IL_026e: Unknown result type (might be due to invalid IL or missing references)
			ScanNodeSupportService.EnsureMessagingReady();
			ScanNodeSupportService.TryResolvePending(roundManager);
			if (!GuaranteeApparatusPlugin.Enabled.Value)
			{
				return;
			}
			NetworkManager singleton = NetworkManager.Singleton;
			if ((Object)(object)singleton == (Object)null || !singleton.IsServer)
			{
				return;
			}
			if (!TryBuildContext(roundManager, out ValidationContext context))
			{
				GuaranteeApparatusPlugin.Verbose("Skipping apparatus validation because dungeon context was incomplete.");
				return;
			}
			DetectedCustomApparatusCandidate detectedCustomApparatusCandidate = null;
			bool flag = false;
			if (context.Classification == InteriorClassification.KnownCustom)
			{
				IKnownCustomInteriorRule knownRule = context.KnownRule;
				if (knownRule != null)
				{
					CustomApparatusDetectionResult customApparatusDetectionResult = knownRule.DetectCustomApparatus(context);
					GuaranteeApparatusPlugin.Verbose($"Known custom detector '{knownRule.DisplayName}' => detected={customApparatusDetectionResult.Detected}, reason='{customApparatusDetectionResult.Reason}'.");
					if (customApparatusDetectionResult.Detected && (Object)(object)customApparatusDetectionResult.ApparatusRoot != (Object)null)
					{
						flag = true;
						detectedCustomApparatusCandidate = new DetectedCustomApparatusCandidate(InteriorClassification.KnownCustom, knownRule.RuleId, knownRule.DisplayName, customApparatusDetectionResult.ApparatusRoot, context.GetRelativeDungeonPath(customApparatusDetectionResult.ApparatusRoot), string.IsNullOrWhiteSpace(customApparatusDetectionResult.DisplayName) ? ((Object)customApparatusDetectionResult.ApparatusRoot).name : customApparatusDetectionResult.DisplayName, customApparatusDetectionResult.Reason, 0);
						ScanNodeSupportService.EnsureCustomScanSupport(context, detectedCustomApparatusCandidate);
						GuaranteeApparatusPlugin.Log.LogInfo((object)"known custom apparatus detected");
						if (GuaranteeApparatusPlugin.RespectCustomApparatus.Value && !GuaranteeApparatusPlugin.ForceVanillaFallbackOnKnownCustomInteriors.Value)
						{
							return;
						}
					}
					goto IL_019c;
				}
			}
			if (context.Classification == InteriorClassification.UnknownCustom && UnknownCustomApparatusDiscovery.TryDiscover(context, out DetectedCustomApparatusCandidate detectedCandidate))
			{
				flag = true;
				detectedCustomApparatusCandidate = detectedCandidate;
				ScanNodeSupportOutcome scanNodeSupportOutcome = ScanNodeSupportService.EnsureCustomScanSupport(context, detectedCustomApparatusCandidate);
				GuaranteeApparatusPlugin.Log.LogInfo((object)((scanNodeSupportOutcome == ScanNodeSupportOutcome.Generated) ? "unknown custom apparatus detected; scan node generated" : "unknown custom apparatus detected"));
				if (GuaranteeApparatusPlugin.RespectUnknownCustomApparatus.Value)
				{
					return;
				}
			}
			else if (context.Classification == InteriorClassification.UnknownCustom)
			{
				GuaranteeApparatusPlugin.Log.LogInfo((object)"unknown custom apparatus NOT found; proceeding to vanilla/fallback evaluation");
			}
			goto IL_019c;
			IL_019c:
			if (TryFindValidVanillaApparatus(context, detectedCustomApparatusCandidate, out LungProp existingVanillaApparatus))
			{
				GuaranteeApparatusPlugin.Verbose("Accepted vanilla apparatus at '" + GetStableTransformPath(((Component)existingVanillaApparatus).transform) + "'.");
				GuaranteeApparatusPlugin.Log.LogInfo((object)"vanilla apparatus detected");
			}
			else
			{
				if ((context.Classification != 0 && (context.Classification != InteriorClassification.KnownCustom || !GuaranteeApparatusPlugin.ForceVanillaFallbackOnKnownCustomInteriors.Value) && (context.Classification != InteriorClassification.UnknownCustom || flag || !GuaranteeApparatusPlugin.SpawnFallbackWhenUnknownCustomHasNoDetectedApparatus.Value)) || GuaranteeApparatusPlugin.HasSpawnedFallbackThisRound)
				{
					return;
				}
				if (TrySpawnFallback(context, out var fallbackSpawnResult))
				{
					GuaranteeApparatusPlugin.HasSpawnedFallbackThisRound = true;
					GuaranteeApparatusPlugin.Verbose("Spawned fallback vanilla apparatus using placement key '" + fallbackSpawnResult.PlacementKey + "'.");
					GuaranteeApparatusPlugin.Log.LogInfo((object)"fallback vanilla apparatus spawned");
					GuaranteeApparatusPlugin.Log.LogInfo((object)("fallback vanilla apparatus location: position=" + FormatVector3(fallbackSpawnResult.Position) + ", dungeonPath='" + fallbackSpawnResult.RelativeDungeonPath + "'"));
					switch (ScanNodeSupportService.EnsureFallbackScanSupport(fallbackSpawnResult.LungProp, fallbackSpawnResult.RelativeDungeonPath))
					{
					case ScanNodeSupportOutcome.Generated:
						GuaranteeApparatusPlugin.Log.LogInfo((object)"fallback vanilla apparatus scan node generated");
						break;
					case ScanNodeSupportOutcome.AlreadyPresent:
						GuaranteeApparatusPlugin.Log.LogInfo((object)"fallback vanilla apparatus already had valid scan support");
						break;
					default:
						GuaranteeApparatusPlugin.Log.LogWarning((object)"fallback vanilla apparatus scan support could not be ensured");
						break;
					}
				}
				else
				{
					GuaranteeApparatusPlugin.Log.LogInfo((object)"skipped because no safe fallback point existed");
				}
			}
		}

		internal static string GetRelativeTransformPath(Transform transform, Transform rootTransform)
		{
			if ((Object)(object)transform == (Object)(object)rootTransform)
			{
				return string.Empty;
			}
			Stack<string> stack = new Stack<string>();
			Transform val = transform;
			while ((Object)(object)val != (Object)null && (Object)(object)val != (Object)(object)rootTransform)
			{
				stack.Push(((Object)val).name);
				val = val.parent;
			}
			if (!((Object)(object)val == (Object)(object)rootTransform))
			{
				return GetStableTransformPath(transform);
			}
			return string.Join("/", stack);
		}

		private static bool TryBuildContext(RoundManager roundManager, out ValidationContext context)
		{
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			context = null;
			StartOfRound instance = StartOfRound.Instance;
			if ((Object)(object)instance == (Object)null || (Object)(object)roundManager.dungeonGenerator == (Object)null || roundManager.dungeonGenerator.Generator == null)
			{
				return false;
			}
			Dungeon currentDungeon = roundManager.dungeonGenerator.Generator.CurrentDungeon;
			if ((Object)(object)currentDungeon == (Object)null)
			{
				return false;
			}
			List<Tile> list = new List<Tile>();
			foreach (Tile allTile in currentDungeon.AllTiles)
			{
				if ((Object)(object)allTile != (Object)null)
				{
					list.Add(allTile);
				}
			}
			if (list.Count == 0)
			{
				return false;
			}
			LllContext lllContext = LllReflection.Capture();
			string flowName = GetFlowName(roundManager, lllContext);
			bool isFactoryLike = IsFactoryLikeFlow(flowName);
			context = new ValidationContext(roundManager, instance, currentDungeon, list, lllContext, flowName, isFactoryLike);
			context.KnownRule = KnownCustomInteriorRules.Match(context);
			context.Classification = ((context.KnownRule != null) ? InteriorClassification.KnownCustom : ((lllContext.IsLoaded && lllContext.CurrentExtendedDungeonIsCustom) ? InteriorClassification.UnknownCustom : InteriorClassification.Vanilla));
			context.EntrancePosition = FindEntrancePosition(context);
			GuaranteeApparatusPlugin.Verbose($"Built context: flow='{context.FlowName}', factoryLike={context.IsFactoryLike}, classification={context.Classification}, " + $"tiles={context.Tiles.Count}, doors={context.Dungeon.Doors.Count}, connections={context.Dungeon.Connections.Count}.");
			return true;
		}

		private static string GetFlowName(RoundManager roundManager, LllContext lllContext)
		{
			if (!string.IsNullOrWhiteSpace(lllContext.DungeonName))
			{
				return lllContext.DungeonName;
			}
			IndoorMapType[] dungeonFlowTypes = roundManager.dungeonFlowTypes;
			if (dungeonFlowTypes != null && roundManager.currentDungeonType >= 0 && roundManager.currentDungeonType < dungeonFlowTypes.Length)
			{
				IndoorMapType val = dungeonFlowTypes[roundManager.currentDungeonType];
				if (val != null && (Object)(object)val.dungeonFlow != (Object)null && !string.IsNullOrWhiteSpace(((Object)val.dungeonFlow).name))
				{
					return ((Object)val.dungeonFlow).name;
				}
			}
			return "unknown";
		}

		private static bool IsFactoryLikeFlow(string? flowName)
		{
			if (string.IsNullOrWhiteSpace(flowName))
			{
				return false;
			}
			string[] array = GuaranteeApparatusPlugin.FactoryFlowPatterns.Value.Split(',');
			for (int i = 0; i < array.Length; i++)
			{
				string text = array[i].Trim();
				if (text.Length != 0 && flowName.Contains(text, StringComparison.OrdinalIgnoreCase))
				{
					return true;
				}
			}
			return false;
		}

		private static Vector3 FindEntrancePosition(ValidationContext context)
		{
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bc: 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)
			List<(int, string, Vector3)> list = new List<(int, string, Vector3)>();
			foreach (EntranceTeleport item in context.FindSceneObjects<EntranceTeleport>())
			{
				if (!((Object)(object)item == (Object)null) && item.isEntranceToBuilding)
				{
					Transform val = null;
					if ((Object)(object)item.entrancePoint != (Object)null && context.IsInDungeonHierarchy(item.entrancePoint))
					{
						val = item.entrancePoint;
					}
					else if (context.IsInDungeonHierarchy(((Component)item).transform))
					{
						val = ((Component)item).transform;
					}
					else if ((Object)(object)item.exitPoint != (Object)null && context.IsInDungeonHierarchy(item.exitPoint))
					{
						val = item.exitPoint;
					}
					if (!((Object)(object)val == (Object)null))
					{
						list.Add((item.entranceId, context.GetRelativeDungeonPath(val), val.position));
					}
				}
			}
			if (list.Count > 0)
			{
				list.Sort(delegate((int EntranceId, string StablePath, Vector3 Position) left, (int EntranceId, string StablePath, Vector3 Position) right)
				{
					int num = left.EntranceId.CompareTo(right.EntranceId);
					return (num == 0) ? string.Compare(left.StablePath, right.StablePath, StringComparison.Ordinal) : num;
				});
				return list[0].Item3;
			}
			Tile val2 = null;
			string strB = string.Empty;
			for (int i = 0; i < context.Tiles.Count; i++)
			{
				Tile val3 = context.Tiles[i];
				string relativeDungeonPath = context.GetRelativeDungeonPath(((Component)val3).transform);
				if ((Object)(object)val2 == (Object)null)
				{
					val2 = val3;
					strB = relativeDungeonPath;
					continue;
				}
				float normalizedDepth = GetNormalizedDepth(val3);
				float normalizedDepth2 = GetNormalizedDepth(val2);
				if (normalizedDepth < normalizedDepth2 || (Math.Abs(normalizedDepth - normalizedDepth2) < 0.0001f && string.Compare(relativeDungeonPath, strB, StringComparison.Ordinal) < 0))
				{
					val2 = val3;
					strB = relativeDungeonPath;
				}
			}
			if (!((Object)(object)val2 != (Object)null))
			{
				return context.DungeonRootTransform.position;
			}
			Bounds bounds = val2.Bounds;
			return ((Bounds)(ref bounds)).center;
		}

		private static bool TryFindValidVanillaApparatus(ValidationContext context, DetectedCustomApparatusCandidate? detectedCustomCandidate, out LungProp? existingVanillaApparatus)
		{
			List<LungProp> list = new List<LungProp>();
			foreach (LungProp item in context.FindSceneObjects<LungProp>())
			{
				list.Add(item);
			}
			list.Sort((LungProp left, LungProp right) => string.Compare(GetStableTransformPath(((Component)left).transform), GetStableTransformPath(((Component)right).transform), StringComparison.Ordinal));
			for (int i = 0; i < list.Count; i++)
			{
				LungProp val = list[i];
				if (IsValidVanillaLungProp(context, val, detectedCustomCandidate))
				{
					existingVanillaApparatus = val;
					return true;
				}
			}
			existingVanillaApparatus = null;
			return false;
		}

		private static bool IsValidVanillaLungProp(ValidationContext context, LungProp? lungProp, DetectedCustomApparatusCandidate? detectedCustomCandidate)
		{
			//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_00ab: 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_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: 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_00fd: 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)
			if (!((Object)(object)lungProp == (Object)null))
			{
				Scene scene = ((Component)lungProp).gameObject.scene;
				if (((Scene)(ref scene)).IsValid() && ((Component)lungProp).gameObject.activeInHierarchy && ((Behaviour)lungProp).isActiveAndEnabled && !((GrabbableObject)lungProp).deactivated)
				{
					if ((Object)(object)lungProp.roundManager == (Object)null || lungProp.roundManager != context.RoundManager)
					{
						return false;
					}
					if (!IsVanillaApparatusItem(((GrabbableObject)lungProp).itemProperties))
					{
						return false;
					}
					if (context.KnownRule != null && context.KnownRule.IsCustomControlledLungProp(context, lungProp))
					{
						return false;
					}
					if (detectedCustomCandidate != null && detectedCustomCandidate.ControlsTransform(((Component)lungProp).transform))
					{
						return false;
					}
					Bounds dungeonBounds;
					if (!context.IsInDungeonHierarchy(((Component)lungProp).transform) && !context.IsInDungeon(((Component)lungProp).transform.position))
					{
						dungeonBounds = context.DungeonBounds;
						if (!((Bounds)(ref dungeonBounds)).Contains(((Component)lungProp).transform.position))
						{
							return false;
						}
					}
					EvaluateReachability(context, ((Component)lungProp).transform.position, out var available, out var reachable);
					if (available && !reachable)
					{
						return false;
					}
					if (!available)
					{
						dungeonBounds = context.DungeonBounds;
						if (!((Bounds)(ref dungeonBounds)).Contains(((Component)lungProp).transform.position) || !((Component)lungProp).gameObject.activeInHierarchy)
						{
							return false;
						}
					}
					return true;
				}
			}
			return false;
		}

		private static bool IsVanillaApparatusItem(Item? item)
		{
			if ((Object)(object)item != (Object)null && string.Equals(item.itemName, "Apparatus", StringComparison.OrdinalIgnoreCase) && (Object)(object)item.spawnPrefab != (Object)null && (Object)(object)item.spawnPrefab.GetComponent<LungProp>() != (Object)null)
			{
				return LllReflection.IsVanillaItem(item);
			}
			return false;
		}

		private static bool TrySpawnFallback(ValidationContext context, out FallbackSpawnResult fallbackSpawnResult)
		{
			//IL_007d: 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_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_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: 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_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: 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_01de: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0203: Unknown result type (might be due to invalid IL or missing references)
			//IL_0208: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_0266: Unknown result type (might be due to invalid IL or missing references)
			//IL_026d: 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_02b8: Unknown result type (might be due to invalid IL or missing references)
			fallbackSpawnResult = default(FallbackSpawnResult);
			if (!ResolveVanillaApparatusItem(context.StartOfRound, out Item apparatusItem) || (Object)(object)apparatusItem?.spawnPrefab == (Object)null)
			{
				GuaranteeApparatusPlugin.Verbose("Could not resolve the real vanilla Apparatus item.");
				return false;
			}
			if (!TryFindFallbackPosition(context, out Vector3 position, out string stableKey, out string relativeDungeonPath))
			{
				return false;
			}
			GameObject mapPropsContainer = context.RoundManager.mapPropsContainer;
			Transform val = ((mapPropsContainer != null) ? mapPropsContainer.transform : null) ?? context.RoundManager.spawnedScrapContainer ?? ((Component)context.RoundManager).transform;
			Vector3 val2 = position;
			Quaternion val3 = Quaternion.identity;
			bool flag = false;
			Transform val4 = null;
			if (VanillaApparatusSetpieceService.TryCreateServerSetpiece(context.RoundManager, val, position, out var result))
			{
				flag = true;
				val4 = result.DockAnchor;
				val2 = result.DockPosition;
				val3 = result.DockRotation;
				GuaranteeApparatusPlugin.Log.LogInfo((object)("fallback vanilla apparatus machine spawned: sourceFlow='" + result.SourceFlowName + "', tile='" + result.TilePrefabName + "', machineRoot='" + result.MachineRootPath + "', dockPosition=" + FormatVector3(val2)));
			}
			else
			{
				GuaranteeApparatusPlugin.Log.LogWarning((object)"fallback vanilla apparatus machine could not be resolved; using loose vanilla fallback");
			}
			GameObject val5 = Object.Instantiate<GameObject>(apparatusItem.spawnPrefab, val2, val3, val);
			if ((Object)(object)val5 == (Object)null)
			{
				return false;
			}
			LungProp component = val5.GetComponent<LungProp>();
			NetworkObject component2 = val5.GetComponent<NetworkObject>();
			if ((Object)(object)component == (Object)null || (Object)(object)component2 == (Object)null)
			{
				Object.Destroy((Object)(object)val5);
				return false;
			}
			int num = CalculateScrapValue(apparatusItem, context.StartOfRound.randomMapSeed, stableKey);
			((GrabbableObject)component).itemProperties = apparatusItem;
			component.roundManager = context.RoundManager;
			((GrabbableObject)component).isInFactory = true;
			((GrabbableObject)component).isInElevator = false;
			((GrabbableObject)component).isInShipRoom = false;
			component.isLungDocked = flag;
			component.isLungDockedInElevator = false;
			component.isLungPowered = flag;
			((GrabbableObject)component).deactivated = false;
			((GrabbableObject)component).targetFloorPosition = val2;
			((GrabbableObject)component).startFallingPosition = val2 + Vector3.up * (flag ? 0.1f : 2f);
			((GrabbableObject)component).scrapValue = num;
			((GrabbableObject)component).SetScrapValue(num);
			if (!component2.IsSpawned)
			{
				component2.Spawn(false);
			}
			if (flag && (Object)(object)val4 != (Object)null)
			{
				DockedFallbackApparatusController.Attach(component, val4, result.DockVisualRoot);
				((GrabbableObject)component).parentObject = val4;
				((Component)component).transform.SetPositionAndRotation(val4.position, val4.rotation);
				if ((Object)(object)((GrabbableObject)component).propBody != (Object)null)
				{
					((GrabbableObject)component).propBody.isKinematic = true;
					((GrabbableObject)component).propBody.useGravity = false;
					((GrabbableObject)component).propBody.velocity = Vector3.zero;
					((GrabbableObject)component).propBody.angularVelocity = Vector3.zero;
				}
			}
			else
			{
				((GrabbableObject)component).FallToGround(true, true, val2);
			}
			FallbackApparatusFacilityMeltdownBridge.Attach(component);
			RoundManager roundManager = context.RoundManager;
			roundManager.totalScrapValueInLevel += (float)num;
			fallbackSpawnResult = new FallbackSpawnResult(component, val2, stableKey, relativeDungeonPath);
			return true;
		}

		private static bool ResolveVanillaApparatusItem(StartOfRound startOfRound, out Item? apparatusItem)
		{
			apparatusItem = null;
			if ((Object)(object)startOfRound.allItemsList == (Object)null || startOfRound.allItemsList.itemsList == null)
			{
				return false;
			}
			List<Item> itemsList = startOfRound.allItemsList.itemsList;
			for (int i = 0; i < itemsList.Count; i++)
			{
				Item val = itemsList[i];
				if (IsVanillaApparatusItem(val))
				{
					apparatusItem = val;
					return true;
				}
			}
			return false;
		}

		private static int CalculateScrapValue(Item apparatusItem, int mapSeed, string stableKey)
		{
			int num = Math.Max(0, apparatusItem.minValue);
			int num2 = Math.Max(num, apparatusItem.maxValue);
			if (num2 <= num)
			{
				return num;
			}
			return new Random(mapSeed ^ GetStableHash(stableKey) ^ 0x5F3759DF).Next(num, num2 + 1);
		}

		private static bool TryFindFallbackPosition(ValidationContext context, out Vector3 position, out string stableKey, out string relativeDungeonPath)
		{
			//IL_0029: 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_0038: 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)
			List<SpawnCandidate> list = new List<SpawnCandidate>();
			BuildAnchorCandidates(context, list);
			BuildTileCandidates(context, list);
			SortCandidates(list);
			for (int i = 0; i < list.Count; i++)
			{
				SpawnCandidate spawnCandidate = list[i];
				if (TryValidateSpawnPosition(context, spawnCandidate.Position, out var validatedPosition))
				{
					position = validatedPosition;
					stableKey = spawnCandidate.StableKey;
					relativeDungeonPath = spawnCandidate.RelativeDungeonPath;
					return true;
				}
			}
			position = default(Vector3);
			stableKey = string.Empty;
			relativeDungeonPath = string.Empty;
			return false;
		}

		private static void BuildAnchorCandidates(ValidationContext context, List<SpawnCandidate> candidates)
		{
			//IL_0056: 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_0087: 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_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: 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_010d: Unknown result type (might be due to invalid IL or missing references)
			ValidationContext context2 = context;
			RandomScrapSpawn[] array = context2.FindDungeonComponents<RandomScrapSpawn>();
			Array.Sort(array, (RandomScrapSpawn left, RandomScrapSpawn right) => string.Compare(context2.GetRelativeDungeonPath(((Component)left).transform), context2.GetRelativeDungeonPath(((Component)right).transform), StringComparison.Ordinal));
			HashSet<string> hashSet = new HashSet<string>(StringComparer.Ordinal);
			foreach (RandomScrapSpawn val in array)
			{
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				Scene scene = ((Component)val).gameObject.scene;
				if (!((Scene)(ref scene)).IsValid() || !context2.IsInDungeonHierarchy(((Component)val).transform))
				{
					continue;
				}
				Vector3 position = ((Component)val).transform.position;
				if (context2.TryFindContainingTile(position, out Tile tile, out Bounds containingBounds) && !((Object)(object)tile == (Object)null))
				{
					string relativeDungeonPath = context2.GetRelativeDungeonPath(((Component)val).transform);
					string text = "anchor:" + relativeDungeonPath;
					if (hashSet.Add(text))
					{
						candidates.Add(new SpawnCandidate(position, Vector3.Distance(context2.EntrancePosition, position), ((Bounds)(ref containingBounds)).size.x * ((Bounds)(ref containingBounds)).size.y * ((Bounds)(ref containingBounds)).size.z, GetNormalizedDepth(tile), !val.spawnUsed, text, relativeDungeonPath));
					}
				}
			}
		}

		private static void BuildTileCandidates(ValidationContext context, List<SpawnCandidate> candidates)
		{
			//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)
			//IL_0097: 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_00f0: 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_011b: 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_0135: 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_0139: 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_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: 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_0147: 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)
			List<(Tile, string)> list = new List<(Tile, string)>(context.Tiles.Count);
			for (int i = 0; i < context.Tiles.Count; i++)
			{
				Tile val = context.Tiles[i];
				list.Add((val, context.GetRelativeDungeonPath(((Component)val).transform)));
			}
			list.Sort(((Tile Tile, string Path) left, (Tile Tile, string Path) right) => string.Compare(left.Path, right.Path, StringComparison.Ordinal));
			for (int j = 0; j < list.Count; j++)
			{
				Tile item = list[j].Item1;
				Bounds tileBounds = context.GetTileBounds(item);
				float num = Math.Max(1.5f, Math.Min(((Bounds)(ref tileBounds)).extents.x, ((Bounds)(ref tileBounds)).extents.z) * 0.75f);
				int seed = context.StartOfRound.randomMapSeed ^ GetStableHash("tile:" + list[j].Item2);
				Vector3 val2 = context.RoundManager.GetRandomNavMeshPositionInBoxPredictable(((Bounds)(ref tileBounds)).center, num, context.RoundManager.navHit, new Random(seed), context.RoundManager.collisionsMask, Math.Max(2f, ((Bounds)(ref tileBounds)).extents.y + 2f));
				if (val2 == Vector3.zero)
				{
					val2 = ((Bounds)(ref tileBounds)).center;
				}
				candidates.Add(new SpawnCandidate(val2, Vector3.Distance(context.EntrancePosition, val2), ((Bounds)(ref tileBounds)).size.x * ((Bounds)(ref tileBounds)).size.y * ((Bounds)(ref tileBounds)).size.z, GetNormalizedDepth(item), preferredUnusedAnchor: false, "tile:" + list[j].Item2, list[j].Item2));
			}
		}

		private static void SortCandidates(List<SpawnCandidate> candidates)
		{
			candidates.Sort(delegate(SpawnCandidate left, SpawnCandidate right)
			{
				int num = right.PreferredUnusedAnchor.CompareTo(left.PreferredUnusedAnchor);
				if (num != 0)
				{
					return num;
				}
				int num2 = right.DistanceFromEntrance.CompareTo(left.DistanceFromEntrance);
				if (num2 != 0)
				{
					return num2;
				}
				int num3 = right.NormalizedDepth.CompareTo(left.NormalizedDepth);
				if (num3 != 0)
				{
					return num3;
				}
				int num4 = right.TileVolume.CompareTo(left.TileVolume);
				return (num4 != 0) ? num4 : string.Compare(left.StableKey, right.StableKey, StringComparison.Ordinal);
			});
		}

		private static bool TryValidateSpawnPosition(ValidationContext context, Vector3 candidatePosition, out Vector3 validatedPosition)
		{
			//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_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: 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_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_002a: 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_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_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_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: 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_00a7: 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_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_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			validatedPosition = candidatePosition;
			Vector3 val = candidatePosition;
			int collidersAndRoomMask = context.StartOfRound.collidersAndRoomMask;
			RaycastHit val2 = default(RaycastHit);
			if (Physics.Raycast(candidatePosition + Vector3.up * 6f, Vector3.down, ref val2, 16f, collidersAndRoomMask))
			{
				val = ((RaycastHit)(ref val2)).point + Vector3.up * 0.15f;
			}
			if (!context.TryFindContainingTile(val, out Tile _, out Bounds containingBounds))
			{
				Bounds dungeonBounds = context.DungeonBounds;
				if (!((Bounds)(ref dungeonBounds)).Contains(val))
				{
					return false;
				}
				containingBounds = ValidationContext.ExpandedBounds(context.DungeonBounds, 1f);
			}
			if (Vector3.Distance(context.EntrancePosition, val) < GuaranteeApparatusPlugin.MinimumEntranceDistance.Value)
			{
				return false;
			}
			EvaluateReachability(context, val, out var available, out var reachable);
			if (available && !reachable)
			{
				return false;
			}
			if (!available && !((Bounds)(ref containingBounds)).Contains(val))
			{
				return false;
			}
			validatedPosition = val;
			return true;
		}

		private static void EvaluateReachability(ValidationContext context, Vector3 position, out bool available, out bool reachable)
		{
			//IL_0006: 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_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			//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_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Invalid comparison between Unknown and I4
			available = false;
			reachable = false;
			NavMeshHit val = default(NavMeshHit);
			NavMeshHit val2 = default(NavMeshHit);
			if (NavMesh.SamplePosition(position, ref val, 2f, -1) && NavMesh.SamplePosition(context.EntrancePosition, ref val2, 3f, -1))
			{
				available = true;
				NavMeshPath val3 = new NavMeshPath();
				reachable = NavMesh.CalculatePath(((NavMeshHit)(ref val2)).position, ((NavMeshHit)(ref val)).position, -1, val3) && (int)val3.status == 0;
			}
		}

		private static float GetNormalizedDepth(Tile tile)
		{
			object placement = tile.Placement;
			object obj = NormalizedPathDepthField?.GetValue(placement);
			if (obj is float)
			{
				return (float)obj;
			}
			return 0f;
		}

		private static string GetStableTransformPath(Transform transform)
		{
			Stack<string> stack = new Stack<string>();
			Transform val = transform;
			while ((Object)(object)val != (Object)null)
			{
				stack.Push(((Object)val).name);
				val = val.parent;
			}
			return string.Join("/", stack);
		}

		private static int GetStableHash(string value)
		{
			int num = -2128831035;
			for (int i = 0; i < value.Length; i++)
			{
				num ^= value[i];
				num *= 16777619;
			}
			return num;
		}

		private static string FormatVector3(Vector3 vector)
		{
			//IL_0005: 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)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			return $"({vector.x:F2}, {vector.y:F2}, {vector.z:F2})";
		}
	}
	internal readonly struct CustomApparatusDetectionResult
	{
		public bool Detected { get; }

		public string Reason { get; }

		public Transform? ApparatusRoot { get; }

		public string DisplayName { get; }

		public CustomApparatusDetectionResult(bool detected, string reason, Transform? apparatusRoot = null, string? displayName = null)
		{
			Detected = detected;
			Reason = reason;
			ApparatusRoot = apparatusRoot;
			DisplayName = displayName ?? ((apparatusRoot != null) ? ((Object)apparatusRoot).name : null) ?? string.Empty;
		}
	}
	internal interface IKnownCustomInteriorRule
	{
		string RuleId { get; }

		string DisplayName { get; }

		bool Matches(ValidationContext context);

		CustomApparatusDetectionResult DetectCustomApparatus(ValidationContext context);

		bool IsCustomControlledLungProp(ValidationContext context, LungProp lungProp);
	}
	internal static class KnownCustomInteriorRules
	{
		private static readonly IKnownCustomInteriorRule[] Rules = new IKnownCustomInteriorRule[1]
		{
			new LcOfficeRule()
		};

		public static IKnownCustomInteriorRule? Match(ValidationContext context)
		{
			IKnownCustomInteriorRule[] rules = Rules;
			foreach (IKnownCustomInteriorRule knownCustomInteriorRule in rules)
			{
				if (knownCustomInteriorRule.Matches(context))
				{
					return knownCustomInteriorRule;
				}
			}
			return null;
		}
	}
	internal sealed class LcOfficeRule : IKnownCustomInteriorRule
	{
		private const string PluginGuid = "Piggy.LCOffice";

		private const string OfficeModName = "LC Office";

		private const string OfficeElevatorTypeName = "LCOffice.Components.ElevatorSystem";

		private const string OfficeInsertedFieldName = "inserted";

		private const string OfficeSystemPropertyName = "System";

		private const string OfficeLungParentFieldName = "lungParent";

		private static readonly Type? ElevatorSystemType = AccessTools.TypeByName("LCOffice.Components.ElevatorSystem");

		private static readonly PropertyInfo? ElevatorSystemProperty = AccessTools.Property(ElevatorSystemType, "System");

		private static readonly FieldInfo? ElevatorInsertedField = AccessTools.Field(ElevatorSystemType, "inserted");

		private static readonly FieldInfo? ElevatorLungParentField = AccessTools.Field(ElevatorSystemType, "lungParent");

		public string RuleId => "lc_office";

		public string DisplayName => "LC_Office";

		public bool Matches(ValidationContext context)
		{
			if (!Chainloader.PluginInfos.ContainsKey("Piggy.LCOffice"))
			{
				return false;
			}
			if (context.LllContext.IsLoaded && (MatchesOfficeString(context.LllContext.DungeonModName) || MatchesOfficeString(context.LllContext.DungeonUniqueId) || MatchesOfficeString(context.LllContext.DungeonName)))
			{
				return true;
			}
			if (TryFindOfficeItemRoot(context, out Transform officeRoot))
			{
				return (Object)(object)officeRoot != (Object)null;
			}
			if (TryGetElevatorSystemComponent(out Component elevatorSystem) && (Object)(object)elevatorSystem != (Object)null)
			{
				return context.IsInDungeonHierarchy(elevatorSystem.transform);
			}
			return false;
		}

		public CustomApparatusDetectionResult DetectCustomApparatus(ValidationContext context)
		{
			if (TryGetElevatorSystemComponent(out Component elevatorSystem) && (Object)(object)elevatorSystem != (Object)null && context.IsInDungeonHierarchy(elevatorSystem.transform))
			{
				return new CustomApparatusDetectionResult(detected: true, "active LC_Office elevator system marker found", elevatorSystem.transform, ((Object)elevatorSystem).name);
			}
			if (TryFindOfficeItemRoot(context, out Transform officeRoot) && (Object)(object)officeRoot != (Object)null)
			{
				return new CustomApparatusDetectionResult(detected: true, "LC_Office apparatus item found in dungeon", officeRoot, ((Object)officeRoot).name);
			}
			return new CustomApparatusDetectionResult(detected: false, "no LC_Office custom apparatus markers found");
		}

		public bool IsCustomControlledLungProp(ValidationContext context, LungProp lungProp)
		{
			//IL_006c: 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 (IsOfficeApparatusItem(((GrabbableObject)lungProp).itemProperties))
			{
				return true;
			}
			if (!TryGetElevatorSystemComponent(out Component elevatorSystem))
			{
				return false;
			}
			object? obj = ElevatorInsertedField?.GetValue(elevatorSystem);
			LungProp val = (LungProp)((obj is LungProp) ? obj : null);
			if (val != null && val == lungProp)
			{
				return true;
			}
			object? obj2 = ElevatorLungParentField?.GetValue(elevatorSystem);
			Transform val2 = (Transform)((obj2 is Transform) ? obj2 : null);
			if (val2 != null)
			{
				if (((Component)lungProp).transform.IsChildOf(val2))
				{
					return true;
				}
				if (Vector3.Distance(((Component)lungProp).transform.position, val2.position) <= 1.5f)
				{
					return true;
				}
			}
			return false;
		}

		private static bool TryGetElevatorSystemComponent(out Component? elevatorSystem)
		{
			//IL_0026: 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)
			elevatorSystem = null;
			object? obj = ElevatorSystemProperty?.GetValue(null);
			Component val = (Component)((obj is Component) ? obj : null);
			if (val == null)
			{
				return false;
			}
			Scene scene = val.gameObject.scene;
			if (!((Scene)(ref scene)).IsValid())
			{
				return false;
			}
			elevatorSystem = val;
			return true;
		}

		private static bool TryFindOfficeItemRoot(ValidationContext context, out Transform? officeRoot)
		{
			LungProp[] array = context.FindDungeonComponents<LungProp>();
			foreach (LungProp val in array)
			{
				if (IsOfficeApparatusItem(((GrabbableObject)val).itemProperties))
				{
					officeRoot = ((Component)val).transform;
					return true;
				}
			}
			GrabbableObject[] array2 = context.FindDungeonComponents<GrabbableObject>();
			foreach (GrabbableObject val2 in array2)
			{
				if (IsOfficeApparatusItem(val2.itemProperties))
				{
					officeRoot = ((Component)val2).transform;
					return true;
				}
			}
			officeRoot = null;
			return false;
		}

		private static bool IsOfficeApparatusItem(Item? item)
		{
			if ((Object)(object)item == (Object)null)
			{
				return false;
			}
			string text = item.itemName ?? string.Empty;
			string text2 = ((Object)item).name ?? string.Empty;
			if (!text.Contains("apparatus", StringComparison.OrdinalIgnoreCase) && !text2.Contains("apparatus", StringComparison.OrdinalIgnoreCase))
			{
				return false;
			}
			if (text.Contains("office", StringComparison.OrdinalIgnoreCase) || text2.Contains("office", StringComparison.OrdinalIgnoreCase) || text2.Contains("upturned", StringComparison.OrdinalIgnoreCase))
			{
				return true;
			}
			if (LllReflection.TryGetExtendedItemMetadata(item, out string modName, out string uniqueId))
			{
				if (!MatchesOfficeString(modName))
				{
					return MatchesOfficeString(uniqueId);
				}
				return true;
			}
			return false;
		}

		private static bool MatchesOfficeString(string? value)
		{
			if (string.IsNullOrWhiteSpace(value))
			{
				return false;
			}
			if (!value.Contains("LC Office", StringComparison.OrdinalIgnoreCase))
			{
				return value.Contains("office", StringComparison.OrdinalIgnoreCase);
			}
			return true;
		}
	}
	internal sealed class DockedFallbackApparatusController : MonoBehaviour
	{
		private LungProp? _lungProp;

		private Transform? _dockAnchor;

		private Transform? _dockVisualRoot;

		private bool _released;

		public static void Attach(LungProp lungProp, Transform dockAnchor, Transform dockVisualRoot)
		{
			DockedFallbackApparatusController obj = ((Component)lungProp).GetComponent<DockedFallbackApparatusController>() ?? ((Component)lungProp).gameObject.AddComponent<DockedFallbackApparatusController>();
			obj._lungProp = lungProp;
			obj._dockAnchor = dockAnchor;
			obj._dockVisualRoot = dockVisualRoot;
			obj.LockToDock();
		}

		private void LateUpdate()
		{
			if ((Object)(object)_lungProp == (Object)null || (Object)(object)_dockAnchor == (Object)null)
			{
				Object.Destroy((Object)(object)this);
			}
			else if (ShouldRelease())
			{
				ReleaseDock();
			}
			else
			{
				LockToDock();
			}
		}

		private bool ShouldRelease()
		{
			if ((Object)(object)_lungProp == (Object)null || (Object)(object)_dockAnchor == (Object)null)
			{
				return true;
			}
			if (!_lungProp.isLungDocked)
			{
				return true;
			}
			if (((GrabbableObject)_lungProp).isHeld || (Object)(object)((GrabbableObject)_lungProp).playerHeldBy != (Object)null)
			{
				return true;
			}
			if ((Object)(object)((GrabbableObject)_lungProp).parentObject != (Object)null)
			{
				return (Object)(object)((GrabbableObject)_lungProp).parentObject != (Object)(object)_dockAnchor;
			}
			return false;
		}

		private void LockToDock()
		{
			//IL_003f: 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_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_lungProp == (Object)null) && !((Object)(object)_dockAnchor == (Object)null))
			{
				((GrabbableObject)_lungProp).parentObject = _dockAnchor;
				((Component)_lungProp).transform.SetPositionAndRotation(_dockAnchor.position, _dockAnchor.rotation);
				if ((Object)(object)((GrabbableObject)_lungProp).propBody != (Object)null)
				{
					((GrabbableObject)_lungProp).propBody.isKinematic = true;
					((GrabbableObject)_lungProp).propBody.useGravity = false;
					((GrabbableObject)_lungProp).propBody.velocity = Vector3.zero;
					((GrabbableObject)_lungProp).propBody.angularVelocity = Vector3.zero;
				}
				((GrabbableObject)_lungProp).EnableItemMeshes(false);
				if ((Object)(object)_dockVisualRoot != (Object)null)
				{
					((Component)_dockVisualRoot).gameObject.SetActive(true);
				}
			}
		}

		private void ReleaseDock()
		{
			//IL_0075: 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)(object)_lungProp != (Object)null)
			{
				if ((Object)(object)((GrabbableObject)_lungProp).parentObject == (Object)(object)_dockAnchor)
				{
					((GrabbableObject)_lungProp).parentObject = null;
				}
				if ((Object)(object)((GrabbableObject)_lungProp).propBody != (Object)null)
				{
					((GrabbableObject)_lungProp).propBody.isKinematic = false;
					((GrabbableObject)_lungProp).propBody.useGravity = true;
					((GrabbableObject)_lungProp).propBody.velocity = Vector3.zero;
					((GrabbableObject)_lungProp).propBody.angularVelocity = Vector3.zero;
				}
				((GrabbableObject)_lungProp).EnableItemMeshes(true);
			}
			if (!_released && (Object)(object)_dockVisualRoot != (Object)null)
			{
				((Component)_dockVisualRoot).gameObject.SetActive(false);
			}
			_released = true;
			Object.Destroy((Object)(object)this);
		}
	}
	internal sealed class FallbackApparatusFacilityMeltdownBridge : MonoBehaviour
	{
		private LungProp? _lungProp;

		private bool _checked;

		public static void Attach(LungProp lungProp)
		{
			if (FacilityMeltdownCompatibility.IsLoaded)
			{
				(((Component)lungProp).GetComponent<FallbackApparatusFacilityMeltdownBridge>() ?? ((Component)lungProp).gameObject.AddComponent<FallbackApparatusFacilityMeltdownBridge>())._lungProp = lungProp;
			}
		}

		private void Update()
		{
			if (!_checked)
			{
				if ((Object)(object)_lungProp == (Object)null)
				{
					Object.Destroy((Object)(object)this);
				}
				else if (((GrabbableObject)_lungProp).hasBeenHeld || ((GrabbableObject)_lungProp).isHeld || !((Object)(object)((GrabbableObject)_lungProp).playerHeldBy == (Object)null))
				{
					_checked = true;
					FacilityMeltdownCompatibility.TryBeginMeltdownForFallback(_lungProp);
					Object.Destroy((Object)(object)this);
				}
			}
		}
	}
	internal static class FacilityMeltdownCompatibility
	{
		private const string FacilityMeltdownGuid = "me.loaforc.facilitymeltdown";

		private static readonly Type? MeltdownApiType = AccessTools.TypeByName("FacilityMeltdown.API.MeltdownAPI");

		private static readonly Type? MeltdownPluginType = AccessTools.TypeByName("FacilityMeltdown.MeltdownPlugin");

		private static readonly Type? MeltdownAssetsType = AccessTools.TypeByName("FacilityMeltdown.MeltdownAssets");

		private static readonly Type? MeltdownHandlerType = AccessTools.TypeByName("FacilityMeltdown.MeltdownSequence.Behaviours.MeltdownHandler");

		private static readonly PropertyInfo? MeltdownStartedProperty = AccessTools.Property(MeltdownApiType, "MeltdownStarted");

		private static readonly PropertyInfo? AssetsProperty = AccessTools.Property(MeltdownPluginType, "assets");

		private static readonly PropertyInfo? MeltdownHandlerPrefabProperty = AccessTools.Property(MeltdownAssetsType, "meltdownHandlerPrefab");

		private static readonly FieldInfo? CausingLungPropField = AccessTools.Field(MeltdownHandlerType, "causingLungProp");

		public static bool IsLoaded
		{
			get
			{
				if (Chainloader.PluginInfos.ContainsKey("me.loaforc.facilitymeltdown") && MeltdownStartedProperty != null && AssetsProperty != null && MeltdownHandlerPrefabProperty != null && MeltdownHandlerType != null)
				{
					return CausingLungPropField != null;
				}
				return false;
			}
		}

		public static void TryBeginMeltdownForFallback(LungProp lungProp)
		{
			if (!IsLoaded || (Object)(object)lungProp == (Object)null)
			{
				return;
			}
			NetworkManager singleton = NetworkManager.Singleton;
			if ((Object)(object)singleton == (Object)null || !singleton.IsServer || GetMeltdownStarted())
			{
				return;
			}
			object? obj = SafeGetValue(SafeGetValue(null, AssetsProperty), MeltdownHandlerPrefabProperty);
			GameObject val = (GameObject)((obj is GameObject) ? obj : null);
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			GameObject val2 = Object.Instantiate<GameObject>(val);
			Component component = val2.GetComponent(MeltdownHandlerType);
			NetworkObject component2 = val2.GetComponent<NetworkObject>();
			if ((Object)(object)component == (Object)null || (Object)(object)component2 == (Object)null)
			{
				Object.Destroy((Object)(object)val2);
				return;
			}
			CausingLungPropField.SetValue(component, lungProp);
			if (!component2.IsSpawned)
			{
				component2.Spawn(false);
			}
			GuaranteeApparatusPlugin.Verbose("Facility Meltdown compatibility bridge spawned a meltdown handler for fallback apparatus pickup.");
		}

		private static bool GetMeltdownStarted()
		{
			try
			{
				object obj = SafeGetValue(null, MeltdownStartedProperty);
				bool flag = default(bool);
				int num;
				if (obj is bool)
				{
					flag = (bool)obj;
					num = 1;
				}
				else
				{
					num = 0;
				}
				return (byte)((uint)num & (flag ? 1u : 0u)) != 0;
			}
			catch
			{
				return false;
			}
		}

		private static object? SafeGetValue(object? instance, PropertyInfo? property)
		{
			if (property == null)
			{
				return null;
			}
			try
			{
				return property.GetValue(instance);
			}
			catch
			{
				return null;
			}
		}
	}
	internal sealed class LllContext
	{
		public bool IsLoaded { get; set; }

		public bool MetadataUnreliable { get; set; }

		public object? CurrentExtendedDungeon { get; set; }

		public object? CurrentExtendedLevel { get; set; }

		public bool CurrentExtendedDungeonIsCustom { get; set; }

		public string? DungeonModName { get; set; }

		public string? DungeonAuthorName { get; set; }

		public string? DungeonUniqueId { get; set; }

		public string? DungeonName { get; set; }
	}
	internal static class LllReflection
	{
		private const string LllGuid = "imabatby.lethallevelloader";

		private static readonly Type? DungeonManagerType = AccessTools.TypeByName("LethalLevelLoader.DungeonManager");

		private static readonly Type? LevelManagerType = AccessTools.TypeByName("LethalLevelLoader.LevelManager");

		private static readonly Type? PatchedContentType = AccessTools.TypeByName("LethalLevelLoader.PatchedContent");

		private static readonly Type? ExtendedContentType = AccessTools.TypeByName("LethalLevelLoader.ExtendedContent");

		private static readonly Type? ExtendedDungeonFlowType = AccessTools.TypeByName("LethalLevelLoader.ExtendedDungeonFlow");

		private static readonly PropertyInfo? CurrentExtendedDungeonProperty = AccessTools.Property(DungeonManagerType, "CurrentExtendedDungeonFlow");

		private static readonly PropertyInfo? CurrentExtendedLevelProperty = AccessTools.Property(LevelManagerType, "CurrentExtendedLevel");

		private static readonly PropertyInfo? VanillaExtendedDungeonFlowsProperty = AccessTools.Property(PatchedContentType, "VanillaExtendedDungeonFlows");

		private static readonly PropertyInfo? VanillaModProperty = AccessTools.Property(PatchedContentType, "VanillaMod");

		private static readonly FieldInfo? ExtendedItemDictionaryField = AccessTools.Field(PatchedContentType, "ExtendedItemDictionary");

		private static readonly PropertyInfo? ModNameProperty = AccessTools.Property(ExtendedContentType, "ModName");

		private static readonly PropertyInfo? AuthorNameProperty = AccessTools.Property(ExtendedContentType, "AuthorName");

		private static readonly PropertyInfo? UniqueIdentificationNameProperty = AccessTools.Property(ExtendedContentType, "UniqueIdentificationName");

		private static readonly PropertyInfo? DungeonNameProperty = AccessTools.Property(ExtendedDungeonFlowType, "DungeonName");

		public static bool IsLoaded
		{
			get
			{
				if (Chainloader.PluginInfos.ContainsKey("imabatby.lethallevelloader") && DungeonManagerType != null)
				{
					return PatchedContentType != null;
				}
				return false;
			}
		}

		public static LllContext Capture()
		{
			if (!IsLoaded)
			{
				return new LllContext
				{
					IsLoaded = false
				};
			}
			bool metadataUnreliable = false;
			object obj = TryGetPropertyValue(null, CurrentExtendedDungeonProperty, "CurrentExtendedDungeonProperty", ref metadataUnreliable);
			object currentExtendedLevel = TryGetPropertyValue(null, CurrentExtendedLevelProperty, "CurrentExtendedLevelProperty", ref metadataUnreliable);
			string contentString = GetContentString(obj, ModNameProperty, "ModNameProperty", ref metadataUnreliable);
			string contentString2 = GetContentString(obj, AuthorNameProperty, "AuthorNameProperty", ref metadataUnreliable);
			string contentString3 = GetContentString(obj, UniqueIdentificationNameProperty, "UniqueIdentificationNameProperty", ref metadataUnreliable);
			string contentString4 = GetContentString(obj, DungeonNameProperty, "DungeonNameProperty", ref metadataUnreliable);
			return new LllContext
			{
				IsLoaded = true,
				MetadataUnreliable = metadataUnreliable,
				CurrentExtendedDungeon = obj,
				CurrentExtendedLevel = currentExtendedLevel,
				CurrentExtendedDungeonIsCustom = (!metadataUnreliable && IsCustomExtendedDungeon(obj)),
				DungeonModName = contentString,
				DungeonAuthorName = contentString2,
				DungeonUniqueId = contentString3,
				DungeonName = contentString4
			};
		}

		public static bool TryGetExtendedItemMetadata(Item? item, out string? modName, out string? uniqueId)
		{
			modName = null;
			uniqueId = null;
			if (!IsLoaded || (Object)(object)item == (Object)null || ExtendedItemDictionaryField == null)
			{
				return false;
			}
			object value;
			try
			{
				value = ExtendedItemDictionaryField.GetValue(null);
			}
			catch
			{
				return false;
			}
			if (!(value is IDictionary dictionary) || !dictionary.Contains(item))
			{
				return false;
			}
			object obj2 = dictionary[item];
			if (obj2 == null)
			{
				return false;
			}
			bool metadataUnreliable = false;
			modName = GetContentString(obj2, ModNameProperty, "ModNameProperty", ref metadataUnreliable);
			uniqueId = GetContentString(obj2, UniqueIdentificationNameProperty, "UniqueIdentificationNameProperty", ref metadataUnreliable);
			return true;
		}

		public static bool IsVanillaItem(Item? item)
		{
			if ((Object)(object)item == (Object)null)
			{
				return false;
			}
			if (!TryGetExtendedItemMetadata(item, out string modName, out string _))
			{
				return true;
			}
			string vanillaModName = GetVanillaModName();
			if (!string.IsNullOrWhiteSpace(vanillaModName))
			{
				return string.Equals(modName, vanillaModName, StringComparison.OrdinalIgnoreCase);
			}
			return false;
		}

		private static bool IsCustomExtendedDungeon(object? currentExtendedDungeon)
		{
			if (currentExtendedDungeon == null || VanillaExtendedDungeonFlowsProperty == null)
			{
				return false;
			}
			bool metadataUnreliable = false;
			if (!(TryGetPropertyValue(null, VanillaExtendedDungeonFlowsProperty, "VanillaExtendedDungeonFlowsProperty", ref metadataUnreliable) is IEnumerable enumerable))
			{
				return false;
			}
			try
			{
				foreach (object item in enumerable)
				{
					if (item == currentExtendedDungeon)
					{
						return false;
					}
				}
			}
			catch
			{
				return false;
			}
			return true;
		}

		private static string? GetVanillaModName()
		{
			bool metadataUnreliable = false;
			object? obj = TryGetPropertyValue(null, VanillaModProperty, "VanillaModProperty", ref metadataUnreliable);
			PropertyInfo property = AccessTools.Property(obj?.GetType(), "ModName");
			return GetContentString(obj, property, "VanillaMod.ModName", ref metadataUnreliable);
		}

		private static string? GetContentString(object? instance, PropertyInfo? property, string propertyName, ref bool metadataUnreliable)
		{
			return TryGetPropertyValue(instance, property, propertyName, ref metadataUnreliable) as string;
		}

		private static object? TryGetPropertyValue(object? instance, PropertyInfo? property, string propertyName, ref bool metadataUnreliable)
		{
			if (property == null)
			{
				metadataUnreliable = true;
				return null;
			}
			try
			{
				return property.GetValue(instance);
			}
			catch
			{
				metadataUnreliable = true;
				GuaranteeApparatusPlugin.Verbose("LLL reflection failed while reading '" + propertyName + "'.");
				return null;
			}
		}
	}
	[BepInPlugin("squirt.guaranteeapparatus", "GuaranteeApparatus", "1.0.0")]
	public sealed class GuaranteeApparatusPlugin : BaseUnityPlugin
	{
		internal const string PluginGuid = "squirt.guaranteeapparatus";

		internal const string PluginName = "GuaranteeApparatus";

		internal const string PluginVersion = "1.0.0";

		internal static ManualLogSource Log;

		internal static ConfigEntry<bool> Enabled;

		internal static ConfigEntry<bool> VerboseLogging;

		internal static ConfigEntry<bool> RespectCustomApparatus;

		internal static ConfigEntry<bool> RespectUnknownCustomApparatus;

		internal static ConfigEntry<bool> SpawnFallbackWhenUnknownCustomHasNoDetectedApparatus;

		internal static ConfigEntry<bool> GenerateScanNodesForDetectedCustomApparatus;

		internal static ConfigEntry<bool> ForceVanillaFallbackOnKnownCustomInteriors;

		internal static ConfigEntry<bool> EnableVanillaSetpieceFallback;

		internal static ConfigEntry<float> MinimumEntranceDistance;

		internal static ConfigEntry<string> FactoryFlowPatterns;

		private Harmony? _harmony;

		internal static bool HasSpawnedFallbackThisRound { get; set; }

		private void Awake()
		{
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Enable GuaranteeApparatus.");
			VerboseLogging = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "VerboseLogging", false, "Enable verbose logging for classification and validation details.");
			RespectCustomApparatus = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "RespectCustomApparatus", true, "When enabled, known custom apparatus systems suppress fallback by default.");
			RespectUnknownCustomApparatus = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "RespectUnknownCustomApparatus", true, "When enabled, detected unknown custom apparatuses suppress fallback by default.");
			SpawnFallbackWhenUnknownCustomHasNoDetectedApparatus = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "SpawnFallbackWhenUnknownCustomHasNoDetectedApparatus", true, "Allow vanilla fallback inside unknown custom interiors when no plausible custom apparatus is detected.");
			GenerateScanNodesForDetectedCustomApparatus = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "GenerateScanNodesForDetectedCustomApparatus", true, "Generate scan-node support for detected custom apparatuses when they lack discoverability metadata.");
			ForceVanillaFallbackOnKnownCustomInteriors = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ForceVanillaFallbackOnKnownCustomInteriors", false, "Force vanilla fallback inside known custom interiors when no valid vanilla apparatus is found.");
			EnableVanillaSetpieceFallback = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "EnableVanillaSetpieceFallback", false, "Deprecated. The fallback now always prefers a strict vanilla LungMachine setpiece sourced from factory tile prefabs, so this setting is ignored.");
			MinimumEntranceDistance = ((BaseUnityPlugin)this).Config.Bind<float>("General", "MinimumEntranceDistance", 10f, "Minimum distance from the main dungeon entrance required for fallback placement.");
			FactoryFlowPatterns = ((BaseUnityPlugin)this).Config.Bind<string>("General", "FactoryFlowPatterns", "factory,facility,level1flow,level2flow", "Comma-separated flow name fragments treated as factory-like for diagnostics.");
			_harmony = new Harmony("squirt.guaranteeapparatus");
			_harmony.PatchAll(typeof(RoundManagerPatches));
			Log.LogInfo((object)"GuaranteeApparatus 1.0.0 loaded.");
		}

		internal static void Verbose(string message)
		{
			if (VerboseLogging.Value)
			{
				Log.LogInfo((object)message);
			}
		}
	}
	internal static class RoundManagerPatches
	{
		[HarmonyPatch(typeof(RoundManager), "GenerateNewFloor")]
		[HarmonyPrefix]
		private static void GenerateNewFloorPrefix(RoundManager __instance)
		{
			GuaranteeApparatusPlugin.HasSpawnedFallbackThisRound = false;
			SafeRun("GenerateNewFloorPrefix/ScanNodeSupportService.EnsureMessagingReady", ScanNodeSupportService.EnsureMessagingReady);
			SafeRun("GenerateNewFloorPrefix/VanillaApparatusSetpieceService.EnsureMessagingReady", VanillaApparatusSetpieceService.EnsureMessagingReady);
		}

		[HarmonyPatch(typeof(RoundManager), "GeneratedFloorPostProcessing")]
		[HarmonyPostfix]
		private static void GeneratedFloorPostProcessingPostfix(RoundManager __instance)
		{
			RoundManager __instance2 = __instance;
			SafeRun("GeneratedFloorPostProcessing/ScanNodeSupportService.EnsureMessagingReady", ScanNodeSupportService.EnsureMessagingReady);
			SafeRun("GeneratedFloorPostProcessing/ScanNodeSupportService.TryResolvePending", delegate
			{
				ScanNodeSupportService.TryResolvePending(__instance2);
			});
			SafeRun("GeneratedFloorPostProcessing/VanillaApparatusSetpieceService.EnsureMessagingReady", VanillaApparatusSetpieceService.EnsureMessagingReady);
			SafeRun("GeneratedFloorPostProcessing/VanillaApparatusSetpieceService.TryResolvePending", VanillaApparatusSetpieceService.TryResolvePending);
			SafeRun("GeneratedFloorPostProcessing/ApparatusValidator.Evaluate", delegate
			{
				ApparatusValidator.Evaluate(__instance2);
			});
		}

		private static void SafeRun(string operationName, Action action)
		{
			try
			{
				action();
			}
			catch (Exception ex)
			{
				GuaranteeApparatusPlugin.Log.LogWarning((object)(operationName + " failed; continuing without that step. " + ex.GetType().Name + ": " + ex.Message));
			}
		}
	}
	internal sealed class GuaranteeApparatusScanNodeMarker : MonoBehaviour
	{
		public string RelativeDungeonPath = string.Empty;
	}
	internal sealed class GuaranteeApparatusPendingScanNodeResolver : MonoBehaviour
	{
		private void Update()
		{
			ScanNodeSupportService.TryResolvePendingForActiveRound();
		}
	}
	internal enum ScanNodeSupportOutcome
	{
		Failed,
		AlreadyPresent,
		Generated
	}
	internal readonly struct ScanNodeDescriptor
	{
		public bool UseNetworkObjectLookup { get; }

		public ulong NetworkObjectId { get; }

		public string RelativeDungeonPath { get; }

		public string HeaderText { get; }

		public string SubText { get; }

		public int MinRange { get; }

		public int MaxRange { get; }

		public bool RequiresLineOfSight { get; }

		public int NodeType { get; }

		public ScanNodeDescriptor(bool useNetworkObjectLookup, ulong networkObjectId, string relativeDungeonPath, string headerText, string subText, int minRange, int maxRange, bool requiresLineOfSight, int nodeType)
		{
			UseNetworkObjectLookup = useNetworkObjectLookup;
			NetworkObjectId = networkObjectId;
			RelativeDungeonPath = relativeDungeonPath;
			HeaderText = headerText;
			SubText = subText;
			MinRange = minRange;
			MaxRange = maxRange;
			RequiresLineOfSight = requiresLineOfSight;
			NodeType = nodeType;
		}
	}
	internal static class ScanNodeSupportService
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static HandleNamedMessageDelegate <0>__OnScanNodeMessageReceived;
		}

		private const string MessageName = "GuaranteeApparatus/ScanNode";

		private const string HelperObjectName = "GuaranteeApparatusScanNode";

		private const string ResolverObjectName = "GuaranteeApparatusPendingScanNodeResolver";

		private static readonly List<ScanNodeDescriptor> PendingDescriptors = new List<ScanNodeDescriptor>();

		private static NetworkManager? _registeredManager;

		private static bool _messageHandlerRegistered;

		private static GuaranteeApparatusPendingScanNodeResolver? _resolver;

		public static void EnsureMessagingReady()
		{
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Expected O, but got Unknown
			EnsureResolver();
			NetworkManager singleton = NetworkManager.Singleton;
			if (!((Object)(object)singleton == (Object)null) && singleton.CustomMessagingManager != null && (_registeredManager != singleton || !_messageHandlerRegistered))
			{
				if ((Object)(object)_registeredManager != (Object)null && _messageHandlerRegistered && _registeredManager.CustomMessagingManager != null)
				{
					_registeredManager.CustomMessagingManager.UnregisterNamedMessageHandler("GuaranteeApparatus/ScanNode");
				}
				CustomMessagingManager customMessagingManager = singleton.CustomMessagingManager;
				object obj = <>O.<0>__OnScanNodeMessageReceived;
				if (obj == null)
				{
					HandleNamedMessageDelegate val = OnScanNodeMessageReceived;
					<>O.<0>__OnScanNodeMessageReceived = val;
					obj = (object)val;
				}
				customMessagingManager.RegisterNamedMessageHandler("GuaranteeApparatus/ScanNode", (HandleNamedMessageDelegate)obj);
				_registeredManager = singleton;
				_messageHandlerRegistered = true;
			}
		}

		public static void TryResolvePending(RoundManager roundManager)
		{
			if (PendingDescriptors.Count == 0)
			{
				return;
			}
			for (int num = PendingDescriptors.Count - 1; num >= 0; num--)
			{
				ScanNodeDescriptor descriptor = PendingDescriptors[num];
				if (TryApplyDescriptor(roundManager, descriptor, out var _))
				{
					PendingDescriptors.RemoveAt(num);
				}
			}
		}

		public static void TryResolvePendingForActiveRound()
		{
			if (PendingDescriptors.Count != 0)
			{
				RoundManager val = Object.FindObjectOfType<RoundManager>();
				if ((Object)(object)val != (Object)null)
				{
					TryResolvePending(val);
				}
			}
		}

		public static ScanNodeSupportOutcome EnsureCustomScanSupport(ValidationContext context, DetectedCustomApparatusCandidate candidate)
		{
			if (!GuaranteeApparatusPlugin.GenerateScanNodesForDetectedCustomApparatus.Value || (Object)(object)candidate.RootTransform == (Object)null || !context.IsInDungeonHierarchy(candidate.RootTransform))
			{
				return ScanNodeSupportOutcome.Failed;
			}
			ScanNodeDescriptor descriptor = BuildCustomDescriptor(candidate);
			return EnsureDescriptor(candidate.RootTransform, descriptor);
		}

		public static ScanNodeSupportOutcome EnsureFallbackScanSupport(LungProp lungProp, string relativeDungeonPath)
		{
			NetworkObject val = (((Object)(object)lungProp != (Object)null) ? ((Component)lungProp).GetComponent<NetworkObject>() : null);
			if ((Object)(object)lungProp == (Object)null || (Object)(object)val == (Object)null || !val.IsSpawned)
			{
				return ScanNodeSupportOutcome.Failed;
			}
			ScanNodeDescriptor descriptor = BuildFallbackDescriptor(lungProp, val.NetworkObjectId, relativeDungeonPath);
			return EnsureFallbackDescriptor(((Component)lungProp).transform, descriptor);
		}

		private static void OnScanNodeMessageReceived(ulong senderClientId, FastBufferReader reader)
		{
			//IL_002a: 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_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_006e: 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_0081: 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_0094: 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)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			bool useNetworkObjectLookup = false;
			ulong networkObjectId = 0uL;
			string empty = string.Empty;
			string empty2 = string.Empty;
			string empty3 = string.Empty;
			int minRange = 0;
			int maxRange = 0;
			bool requiresLineOfSight = false;
			int nodeType = 0;
			((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref useNetworkObjectLookup, default(ForPrimitives));
			((FastBufferReader)(ref reader)).ReadValueSafe<ulong>(ref networkObjectId, default(ForPrimitives));
			((FastBufferReader)(ref reader)).ReadValueSafe(ref empty, true);
			((FastBufferReader)(ref reader)).ReadValueSafe(ref empty2, true);
			((FastBufferReader)(ref reader)).ReadValueSafe(ref empty3, true);
			((FastBufferReader)(ref reader)).ReadValueSafe<int>(ref minRange, default(ForPrimitives));
			((FastBufferReader)(ref reader)).ReadValueSafe<int>(ref maxRange, default(ForPrimitives));
			((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref requiresLineOfSight, default(ForPrimitives));
			((FastBufferReader)(ref reader)).ReadValueSafe<int>(ref nodeType, default(ForPrimitives));
			ScanNodeDescriptor scanNodeDescriptor = new ScanNodeDescriptor(useNetworkObjectLookup, networkObjectId, empty, empty2, empty3, minRange, maxRange, requiresLineOfSight, nodeType);
			if (!TryApplyDescriptor(Object.FindObjectOfType<RoundManager>(), scanNodeDescriptor, out var _))
			{
				PendingDescriptors.Add(scanNodeDescriptor);
			}
		}

		private static void SendDescriptorToAll(ScanNodeDescriptor descriptor)
		{
			//IL_0040: 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)
			//IL_005b: 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_00a3: 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_00be: 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_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: 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_00f9: 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)
			NetworkManager singleton = NetworkManager.Singleton;
			if ((Object)(object)singleton == (Object)null || !singleton.IsServer || singleton.CustomMessagingManager == null)
			{
				return;
			}
			FastBufferWriter val = default(FastBufferWriter);
			((FastBufferWriter)(ref val))..ctor(2048, (Allocator)2, 2048);
			try
			{
				bool useNetworkObjectLookup = descriptor.UseNetworkObjectLookup;
				((FastBufferWriter)(ref val)).WriteValueSafe<bool>(ref useNetworkObjectLookup, default(ForPrimitives));
				ulong networkObjectId = descriptor.NetworkObjectId;
				((FastBufferWriter)(ref val)).WriteValueSafe<ulong>(ref networkObjectId, default(ForPrimitives));
				((FastBufferWriter)(ref val)).WriteValueSafe(descriptor.RelativeDungeonPath, true);
				((FastBufferWriter)(ref val)).WriteValueSafe(descriptor.HeaderText, true);
				((FastBufferWriter)(ref val)).WriteValueSafe(descriptor.SubText, true);
				int minRange = descriptor.MinRange;
				((FastBufferWriter)(ref val)).WriteValueSafe<int>(ref minRange, default(ForPrimitives));
				minRange = descriptor.MaxRange;
				((FastBufferWriter)(ref val)).WriteValueSafe<int>(ref minRange, default(ForPrimitives));
				useNetworkObjectLookup = descriptor.RequiresLineOfSight;
				((FastBufferWriter)(ref val)).WriteValueSafe<bool>(ref useNetworkObjectLookup, default(ForPrimitives));
				minRange = descriptor.NodeType;
				((FastBufferWriter)(ref val)).WriteValueSafe<int>(ref minRange, default(ForPrimitives));
				singleton.CustomMessagingManager.SendNamedMessageToAll("GuaranteeApparatus/ScanNode", val, (NetworkDelivery)2);
			}
			finally
			{
				((IDisposable)(FastBufferWriter)(ref val)).Dispose();
			}
		}

		private static ScanNodeDescriptor BuildCustomDescriptor(DetectedCustomApparatusCandidate candidate)
		{
			string headerText = (string.IsNullOrWhiteSpace(candidate.DisplayName) ? "Custom Apparatus" : candidate.DisplayName);
			string subText = ((candidate.Classification == InteriorClassification.KnownCustom) ? "Known Custom Apparatus" : "Unknown Custom Apparatus");
			return new ScanNodeDescriptor(useNetworkObjectLookup: false, 0uL, candidate.RelativeDungeonPath, headerText, subText, 0, 30, requiresLineOfSight: false, 0);
		}

		private static ScanNodeDescriptor BuildFallbackDescriptor(LungProp lungProp, ulong networkObjectId, string relativeDungeonPath)
		{
			string headerText = (string.IsNullOrWhiteSpace(((GrabbableObject)lungProp).itemProperties?.itemName) ? "Apparatus" : ((GrabbableObject)lungProp).itemProperties.itemName);
			return new ScanNodeDescriptor(useNetworkObjectLookup: true, networkObjectId, relativeDungeonPath, headerText, "Fallback Vanilla Apparatus", 0, 30, requiresLineOfSight: false, 0);
		}

		private static ScanNodeSupportOutcome EnsureDescriptor(Transform localTargetRoot, ScanNodeDescriptor descriptor)
		{
			if (HasExistingScanSupport(localTargetRoot))
			{
				return ScanNodeSupportOutcome.AlreadyPresent;
			}
			if (!TryApplyDescriptorToResolvedTarget(localTargetRoot, descriptor, out var generatedScanNode) || !generatedScanNode)
			{
				return ScanNodeSupportOutcome.Failed;
			}
			EnsureMessagingReady();
			SendDescriptorToAll(descriptor);
			return ScanNodeSupportOutcome.Generated;
		}

		private static ScanNodeSupportOutcome EnsureFallbackDescriptor(Transform localTargetRoot, ScanNodeDescriptor descriptor)
		{
			Transform val = SelectAttachmentTransform(localTargetRoot);
			bool num = (Object)(object)((Component)val).GetComponent<GuaranteeApparatusScanNodeMarker>() != (Object)null;
			EnsureMarker(((Component)val).gameObject, descriptor.RelativeDungeonPath);
			ApplyScanNodeComponent(((Component)val).gameObject, descriptor);
			if ((Object)(object)((Component)val).GetComponent<Collider>() == (Object)null && (Object)(object)((Component)val).GetComponent<Renderer>() == (Object)null)
			{
				EnsureHelperCollider(((Component)val).gameObject, localTargetRoot);
			}
			EnsureMessagingReady();
			SendDescriptorToAll(descriptor);
			if (!num)
			{
				return ScanNodeSupportOutcome.Generated;
			}
			return ScanNodeSupportOutcome.AlreadyPresent;
		}

		private static bool TryApplyDescriptor(RoundManager? roundManager, ScanNodeDescriptor descriptor, out bool generatedScanNode)
		{
			generatedScanNode = false;
			if (!TryResolveTargetTransform(roundManager, descriptor, out Transform targetRoot) || (Object)(object)targetRoot == (Object)null)
			{
				return false;
			}
			if (descriptor.UseNetworkObjectLookup)
			{
				Transform val = SelectAttachmentTransform(targetRoot);
				bool flag = (Object)(object)((Component)val).GetComponent<GuaranteeApparatusScanNodeMarker>() != (Object)null;
				EnsureMarker(((Component)val).gameObject, descriptor.RelativeDungeonPath);
				ApplyScanNodeComponent(((Component)val).gameObject, descriptor);
				if ((Object)(object)((Component)val).GetComponent<Collider>() == (Object)null && (Object)(object)((Component)val).GetComponent<Renderer>() == (Object)null)
				{
					EnsureHelperCollider(((Component)val).gameObject, targetRoot);
				}
				generatedScanNode = !flag;
				return true;
			}
			return TryApplyDescriptorToResolvedTarget(targetRoot, descriptor, out generatedScanNode);
		}

		private static bool TryResolveTargetTransform(RoundManager? roundManager, ScanNodeDescriptor descriptor, out Transform? targetRoot)
		{
			if (descriptor.UseNetworkObjectLookup)
			{
				NetworkManager singleton = NetworkManager.Singleton;
				if ((Object)(object)singleton != (Object)null && singleton.SpawnManager != null && singleton.SpawnManager.SpawnedObjects.TryGetValue(descriptor.NetworkObjectId, out var value) && (Object)(object)value != (Object)null)
				{
					targetRoot = ((Component)value).transform;
					return true;
				}
			}
			if ((Object)(object)roundManager == (Object)null || (Object)(object)roundManager.dungeonGenerator == (Object)null || roundManager.dungeonGenerator.Generator == null)
			{
				targetRoot = null;
				return false;
			}
			Dungeon currentDungeon = roundManager.dungeonGenerator.Generator.CurrentDungeon;
			if ((Object)(object)currentDungeon == (Object)null)
			{
				targetRoot = null;
				return false;
			}
			return TryFindByRelativePath(((Component)currentDungeon).transform, descriptor.RelativeDungeonPath, out targetRoot);
		}

		private static bool TryApplyDescriptorToResolvedTarget(Transform targetRoot, ScanNodeDescriptor descriptor, out bool generatedScanNode)
		{
			generatedScanNode = false;
			if (HasExistingScanSupport(targetRoot))
			{
				return true;
			}
			Transform val = SelectAttachmentTransform(targetRoot);
			if (CanAttachDirectly(val))
			{
				EnsureMarker(((Component)val).gameObject, descriptor.RelativeDungeonPath);
				ApplyScanNodeComponent(((Component)val).gameObject, descriptor);
				generatedScanNode = true;
				return true;
			}
			GameObject orCreateHelperObject = GetOrCreateHelperObject(targetRoot, descriptor.RelativeDungeonPath);
			ApplyScanNodeComponent(orCreateHelperObject, descriptor);
			EnsureHelperCollider(orCreateHelperObject, targetRoot);
			generatedScanNode = true;
			return true;
		}

		private static bool HasExistingScanSupport(Transform rootTransform)
		{
			//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)
			if (((Component)rootTransform).GetComponentsInChildren<GuaranteeApparatusScanNodeMarker>(true).Length != 0)
			{
				return true;
			}
			ScanNodeProperties[] componentsInChildren = ((Component)rootTransform).GetComponentsInChildren<ScanNodeProperties>(true);
			foreach (ScanNodeProperties val in componentsInChildren)
			{
				if ((Object)(object)val != (Object)null)
				{
					Scene scene = ((Component)val).gameObject.scene;
					if (((Scene)(ref scene)).IsValid() && ((Behaviour)val).isActiveAndEnabled)
					{
						return true;
					}
				}
			}
			return false;
		}

		private static void EnsureResolver()
		{
			//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_0034: Expected O, but got Unknown
			if (!((Object)(object)_resolver != (Object)null))
			{
				GuaranteeApparatusPendingScanNodeResolver guaranteeApparatusPendingScanNodeResolver = Object.FindObjectOfType<GuaranteeApparatusPendingScanNodeResolver>();
				if ((Object)(object)guaranteeApparatusPendingScanNodeResolver != (Object)null)
				{
					_resolver = guaranteeApparatusPendingScanNodeResolver;
					return;
				}
				GameObject val = new GameObject("GuaranteeApparatusPendingScanNodeResolver");
				Object.DontDestroyOnLoad((Object)val);
				_resolver = val.AddComponent<GuaranteeApparatusPendingScanNodeResolver>();
			}
		}

		private static Transform SelectAttachmentTransform(Transform targetRoot)
		{
			Transform targetRoot2 = targetRoot;
			Transform[] componentsInChildren = ((Component)targetRoot2).GetComponentsInChildren<Transform>(true);
			Array.Sort(componentsInChildren, (Transform left, Transform right) => string.Compare(GetRelativePath(left, targetRoot2), GetRelativePath(right, targetRoot2), StringComparison.Ordinal));
			Transform val = null;
			Transform val2 = null;
			GrabbableObject val4 = default(GrabbableObject);
			InteractTrigger val5 = default(InteractTrigger);
			TerminalAccessibleObject val6 = default(TerminalAccessibleObject);
			foreach (Transform val3 in componentsInChildren)
			{
				if (((Component)val3).TryGetComponent<GrabbableObject>(ref val4) || ((Component)val3).TryGetComponent<InteractTrigger>(ref val5) || ((Component)val3).TryGetComponent<TerminalAccessibleObject>(ref val6))
				{
					return val3;
				}
				if ((Object)(object)val == (Object)null && (Object)(object)((Component)val3).GetComponent<Collider>() != (Object)null)
				{
					val = val3;
				}
				if ((Object)(object)val2 == (Object)null && (Object)(object)((Component)val3).GetComponent<Renderer>() != (Object)null)
				{
					val2 = val3;
				}
			}
			return val ?? val2 ?? targetRoot2;
		}

		private static bool CanAttachDirectly(Transform attachmentTransform)
		{
			GrabbableObject val = default(GrabbableObject);
			InteractTrigger val2 = default(InteractTrigger);
			TerminalAccessibleObject val3 = default(TerminalAccessibleObject);
			if (!((Component)attachmentTransform).TryGetComponent<GrabbableObject>(ref val) && !((Component)attachmentTransform).TryGetComponent<InteractTrigger>(ref val2) && !((Component)attachmentTransform).TryGetComponent<TerminalAccessibleObject>(ref val3) && !((Object)(object)((Component)attachmentTransform).GetComponent<Collider>() != (Object)null))
			{
				return (Object)(object)((Component)attachmentTransform).GetComponent<Renderer>() != (Object)null;
			}
			return true;
		}

		private static void EnsureMarker(GameObject gameObject, string relativeDungeonPath)
		{
			(gameObject.GetComponent<GuaranteeApparatusScanNodeMarker>() ?? gameObject.AddComponent<GuaranteeApparatusScanNodeMarker>()).RelativeDungeonPath = relativeDungeonPath;
		}

		private static void ApplyScanNodeComponent(GameObject gameObject, ScanNodeDescriptor descriptor)
		{
			ScanNodeProperties obj = gameObject.GetComponent<ScanNodeProperties>() ?? gameObject.AddComponent<ScanNodeProperties>();
			obj.headerText = descriptor.HeaderText;
			obj.subText = descriptor.SubText;
			obj.minRange = descriptor.MinRange;
			obj.maxRange = descriptor.MaxRange;
			obj.requiresLineOfSight = descriptor.RequiresLineOfSight;
			obj.nodeType = descriptor.NodeType;
			obj.scrapValue = 0;
			obj.creatureScanID = -1;
		}

		private static GameObject GetOrCreateHelperObject(Transform targetRoot, string relativeDungeonPath)
		{
			//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_0050: 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_0060: 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)
			//IL_0070: 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_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Expected O, but got Unknown
			//IL_0099: Expected O, but got Unknown
			GuaranteeApparatusScanNodeMarker[] componentsInChildren = ((Component)targetRoot).GetComponentsInChildren<GuaranteeApparatusScanNodeMarker>(true);
			foreach (GuaranteeApparatusScanNodeMarker guaranteeApparatusScanNodeMarker in componentsInChildren)
			{
				if (!((Object)(object)guaranteeApparatusScanNodeMarker == (Object)null) && string.Equals(guaranteeApparatusScanNodeMarker.RelativeDungeonPath, relativeDungeonPath, StringComparison.Ordinal))
				{
					return ((Component)guaranteeApparatusScanNodeMarker).gameObject;
				}
			}
			GameObject val = new GameObject("GuaranteeApparatusScanNode");
			val.transform.SetParent(targetRoot, false);
			val.transform.localPosition = Vector3.zero;
			val.transform.localRotation = Quaternion.identity;
			val.transform.localScale = Vector3.one;
			val.layer = ((Component)targetRoot).gameObject.layer;
			EnsureMarker(val, relativeDungeonPath);
			return val;
		}

		private static void EnsureHelperCollider(GameObject helperObject, Transform targetRoot)
		{
			SphereCollider obj = helperObject.GetComponent<SphereCollider>() ?? helperObject.AddComponent<SphereCollider>();
			((Collider)obj).isTrigger = true;
			obj.radius = 0.35f;
			helperObject.layer = ((Component)targetRoot).gameObject.layer;
		}

		private static string GetRelativePath(Transform transform, Transform rootTransform)
		{
			if ((Object)(object)transform == (Object)(object)rootTransform)
			{
				return string.Empty;
			}
			Stack<string> stack = new Stack<string>();
			Transform val = transform;
			while ((Object)(object)val != (Object)null && (Object)(object)val != (Object)(object)rootTransform)
			{
				stack.Push(((Object)val).name);
				val = val.parent;
			}
			return string.Join("/", stack);
		}

		private static bool TryFindByRelativePath(Transform rootTransform, string relativePath, out Transform? foundTransform)
		{
			if (string.IsNullOrWhiteSpace(relativePath))
			{
				foundTransform = null;
				return false;
			}
			string[] array = relativePath.Split('/');
			Transform val = rootTransform;
			foreach (string b in array)
			{
				Transform val2 = null;
				int childCount = val.childCount;
				for (int j = 0; j < childCount; j++)
				{
					Transform child = val.GetChild(j);
					if (string.Equals(((Object)child).name, b, StringComparison.Ordinal))
					{
						val2 = child;
						break;
					}
				}
				if ((Object)(object)val2 == (Object)null)
				{
					foundTransform = null;
					return false;
				}
				val = val2;
			}
			foundTransform = val;
			return (Object)(object)foundTransform != (Object)null;
		}
	}
	internal sealed class DetectedCustomApparatusCandidate
	{
		public InteriorClassification Classification { get; }

		public string SourceId { get; }

		public string SourceDisplayName { get; }

		public Transform RootTransform { get; }

		public string RelativeDungeonPath { get; }

		public string DisplayName { get; }

		public string Reason { get; }

		public int Score { get; }

		public DetectedCustomApparatusCandidate(InteriorClassification classification, string sourceId, string sourceDisplayName, Transform rootTransform, string relativeDungeonPath, string displayName, string reason, int score)
		{
			Classification = classification;
			SourceId = sourceId;
			SourceDisplayName = sourceDisplayName;
			RootTransform = rootTransform;
			RelativeDungeonPath = relativeDungeonPath;
			DisplayName = displayName;
			Reason = reason;
			Score = score;
		}

		public bool ControlsTransform(Transform transform)
		{
			if (!((Object)(object)transform == (Object)(object)RootTransform))
			{
				return transform.IsChildOf(RootTransform);
			}
			return true;
		}
	}
	internal readonly struct SignalEvidence
	{
		public string Key { get; }

		public string Reason { get; }

		public SignalEvidence(string key, string reason)
		{
			Key = key;
			Reason = reason;
		}
	}
	internal readonly struct RootCandidateGroup
	{
		public Transform RootTransform { get; }

		public string RelativeDungeonPath { get; }

		public RootCandidateGroup(Transform rootTransform, string relativeDungeonPath)
		{
			RootTransform = rootTransform;
			RelativeDungeonPath = relativeDungeonPath;
		}
	}
	internal static class UnknownCustomApparatusDiscovery
	{
		private static readonly string[] PrimaryTokens = new string[7] { "apparatus", "lung", "generator", "socket", "upturned", "power", "core" };

		private static readonly string[] PowerTokens = new string[11]
		{
			"power", "generator", "socket", "breaker", "battery", "reactor", "charge", "switch", "fuse", "core",
			"elevator"
		};

		private static readonly string[] VariantTokens = new string[6] { "off", "disabled", "inactive", "turnedoff", "turned_off", "turned-off" };

		private const int MaxGroupedRootsPerScan = 100;

		public static bool TryDiscover(ValidationContext context, out DetectedCustomApparatusCandidate? detectedCandidate)
		{
			List<RootCandidateGroup> list = BuildRootCandidateGroups(context);
			for (int i = 0; i < list.Count; i++)
			{
				if (TryEvaluateGroup(context, list[i], out DetectedCustomApparatusCandidate detectedCandidate2))
				{
					DetectedCustomApparatusCandidate detectedCustomApparatusCandidate = (detectedCandidate = detectedCandidate2);
					Guara

BepInEx/plugins/GUILTY-ChaseMechanic/AdrenalineRush.dll

Decompiled a month 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.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using Hypick.AdrenalineRush.NetcodePatcher;
using Microsoft.CodeAnalysis;
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: IgnoresAccessChecksTo("")]
[assembly: AssemblyCompany("Hypick.AdrenalineRush")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.1.0")]
[assembly: AssemblyInformationalVersion("1.0.1+72a3a75c61550d06466a210a2037d9c74edca775")]
[assembly: AssemblyProduct("AdrenalineRush")]
[assembly: AssemblyTitle("Hypick.AdrenalineRush")]
[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.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace Hypick
{
	[BepInPlugin("Hypick.AdrenalineRush", "AdrenalineRush", "1.0.0")]
	public class Plugin : BaseUnityPlugin
	{
		public static PluginConfig Config;

		private readonly Harmony _harmony = new Harmony("Hypick.AdrenalineRush");

		public static Plugin Instance { get; set; }

		public static ManualLogSource Log => ((BaseUnityPlugin)Instance).Logger;

		public Plugin()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			Instance = this;
		}

		private void Awake()
		{
			Config = new PluginConfig(((BaseUnityPlugin)this).Config);
			Log.LogInfo((object)"Applying patches...");
			_harmony.PatchAll();
			Log.LogInfo((object)"Patches applied");
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Hypick.AdrenalineRush is fully loaded!");
		}
	}
	public static class Category
	{
		public const string General = "1 >> General << 1";
	}
	public class PluginConfig
	{
		public float Multiplier { get; }

		public bool ChangeSpeed { get; }

		public float MaxSpeed { get; }

		public bool ChangeFOV { get; }

		public float MaxFOV { get; }

		public PluginConfig(ConfigFile cfg)
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Expected O, but got Unknown
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Expected O, but got Unknown
			Multiplier = cfg.Bind<float>("1 >> General << 1", "Multiplier", 200f, new ConfigDescription("multiplier to increase the player's speed and FOV (formula: fearLevel * (multiplier / 100))", (AcceptableValueBase)(object)new AcceptableValueRange<float>(150f, 999f), Array.Empty<object>())).Value;
			ChangeSpeed = cfg.Bind<bool>("1 >> General << 1", "ChangeSpeed", true, "Should the player's running speed increase when entering fear?").Value;
			MaxSpeed = cfg.Bind<float>("1 >> General << 1", "MaxSpeed", 2.5f, "Maximum speed to increase").Value;
			ChangeFOV = cfg.Bind<bool>("1 >> General << 1", "ChangeFOV", true, "Should the player's FOV increase when entering fear?").Value;
			MaxFOV = cfg.Bind<float>("1 >> General << 1", "MaxFOV", 130f, new ConfigDescription("Maximum FOV to increase", (AcceptableValueBase)(object)new AcceptableValueRange<float>(66f, 130f), Array.Empty<object>())).Value;
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "Hypick.AdrenalineRush";

		public const string PLUGIN_NAME = "AdrenalineRush";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}
namespace Hypick.Patches
{
	[HarmonyPatch(typeof(PlayerControllerB))]
	internal class PlayerControllerBPatch
	{
		[HarmonyPatch("Update")]
		[HarmonyPrefix]
		private static void Update(PlayerControllerB __instance, ref StartOfRound ___playersManager)
		{
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: 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_0147: Unknown result type (might be due to invalid IL or missing references)
			if (!(___playersManager.fearLevel >= 0.4f))
			{
				return;
			}
			float num = ___playersManager.fearLevel * (Plugin.Config.Multiplier / 100f);
			if (Plugin.Config.ChangeSpeed)
			{
				__instance.sprintMultiplier = Mathf.Lerp(__instance.sprintMultiplier, 1f + num, Time.deltaTime * 0.25f);
			}
			if (Plugin.Config.ChangeFOV)
			{
				float num2 = Mathf.Clamp(66f * num, 66f, Plugin.Config.MaxFOV);
				__instance.gameplayCamera.fieldOfView = Mathf.Lerp(__instance.gameplayCamera.fieldOfView, num2, 0.25f);
				if (__instance.gameplayCamera.fieldOfView > 67f)
				{
					float num3 = (__instance.gameplayCamera.fieldOfView - 66f) / (Plugin.Config.MaxFOV - 66f);
					num3 = Mathf.Lerp(num3, Mathf.Sin(num3 * MathF.PI / 2f), 0.6f);
					__instance.localVisor.localScale = Vector3.LerpUnclamped(new Vector3(0.68f, 0.8f, 0.95f), new Vector3(0.68f, 0.35f, 0.99f), num3);
				}
				else
				{
					__instance.localVisor.localScale = new Vector3(0.36f, 0.49f, 0.49f);
				}
			}
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}
namespace Hypick.AdrenalineRush.NetcodePatcher
{
	[AttributeUsage(AttributeTargets.Module)]
	internal class NetcodePatchedAssemblyAttribute : Attribute
	{
	}
}

BepInEx/plugins/The Perfect Immortal Snail/ItalicBlackbird.The Perfect Immortal Snail.dll

Decompiled a month ago
using System;
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 HarmonyLib;
using ImmortalSnail;
using LCSoundTool;
using Microsoft.CodeAnalysis;
using SoThisIsImmortalSnail;
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: 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("Snowlance.SoThisIsImmortalSnail")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+dc8111b331b16e38a3ad6e3ff61b36912c65e465")]
[assembly: AssemblyProduct("SoThisIsImmortalSnail")]
[assembly: AssemblyTitle("Snowlance.SoThisIsImmortalSnail")]
[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;
		}
	}
}
public class SnailMusicController : MonoBehaviour
{
	public SnailAI SnailInstance;

	public void Update()
	{
		//IL_0038: Unknown result type (might be due to invalid IL or missing references)
		SoThisIsImmortalSnailBase.LoggerInstance.LogDebug((object)"SnailMusicController.Update");
		if (!SoThisIsImmortalSnailBase.configPlayWhenLookingAtSnail.Value)
		{
			return;
		}
		if (GameNetworkManager.Instance.localPlayerController.HasLineOfSightToPosition(((Component)SnailInstance).transform.position, 70f, SoThisIsImmortalSnailBase.configDistance.Value, -1f))
		{
			if (!((EnemyAI)SnailInstance).creatureSFX.isPlaying)
			{
				((EnemyAI)SnailInstance).creatureSFX.Play();
			}
		}
		else if (SoThisIsImmortalSnailBase.configPauseWhenNotLooking.Value)
		{
			((EnemyAI)SnailInstance).creatureSFX.Pause();
		}
		else
		{
			((EnemyAI)SnailInstance).creatureSFX.Stop();
		}
	}
}
namespace SoThisIsImmortalSnail
{
	[BepInPlugin("Snowlance.SoThisIsImmortalSnail", "SoThisIsImmortalSnail", "1.0.0")]
	public class SoThisIsImmortalSnailBase : BaseUnityPlugin
	{
		private const string modGUID = "Snowlance.SoThisIsImmortalSnail";

		private const string modName = "SoThisIsImmortalSnail";

		private const string modVersion = "1.0.0";

		private readonly Harmony harmony = new Harmony("Snowlance.SoThisIsImmortalSnail");

		public static ConfigEntry<float> configVolume;

		public static ConfigEntry<bool> configPlayWhenLookingAtSnail;

		public static ConfigEntry<int> configDistance;

		public static ConfigEntry<bool> configPauseWhenNotLooking;

		public static AudioClip christmasMusic;

		public static SoThisIsImmortalSnailBase PluginInstance { get; private set; }

		public static ManualLogSource LoggerInstance { get; private set; }

		private void Awake()
		{
			if ((Object)(object)PluginInstance == (Object)null)
			{
				PluginInstance = this;
			}
			LoggerInstance = ((BaseUnityPlugin)PluginInstance).Logger;
			LoggerInstance.LogDebug((object)"Plugin SoThisIsImmortalSnail loaded successfully.");
			configVolume = ((BaseUnityPlugin)this).Config.Bind<float>("Volume", "MusicVolume", 1f, "Volume of the music. Must be between 0 and 1.");
			configPlayWhenLookingAtSnail = ((BaseUnityPlugin)this).Config.Bind<bool>("Looking Mechanic", "PlayWhenLookingAtSnail", true, "Play the music only when the player is looking at the snail. Everything below this only works if this is set to true.");
			configDistance = ((BaseUnityPlugin)this).Config.Bind<int>("Looking Mechanic", "Distance", 50, "Play the music only when the player is looking at a certain distance of the snail.");
			configPauseWhenNotLooking = ((BaseUnityPlugin)this).Config.Bind<bool>("Looking Mechanic", "PauseWhenNotLooking", true, "Wether to pause the music when not looking at the snail, or stop it and start it over again when looking again. true = Pause, false = Stop.");
			christmasMusic = SoundTool.GetAudioClip(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "christmasMusic.wav");
			LoggerInstance.LogDebug((object)$"Loaded christmasMusic: {christmasMusic}");
			harmony.PatchAll();
			LoggerInstance.LogInfo((object)"Snowlance.SoThisIsImmortalSnail v1.0.0 has loaded!");
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "Snowlance.SoThisIsImmortalSnail";

		public const string PLUGIN_NAME = "SoThisIsImmortalSnail";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}
namespace SoThisIsImmortalSnail.Patches
{
	[HarmonyPatch(typeof(SnailAI))]
	internal class SnailAIPatch
	{
		private static ManualLogSource LoggerInstance = SoThisIsImmortalSnailBase.LoggerInstance;

		[HarmonyPatch("Start")]
		[HarmonyPostfix]
		private static void StartPatch(SnailAI __instance)
		{
			((EnemyAI)__instance).creatureSFX = ((Component)__instance).gameObject.AddComponent<AudioSource>();
			((EnemyAI)__instance).creatureSFX.clip = SoThisIsImmortalSnailBase.christmasMusic;
			((EnemyAI)__instance).creatureSFX.loop = true;
			((EnemyAI)__instance).creatureSFX.volume = 1f;
			((EnemyAI)__instance).creatureSFX.spatialBlend = 1f;
			SnailMusicController snailMusicController = ((Component)__instance).gameObject.AddComponent<SnailMusicController>();
			snailMusicController.SnailInstance = __instance;
			if (!SoThisIsImmortalSnailBase.configPlayWhenLookingAtSnail.Value)
			{
				((EnemyAI)__instance).creatureSFX.Play();
			}
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}