Decompiled source of LegaFusionCore v1.0.5

LegaFusionCore.dll

Decompiled a week ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using LegaFusionCore.Behaviours;
using LegaFusionCore.Behaviours.Addons;
using LegaFusionCore.Behaviours.Shaders;
using LegaFusionCore.CustomInputs;
using LegaFusionCore.Managers;
using LegaFusionCore.Managers.NetworkManagers;
using LegaFusionCore.ModsCompat;
using LegaFusionCore.NetcodePatcher;
using LegaFusionCore.Patches;
using LegaFusionCore.Registries;
using LegaFusionCore.Utilities;
using LethalCompanyInputUtils.Api;
using LethalLib.Modules;
using Microsoft.CodeAnalysis;
using TMPro;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.InputSystem;
using UnityEngine.Rendering.HighDefinition;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("LegaFusionCore")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("LegaFusionCore")]
[assembly: AssemblyCopyright("Copyright ©  2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("7dc7a313-3468-48ad-8189-4f22764cd9ee")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: IgnoresAccessChecksTo("AmazingAssets.TerrainToMesh")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp-firstpass")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: IgnoresAccessChecksTo("ClientNetworkTransform")]
[assembly: IgnoresAccessChecksTo("com.olegknyazev.softmask")]
[assembly: IgnoresAccessChecksTo("DissonanceVoip")]
[assembly: IgnoresAccessChecksTo("EasyTextEffects")]
[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.Components")]
[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: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
[module: NetcodePatchedAssembly]
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 LegaFusionCore
{
	public class Constants
	{
		public const string STAT_SPEED = "Speed";

		public const string KNIFE_PREFAB = "KnifeItem";

		public const string MOUTH_DOG_PREFAB = "MouthDog";

		public const string EARTH_LEVIATHAN_PREFAB = "SandWorm";

		public const string MESSAGE_NO_SHIP_ENERGY = "Not enough energy left...";

		public const string MESSAGE_DEFAULT_ITEM_CHARGER = "(Requires battery-powered item)";

		public const string MESSAGE_DEFAULT_SHIP_LEVER = "[Wait for ship to land]";
	}
	[BepInPlugin("Lega.LegaFusionCore", "Lega Fusion Core", "1.0.5")]
	public class LegaFusionCore : BaseUnityPlugin
	{
		public const string modGUID = "Lega.LegaFusionCore";

		public const string modName = "Lega Fusion Core";

		public const string modVersion = "1.0.5";

		private readonly Harmony harmony = new Harmony("Lega.LegaFusionCore");

		private static readonly AssetBundle bundle = AssetBundle.LoadFromFile(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "legafusioncore"));

		internal static ManualLogSource mls;

		public static GameObject managerPrefab = NetworkPrefabs.CreateNetworkPrefab("LFCNetworkManager");

		public static Material wallhackShader;

		public static Material transparentShader;

		public static Material bloodShader;

		public static Material frostShader;

		public static Material poisonShader;

		public static GameObject smokeParticle;

		public static GameObject darkExplosionParticle;

		public static GameObject brownExplosionParticle;

		public static GameObject poisonExplosionParticle;

		public static GameObject bluePortalParticle;

		public static GameObject redPortalParticle;

		public static GameObject bloodParticle;

		public static GameObject groundParticle;

		public static GameObject poofExplosionAudio;

		public static GameObject poisonExplosionAudio;

		public static GameObject hitProjectileAudio;

		public void Awake()
		{
			mls = Logger.CreateLogSource("LegaFusionCore");
			LoadManager();
			NetcodePatcher();
			LoadPrefabs();
			LoadNetworkPrefabs();
			harmony.PatchAll(typeof(MenuManagerPatch));
			harmony.PatchAll(typeof(StartOfRoundPatch));
			harmony.PatchAll(typeof(RoundManagerPatch));
			harmony.PatchAll(typeof(NetworkBehaviourPatch));
			harmony.PatchAll(typeof(HangarShipDoorPatch));
			harmony.PatchAll(typeof(ItemChargerPatch));
			harmony.PatchAll(typeof(ManualCameraRendererPatch));
			harmony.PatchAll(typeof(ShipLightsPatch));
			harmony.PatchAll(typeof(ShipTeleporterPatch));
			harmony.PatchAll(typeof(TVScriptPatch));
			harmony.PatchAll(typeof(PlayerControllerBPatch));
			harmony.PatchAll(typeof(GrabbableObjectPatch));
			harmony.PatchAll(typeof(EnemyAIPatch));
			harmony.PatchAll(typeof(VehicleControllerPatch));
			GeneralImprovementsSoftCompat.Patch(harmony);
			GoodItemScanSoftCompat.Patch(harmony);
			MoreCompantSoftCompat.Patch(harmony);
			SelfSortingStorageSoftCompat.Patch(harmony);
		}

		public static void LoadManager()
		{
			Utilities.FixMixerGroups(managerPrefab);
			managerPrefab.AddComponent<LFCNetworkManager>();
		}

		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.ContainsGenericParameters)
					{
						methodInfo.Invoke(null, null);
					}
				}
			}
		}

		public static void LoadPrefabs()
		{
			wallhackShader = bundle.LoadAsset<Material>("Assets/Shaders/WallhackMaterial.mat");
			transparentShader = bundle.LoadAsset<Material>("Assets/Shaders/TransparentMaterial.mat");
			bloodShader = bundle.LoadAsset<Material>("Assets/Shaders/BloodMaterial.mat");
			frostShader = bundle.LoadAsset<Material>("Assets/Shaders/FrostMaterial.mat");
			poisonShader = bundle.LoadAsset<Material>("Assets/Shaders/PoisonMaterial.mat");
		}

		public void LoadNetworkPrefabs()
		{
			HashSet<GameObject> hashSet = new HashSet<GameObject>
			{
				smokeParticle = bundle.LoadAsset<GameObject>("Assets/Particles/SmokeParticle.prefab"),
				darkExplosionParticle = bundle.LoadAsset<GameObject>("Assets/Particles/DarkExplosionParticle.prefab"),
				brownExplosionParticle = bundle.LoadAsset<GameObject>("Assets/Particles/BrownExplosionParticle.prefab"),
				poisonExplosionParticle = bundle.LoadAsset<GameObject>("Assets/Particles/PoisonExplosionParticle.prefab"),
				bluePortalParticle = bundle.LoadAsset<GameObject>("Assets/Particles/BluePortalParticle.prefab"),
				redPortalParticle = bundle.LoadAsset<GameObject>("Assets/Particles/RedPortalParticle.prefab"),
				poofExplosionAudio = bundle.LoadAsset<GameObject>("Assets/Audios/PoofExplosionAudio.prefab"),
				poisonExplosionAudio = bundle.LoadAsset<GameObject>("Assets/Audios/PoisonExplosionAudio.prefab"),
				hitProjectileAudio = bundle.LoadAsset<GameObject>("Assets/Audios/HitProjectileAudio.prefab")
			};
			foreach (GameObject item in hashSet)
			{
				NetworkPrefabs.RegisterNetworkPrefab(item);
				Utilities.FixMixerGroups(item);
				LFCPrefabRegistry.RegisterPrefab("Lega Fusion Core" + ((Object)item).name, item);
			}
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "LegaFusionCore";

		public const string PLUGIN_NAME = "LegaFusionCore";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}
namespace LegaFusionCore.Utilities
{
	public static class LFCUtilities
	{
		public static PlayerControllerB LocalPlayer => GameNetworkManager.Instance?.localPlayerController;

		public static bool IsServer
		{
			get
			{
				if ((Object)(object)LocalPlayer != (Object)null)
				{
					if (!((NetworkBehaviour)LocalPlayer).IsServer)
					{
						return ((NetworkBehaviour)LocalPlayer).IsHost;
					}
					return true;
				}
				return false;
			}
		}

		public static bool ShouldBeLocalPlayer(PlayerControllerB player)
		{
			if ((Object)(object)player != (Object)null)
			{
				return (Object)(object)player == (Object)(object)GameNetworkManager.Instance?.localPlayerController;
			}
			return false;
		}

		public static bool ShouldNotBeLocalPlayer(PlayerControllerB player)
		{
			if ((Object)(object)player != (Object)null)
			{
				return (Object)(object)player != (Object)(object)GameNetworkManager.Instance?.localPlayerController;
			}
			return false;
		}

		public static bool TryGetComponentInParent<T>(this GameObject gameObject, out T result) where T : Component
		{
			result = gameObject.GetComponentInParent<T>();
			return (Object)(object)result != (Object)null;
		}

		public static bool TryGetComponentInChildren<T>(this GameObject gameObject, out T result) where T : Component
		{
			result = gameObject.GetComponentInChildren<T>();
			return (Object)(object)result != (Object)null;
		}

		public static void Shuffle<T>(IList<T> list)
		{
			for (int num = list.Count - 1; num > 0; num--)
			{
				int num2 = Random.Range(0, num + 1);
				int index = num2;
				int index2 = num;
				T value = list[num];
				T value2 = list[num2];
				list[index] = value;
				list[index2] = value2;
			}
		}

		public static string GetGameObjectName(GameObject gObject)
		{
			if ((Object)(object)gObject == (Object)null)
			{
				return string.Empty;
			}
			string text = ((Object)gObject).name ?? string.Empty;
			if (text.EndsWith("(Clone)", StringComparison.Ordinal))
			{
				string text2 = text;
				int length = "(Clone)".Length;
				text = text2.Substring(0, text2.Length - length);
			}
			return text.Trim();
		}

		public static bool HasNameFromList(string name, string listName)
		{
			if (string.IsNullOrWhiteSpace(name) || string.IsNullOrWhiteSpace(listName))
			{
				return false;
			}
			string[] array = listName.Split(',');
			foreach (string text in array)
			{
				string text2 = text.Trim();
				if (text2.Length != 0 && string.Equals(text2, name, StringComparison.Ordinal))
				{
					return true;
				}
			}
			return false;
		}

		public static void UpdateTimer(ref float timer, float cooldown, bool isActive, Action onReady)
		{
			if (isActive)
			{
				timer += Time.deltaTime;
				if (timer >= cooldown)
				{
					timer = 0f;
					onReady?.Invoke();
				}
			}
		}

		public static GameObject GetPrefabFromName(string name)
		{
			GameObject val = null;
			IEnumerable<NetworkPrefabsList> networkPrefabsLists = NetworkManager.Singleton.NetworkConfig.Prefabs.NetworkPrefabsLists;
			foreach (NetworkPrefabsList item in networkPrefabsLists ?? Enumerable.Empty<NetworkPrefabsList>())
			{
				IEnumerable<NetworkPrefab> prefabList = item.PrefabList;
				foreach (NetworkPrefab item2 in prefabList ?? Enumerable.Empty<NetworkPrefab>())
				{
					if (((Object)item2.Prefab).name.Equals(name))
					{
						val = item2.Prefab;
						if ((Object)(object)val != (Object)null)
						{
							break;
						}
					}
				}
			}
			return val;
		}

		public static T GetSafeComponent<T>(GameObject gameObject) where T : Component
		{
			if (!((Object)(object)gameObject == (Object)null))
			{
				if (gameObject != null && Object.op_Implicit((Object)(object)gameObject))
				{
					return gameObject.GetComponent<T>();
				}
			}
			return default(T);
		}

		public static void SetAddonComponent<T>(GrabbableObject grabbableObject, string addonName, bool isPassive = false) where T : AddonComponent
		{
			T val = ((Component)grabbableObject).gameObject.AddComponent<T>();
			val.grabbableObject = grabbableObject;
			val.addonName = addonName;
			val.isPassive = isPassive;
			ScanNodeProperties componentInChildren = ((Component)grabbableObject).gameObject.GetComponentInChildren<ScanNodeProperties>();
			if ((Object)(object)componentInChildren != (Object)null)
			{
				componentInChildren.subText = componentInChildren.subText + ((componentInChildren.subText != null) ? "\n" : "") + "Addon: " + addonName;
			}
		}

		public static T GetAddonComponent<T>(PlayerControllerB player) where T : AddonComponent
		{
			if ((Object)(object)player == (Object)null)
			{
				return null;
			}
			T val = null;
			for (int i = 0; i < player.ItemSlots.Length; i++)
			{
				val = GetAddonComponent<T>(player.ItemSlots[i]);
				if ((Object)(object)val != (Object)null)
				{
					break;
				}
			}
			return val;
		}

		public static T GetAddonComponent<T>(GrabbableObject grabbableObject) where T : AddonComponent
		{
			if (grabbableObject == null)
			{
				return null;
			}
			return ((Component)grabbableObject).GetComponent<T>();
		}
	}
}
namespace LegaFusionCore.Registries
{
	public class LFCObjectStateRegistry
	{
		private static readonly Dictionary<FlashlightItem, HashSet<string>> flickeringFlashlightRegistry = new Dictionary<FlashlightItem, HashSet<string>>();

		public static void AddFlickeringFlashlight(FlashlightItem flashlight, string tag)
		{
			if (!flickeringFlashlightRegistry.TryGetValue(flashlight, out var value))
			{
				value = new HashSet<string>();
				flickeringFlashlightRegistry[flashlight] = value;
			}
			if (value.Add(tag) && value.Count == 1)
			{
				SetFlickeringFlashlightEnabled(flashlight, enabled: true);
			}
		}

		public static void RemoveFlickeringFlashlight(FlashlightItem flashlight, string tag)
		{
			if (flickeringFlashlightRegistry.TryGetValue(flashlight, out var value) && value.Remove(tag) && value.Count == 0)
			{
				SetFlickeringFlashlightEnabled(flashlight, enabled: false);
			}
		}

		public static void ClearFlickeringFlashlight()
		{
			foreach (FlashlightItem flashlight in flickeringFlashlightRegistry.Keys.ToList())
			{
				if (flickeringFlashlightRegistry.TryGetValue(flashlight, out var value))
				{
					value.ToList().ForEach(delegate(string t)
					{
						RemoveFlickeringFlashlight(flashlight, t);
					});
					flickeringFlashlightRegistry.Remove(flashlight);
				}
			}
		}

		public static bool IsFlickeringFlashlight(FlashlightItem flashlight)
		{
			if (flickeringFlashlightRegistry.TryGetValue(flashlight, out var value))
			{
				return value.Count > 0;
			}
			return false;
		}

		private static void SetFlickeringFlashlightEnabled(FlashlightItem flashlight, bool enabled)
		{
			if ((Object)(object)flashlight != (Object)null)
			{
				if (enabled)
				{
					flashlight.flashlightAudio.PlayOneShot(flashlight.flashlightFlicker);
					WalkieTalkie.TransmitOneShotAudio(flashlight.flashlightAudio, flashlight.flashlightFlicker, 0.8f);
					flashlight.flashlightInterferenceLevel = 1;
				}
				else
				{
					flashlight.flashlightInterferenceLevel = 0;
				}
			}
		}
	}
	public static class LFCPlayerActionRegistry
	{
		private static readonly Dictionary<string, HashSet<string>> lockRegistry = new Dictionary<string, HashSet<string>>();

		public static void AddLock(string actionName, string tag)
		{
			if (!lockRegistry.TryGetValue(actionName, out var value))
			{
				value = new HashSet<string>();
				lockRegistry[actionName] = value;
			}
			SetActionEnabled(actionName, enabled: false);
			value.Add(tag);
		}

		public static void RemoveLock(string actionName, string tag)
		{
			if (lockRegistry.TryGetValue(actionName, out var value) && value.Remove(tag) && value.Count == 0)
			{
				SetActionEnabled(actionName, enabled: true);
			}
		}

		public static bool IsLocked(string actionName)
		{
			if (lockRegistry.TryGetValue(actionName, out var value))
			{
				return value.Count > 0;
			}
			return false;
		}

		private static void SetActionEnabled(string actionName, bool enabled)
		{
			InputAction val = IngamePlayerSettings.Instance.playerInput.actions.FindAction(actionName, false);
			if (val == null)
			{
				LegaFusionCore.mls.LogWarning((object)("Action '" + actionName + "' not found"));
			}
			else if (enabled)
			{
				val.Enable();
			}
			else
			{
				val.Disable();
			}
		}
	}
	public static class LFCPoweredLightsRegistry
	{
		private static readonly Dictionary<Animator, HashSet<string>> lockRegistry = new Dictionary<Animator, HashSet<string>>();

		public static void AddLock(Animator poweredLight, string tag)
		{
			if (!lockRegistry.TryGetValue(poweredLight, out var value))
			{
				value = new HashSet<string>();
				lockRegistry[poweredLight] = value;
			}
			SetPoweredLightEnabled(poweredLight, enabled: false);
			value.Add(tag);
		}

		public static void RemoveLock(Animator poweredLight, string tag)
		{
			if (lockRegistry.TryGetValue(poweredLight, out var value) && value.Remove(tag) && value.Count == 0)
			{
				SetPoweredLightEnabled(poweredLight, enabled: true);
			}
		}

		public static void ClearLocks()
		{
			foreach (Animator poweredLight in lockRegistry.Keys.ToList())
			{
				if (lockRegistry.TryGetValue(poweredLight, out var value))
				{
					value.ToList().ForEach(delegate(string t)
					{
						RemoveLock(poweredLight, t);
					});
					lockRegistry.Remove(poweredLight);
				}
			}
		}

		public static bool IsLocked(Animator poweredLight)
		{
			if (lockRegistry.TryGetValue(poweredLight, out var value))
			{
				return value.Count > 0;
			}
			return false;
		}

		private static void SetPoweredLightEnabled(Animator poweredLight, bool enabled)
		{
			if ((Object)(object)poweredLight != (Object)null && (Object)(object)((Component)poweredLight).gameObject != (Object)null)
			{
				poweredLight.SetBool("on", enabled);
			}
		}
	}
	public static class LFCPrefabRegistry
	{
		private static readonly Dictionary<string, GameObject> registry = new Dictionary<string, GameObject>();

		public static void RegisterPrefab(string tag, GameObject prefab)
		{
			if (!registry.ContainsKey(tag))
			{
				registry.Add(tag, prefab);
			}
		}

		public static GameObject GetPrefab(string tag)
		{
			registry.TryGetValue(tag, out var value);
			return value;
		}
	}
	public static class LFCShaderFilterRegistry
	{
		private static readonly Dictionary<string, Func<GameObject, bool>> filters = new Dictionary<string, Func<GameObject, bool>>();

		public static void AddFilter(string modName, Func<GameObject, bool> filter)
		{
			if (string.IsNullOrEmpty(modName))
			{
				LegaFusionCore.mls.LogWarning((object)"[RendererVisibilityRegistry] Mod name is null or empty.");
			}
			else if (filter == null)
			{
				LegaFusionCore.mls.LogWarning((object)("[RendererVisibilityRegistry] Null filter provided for " + modName));
			}
			else
			{
				filters[modName] = filter;
			}
		}

		public static void RemoveFilter(string modName)
		{
			if (!string.IsNullOrEmpty(modName))
			{
				filters.Remove(modName);
			}
		}

		public static bool ShouldRender(GameObject sourceObject)
		{
			foreach (KeyValuePair<string, Func<GameObject, bool>> filter in filters)
			{
				try
				{
					if (!filter.Value(sourceObject))
					{
						return false;
					}
				}
				catch (Exception arg)
				{
					LegaFusionCore.mls.LogWarning((object)$"[RendererVisibilityRegistry] Filter '{filter.Key}' threw an exception: {arg}");
				}
			}
			return true;
		}
	}
	public static class LFCShipFeatureRegistry
	{
		public enum ShipFeatureType
		{
			SHIP_LIGHTS,
			MAP_SCREEN,
			SHIP_DOORS,
			SHIP_LEVER,
			SHIP_TERMINAL,
			ITEM_CHARGER,
			SHIP_TV,
			SHIP_TELEPORTERS,
			SMART_CUPBOARD
		}

		private static readonly Dictionary<ShipFeatureType, HashSet<string>> lockRegistry = new Dictionary<ShipFeatureType, HashSet<string>>();

		private static HangarShipDoor shipDoor;

		private static StartMatchLever shipLever;

		private static Terminal shipTerminal;

		private static ItemCharger itemCharger;

		private static TVScript shipTV;

		private static List<ShipTeleporter> shipTeleporters = new List<ShipTeleporter>();

		public static void AddLock(ShipFeatureType featureType, string tag)
		{
			if (!lockRegistry.TryGetValue(featureType, out var value))
			{
				value = new HashSet<string>();
				lockRegistry[featureType] = value;
			}
			SetFeatureEnabled(featureType, enabled: false);
			value.Add(tag);
		}

		public static void RemoveLock(ShipFeatureType featureType, string tag)
		{
			if (lockRegistry.TryGetValue(featureType, out var value) && value.Remove(tag) && value.Count == 0)
			{
				SetFeatureEnabled(featureType, enabled: true);
			}
		}

		public static void ClearLocks(string tag)
		{
			foreach (ShipFeatureType item in lockRegistry.Keys.ToList())
			{
				if (lockRegistry.TryGetValue(item, out var value) && value.Contains(tag))
				{
					RemoveLock(item, tag);
				}
			}
		}

		public static void ClearLocks()
		{
			foreach (ShipFeatureType featureType in lockRegistry.Keys.ToList())
			{
				if (lockRegistry.TryGetValue(featureType, out var value))
				{
					value.ToList().ForEach(delegate(string t)
					{
						RemoveLock(featureType, t);
					});
				}
			}
		}

		public static bool IsLocked(ShipFeatureType featureType)
		{
			if (lockRegistry.TryGetValue(featureType, out var value))
			{
				return value.Count > 0;
			}
			return false;
		}

		private static void SetFeatureEnabled(ShipFeatureType featureType, bool enabled)
		{
			switch (featureType)
			{
			case ShipFeatureType.SHIP_LIGHTS:
				SetShipLights(enabled);
				break;
			case ShipFeatureType.MAP_SCREEN:
				SetMapScreen(enabled);
				break;
			case ShipFeatureType.SHIP_DOORS:
				SetShipDoors(enabled);
				break;
			case ShipFeatureType.SHIP_LEVER:
				SetShipLever(enabled);
				break;
			case ShipFeatureType.SHIP_TERMINAL:
				SetShipTerminal(enabled);
				break;
			case ShipFeatureType.ITEM_CHARGER:
				SetItemCharger(enabled);
				break;
			case ShipFeatureType.SHIP_TV:
				SetShipTV(enabled);
				break;
			case ShipFeatureType.SHIP_TELEPORTERS:
				SetShipTeleporters(enabled);
				break;
			case ShipFeatureType.SMART_CUPBOARD:
				SetSmartCupboard(enabled);
				break;
			default:
				LegaFusionCore.mls.LogWarning((object)$"[ShipFeatureRegistry] Unknown feature '{featureType}'");
				break;
			}
		}

		private static void SetShipLights(bool enabled)
		{
			ShipLights val = StartOfRound.Instance?.shipRoomLights;
			if ((Object)(object)val != (Object)null)
			{
				val.areLightsOn = enabled;
				val.shipLightsAnimator.SetBool("lightsOn", val.areLightsOn);
			}
		}

		private static void SetMapScreen(bool enabled)
		{
			ManualCameraRenderer val = StartOfRound.Instance?.mapScreen;
			if ((Object)(object)val != (Object)null && (Object)(object)((Component)val).gameObject != (Object)null)
			{
				val.SwitchScreenOn(enabled);
			}
		}

		private static void SetShipDoors(bool enabled)
		{
			if (shipDoor == null)
			{
				shipDoor = Object.FindObjectOfType<HangarShipDoor>();
			}
			if (!((Object)(object)shipDoor == (Object)null))
			{
				shipDoor.hydraulicsScreenDisplayed = enabled;
				shipDoor.hydraulicsDisplay.SetActive(enabled);
				shipDoor.SetDoorButtonsEnabled(enabled);
				if (!enabled)
				{
					StartOfRound.Instance.shipDoorsAnimator.SetBool("Closed", enabled);
					shipDoor.SetDoorOpen();
				}
			}
		}

		private static void SetShipLever(bool enabled)
		{
			if (shipLever == null)
			{
				shipLever = Object.FindObjectOfType<StartMatchLever>();
			}
			if (!((Object)(object)shipLever == (Object)null))
			{
				shipLever.triggerScript.disabledHoverTip = (enabled ? "[Wait for ship to land]" : "Not enough energy left...");
				shipLever.triggerScript.interactable = enabled;
			}
		}

		private static void SetShipTerminal(bool enabled)
		{
			if (shipTerminal == null)
			{
				shipTerminal = Object.FindObjectOfType<Terminal>();
			}
			if (!((Object)(object)shipTerminal == (Object)null))
			{
				if (!enabled)
				{
					shipTerminal.terminalTrigger.disabledHoverTip = "Not enough energy left...";
				}
				shipTerminal.terminalTrigger.interactable = enabled;
			}
		}

		private static void SetItemCharger(bool enabled)
		{
			if (itemCharger == null)
			{
				itemCharger = Object.FindObjectOfType<ItemCharger>();
			}
			if (!((Object)(object)itemCharger == (Object)null))
			{
				itemCharger.triggerScript.disabledHoverTip = (enabled ? "(Requires battery-powered item)" : "Not enough energy left...");
				itemCharger.triggerScript.interactable = enabled;
			}
		}

		private static void SetShipTV(bool enabled)
		{
			if (shipTV == null)
			{
				shipTV = Object.FindObjectOfType<TVScript>();
			}
			if (!((Object)(object)shipTV == (Object)null))
			{
				shipTV.TurnTVOnOff(enabled);
			}
		}

		private static void SetShipTeleporters(bool enabled)
		{
			shipTeleporters.RemoveAll((ShipTeleporter t) => (Object)(object)t == (Object)null);
			if (shipTeleporters.Count == 0)
			{
				shipTeleporters = Object.FindObjectsOfType<ShipTeleporter>().ToList();
			}
			foreach (ShipTeleporter shipTeleporter in shipTeleporters)
			{
				shipTeleporter.buttonTrigger.interactable = enabled;
			}
		}

		private static void SetSmartCupboard(bool enabled)
		{
			SelfSortingStorageSoftCompat.SwitchLights(enabled);
		}

		public static void ResetCache()
		{
			shipDoor = null;
			shipLever = null;
			shipTerminal = null;
			itemCharger = null;
			shipTV = null;
			shipTeleporters.Clear();
		}
	}
	public static class LFCSpawnableItemRegistry
	{
		public class SpawnableItem
		{
			public Type Type { get; }

			public Item Item { get; }

			public int MinSpawn { get; }

			public int MaxSpawn { get; }

			public int Rarity { get; }

			public int Value { get; }

			public SpawnableItem(Type type, Item item, int minSpawn, int maxSpawn, int rarity, int value)
			{
				Type = type;
				Item = item;
				MinSpawn = minSpawn;
				MaxSpawn = maxSpawn;
				Rarity = rarity;
				Value = value;
				base..ctor();
			}

			public override bool Equals(object obj)
			{
				if (obj is SpawnableItem spawnableItem)
				{
					return (Object)(object)spawnableItem.Item == (Object)(object)Item;
				}
				return false;
			}

			public override int GetHashCode()
			{
				return ((object)Item)?.GetHashCode() ?? 0;
			}
		}

		private static readonly HashSet<SpawnableItem> spawnableItems = new HashSet<SpawnableItem>();

		public static void Add(Type type, Item item, int minSpawn, int maxSpawn, int rarity, int value = 0)
		{
			LFCObjectsManager.RegisterObject(type, item);
			spawnableItems.Add(new SpawnableItem(type, item, minSpawn, maxSpawn, rarity, value));
		}

		public static IReadOnlyCollection<SpawnableItem> GetAll()
		{
			return spawnableItems;
		}
	}
	public static class LFCSpawnRegistry
	{
		private static readonly Dictionary<Type, HashSet<Component>> registry = new Dictionary<Type, HashSet<Component>>();

		public static void Add(Component obj)
		{
			if (!((Object)(object)obj == (Object)null))
			{
				Type type = ((object)obj).GetType();
				if (!registry.TryGetValue(type, out var value))
				{
					value = new HashSet<Component>();
					registry[type] = value;
				}
				if (!value.Contains(obj))
				{
					value.Add(obj);
				}
			}
		}

		public static void Remove(Component obj)
		{
			if ((Object)(object)obj == (Object)null)
			{
				return;
			}
			Type type = ((object)obj).GetType();
			if (registry.TryGetValue(type, out var value))
			{
				value.RemoveWhere((Component c) => (Object)(object)c == (Object)null || (Object)(object)c == (Object)(object)obj);
			}
		}

		public static List<T> GetAllAs<T>() where T : Component
		{
			List<T> list = new List<T>();
			foreach (KeyValuePair<Type, HashSet<Component>> item in registry)
			{
				item.Value.RemoveWhere((Component c) => (Object)(object)c == (Object)null);
				foreach (Component item2 in item.Value)
				{
					if ((Object)(object)item2 != (Object)null)
					{
						T val = (T)(object)((item2 is T) ? item2 : null);
						if (val != null)
						{
							list.Add(val);
						}
					}
				}
			}
			return list;
		}

		public static HashSet<Component> GetSetExact<T>() where T : Component
		{
			if (!registry.TryGetValue(typeof(T), out var value))
			{
				return null;
			}
			return value;
		}

		public static void Clear()
		{
			registry.Clear();
		}
	}
	public static class LFCStatRegistry
	{
		private class StatEntry
		{
			public float baseValue;

			public float? minValue;

			public float? maxValue;

			public readonly Dictionary<string, float> modifiers = new Dictionary<string, float>();

			public float FinalValue
			{
				get
				{
					float num = 1f + modifiers.Values.Sum();
					float num2 = baseValue * num;
					if (minValue.HasValue)
					{
						num2 = Mathf.Max(minValue.Value, num2);
					}
					if (maxValue.HasValue)
					{
						num2 = Mathf.Min(maxValue.Value, num2);
					}
					return num2;
				}
			}
		}

		private static readonly Dictionary<string, StatEntry> stats = new Dictionary<string, StatEntry>();

		public static void RegisterStat(string id, float baseValue, float? min = null, float? max = null)
		{
			stats[id] = new StatEntry
			{
				baseValue = baseValue,
				minValue = min,
				maxValue = max
			};
		}

		public static void SetBaseValue(string id, float newBase)
		{
			if (stats.TryGetValue(id, out var value))
			{
				value.baseValue = newBase;
			}
		}

		public static void AddModifier(string id, string tag, float value)
		{
			if (stats.TryGetValue(id, out var value2))
			{
				value2.modifiers[tag] = value;
			}
		}

		public static void RemoveModifier(string id, string tag)
		{
			if (stats.TryGetValue(id, out var value))
			{
				value.modifiers.Remove(tag);
			}
		}

		public static float? GetFinalValue(string id)
		{
			if (!stats.TryGetValue(id, out var value))
			{
				return null;
			}
			return value.FinalValue;
		}

		public static bool HasModifier(string id, string sourceTag)
		{
			if (stats.TryGetValue(id, out var value))
			{
				return value.modifiers.ContainsKey(sourceTag);
			}
			return false;
		}

		public static float GetSumModifier(string id)
		{
			if (!stats.TryGetValue(id, out var value))
			{
				return 0f;
			}
			return value.modifiers.Values.Sum();
		}

		public static void ClearModifiers(string id)
		{
			if (stats.TryGetValue(id, out var value))
			{
				value.modifiers.Clear();
			}
		}
	}
	public class LFCStatusEffectRegistry : MonoBehaviour
	{
		public enum StatusEffectType
		{
			BLEEDING,
			FROST,
			POISON,
			FEAR
		}

		public abstract class StatusEffect
		{
			public Action OnApply;

			public Action OnExpire;

			public Action OnTick;

			public StatusEffectType EffectType { get; }

			public int PlayerWhoHit { get; }

			public int Duration { get; }

			public float EndTime { get; private set; }

			public int TotalDamage { get; }

			public int DamagePerTick { get; }

			public float NextTickTime { get; private set; }

			public float RemainingTime => EndTime - Time.time;

			protected StatusEffect(StatusEffectType effectType, int playerWhoHit, int duration, int totalDamage, Action onApply, Action onExpire, Action onTick)
			{
				EffectType = effectType;
				PlayerWhoHit = playerWhoHit;
				Duration = duration;
				EndTime = Time.time + (float)duration;
				TotalDamage = totalDamage;
				OnApply = onApply;
				OnExpire = onExpire;
				OnTick = onTick;
				DamagePerTick = ((duration > 0) ? (totalDamage / duration) : 0);
				NextTickTime = Time.time + 1f;
			}

			public virtual void Apply(GameObject entity)
			{
				OnApply?.Invoke();
			}

			public virtual void Tick(GameObject entity)
			{
				OnTick?.Invoke();
				if (DamagePerTick != 0)
				{
					ApplyDamage(entity, DamagePerTick, PlayerWhoHit);
				}
				NextTickTime += 1f;
			}

			public virtual void Expire(GameObject entity)
			{
				OnExpire?.Invoke();
			}

			public bool ShouldTick()
			{
				return Time.time >= NextTickTime;
			}

			public bool IsExpired()
			{
				return Time.time >= EndTime;
			}

			protected void ApplyDamage(GameObject entity, int damage, int playerWhoHit)
			{
				//IL_0056: 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)
				if (!((Object)(object)entity == (Object)null))
				{
					EnemyAI safeComponent = LFCUtilities.GetSafeComponent<EnemyAI>(entity);
					if ((Object)(object)safeComponent != (Object)null && !safeComponent.isEnemyDead && LFCEnemyManager.CanDie(safeComponent))
					{
						EnemyAIPatch.DamageEnemy(safeComponent, damage, playerWhoHit, playHitSFX: true);
					}
					PlayerControllerB safeComponent2 = LFCUtilities.GetSafeComponent<PlayerControllerB>(entity);
					if ((Object)(object)safeComponent2 != (Object)null && !safeComponent2.isPlayerDead)
					{
						safeComponent2.DamagePlayer(damage, true, true, (CauseOfDeath)0, 0, false, default(Vector3));
					}
				}
			}
		}

		public class BleedingEffect : StatusEffect
		{
			public BleedingEffect(int playerWhoHit, int duration, int totalDamage, Action onApply = null, Action onExpire = null, Action onTick = null)
				: base(StatusEffectType.BLEEDING, playerWhoHit, duration, totalDamage, onApply, onExpire, onTick)
			{
			}

			public override void Apply(GameObject entity)
			{
				//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)
				base.Apply(entity);
				PlayerControllerB safeComponent = LFCUtilities.GetSafeComponent<PlayerControllerB>(entity);
				if (LFCUtilities.ShouldNotBeLocalPlayer(safeComponent))
				{
					CustomPassManager.SetupAuraForObjects((GameObject[])(object)new GameObject[1] { entity.gameObject }, LegaFusionCore.bloodShader, "Lega Fusion Core" + ((Object)LegaFusionCore.bloodShader).name);
				}
			}

			public override void Tick(GameObject entity)
			{
				//IL_0021: Unknown result type (might be due to invalid IL or missing references)
				//IL_0026: Unknown result type (might be due to invalid IL or missing references)
				base.Tick(entity);
				LFCGlobalManager.PlayParticle("Lega Fusion Core" + ((Object)LegaFusionCore.bloodParticle).name, entity.transform.position, Quaternion.identity);
			}

			public override void Expire(GameObject entity)
			{
				base.Expire(entity);
				CustomPassManager.RemoveAuraFromObjects((GameObject[])(object)new GameObject[1] { entity.gameObject }, "Lega Fusion Core" + ((Object)LegaFusionCore.bloodShader).name);
			}
		}

		public class FrostEffect : StatusEffect
		{
			public FrostEffect(int playerWhoHit, int duration, int totalDamage, Action onApply = null, Action onExpire = null, Action onTick = null)
				: base(StatusEffectType.FROST, playerWhoHit, duration, totalDamage, onApply, onExpire, onTick)
			{
			}

			public override void Apply(GameObject entity)
			{
				//IL_00f4: 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_0079: 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)
				base.Apply(entity);
				EnemyAI safeComponent = LFCUtilities.GetSafeComponent<EnemyAI>(entity);
				if ((Object)(object)safeComponent != (Object)null && !safeComponent.isEnemyDead)
				{
					((Component)safeComponent).GetComponent<EnemySpeedBehaviour>()?.AddSpeedData(StatusEffectType.FROST.ToString(), -0.67f, safeComponent.agent.speed);
					CustomPassManager.SetupAuraForObjects((GameObject[])(object)new GameObject[1] { entity.gameObject }, LegaFusionCore.frostShader, "Lega Fusion Core" + ((Object)LegaFusionCore.frostShader).name);
					return;
				}
				PlayerControllerB safeComponent2 = LFCUtilities.GetSafeComponent<PlayerControllerB>(entity);
				if ((Object)(object)safeComponent2 != (Object)null && !safeComponent2.isPlayerDead)
				{
					if (LFCUtilities.ShouldBeLocalPlayer(safeComponent2))
					{
						LFCStatRegistry.AddModifier("Speed", "Lega Fusion Core" + ((Object)LegaFusionCore.frostShader).name, -100f);
						return;
					}
					CustomPassManager.SetupAuraForObjects((GameObject[])(object)new GameObject[1] { entity.gameObject }, LegaFusionCore.frostShader, "Lega Fusion Core" + ((Object)LegaFusionCore.frostShader).name);
				}
			}

			public override void Expire(GameObject entity)
			{
				base.Expire(entity);
				CustomPassManager.RemoveAuraFromObjects((GameObject[])(object)new GameObject[1] { entity.gameObject }, "Lega Fusion Core" + ((Object)LegaFusionCore.frostShader).name);
				EnemyAI safeComponent = LFCUtilities.GetSafeComponent<EnemyAI>(entity);
				if ((Object)(object)safeComponent != (Object)null)
				{
					((Component)safeComponent).GetComponent<EnemySpeedBehaviour>()?.RemoveSpeedData(StatusEffectType.FROST.ToString());
					return;
				}
				PlayerControllerB safeComponent2 = LFCUtilities.GetSafeComponent<PlayerControllerB>(entity);
				if (LFCUtilities.ShouldBeLocalPlayer(safeComponent2))
				{
					LFCStatRegistry.RemoveModifier("Speed", "Lega Fusion Core" + ((Object)LegaFusionCore.frostShader).name);
				}
			}
		}

		public class PoisonEffect : StatusEffect
		{
			public PoisonEffect(int playerWhoHit, int duration, int totalDamage, Action onApply = null, Action onExpire = null, Action onTick = null)
				: base(StatusEffectType.POISON, playerWhoHit, duration, totalDamage, onApply, onExpire, onTick)
			{
			}

			public override void Apply(GameObject entity)
			{
				//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)
				base.Apply(entity);
				PlayerControllerB safeComponent = LFCUtilities.GetSafeComponent<PlayerControllerB>(entity);
				if (LFCUtilities.ShouldNotBeLocalPlayer(safeComponent))
				{
					CustomPassManager.SetupAuraForObjects((GameObject[])(object)new GameObject[1] { entity.gameObject }, LegaFusionCore.poisonShader, "Lega Fusion Core" + ((Object)LegaFusionCore.poisonShader).name);
				}
			}

			public override void Expire(GameObject entity)
			{
				base.Expire(entity);
				CustomPassManager.RemoveAuraFromObjects((GameObject[])(object)new GameObject[1] { entity.gameObject }, "Lega Fusion Core" + ((Object)LegaFusionCore.poisonShader).name);
			}
		}

		private static readonly Dictionary<GameObject, Dictionary<StatusEffectType, StatusEffect>> activeEffects = new Dictionary<GameObject, Dictionary<StatusEffectType, StatusEffect>>();

		private static LFCStatusEffectRegistry _instance;

		public static LFCStatusEffectRegistry Instance
		{
			get
			{
				//IL_0012: Unknown result type (might be due to invalid IL or missing references)
				//IL_0018: Expected O, but got Unknown
				if ((Object)(object)_instance == (Object)null)
				{
					GameObject val = new GameObject("StatusEffect");
					_instance = val.AddComponent<LFCStatusEffectRegistry>();
					Object.DontDestroyOnLoad((Object)(object)val);
				}
				return _instance;
			}
		}

		private void Update()
		{
			List<(GameObject, StatusEffectType)> list = new List<(GameObject, StatusEffectType)>();
			List<GameObject> list2 = new List<GameObject>();
			foreach (KeyValuePair<GameObject, Dictionary<StatusEffectType, StatusEffect>> activeEffect in activeEffects)
			{
				GameObject key = activeEffect.Key;
				if ((Object)(object)key == (Object)null)
				{
					list2.Add(key);
					continue;
				}
				Dictionary<StatusEffectType, StatusEffect> value = activeEffect.Value;
				foreach (KeyValuePair<StatusEffectType, StatusEffect> item in value)
				{
					StatusEffect value2 = item.Value;
					if (value2.ShouldTick())
					{
						value2.Tick(key);
					}
					if (value2.IsExpired())
					{
						list.Add((key, item.Key));
					}
				}
			}
			list2.ForEach(delegate(GameObject e)
			{
				activeEffects.Remove(e);
			});
			list.ForEach(delegate((GameObject, StatusEffectType) e)
			{
				RemoveStatus(e.Item1, e.Item2);
			});
		}

		public static void ApplyStatus(GameObject entity, StatusEffectType type, int playerWhoHit, int duration, int totalDamage = 0, Action onApply = null, Action onExpire = null, Action onTick = null)
		{
			StatusEffect statusEffect = type switch
			{
				StatusEffectType.BLEEDING => new BleedingEffect(playerWhoHit, duration, totalDamage, onApply, onExpire, onTick), 
				StatusEffectType.FROST => new FrostEffect(playerWhoHit, duration, totalDamage, onApply, onExpire, onTick), 
				StatusEffectType.POISON => new PoisonEffect(playerWhoHit, duration, totalDamage, onApply, onExpire, onTick), 
				_ => null, 
			};
			if (statusEffect != null)
			{
				ApplyStatus(entity, statusEffect);
			}
		}

		public static void ApplyStatus(GameObject entity, StatusEffect effect)
		{
			_ = Instance;
			if (!activeEffects.ContainsKey(entity))
			{
				activeEffects[entity] = new Dictionary<StatusEffectType, StatusEffect>();
			}
			Dictionary<StatusEffectType, StatusEffect> dictionary = activeEffects[entity];
			if (dictionary.TryGetValue(effect.EffectType, out var value))
			{
				if (effect.RemainingTime > value.RemainingTime)
				{
					value.Expire(entity);
					dictionary[effect.EffectType] = effect;
					effect.Apply(entity);
				}
			}
			else
			{
				dictionary[effect.EffectType] = effect;
				effect.Apply(entity);
			}
		}

		public static void RemoveStatus(GameObject entity, StatusEffectType effectType)
		{
			if (activeEffects.TryGetValue(entity, out var value) && value.TryGetValue(effectType, out var value2))
			{
				value2.Expire(entity);
				value.Remove(effectType);
			}
		}

		public static bool HasStatus(GameObject target, StatusEffectType effectType)
		{
			if (activeEffects.TryGetValue(target, out var value))
			{
				return value.ContainsKey(effectType);
			}
			return false;
		}

		public static void ClearStatus()
		{
			foreach (GameObject entity in activeEffects.Keys.ToList())
			{
				if (activeEffects.TryGetValue(entity, out var value))
				{
					value.Keys.ToList().ForEach(delegate(StatusEffectType e)
					{
						RemoveStatus(entity, e);
					});
					activeEffects.Remove(entity);
				}
			}
		}
	}
	public class LFCVisibilityRegistry
	{
		private sealed class EntityState
		{
			public readonly HashSet<string> tags = new HashSet<string>();

			public readonly HashSet<Renderer> disabledRenderers = new HashSet<Renderer>();

			public readonly HashSet<Light> disabledLights = new HashSet<Light>();

			public readonly HashSet<Rigidbody> disabledGravitys = new HashSet<Rigidbody>();

			public readonly HashSet<PlayerPhysicsRegion> disabledPhysicsRegions = new HashSet<PlayerPhysicsRegion>();

			public readonly HashSet<Collider> disabledColliders = new HashSet<Collider>();

			public readonly HashSet<TextMeshProUGUI> disabledTextMeshes = new HashSet<TextMeshProUGUI>();

			public readonly HashSet<InteractTrigger> disabledInteractTriggers = new HashSet<InteractTrigger>();

			public readonly HashSet<AnimatedObjectTrigger> disabledAnimatedTriggers = new HashSet<AnimatedObjectTrigger>();

			public readonly HashSet<ParticleSystem> disabledParticles = new HashSet<ParticleSystem>();

			public readonly Dictionary<AudioSource, float> audioVolumes = new Dictionary<AudioSource, float>();
		}

		private static readonly Dictionary<GameObject, EntityState> visibilityStates = new Dictionary<GameObject, EntityState>();

		public static void Hide(GameObject entity, string tag)
		{
			if (!((Object)(object)entity == (Object)null))
			{
				if (string.IsNullOrWhiteSpace(tag))
				{
					tag = "default";
				}
				CleanupDeadEntries();
				if (!visibilityStates.TryGetValue(entity, out var value))
				{
					value = new EntityState();
					visibilityStates[entity] = value;
				}
				HideInternal(entity, value);
				value.tags.Add(tag);
			}
		}

		public static void Restore(GameObject entity, string tag)
		{
			if (!((Object)(object)entity == (Object)null) && visibilityStates.TryGetValue(entity, out var value))
			{
				if (string.IsNullOrWhiteSpace(tag))
				{
					tag = "default";
				}
				value.tags.Remove(tag);
				if (value.tags.Count <= 0)
				{
					RestoreInternal(entity, value);
				}
			}
		}

		public static void ForceRestore(GameObject entity)
		{
			if ((Object)(object)entity != (Object)null && visibilityStates.TryGetValue(entity, out var value))
			{
				RestoreInternal(entity, value);
			}
		}

		public static bool IsHidden(GameObject entity)
		{
			if ((Object)(object)entity != (Object)null)
			{
				return visibilityStates.ContainsKey(entity);
			}
			return false;
		}

		private static void HideInternal(GameObject entity, EntityState state)
		{
			if ((Object)(object)LFCUtilities.LocalPlayer != (Object)null && entity.TryGetComponentInParent<VehicleController>(out VehicleController result))
			{
				result.startKeyIgnitionTrigger.SetActive(false);
				result.removeKeyIgnitionTrigger.SetActive(false);
				result.backDoorContainer.SetActive(false);
				result.destroyedTruckMesh.SetActive(false);
				result.truckDestroyedExplosion.SetActive(false);
				result.backLightsContainer.SetActive(false);
				result.frontCabinLightContainer.SetActive(false);
				result.headlightsContainer.SetActive(false);
				result.SetVehicleCollisionForPlayer(false, LFCUtilities.LocalPlayer);
			}
			Renderer[] componentsInChildren = entity.GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val in componentsInChildren)
			{
				if ((Object)(object)val != (Object)null && val.enabled)
				{
					val.enabled = false;
					state.disabledRenderers.Add(val);
				}
			}
			Light[] componentsInChildren2 = entity.GetComponentsInChildren<Light>(true);
			foreach (Light val2 in componentsInChildren2)
			{
				if ((Object)(object)val2 != (Object)null && ((Behaviour)val2).enabled)
				{
					((Behaviour)val2).enabled = false;
					state.disabledLights.Add(val2);
				}
			}
			Rigidbody[] componentsInChildren3 = entity.GetComponentsInChildren<Rigidbody>(true);
			foreach (Rigidbody val3 in componentsInChildren3)
			{
				if ((Object)(object)val3 != (Object)null && val3.useGravity)
				{
					val3.useGravity = false;
					state.disabledGravitys.Add(val3);
				}
			}
			PlayerPhysicsRegion[] componentsInChildren4 = entity.GetComponentsInChildren<PlayerPhysicsRegion>(true);
			foreach (PlayerPhysicsRegion val4 in componentsInChildren4)
			{
				if ((Object)(object)val4 != (Object)null && !val4.disablePhysicsRegion)
				{
					val4.disablePhysicsRegion = true;
					state.disabledPhysicsRegions.Add(val4);
				}
			}
			Collider[] componentsInChildren5 = entity.GetComponentsInChildren<Collider>(true);
			foreach (Collider val5 in componentsInChildren5)
			{
				if ((Object)(object)val5 != (Object)null && val5.enabled)
				{
					val5.enabled = false;
					state.disabledColliders.Add(val5);
				}
			}
			TextMeshProUGUI[] componentsInChildren6 = entity.GetComponentsInChildren<TextMeshProUGUI>(true);
			foreach (TextMeshProUGUI val6 in componentsInChildren6)
			{
				if ((Object)(object)val6 != (Object)null && ((Behaviour)val6).enabled)
				{
					((Behaviour)val6).enabled = false;
					state.disabledTextMeshes.Add(val6);
				}
			}
			InteractTrigger[] componentsInChildren7 = entity.GetComponentsInChildren<InteractTrigger>(true);
			foreach (InteractTrigger val7 in componentsInChildren7)
			{
				if ((Object)(object)val7 != (Object)null && val7.interactable)
				{
					val7.interactable = false;
					state.disabledInteractTriggers.Add(val7);
				}
			}
			ParticleSystem[] componentsInChildren8 = entity.GetComponentsInChildren<ParticleSystem>(true);
			foreach (ParticleSystem val8 in componentsInChildren8)
			{
				if ((Object)(object)val8 != (Object)null && val8.isPlaying)
				{
					val8.Stop(true, (ParticleSystemStopBehavior)1);
					state.disabledParticles.Add(val8);
				}
			}
			AudioSource[] componentsInChildren9 = entity.GetComponentsInChildren<AudioSource>(true);
			foreach (AudioSource val9 in componentsInChildren9)
			{
				if ((Object)(object)val9 != (Object)null && val9.volume > 0f)
				{
					state.audioVolumes[val9] = val9.volume;
					val9.volume = 0f;
				}
			}
		}

		private static void RestoreInternal(GameObject entity, EntityState state)
		{
			if ((Object)(object)LFCUtilities.LocalPlayer != (Object)null && entity.TryGetComponentInParent<VehicleController>(out VehicleController result))
			{
				if (!result.carDestroyed)
				{
					result.startKeyIgnitionTrigger.SetActive(true);
					result.removeKeyIgnitionTrigger.SetActive(true);
					result.backDoorContainer.SetActive(true);
					result.backLightsContainer.SetActive(true);
					result.frontCabinLightContainer.SetActive(true);
					result.headlightsContainer.SetActive(true);
				}
				else
				{
					result.destroyedTruckMesh.SetActive(true);
				}
				result.SetVehicleCollisionForPlayer(true, LFCUtilities.LocalPlayer);
			}
			foreach (Renderer disabledRenderer in state.disabledRenderers)
			{
				if ((Object)(object)disabledRenderer != (Object)null)
				{
					disabledRenderer.enabled = true;
				}
			}
			foreach (Light disabledLight in state.disabledLights)
			{
				if ((Object)(object)disabledLight != (Object)null)
				{
					((Behaviour)disabledLight).enabled = true;
					CullFactorySoftCompat.RefreshLightPosition(disabledLight);
				}
			}
			foreach (Collider disabledCollider in state.disabledColliders)
			{
				if ((Object)(object)disabledCollider != (Object)null)
				{
					disabledCollider.enabled = true;
				}
			}
			foreach (PlayerPhysicsRegion disabledPhysicsRegion in state.disabledPhysicsRegions)
			{
				if ((Object)(object)disabledPhysicsRegion != (Object)null)
				{
					disabledPhysicsRegion.disablePhysicsRegion = false;
				}
			}
			foreach (Rigidbody disabledGravity in state.disabledGravitys)
			{
				if ((Object)(object)disabledGravity != (Object)null)
				{
					disabledGravity.useGravity = true;
				}
			}
			foreach (TextMeshProUGUI disabledTextMesh in state.disabledTextMeshes)
			{
				if ((Object)(object)disabledTextMesh != (Object)null)
				{
					((Behaviour)disabledTextMesh).enabled = true;
				}
			}
			foreach (InteractTrigger disabledInteractTrigger in state.disabledInteractTriggers)
			{
				if ((Object)(object)disabledInteractTrigger != (Object)null)
				{
					disabledInteractTrigger.interactable = true;
				}
			}
			foreach (ParticleSystem disabledParticle in state.disabledParticles)
			{
				if ((Object)(object)disabledParticle != (Object)null && (Object)(object)((Component)disabledParticle).gameObject != (Object)null)
				{
					disabledParticle.Play(true);
				}
			}
			foreach (KeyValuePair<AudioSource, float> audioVolume in state.audioVolumes)
			{
				if ((Object)(object)audioVolume.Key != (Object)null)
				{
					audioVolume.Key.volume = audioVolume.Value;
				}
			}
			if (entity.TryGetComponentInParent<GrabbableObject>(out GrabbableObject result2))
			{
				CullFactorySoftCompat.RefreshGrabbableObjectPosition(result2);
			}
			state.tags.Clear();
			visibilityStates.Remove(entity);
		}

		private static void CleanupDeadEntries()
		{
			List<GameObject> list = null;
			foreach (KeyValuePair<GameObject, EntityState> visibilityState in visibilityStates)
			{
				if ((Object)(object)visibilityState.Key == (Object)null)
				{
					if (list == null)
					{
						list = new List<GameObject>();
					}
					list.Add(visibilityState.Key);
				}
			}
			if (list == null)
			{
				return;
			}
			foreach (GameObject item in list)
			{
				visibilityStates.Remove(item);
			}
		}
	}
}
namespace LegaFusionCore.Patches
{
	public class EnemyAIPatch
	{
		private static readonly Dictionary<EnemyAI, int> extendedEnemyHP = new Dictionary<EnemyAI, int>();

		private static readonly int rateHP = 100;

		[HarmonyPatch(typeof(EnemyAI), "Start")]
		[HarmonyPostfix]
		public static void PostStart(EnemyAI __instance)
		{
			AddSpeedBehaviour(__instance);
			InitExtendedHP(__instance);
		}

		public static void AddSpeedBehaviour(EnemyAI __instance)
		{
			EnemySpeedBehaviour enemySpeedBehaviour = default(EnemySpeedBehaviour);
			if (!((Component)__instance).TryGetComponent<EnemySpeedBehaviour>(ref enemySpeedBehaviour))
			{
				EnemySpeedBehaviour enemySpeedBehaviour2 = ((Component)__instance).gameObject.AddComponent<EnemySpeedBehaviour>();
				enemySpeedBehaviour2.enemy = __instance;
			}
		}

		public static void InitExtendedHP(EnemyAI __instance)
		{
			if (!extendedEnemyHP.ContainsKey(__instance))
			{
				extendedEnemyHP[__instance] = __instance.enemyHP * rateHP;
			}
		}

		public static int GetExtendedHP(EnemyAI enemy)
		{
			if (!extendedEnemyHP.ContainsKey(enemy))
			{
				InitExtendedHP(enemy);
			}
			return extendedEnemyHP[enemy];
		}

		public static void SetExtendedHP(EnemyAI enemy, int value)
		{
			extendedEnemyHP[enemy] = Mathf.Max(0, value);
		}

		public static void DamageEnemy(EnemyAI enemy, int force, int playerWhoHit = -1, bool playHitSFX = false, int hitID = -1, bool callHitEnemy = true)
		{
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			InitExtendedHP(enemy);
			PlayerControllerB val = ((playerWhoHit == -1) ? null : StartOfRound.Instance.allPlayerObjects[playerWhoHit].GetComponent<PlayerControllerB>());
			if (LFCStatusEffectRegistry.HasStatus(((Component)enemy).gameObject, LFCStatusEffectRegistry.StatusEffectType.POISON))
			{
				force = (int)((double)force * 1.5);
			}
			int num = GetExtendedHP(enemy) - force;
			SetExtendedHP(enemy, num);
			int num2 = Mathf.CeilToInt((float)num / (float)rateHP);
			if (callHitEnemy)
			{
				if (num2 < enemy.enemyHP)
				{
					int num3 = enemy.enemyHP - num2;
					PlayerControllerB val2 = val;
					bool flag = playHitSFX;
					enemy.HitEnemyOnLocalClient(num3, default(Vector3), val2, flag, hitID);
				}
				else if (playHitSFX && (Object)(object)enemy.enemyType?.hitBodySFX != (Object)null && !enemy.isEnemyDead)
				{
					enemy.creatureSFX.PlayOneShot(enemy.enemyType.hitBodySFX);
					WalkieTalkie.TransmitOneShotAudio(enemy.creatureSFX, enemy.enemyType.hitBodySFX, 1f);
				}
			}
			if ((Object)(object)val != (Object)null && LFCStatusEffectRegistry.HasStatus(((Component)enemy).gameObject, LFCStatusEffectRegistry.StatusEffectType.BLEEDING))
			{
				int regenHP = Mathf.CeilToInt((float)force / 10f);
				LFCPlayerManager.HealPlayerOnLocalClient(val, regenHP);
			}
		}

		[HarmonyPatch(typeof(EnemyAI), "HitEnemy")]
		[HarmonyPostfix]
		public static void HitEnemyPostfix(EnemyAI __instance, int force = 1, PlayerControllerB playerWhoHit = null, bool playHitSFX = false, int hitID = -1)
		{
			int num = Mathf.CeilToInt((float)(GetExtendedHP(__instance) / rateHP));
			if (num >= __instance.enemyHP)
			{
				int playerWhoHit2 = (((Object)(object)playerWhoHit != (Object)null) ? ((int)playerWhoHit.playerClientId) : (-1));
				DamageEnemy(__instance, force * rateHP, playerWhoHit2, playHitSFX, hitID, callHitEnemy: false);
			}
		}

		[HarmonyPatch(typeof(EnemyAI), "OnDestroy")]
		[HarmonyPostfix]
		public static void OnDestroyPostfix(EnemyAI __instance)
		{
			extendedEnemyHP.Remove(__instance);
		}
	}
	public class GrabbableObjectPatch
	{
		[HarmonyPatch(typeof(GrabbableObject), "SetScrapValue")]
		[HarmonyPostfix]
		private static void SetAddonScanNode(ref GrabbableObject __instance)
		{
			AddonComponent component = ((Component)__instance).gameObject.GetComponent<AddonComponent>();
			if ((Object)(object)component != (Object)null)
			{
				ScanNodeProperties componentInChildren = ((Component)__instance).gameObject.GetComponentInChildren<ScanNodeProperties>();
				string text = "Addon: " + component.addonName;
				if ((Object)(object)componentInChildren != (Object)null && (componentInChildren.subText == null || !componentInChildren.subText.Contains(text)))
				{
					componentInChildren.subText = componentInChildren.subText + ((componentInChildren.subText != null) ? "\n" : "") + text;
				}
			}
		}

		[HarmonyPatch(typeof(GrabbableObject), "GrabItem")]
		[HarmonyPostfix]
		private static void GrabObject(ref GrabbableObject __instance)
		{
			if (LFCUtilities.ShouldBeLocalPlayer(__instance.playerHeldBy))
			{
				((Component)__instance).gameObject.GetComponent<AddonComponent>()?.StartCooldown(30);
			}
		}

		[HarmonyPatch(typeof(GrabbableObject), "SetControlTipsForItem")]
		[HarmonyPostfix]
		private static void SetControlTipsForAddon(ref GrabbableObject __instance)
		{
			AddonComponent component = ((Component)__instance).gameObject.GetComponent<AddonComponent>();
			if (!((Object)(object)component == (Object)null) && !component.isPassive)
			{
				component.SetTipsForItem(new string[1] { AddonInput.Instance.GetAddonToolTip() });
			}
		}

		[HarmonyPatch(typeof(GrabbableObject), "DestroyObjectInHand")]
		[HarmonyPostfix]
		private static void DestroyObjectRenderers(ref GrabbableObject __instance)
		{
			Renderer[] componentsInChildren = ((Component)__instance).gameObject.GetComponentsInChildren<Renderer>();
			foreach (Renderer val in componentsInChildren)
			{
				Object.Destroy((Object)(object)val);
			}
		}
	}
	public class HangarShipDoorPatch
	{
		[HarmonyPatch(typeof(HangarShipDoor), "Update")]
		[HarmonyPostfix]
		private static void UpdateShipDoor(HangarShipDoor __instance)
		{
			if (LFCShipFeatureRegistry.IsLocked(LFCShipFeatureRegistry.ShipFeatureType.SHIP_DOORS))
			{
				__instance.doorPower = 0f;
				((TMP_Text)__instance.doorPowerDisplay).text = "0%";
			}
		}
	}
	public class ItemChargerPatch
	{
		[HarmonyPatch(typeof(ItemCharger), "Update")]
		[HarmonyPostfix]
		private static void UpdateItemCharger(ref ItemCharger __instance)
		{
			if (LFCShipFeatureRegistry.IsLocked(LFCShipFeatureRegistry.ShipFeatureType.ITEM_CHARGER))
			{
				__instance.triggerScript.disabledHoverTip = "Not enough energy left...";
				__instance.triggerScript.interactable = false;
			}
		}
	}
	public class ManualCameraRendererPatch
	{
		[HarmonyPatch(typeof(ManualCameraRenderer), "SwitchScreenButton")]
		[HarmonyPrefix]
		private static bool SwitchScreenButton()
		{
			return !LFCShipFeatureRegistry.IsLocked(LFCShipFeatureRegistry.ShipFeatureType.MAP_SCREEN);
		}

		[HarmonyPatch(typeof(ManualCameraRenderer), "SwitchScreenOn")]
		[HarmonyPrefix]
		private static bool SwitchScreenOn()
		{
			return !LFCShipFeatureRegistry.IsLocked(LFCShipFeatureRegistry.ShipFeatureType.MAP_SCREEN);
		}

		[HarmonyPatch(typeof(ManualCameraRenderer), "SwitchScreenOnClientRpc")]
		[HarmonyPrefix]
		private static bool SwitchScreenOnClientRpc()
		{
			return !LFCShipFeatureRegistry.IsLocked(LFCShipFeatureRegistry.ShipFeatureType.MAP_SCREEN);
		}
	}
	public class MenuManagerPatch
	{
		[HarmonyPatch(typeof(MenuManager), "Awake")]
		[HarmonyPostfix]
		private static void AwakeMenu()
		{
			LFCStatusEffectRegistry.ClearStatus();
			LFCShipFeatureRegistry.ResetCache();
			LFCShipFeatureRegistry.ClearLocks();
			LFCPoweredLightsRegistry.ClearLocks();
			LFCObjectStateRegistry.ClearFlickeringFlashlight();
		}
	}
	public class NetworkBehaviourPatch
	{
		private static readonly Type[] trackedTypes = new Type[3]
		{
			typeof(GrabbableObject),
			typeof(EnemyAI),
			typeof(EntranceTeleport)
		};

		[HarmonyPatch(typeof(NetworkBehaviour), "InternalOnNetworkSpawn")]
		[HarmonyPostfix]
		private static void SpawnNetworkBehaviour(ref NetworkBehaviour __instance)
		{
			Type[] array = trackedTypes;
			foreach (Type type in array)
			{
				if (type.IsInstanceOfType(__instance))
				{
					LFCSpawnRegistry.Add((Component)(object)__instance);
					break;
				}
			}
		}

		[HarmonyPatch(typeof(NetworkBehaviour), "InternalOnNetworkDespawn")]
		[HarmonyPostfix]
		private static void DestroyNetworkBehaviour(ref NetworkBehaviour __instance)
		{
			Type[] array = trackedTypes;
			foreach (Type type in array)
			{
				if (type.IsInstanceOfType(__instance))
				{
					LFCSpawnRegistry.Remove((Component)(object)__instance);
					break;
				}
			}
		}
	}
	public class PlayerControllerBPatch
	{
		[HarmonyPatch(typeof(PlayerControllerB), "ConnectClientToPlayerObject")]
		[HarmonyPostfix]
		private static void ConnectPlayer(ref PlayerControllerB __instance)
		{
			if (LFCUtilities.ShouldBeLocalPlayer(__instance))
			{
				LFCStatRegistry.RegisterStat("Speed", __instance.movementSpeed, __instance.movementSpeed / 10f);
			}
		}

		[HarmonyPatch(typeof(PlayerControllerB), "Update")]
		[HarmonyPrefix]
		private static void UpdatePlayer(ref PlayerControllerB __instance)
		{
			if (LFCUtilities.ShouldBeLocalPlayer(__instance))
			{
				__instance.movementSpeed = LFCStatRegistry.GetFinalValue("Speed") ?? __instance.movementSpeed;
			}
		}

		[HarmonyPatch(typeof(PlayerControllerB), "DamagePlayer")]
		[HarmonyPrefix]
		private static void DamagePlayer(ref PlayerControllerB __instance, ref int damageNumber)
		{
			if (LFCUtilities.ShouldBeLocalPlayer(__instance) && LFCStatusEffectRegistry.HasStatus(((Component)__instance).gameObject, LFCStatusEffectRegistry.StatusEffectType.POISON))
			{
				damageNumber = Mathf.CeilToInt((float)damageNumber * 1.5f);
			}
		}
	}
	public class RoundManagerPatch
	{
		[HarmonyPatch(typeof(RoundManager), "SpawnScrapInLevel")]
		[HarmonyPostfix]
		private static void SpawnNewItems(ref RoundManager __instance)
		{
			Random random = new Random();
			foreach (LFCSpawnableItemRegistry.SpawnableItem item in LFCSpawnableItemRegistry.GetAll())
			{
				for (int i = 0; i < item.MaxSpawn; i++)
				{
					if (i < item.MinSpawn || random.Next(0, 100) <= item.Rarity)
					{
						LFCObjectsManager.SpawnNewObject(__instance, item.Item);
					}
				}
			}
		}

		[HarmonyTranspiler]
		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		private static IEnumerable<CodeInstruction> TurnOnLights(IEnumerable<CodeInstruction> instructions, ILGenerator il)
		{
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Expected O, but got Unknown
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Expected O, but got Unknown
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Expected O, but got Unknown
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Expected O, but got Unknown
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Expected O, but got Unknown
			List<CodeInstruction> list = new List<CodeInstruction>(instructions);
			MethodInfo methodInfo = AccessTools.Method(typeof(Animator), "SetBool", new Type[2]
			{
				typeof(string),
				typeof(bool)
			}, (Type[])null);
			MethodInfo methodInfo2 = AccessTools.Method(typeof(LFCPoweredLightsRegistry), "IsLocked", new Type[1] { typeof(Animator) }, (Type[])null);
			for (int i = 0; i < list.Count; i++)
			{
				if (!CodeInstructionExtensions.Calls(list[i], methodInfo))
				{
					continue;
				}
				int num = -1;
				for (int num2 = i; num2 >= 0; num2--)
				{
					if (list[num2].opcode == OpCodes.Ldstr && list[num2].operand is string text && text == "on")
					{
						num = num2;
						break;
					}
				}
				if (num == -1)
				{
					continue;
				}
				int num3 = num - 1;
				if (num3 >= 0)
				{
					Label label = il.DefineLabel();
					Label label2 = il.DefineLabel();
					if (i + 1 < list.Count)
					{
						list[i + 1].labels.Add(label2);
					}
					List<CodeInstruction> list2 = new List<CodeInstruction>(5)
					{
						new CodeInstruction(OpCodes.Dup, (object)null),
						new CodeInstruction(OpCodes.Call, (object)methodInfo2),
						new CodeInstruction(OpCodes.Brfalse_S, (object)label),
						new CodeInstruction(OpCodes.Pop, (object)null),
						new CodeInstruction(OpCodes.Br_S, (object)label2)
					};
					int num4 = num3 + 1;
					list.InsertRange(num4, list2);
					list[num4 + list2.Count].labels.Add(label);
					i += list2.Count;
				}
			}
			return list;
		}
	}
	public class ShipLightsPatch
	{
		[HarmonyPatch(typeof(ShipLights), "SetShipLightsBoolean")]
		[HarmonyPrefix]
		private static bool SetShipLightsBoolean()
		{
			return !LFCShipFeatureRegistry.IsLocked(LFCShipFeatureRegistry.ShipFeatureType.SHIP_LIGHTS);
		}

		[HarmonyPatch(typeof(ShipLights), "SetShipLightsClientRpc")]
		[HarmonyPrefix]
		private static bool SetShipLightsClientRpc()
		{
			return !LFCShipFeatureRegistry.IsLocked(LFCShipFeatureRegistry.ShipFeatureType.SHIP_LIGHTS);
		}

		[HarmonyPatch(typeof(ShipLights), "SetShipLightsOnLocalClientOnly")]
		[HarmonyPrefix]
		private static bool SetShipLightsOnLocalClientOnly()
		{
			return !LFCShipFeatureRegistry.IsLocked(LFCShipFeatureRegistry.ShipFeatureType.SHIP_LIGHTS);
		}

		[HarmonyPatch(typeof(ShipLights), "ToggleShipLights")]
		[HarmonyPrefix]
		private static bool ToggleShipLights()
		{
			return !LFCShipFeatureRegistry.IsLocked(LFCShipFeatureRegistry.ShipFeatureType.SHIP_LIGHTS);
		}

		[HarmonyPatch(typeof(ShipLights), "ToggleShipLightsOnLocalClientOnly")]
		[HarmonyPrefix]
		private static bool ToggleShipLightsOnLocalClientOnly()
		{
			return !LFCShipFeatureRegistry.IsLocked(LFCShipFeatureRegistry.ShipFeatureType.SHIP_LIGHTS);
		}
	}
	public class ShipTeleporterPatch
	{
		[HarmonyPatch(typeof(ShipTeleporter), "Update")]
		[HarmonyPostfix]
		private static void UpdateShipTeleporter(ref ShipTeleporter __instance)
		{
			if (LFCShipFeatureRegistry.IsLocked(LFCShipFeatureRegistry.ShipFeatureType.SHIP_TELEPORTERS))
			{
				__instance.buttonTrigger.disabledHoverTip = "Not enough energy left...";
				__instance.buttonTrigger.interactable = false;
			}
		}
	}
	public class StartOfRoundPatch
	{
		[HarmonyPatch(typeof(StartOfRound), "Start")]
		[HarmonyBefore(new string[] { "evaisa.lethallib" })]
		[HarmonyPostfix]
		private static void StartRound(ref StartOfRound __instance)
		{
			LoadVanillaPrefabs();
			AddonInput.Instance.EnableInput();
			if (NetworkManager.Singleton.IsHost && (Object)(object)LFCNetworkManager.Instance == (Object)null)
			{
				GameObject val = Object.Instantiate<GameObject>(LegaFusionCore.managerPrefab, ((Component)__instance).transform.parent);
				val.GetComponent<NetworkObject>().Spawn(false);
				LegaFusionCore.mls.LogInfo((object)"Spawning LFCNetworkManager");
			}
		}

		public static void LoadVanillaPrefabs()
		{
			if ((Object)(object)LegaFusionCore.bloodParticle == (Object)null)
			{
				LegaFusionCore.bloodParticle = LoadVanillaParticle("KnifeItem", "BloodParticle");
			}
			if ((Object)(object)LegaFusionCore.groundParticle == (Object)null)
			{
				LegaFusionCore.groundParticle = LoadVanillaParticle("SandWorm", "AppearFromGround1");
			}
		}

		public static GameObject LoadVanillaParticle(string prefabName, string particleName)
		{
			GameObject prefabFromName = LFCUtilities.GetPrefabFromName(prefabName);
			if ((Object)(object)prefabFromName == (Object)null)
			{
				return null;
			}
			ParticleSystem val = ((IEnumerable<ParticleSystem>)prefabFromName.GetComponentsInChildren<ParticleSystem>(true)).FirstOrDefault((Func<ParticleSystem, bool>)((ParticleSystem p) => ((Object)((Component)p).gameObject).name.Equals(particleName)));
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			GameObject val2 = Object.Instantiate<GameObject>(((Component)val).gameObject);
			((Object)val2).name = ((Object)((Component)val).gameObject).name;
			val2.SetActive(false);
			Object.DontDestroyOnLoad((Object)(object)val2);
			LFCPrefabRegistry.RegisterPrefab("Lega Fusion Core" + ((Object)val2).name, val2);
			return val2;
		}

		[HarmonyPatch(typeof(StartOfRound), "ShipLeave")]
		[HarmonyPostfix]
		public static void EndRound()
		{
			LFCStatusEffectRegistry.ClearStatus();
			LFCShipFeatureRegistry.ClearLocks();
			LFCPoweredLightsRegistry.ClearLocks();
			LFCObjectStateRegistry.ClearFlickeringFlashlight();
			foreach (AddonComponent item in from g in Object.FindObjectsOfType<GrabbableObject>()
				select ((Component)g).GetComponent<AddonComponent>())
			{
				if (!((Object)(object)item == (Object)null))
				{
					item.StopCooldown();
				}
			}
		}

		[HarmonyPatch(typeof(StartOfRound), "OnDisable")]
		[HarmonyPostfix]
		public static void OnDisable()
		{
			AddonInput.Instance.DisableInput();
			LFCNetworkManager.Instance = null;
			LFCSpawnRegistry.Clear();
		}
	}
	public class TVScriptPatch
	{
		[HarmonyPatch(typeof(TVScript), "TurnTVOnOff")]
		[HarmonyPrefix]
		private static bool TurnTVOnOff()
		{
			return !LFCShipFeatureRegistry.IsLocked(LFCShipFeatureRegistry.ShipFeatureType.SHIP_TV);
		}

		[HarmonyPatch(typeof(TVScript), "SwitchTVLocalClient")]
		[HarmonyPrefix]
		private static bool SwitchTVLocalClient()
		{
			return !LFCShipFeatureRegistry.IsLocked(LFCShipFeatureRegistry.ShipFeatureType.SHIP_TV);
		}

		[HarmonyPatch(typeof(TVScript), "TurnOnTVClientRpc")]
		[HarmonyPrefix]
		private static bool TurnOnTVClientRpc()
		{
			return !LFCShipFeatureRegistry.IsLocked(LFCShipFeatureRegistry.ShipFeatureType.SHIP_TV);
		}

		[HarmonyPatch(typeof(TVScript), "TurnOnTVAndSyncClientRpc")]
		[HarmonyPrefix]
		private static bool TurnOnTVAndSyncClientRpc()
		{
			return !LFCShipFeatureRegistry.IsLocked(LFCShipFeatureRegistry.ShipFeatureType.SHIP_TV);
		}

		[HarmonyPatch(typeof(TVScript), "TurnOffTVClientRpc")]
		[HarmonyPrefix]
		private static bool TurnOffTVClientRpc()
		{
			return !LFCShipFeatureRegistry.IsLocked(LFCShipFeatureRegistry.ShipFeatureType.SHIP_TV);
		}
	}
	public class VehicleControllerPatch
	{
		[HarmonyPatch(typeof(VehicleController), "Update")]
		[HarmonyPostfix]
		private static void UpdateVehicle(ref VehicleController __instance)
		{
			if (LFCVisibilityRegistry.IsHidden(((Component)__instance).gameObject))
			{
				__instance.driverSideDoorTrigger.interactable = false;
				__instance.passengerSideDoorTrigger.interactable = false;
			}
		}

		[HarmonyPatch(typeof(VehicleController), "EnableVehicleCollisionForAllPlayers")]
		[HarmonyPrefix]
		private static bool EnableVehicleCollisionForAllPlayers(ref VehicleController __instance)
		{
			return !LFCVisibilityRegistry.IsHidden(((Component)__instance).gameObject);
		}

		[HarmonyPatch(typeof(VehicleController), "SetVehicleCollisionForPlayer")]
		[HarmonyPrefix]
		private static bool SetVehicleCollisionForPlayer(ref VehicleController __instance, bool setEnabled)
		{
			if (setEnabled)
			{
				return !LFCVisibilityRegistry.IsHidden(((Component)__instance).gameObject);
			}
			return true;
		}
	}
}
namespace LegaFusionCore.ModsCompat
{
	public static class CullFactorySoftCompat
	{
		private static readonly bool CullFactoryAvailable;

		private static readonly MethodInfo RefreshGrabbableMethod;

		private static readonly MethodInfo RefreshLightMethod;

		static CullFactorySoftCompat()
		{
			if (Chainloader.PluginInfos.TryGetValue("com.fumiko.CullFactory", out var value) && value.Metadata.Version >= new Version(1, 5, 0))
			{
				Type type = Type.GetType("CullFactory.Behaviours.API.DynamicObjectsAPI, CullFactory");
				if (type != null)
				{
					RefreshGrabbableMethod = type.GetMethod("RefreshGrabbableObjectPosition", BindingFlags.Static | BindingFlags.Public);
					RefreshLightMethod = type.GetMethod("RefreshLightPosition", BindingFlags.Static | BindingFlags.Public);
					CullFactoryAvailable = RefreshGrabbableMethod != null && RefreshLightMethod != null;
				}
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		public static void RefreshGrabbableObjectPosition(GrabbableObject item)
		{
			item.EnableItemMeshes(true);
			if (CullFactoryAvailable)
			{
				RefreshGrabbableMethod?.Invoke(null, new object[1] { item });
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		public static void RefreshLightPosition(Light light)
		{
			if (CullFactoryAvailable)
			{
				RefreshLightMethod?.Invoke(null, new object[1] { light });
			}
		}
	}
	public static class GeneralImprovementsSoftCompat
	{
		public static void Patch(Harmony harmony)
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Expected O, but got Unknown
			Type type = Type.GetType("GeneralImprovements.Patches.ManualCameraRendererPatch, GeneralImprovements");
			if (type != null)
			{
				MethodInfo methodInfo = AccessTools.Method(type, "SwitchScreenOn", (Type[])null, (Type[])null);
				if (methodInfo != null)
				{
					HarmonyMethod val = new HarmonyMethod(AccessTools.Method(typeof(GeneralImprovementsSoftCompat), "SwitchScreenOn", (Type[])null, (Type[])null));
					harmony.Patch((MethodBase)methodInfo, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				}
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		private static bool SwitchScreenOn()
		{
			return !LFCShipFeatureRegistry.IsLocked(LFCShipFeatureRegistry.ShipFeatureType.MAP_SCREEN);
		}
	}
	public static class GoodItemScanSoftCompat
	{
		public static void Patch(Harmony harmony)
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Expected O, but got Unknown
			Type type = Type.GetType("GoodItemScan.Scanner, GoodItemScan");
			if (type != null)
			{
				MethodInfo methodInfo = AccessTools.Method(type, "ScanNodes", (Type[])null, (Type[])null);
				if (methodInfo != null)
				{
					HarmonyMethod val = new HarmonyMethod(AccessTools.Method(typeof(GoodItemScanSoftCompat), "ScanNodes", (Type[])null, (Type[])null));
					harmony.Patch((MethodBase)methodInfo, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				}
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		private static void ScanNodes(ref ScanNodeProperties[] scanNodes)
		{
			if (scanNodes != null && scanNodes.Length != 0)
			{
				Collider val = default(Collider);
				scanNodes = scanNodes.Where((ScanNodeProperties n) => (Object)(object)n != (Object)null && ((Component)n).TryGetComponent<Collider>(ref val) && val.enabled).ToArray();
			}
		}
	}
	public static class MoreCompantSoftCompat
	{
		public static void Patch(Harmony harmony)
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Expected O, but got Unknown
			Type type = Type.GetType("MoreCompany.Cosmetics.CosmeticApplication, MoreCompany");
			if (type != null)
			{
				MethodInfo methodInfo = AccessTools.Method(type, "UpdateAllCosmeticVisibilities", (Type[])null, (Type[])null);
				if (methodInfo != null)
				{
					HarmonyMethod val = new HarmonyMethod(AccessTools.Method(typeof(MoreCompantSoftCompat), "UpdateAllCosmeticVisibilities", (Type[])null, (Type[])null));
					harmony.Patch((MethodBase)methodInfo, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				}
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		public static bool UpdateAllCosmeticVisibilities(object __instance)
		{
			MonoBehaviour val = (MonoBehaviour)((__instance is MonoBehaviour) ? __instance : null);
			if (val != null)
			{
				PlayerControllerB componentInParent = ((Component)val).GetComponentInParent<PlayerControllerB>();
				object obj = ((componentInParent != null) ? ((Component)componentInParent).gameObject : null);
				if (obj == null)
				{
					EnemyAI componentInParent2 = ((Component)val).GetComponentInParent<EnemyAI>();
					obj = ((componentInParent2 != null) ? ((Component)componentInParent2).gameObject : null) ?? ((Component)((Component)val).transform.root).gameObject;
				}
				GameObject val2 = (GameObject)obj;
				return !LFCVisibilityRegistry.IsHidden(val2.gameObject);
			}
			return true;
		}
	}
	public static class SelfSortingStorageSoftCompat
	{
		private static Type LightButtonType;

		private static MethodInfo SwitchLightsMethod;

		public static void Patch(Harmony harmony)
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Expected O, but got Unknown
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Expected O, but got Unknown
			Type type = Type.GetType("SelfSortingStorage.Utils.Effects, SelfSortingStorage");
			if (type != null)
			{
				MethodInfo methodInfo = AccessTools.Method(type, "IsTriggerValid", (Type[])null, (Type[])null);
				if (methodInfo != null)
				{
					HarmonyMethod val = new HarmonyMethod(AccessTools.Method(typeof(SelfSortingStorageSoftCompat), "IsTriggerValid", (Type[])null, (Type[])null));
					harmony.Patch((MethodBase)methodInfo, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				}
			}
			LightButtonType = Type.GetType("SelfSortingStorage.Buttons.LightButton, SelfSortingStorage");
			if (LightButtonType != null)
			{
				SwitchLightsMethod = AccessTools.Method(LightButtonType, "SwitchLights", (Type[])null, (Type[])null);
				if (SwitchLightsMethod != null)
				{
					HarmonyMethod val2 = new HarmonyMethod(AccessTools.Method(typeof(SelfSortingStorageSoftCompat), "PreSwitchLights", (Type[])null, (Type[])null));
					harmony.Patch((MethodBase)SwitchLightsMethod, val2, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				}
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		private static bool IsTriggerValid(out string notValidText)
		{
			if (LFCShipFeatureRegistry.IsLocked(LFCShipFeatureRegistry.ShipFeatureType.SMART_CUPBOARD))
			{
				notValidText = "Not enough energy left...";
				return false;
			}
			notValidText = "[Nothing to store]";
			return true;
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		public static bool PreSwitchLights()
		{
			return !LFCShipFeatureRegistry.IsLocked(LFCShipFeatureRegistry.ShipFeatureType.SMART_CUPBOARD);
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		public static void SwitchLights(bool on)
		{
			if (LightButtonType != null)
			{
				Object val = Object.FindObjectOfType(LightButtonType);
				if (SwitchLightsMethod != null && val != (Object)null)
				{
					SwitchLightsMethod.Invoke(val, new object[1] { on });
				}
			}
		}
	}
	public static class SellBodiesFixedSoftCompat
	{
		private static readonly BaseUnityPlugin SellBodiesInstance;

		static SellBodiesFixedSoftCompat()
		{
			if (Chainloader.PluginInfos.TryGetValue("Entity378.sellbodies", out var value))
			{
				SellBodiesInstance = value.Instance;
			}
		}

		public static void RegisterBody(string enemyName, Item item, int minValue, int maxValue, bool enabled)
		{
			if ((Object)(object)SellBodiesInstance != (Object)null && (Object)(object)item != (Object)null)
			{
				Utilities.FixMixerGroups(item.spawnPrefab);
				item.spawnPrefab.AddComponent(AccessTools.TypeByName("BodySyncer"));
				item.minValue = minValue;
				item.maxValue = maxValue;
				NetworkPrefabs.RegisterNetworkPrefab(item.spawnPrefab);
				Items.RegisterItem(item);
				if (enabled && AccessTools.Field(((object)SellBodiesInstance).GetType(), "BodySpawns")?.GetValue(SellBodiesInstance) is IDictionary dictionary)
				{
					dictionary[enemyName] = item;
				}
			}
		}
	}
}
namespace LegaFusionCore.Managers
{
	public static class LFCEnemyManager
	{
		public static bool CanDie(EnemyAI enemy)
		{
			if ((Object)(object)enemy?.enemyType == (Object)null)
			{
				return false;
			}
			string[] source = new string[11]
			{
				"Spring", "Jester", "Clay Surgeon", "Red Locust Bees", "Earth Leviathan", "Girl", "Blob", "Butler Bees", "RadMech", "Docile Locust Bees",
				"Puffer"
			};
			if (enemy.enemyType.canDie)
			{
				return !source.Contains(enemy.enemyType.enemyName);
			}
			return false;
		}

		public static bool FoundClosestPlayerInRange(this EnemyAI enemy, int range, int senseRange, float width = 60f, bool cannotBeInShip = false)
		{
			PlayerControllerB val = enemy.CheckLineOfSightForPlayer(width, range, senseRange);
			if ((Object)(object)val != (Object)null && enemy.PlayerIsTargetable(val, cannotBeInShip, false))
			{
				return Object.op_Implicit((Object)(object)(enemy.targetPlayer = val));
			}
			return false;
		}

		public static bool TargetClosestPlayerInAnyCase(this EnemyAI enemy, out float distance, bool cannotBeInShip = false)
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			enemy.mostOptimalDistance = 2000f;
			distance = enemy.mostOptimalDistance;
			enemy.targetPlayer = null;
			for (int i = 0; i < StartOfRound.Instance.connectedPlayersAmount + 1; i++)
			{
				PlayerControllerB val = StartOfRound.Instance.allPlayerScripts[i];
				if (enemy.PlayerIsTargetable(val, cannotBeInShip, false))
				{
					enemy.tempDist = Vector3.Distance(((Component)enemy).transform.position, ((Component)StartOfRound.Instance.allPlayerScripts[i]).transform.position);
					if (enemy.tempDist < enemy.mostOptimalDistance)
					{
						distance = enemy.tempDist;
						enemy.mostOptimalDistance = enemy.tempDist;
						enemy.targetPlayer = StartOfRound.Instance.allPlayerScripts[i];
					}
				}
			}
			return (Object)(object)enemy.targetPlayer != (Object)null;
		}

		public static bool TargetOutsideChasedPlayer(this EnemyAI enemy)
		{
			if ((Object)(object)enemy.targetPlayer != (Object)null && enemy.targetPlayer.isInsideFactory == enemy.isOutside)
			{
				enemy.GoTowardsEntrance();
				return true;
			}
			return false;
		}

		public static void GoTowardsEntrance(this EnemyAI enemy)
		{
			//IL_000d: 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_0046: 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_002f: 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)
			EntranceTeleport closestEntrance = enemy.GetClosestEntrance();
			if (Vector3.Distance(((Component)enemy).transform.position, closestEntrance.entrancePoint.position) < 1f)
			{
				Vector3 entranceExitPosition = GetEntranceExitPosition(closestEntrance);
				((MonoBehaviour)enemy).StartCoroutine(enemy.GoTowardsCoroutine(entranceExitPosition));
			}
			else
			{
				enemy.SetDestinationToPosition(closestEntrance.entrancePoint.position, false);
			}
		}

		public static EntranceTeleport GetClosestEntrance(this EnemyAI enemy)
		{
			return (from e in LFCSpawnRegistry.GetAllAs<EntranceTeleport>()
				where e.isEntranceToBuilding == enemy.isOutside
				orderby Vector3.Distance(((Component)enemy).transform.position, e.entrancePoint.position)
				select e).FirstOrDefault();
		}

		public static Vector3 GetEntranceExitPosition(EntranceTeleport entranceTeleport)
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			EntranceTeleport? obj = ((IEnumerable<EntranceTeleport>)LFCSpawnRegistry.GetAllAs<EntranceTeleport>()).FirstOrDefault((Func<EntranceTeleport, bool>)((EntranceTeleport e) => e.isEntranceToBuilding != entranceTeleport.isEntranceToBuilding && e.entranceId == entranceTeleport.entranceId));
			if (obj == null)
			{
				return Vector3.zero;
			}
			return obj.entrancePoint.position;
		}

		public static IEnumerator GoTowardsCoroutine(this EnemyAI enemy, Vector3 position)
		{
			//IL_000e: 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)
			yield return (object)new WaitForSeconds(1f);
			LFCNetworkManager.Instance.TeleportEnemyEveryoneRpc(NetworkObjectReference.op_Implicit(enemy.thisNetworkObject), position, !enemy.isOutside);
		}

		public static void TeleportEnemy(this EnemyAI enemy, Vector3 teleportPosition, bool isOutside)
		{
			//IL_0011: 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_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)enemy != (Object)null)
			{
				enemy.SetEnemyOutside(isOutside);
				enemy.serverPosition = teleportPosition;
				((Component)enemy).transform.position = teleportPosition;
				enemy.agent.Warp(teleportPosition);
				enemy.SyncPositionToClients();
			}
		}

		public static bool TryGetSafeRandomNavMeshPosition(this EnemyAI enemy, Vector3 origin, float radius, out Vector3 position, int maxAttempts = 15)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: 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_0031: 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_005d: 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)
			enemy.path1 = new NavMeshPath();
			for (int i = 0; i < maxAttempts; i++)
			{
				position = RoundManager.Instance.GetRandomNavMeshPositionInRadius(origin, radius, default(NavMeshHit));
				if (enemy.agent.CalculatePath(position, enemy.path1) && (int)enemy.path1.status == 0)
				{
					return true;
				}
			}
			position = origin;
			return false;
		}

		public static IEnumerator WaitForFullAnimation(this EnemyAI enemy, string clipName, float maxDuration = 10f, int layer = 0)
		{
			float timer = 0f;
			while (true)
			{
				AnimatorClipInfo[] currentAnimatorClipInfo = enemy.creatureAnimator.GetCurrentAnimatorClipInfo(layer);
				if (currentAnimatorClipInfo.Length != 0 && ((Object)((AnimatorClipInfo)(ref currentAnimatorClipInfo[0])).clip).name.Contains(clipName))
				{
					break;
				}
				timer += Time.deltaTime;
				if (timer > maxDuration)
				{
					yield break;
				}
				yield return null;
			}
			while (true)
			{
				AnimatorStateInfo currentAnimatorStateInfo = enemy.creatureAnimator.GetCurrentAnimatorStateInfo(layer);
				if (((AnimatorStateInfo)(ref currentAnimatorStateInfo)).normalizedTime < 1f)
				{
					timer += Time.deltaTime;
					if (timer > maxDuration)
					{
						break;
					}
					yield return null;
					continue;
				}
				break;
			}
		}
	}
	public static class LFCGlobalManager
	{
		public static void PlayParticle(string tag, Vector3 position, Quaternion rotation, float scaleFactor = 1f, bool active = true)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			GameObject prefab = LFCPrefabRegistry.GetPrefab(tag);
			if ((Object)(object)prefab == (Object)null)
			{
				LegaFusionCore.mls.LogWarning((object)("[PlayParticle] No prefab found for the tag: " + tag));
			}
			else
			{
				PlayParticle(prefab, position, rotation, scaleFactor, active);
			}
		}

		public static void PlayParticle(GameObject prefab, Vector3 position, Quaternion rotation, float scaleFactor = 1f, bool active = true)
		{
			//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_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_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_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_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = Object.Instantiate<GameObject>(prefab, position, rotation);
			val.transform.localScale = prefab.transform.localScale * scaleFactor;
			val.SetActive(active);
			ParticleSystem component = val.GetComponent<ParticleSystem>();
			if ((Object)(object)component == (Object)null)
			{
				LegaFusionCore.mls.LogWarning((object)("[PlayParticle] Prefab " + ((Object)prefab).name + " has no ParticleSystem."));
				Object.Destroy((Object)(object)val);
				return;
			}
			MainModule main = component.main;
			if (scaleFactor != 1f)
			{
				((MainModule)(ref main)).startSizeMultiplier = ((MainModule)(ref main)).startSizeMultiplier * scaleFactor;
				((MainModule)(ref main)).startSpeedMultiplier = ((MainModule)(ref main)).startSpeedMultiplier * scaleFactor;
				EmissionModule emission = component.emission;
				if (((EmissionModule)(ref emission)).burstCount > 0)
				{
					for (int i = 0; i < ((EmissionModule)(ref emission)).burstCount; i++)
					{
						Burst burst = ((EmissionModule)(ref emission)).GetBurst(i);
						MinMaxCurve count = ((Burst)(ref burst)).count;
						((Burst)(ref burst)).count = new MinMaxCurve(((MinMaxCurve)(ref count)).constant * scaleFactor);
						((EmissionModule)(ref emission)).SetBurst(i, burst);
					}
				}
				((EmissionModule)(ref emission)).rateOverTimeMultiplier = ((EmissionModule)(ref emission)).rateOverTimeMultiplier * scaleFactor;
				((MainModule)(ref main)).maxParticles = Mathf.RoundToInt((float)((MainModule)(ref main)).maxParticles * scaleFactor);
			}
			MainModule main2 = component.main;
			if (!((MainModule)(ref main2)).playOnAwake)
			{
				component.Play();
			}
			main2 = component.main;
			Object.Destroy((Object)(object)val, ((MainModule)(ref main2)).duration);
		}

		public static void PlayAudio(string tag, Vector3 position, bool active = true)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			GameObject prefab = LFCPrefabRegistry.GetPrefab(tag);
			if ((Object)(object)prefab == (Object)null)
			{
				LegaFusionCore.mls.LogWarning((object)("[PlayAudio] No prefab found for the tag: " + tag));
			}
			else
			{
				PlayAudio(prefab, position, active);
			}
		}

		public static void PlayAudio(GameObject prefab, Vector3 position, bool active = true)
		{
			//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)
			GameObject val = Object.Instantiate<GameObject>(prefab, position, Quaternion.identity);
			AudioSource component = val.GetComponent<AudioSource>();
			if ((Object)(object)component == (Object)null || (Object)(object)component.clip == (Object)null)
			{
				LegaFusionCore.mls.LogWarning((object)("[PlayAudio] Prefab " + ((Object)prefab).name + " has no AudioSource or clip."));
				Object.Destroy((Object)(object)val);
				return;
			}
			val.SetActive(active);
			if (!component.playOnAwake)
			{
				component.Play();
			}
			Object.Destroy((Object)(object)val, component.clip.length);
		}
	}
	public static class LFCMapObjectsManager
	{
		public static void SpawnOutsideMapObjectsForServer(int min, int max, Action<Vector3, Quaternion> spawnAction)
		{
			//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)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: 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)
			Random random = new Random();
			for (int i = 0; i < random.Next(min, max); i++)
			{
				GameObject[] outsideAINodes = RoundManager.Instance.outsideAINodes;
				Vector3 position = outsideAINodes[random.Next(0, outsideAINodes.Length)].transform.position;
				position = RoundManager.Instance.GetRandomNavMeshPositionInBoxPredictable(position, 10f, default(NavMeshHit), random, -1, 1f) + Vector3.up;
				spawnAction(position, Quaternion.identity);
			}
		}

		public static void SpawnScatteredMapObjectsForServer(int mapObjectsAmount, int minInside, int minOutside, Action<Vector3, bool> spawnAction)
		{
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01be: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01da: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0200: Unknown result type (might be due to invalid IL or missing references)
			//IL_027b: Unknown result type (might be due to invalid IL or missing references)
			//IL_027d: Unknown result type (might be due to invalid IL or missing references)
			//IL_028f: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0249: Unknown result type (might be due to invalid IL or missing references)
			//IL_024e: Unknown result type (might be due to invalid IL or missing references)
			if (!LFCUtilities.IsServer || (Object)(object)RoundManager.Instance == (Object)null)
			{
				return;
			}
			Random random = new Random();
			List<Vector3> selectedPositions = new List<Vector3>();
			StartOfRound.Instance.allPlayerScripts.Where((PlayerControllerB p) => !p.isPlayerDead).ToList().ForEach(delegate(PlayerControllerB p)
			{
				//IL_000c: Unknown result type (might be due to invalid IL or missing references)
				selectedPositions.Add(((Component)p).transform.position);
			});
			List<GameObject> list = RoundManager.Instance.insideAINodes.Where((GameObject n) => (Object)(object)n != (Object)null).ToList();
			List<GameObject> list2 = RoundManager.Instance.outsideAINodes.Where((GameObject n) => (Object)(object)n != (Object)null).ToList();
			LFCUtilities.Shuffle(list);
			LFCUtilities.Shuffle(list2);
			List<bool> list3 = new List<bool>(mapObjectsAmount);
			minInside = Mathf.Clamp(minInside, 0, mapObjectsAmount);
			minOutside = Mathf.Clamp(minOutside, 0, mapObjectsAmount - minInside);
			for (int i = 0; i < minInside; i++)
			{
				list3.Add(item: false);
			}
			for (int j = 0; j < minOutside; j++)
			{
				list3.Add(item: true);
			}
			while (list3.Count < mapObjectsAmount)
			{
				list3.Add(random.Next(0, 2) == 0);
			}
			RaycastHit val3 = default(RaycastHit);
			foreach (bool item2 in list3)
			{
				float num = float.MinValue;
				Vector3 val = Vector3.zero;
				GameObject item = null;
				List<GameObject> list4 = (item2 ? list2 : list);
				foreach (GameObject item3 in list4)
				{
					Vector3 val2 = RoundManager.Instance.GetRandomNavMeshPositionInBoxPredictable(item3.transform.position, 10f, default(NavMeshHit), random, -1, 1f) + Vector3.up;
					if (!Physics.Raycast(val2, Vector3.down, ref val3, 5f, StartOfRound.Instance.collidersAndRoomMaskAndDefault))
					{
						continue;
					}
					Vector3 validPosition = ((RaycastHit)(ref val3)).point;
					float num2 = ((selectedPositions.Count > 0) ? selectedPositions.Min((Vector3 p) => Vector3.Distance(p, validPosition)) : float.MaxValue);
					if (num2 > 50f || num2 > num)
					{
						num = num2;
						val = validPosition;
						item = item3;
						if (num2 > 50f)
						{
							break;
						}
					}
				}
				if (val != Vector3.zero)
				{
					selectedPositions.Add(v