Decompiled source of LethalMon v0.6.7

plugins/LethalMon/LethalMon.dll

Decompiled a month ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using AntlerShed.SkinRegistry;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using DigitalRuby.ThunderAndLightning;
using DunGen;
using GameNetcodeStuff;
using HarmonyLib;
using LethalCompanyInputUtils.Api;
using LethalCompanyInputUtils.BindingPathEnums;
using LethalLib.Modules;
using LethalMon;
using LethalMon.Behaviours;
using LethalMon.CatchableEnemy;
using LethalMon.Compatibility;
using LethalMon.CustomPasses;
using LethalMon.Items;
using LethalMon.NetcodePatcher;
using LethalMon.PC;
using LethalMon.Patches;
using LethalMon.Save;
using LethalMon.Throw;
using Microsoft.CodeAnalysis;
using Mirage.Unity;
using ModelReplacement;
using ModelReplacement.Monobehaviors.Enemies;
using Newtonsoft.Json;
using TMPro;
using Unity.Collections;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.Animations.Rigging;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.InputSystem;
using UnityEngine.Rendering;
using UnityEngine.Rendering.HighDefinition;
using UnityEngine.Rendering.RendererUtils;
using UnityEngine.Serialization;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("LethalMon")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+6c08b8ab2db1c30cc011bc23574d46e6b738daa1")]
[assembly: AssemblyProduct("LethalMon")]
[assembly: AssemblyTitle("LethalMon")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
[module: NetcodePatchedAssembly]
internal class <Module>
{
	static <Module>()
	{
		NetworkVariableSerializationTypes.InitializeSerializer_FixedString<FixedString64Bytes>();
		NetworkVariableSerializationTypes.InitializeEqualityChecker_UnmanagedIEquatable<FixedString64Bytes>();
		NetworkVariableSerializationTypes.InitializeSerializer_FixedString<FixedString512Bytes>();
		NetworkVariableSerializationTypes.InitializeEqualityChecker_UnmanagedIEquatable<FixedString512Bytes>();
		NetworkVariableSerializationTypes.InitializeSerializer_UnmanagedByMemcpy<float>();
		NetworkVariableSerializationTypes.InitializeEqualityChecker_UnmanagedIEquatable<float>();
	}
}
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
public class SeeThroughCustomPass : CustomPass
{
	public Material seeThroughMaterial = new Material(Utils.WireframeMaterial);

	public LayerMask seeThroughLayer;

	public float maxVisibilityDistance = 20f;

	[SerializeField]
	private readonly Shader stencilShader = Utils.SeeThroughShader;

	private Material? stencilMaterial;

	private ShaderTagId[] shaderTags = Array.Empty<ShaderTagId>();

	protected override bool executeInSceneView => true;

	public void ConfigureMaterial(Color edgeColor, Color fillColor, float thickness)
	{
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		seeThroughMaterial.SetColor("_EdgeColor", edgeColor);
		seeThroughMaterial.SetColor("_MainColor", fillColor);
		seeThroughMaterial.SetFloat("_WireframeVal", thickness);
	}

	protected override void Setup(ScriptableRenderContext renderContext, CommandBuffer cmd)
	{
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_0041: Unknown result type (might be due to invalid IL or missing references)
		//IL_0046: Unknown result type (might be due to invalid IL or missing references)
		//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)
		stencilMaterial = CoreUtils.CreateEngineMaterial(stencilShader);
		shaderTags = (ShaderTagId[])(object)new ShaderTagId[4]
		{
			new ShaderTagId("Forward"),
			new ShaderTagId("ForwardOnly"),
			new ShaderTagId("SRPDefaultUnlit"),
			new ShaderTagId("FirstPass")
		};
	}

	protected override void Execute(CustomPassContext ctx)
	{
		//IL_0048: Unknown result type (might be due to invalid IL or missing references)
		//IL_0049: Unknown result type (might be due to invalid IL or missing references)
		//IL_004e: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_0062: Unknown result type (might be due to invalid IL or missing references)
		//IL_008a: Unknown result type (might be due to invalid IL or missing references)
		//IL_008b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0090: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)stencilMaterial == (Object)null)
		{
			stencilMaterial = CoreUtils.CreateEngineMaterial(stencilShader);
		}
		stencilMaterial.SetInt("_StencilWriteMask", 64);
		seeThroughMaterial.SetFloat("_MaxVisibilityDistance", maxVisibilityDistance);
		RenderObjects(ctx.renderContext, ctx.cmd, stencilMaterial, 0, (CompareFunction)4, ctx.cullingResults, ctx.hdCamera);
		StencilState value = default(StencilState);
		((StencilState)(ref value))..ctor(true, (byte)64, byte.MaxValue, (CompareFunction)3, (StencilOp)0, (StencilOp)0, (StencilOp)0);
		RenderObjects(ctx.renderContext, ctx.cmd, seeThroughMaterial, seeThroughMaterial.FindPass("ForwardOnly"), (CompareFunction)7, ctx.cullingResults, ctx.hdCamera, value);
	}

	public override IEnumerable<Material> RegisterMaterialForInspector()
	{
		yield return seeThroughMaterial;
	}

	private void RenderObjects(ScriptableRenderContext renderContext, CommandBuffer cmd, Material overrideMaterial, int passIndex, CompareFunction depthCompare, CullingResults cullingResult, HDCamera hdCamera, StencilState? overrideStencil = null)
	{
		//IL_0008: 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_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_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_004e: Unknown result type (might be due to invalid IL or missing references)
		//IL_006a: Unknown result type (might be due to invalid IL or missing references)
		//IL_006c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0076: Unknown result type (might be due to invalid IL or missing references)
		//IL_0081: Unknown result type (might be due to invalid IL or missing references)
		//IL_0082: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c7: 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_0093: Unknown result type (might be due to invalid IL or missing references)
		//IL_0098: Unknown result type (might be due to invalid IL or missing references)
		//IL_009c: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ac: 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)
		RendererListDesc val = default(RendererListDesc);
		((RendererListDesc)(ref val))..ctor(shaderTags, cullingResult, hdCamera.camera);
		val.rendererConfiguration = (PerObjectData)0;
		val.renderQueueRange = RenderQueueRange.all;
		val.sortingCriteria = (SortingCriteria)4;
		val.excludeObjectMotionVectors = false;
		val.overrideMaterial = overrideMaterial;
		val.overrideMaterialPassIndex = passIndex;
		val.layerMask = LayerMask.op_Implicit(seeThroughLayer);
		RenderStateBlock value = default(RenderStateBlock);
		((RenderStateBlock)(ref value))..ctor((RenderStateMask)4);
		((RenderStateBlock)(ref value)).depthState = new DepthState(true, depthCompare);
		val.stateBlock = value;
		RendererListDesc val2 = val;
		if (overrideStencil.HasValue)
		{
			RenderStateBlock value2 = val2.stateBlock.Value;
			((RenderStateBlock)(ref value2)).mask = (RenderStateMask)(((RenderStateBlock)(ref value2)).mask | 8);
			((RenderStateBlock)(ref value2)).stencilState = overrideStencil.Value;
			val2.stateBlock = value2;
		}
		CoreUtils.DrawRendererList(renderContext, cmd, ((ScriptableRenderContext)(ref renderContext)).CreateRendererList(val2));
	}

	protected override void Cleanup()
	{
	}
}
namespace LethalMon
{
	internal class Cache
	{
		private static readonly Dictionary<int, TamedEnemyBehaviour?> TamedEnemyBehaviours = new Dictionary<int, TamedEnemyBehaviour>();

		private static readonly Dictionary<ulong, TamedEnemyBehaviour?> PlayerPets = new Dictionary<ulong, TamedEnemyBehaviour>();

		private static readonly Dictionary<int, PlayerControllerB> PlayersColliders = new Dictionary<int, PlayerControllerB>();

		private static readonly Dictionary<int, GrabbableObject> GrabbableObjectsColliders = new Dictionary<int, GrabbableObject>();

		private static readonly Dictionary<int, AnimatedObjectTrigger> DoorsAnimatedObjectTriggers = new Dictionary<int, AnimatedObjectTrigger>();

		private static readonly Dictionary<int, Collider> TerminalAccessibleObjectsColliders = new Dictionary<int, Collider>();

		private static readonly Dictionary<int, DoorLock> DoorLocksColliders = new Dictionary<int, DoorLock>();

		private static readonly Dictionary<int, EnemyAI> EnemiesColliders = new Dictionary<int, EnemyAI>();

		public static TamedEnemyBehaviour? GetTamedEnemyBehaviour(EnemyAI enemyAI)
		{
			if ((Object)(object)enemyAI == (Object)null)
			{
				return null;
			}
			if (TamedEnemyBehaviours.TryGetValue(((Object)enemyAI).GetInstanceID(), out TamedEnemyBehaviour value))
			{
				return value;
			}
			value = ((Component)enemyAI).GetComponent<TamedEnemyBehaviour>();
			TamedEnemyBehaviours.Add(((Object)enemyAI).GetInstanceID(), value);
			return value;
		}

		public static void SetPlayerPet(PlayerControllerB player, TamedEnemyBehaviour tamedEnemyBehaviour)
		{
			PlayerPets[player.playerClientId] = tamedEnemyBehaviour;
		}

		public static void RemovePlayerPet(PlayerControllerB player)
		{
			PlayerPets.Remove(player.playerClientId);
		}

		public static void ClearPlayerPets()
		{
			PlayerPets.Clear();
		}

		public static bool GetPlayerPet(PlayerControllerB player, out TamedEnemyBehaviour? playerPet)
		{
			return PlayerPets.TryGetValue(player.playerClientId, out playerPet);
		}

		public static PlayerControllerB? GetPlayerFromCollider(Collider collider)
		{
			if ((Object)(object)collider == (Object)null)
			{
				return null;
			}
			if (PlayersColliders.TryGetValue(((Object)collider).GetInstanceID(), out PlayerControllerB value))
			{
				return value;
			}
			value = ((Component)collider).gameObject.GetComponent<PlayerControllerB>();
			PlayersColliders.Add(((Object)collider).GetInstanceID(), value);
			return value;
		}

		public static GrabbableObject? GetGrabbableObjectFromCollider(Collider collider)
		{
			if ((Object)(object)collider == (Object)null)
			{
				return null;
			}
			if (GrabbableObjectsColliders.TryGetValue(((Object)collider).GetInstanceID(), out GrabbableObject value))
			{
				return value;
			}
			value = ((Component)collider).gameObject.GetComponent<GrabbableObject>();
			GrabbableObjectsColliders.Add(((Object)collider).GetInstanceID(), value);
			return value;
		}

		public static AnimatedObjectTrigger? GetDoorAnimatedObjectTrigger(DoorLock doorLock)
		{
			if ((Object)(object)doorLock == (Object)null)
			{
				return null;
			}
			if (DoorsAnimatedObjectTriggers.TryGetValue(((Object)doorLock).GetInstanceID(), out AnimatedObjectTrigger value))
			{
				return value;
			}
			value = ((Component)doorLock).GetComponent<AnimatedObjectTrigger>();
			DoorsAnimatedObjectTriggers.Add(((Object)doorLock).GetInstanceID(), value);
			return value;
		}

		public static Collider? GetTerminalAccessibleObjectCollider(TerminalAccessibleObject terminalAccessibleObject)
		{
			if ((Object)(object)terminalAccessibleObject == (Object)null)
			{
				return null;
			}
			if (TerminalAccessibleObjectsColliders.TryGetValue(((Object)terminalAccessibleObject).GetInstanceID(), out Collider value))
			{
				return value;
			}
			value = ((Component)terminalAccessibleObject).GetComponentInParent<Collider>();
			TerminalAccessibleObjectsColliders.Add(((Object)terminalAccessibleObject).GetInstanceID(), value);
			return value;
		}

		public static DoorLock? GetDoorLockFromCollider(Collider collider)
		{
			if ((Object)(object)collider == (Object)null)
			{
				return null;
			}
			if (DoorLocksColliders.TryGetValue(((Object)collider).GetInstanceID(), out DoorLock value))
			{
				return value;
			}
			value = ((Component)collider).gameObject.GetComponent<DoorLock>();
			DoorLocksColliders.Add(((Object)collider).GetInstanceID(), value);
			return value;
		}

		public static EnemyAI? GetEnemyFromCollider(Collider collider)
		{
			if ((Object)(object)collider == (Object)null)
			{
				return null;
			}
			if (EnemiesColliders.TryGetValue(((Object)collider).GetInstanceID(), out EnemyAI value))
			{
				return value;
			}
			value = ((Component)collider).gameObject.GetComponentInParent<EnemyAI>();
			EnemiesColliders.Add(((Object)collider).GetInstanceID(), value);
			return value;
		}
	}
	public sealed class ModConfig : LcInputActions
	{
		public struct ConfigValues
		{
			public enum KeepBalls
			{
				No,
				FullOnly,
				Yes
			}

			public int Tier1BallSpawnWeight { get; set; }

			public int Tier2BallSpawnWeight { get; set; }

			public int Tier3BallSpawnWeight { get; set; }

			public int Tier4BallSpawnWeight { get; set; }

			public int Tier1BallCost { get; set; }

			public int Tier2BallCost { get; set; }

			public int Tier3BallCost { get; set; }

			public int Tier4BallCost { get; set; }

			public float FilledBallsPercentage { get; set; }

			public float EnemyHPCaptureProbabilityMultiplier { get; set; }

			public KeepBalls KeepBallsIfAllPlayersDead { get; set; }

			public int CaptureRateModifier { get; set; }

			public int[] DuplicationPrices { get; set; }

			public float TamedNameFontSize { get; set; }

			public string[] DisabledMonsters { get; set; }

			public bool MonstersReactToFailedCaptures { get; set; }

			public float BrackenGrabCooldown { get; set; }

			public float DressGirlTeleportCooldown { get; set; }

			public float HoardingBugBringItemCooldown { get; set; }

			public float FoxTongueHitCooldown { get; set; }

			public float EyelessDogHowlCooldown { get; set; }

			public float MaskedLendCooldown { get; set; }

			public float BeesStunCooldown { get; set; }

			public float MaskedEffectDistance { get; set; }

			public int BlobMaxItems { get; set; }

			public float SpiderWebCooldown { get; set; }

			public bool PcGlobalSave { get; set; }

			public float BarberCutWallCooldown { get; set; }
		}

		public struct NetworkSyncData
		{
			public ConfigValues values;

			public global::LethalMon.Save.Save save;

			public Dictionary<ulong, PokeballSaveData> ballSaves;
		}

		[HarmonyPatch]
		public class SyncHandshake
		{
			private const string REQUEST_MESSAGE = "LethalMon_HostConfigRequested";

			private const string RECEIVE_MESSAGE = "LethalMon_HostConfigReceived";

			[HarmonyPatch(typeof(PlayerControllerB), "ConnectClientToPlayerObject")]
			[HarmonyPostfix]
			public static void Initialize(PlayerControllerB __instance)
			{
				//IL_0078: Unknown result type (might be due to invalid IL or missing references)
				//IL_0082: Expected O, but got Unknown
				//IL_0034: Unknown result type (might be due to invalid IL or missing references)
				//IL_003e: Expected O, but got Unknown
				if ((Object)(object)Utils.CurrentPlayer == (Object)(object)__instance)
				{
					if (Utils.IsHost)
					{
						Debug.Log((object)"Current player is the host.");
						NetworkManager.Singleton.CustomMessagingManager.RegisterNamedMessageHandler("LethalMon_HostConfigRequested", new HandleNamedMessageDelegate(HostConfigRequested));
						Instance.values = Instance.originalValues;
						ProcessValues();
					}
					else
					{
						Debug.Log((object)"Current player is not the host.");
						NetworkManager.Singleton.CustomMessagingManager.RegisterNamedMessageHandler("LethalMon_HostConfigReceived", new HandleNamedMessageDelegate(HostConfigReceived));
						RequestHostConfig();
					}
				}
			}

			public static void RequestHostConfig()
			{
				//IL_0025: Unknown result type (might be due to invalid IL or missing references)
				if (!Utils.IsHost)
				{
					Debug.Log((object)"Sending config request to host.");
					NetworkManager.Singleton.CustomMessagingManager.SendNamedMessage("LethalMon_HostConfigRequested", 0uL, new FastBufferWriter(0, (Allocator)2, -1), (NetworkDelivery)3);
				}
				else
				{
					Debug.Log((object)"Config request not required. No other player available.");
				}
			}

			public static void HostConfigRequested(ulong clientId, FastBufferReader reader)
			{
				//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
				if (!Utils.IsHost)
				{
					return;
				}
				NetworkSyncData networkSyncData = default(NetworkSyncData);
				networkSyncData.save = SaveManager.GetSave();
				networkSyncData.values = Instance.values;
				networkSyncData.ballSaves = Object.FindObjectsOfType<PokeballItem>().ToDictionary((PokeballItem ball) => ((NetworkBehaviour)ball).NetworkObjectId, (PokeballItem ball) => (PokeballSaveData)ball.GetAdvancedItemDataToSave());
				string text = JsonConvert.SerializeObject((object)networkSyncData);
				Debug.Log((object)("Client [" + clientId + "] requested host config. Sending own config: " + text));
				int writeSize = FastBufferWriter.GetWriteSize(text, false);
				FastBufferWriter val = default(FastBufferWriter);
				((FastBufferWriter)(ref val))..ctor(writeSize, (Allocator)2, -1);
				try
				{
					((FastBufferWriter)(ref val)).WriteValueSafe(text, false);
					NetworkManager.Singleton.CustomMessagingManager.SendNamedMessage("LethalMon_HostConfigReceived", clientId, val, (NetworkDelivery)4);
				}
				finally
				{
					((IDisposable)(FastBufferWriter)(ref val)).Dispose();
				}
			}

			public static void HostConfigReceived(ulong clientId, FastBufferReader reader)
			{
				string text = default(string);
				((FastBufferReader)(ref reader)).ReadValueSafe(ref text, false);
				Debug.Log((object)("Received host config: " + text));
				NetworkSyncData networkSyncData = JsonConvert.DeserializeObject<NetworkSyncData>(text);
				SaveManager.SyncSave(networkSyncData.save);
				Instance.values = networkSyncData.values;
				if ((Object)(object)global::LethalMon.PC.PC.Instance != (Object)null)
				{
					global::LethalMon.PC.PC.Instance.tutorialApp.UpdateTutorialPage2();
				}
				PokeballItem[] array = Object.FindObjectsOfType<PokeballItem>();
				foreach (PokeballItem pokeballItem in array)
				{
					if (networkSyncData.ballSaves.TryGetValue(((NetworkBehaviour)pokeballItem).NetworkObjectId, out PokeballSaveData value))
					{
						pokeballItem.LoadAdvancedItemData(value);
					}
				}
				ProcessValues();
			}
		}

		public ConfigValues values;

		public ConfigValues originalValues;

		private static ModConfig? _instance;

		public InputAction RetrieveBallKey => ((LcInputActions)this).Asset["retreiveBallKey"];

		public InputAction ActionKey1 => ((LcInputActions)this).Asset["actionKey1"];

		public static ModConfig Instance
		{
			get
			{
				if (_instance == null)
				{
					_instance = new ModConfig();
				}
				return _instance;
			}
		}

		public void Setup()
		{
			//IL_0301: Unknown result type (might be due to invalid IL or missing references)
			//IL_030b: Expected O, but got Unknown
			//IL_034d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0357: Expected O, but got Unknown
			values.PcGlobalSave = ((BaseUnityPlugin)LethalMon.Instance).Config.Bind<bool>("Saves", "PcGlobalSave", true, "Make the PC saves global (true) or per save file (false)").Value;
			values.Tier1BallCost = ((BaseUnityPlugin)LethalMon.Instance).Config.Bind<int>("Items", "Tier1BallCost", 40, "The cost of the tier 1 ball (pokeball) item in the shop. -1 to disable").Value;
			values.Tier2BallCost = ((BaseUnityPlugin)LethalMon.Instance).Config.Bind<int>("Items", "Tier2BallCost", 125, "The cost of the tier 1 ball (great ball) item in the shop. -1 to disable").Value;
			values.Tier3BallCost = ((BaseUnityPlugin)LethalMon.Instance).Config.Bind<int>("Items", "Tier3BallCost", 375, "The cost of the tier 1 ball (ultra ball) item in the shop. -1 to disable").Value;
			values.Tier4BallCost = ((BaseUnityPlugin)LethalMon.Instance).Config.Bind<int>("Items", "Tier4BallCost", 700, "The cost of the tier 1 ball (master ball) item in the shop. -1 to disable").Value;
			values.Tier1BallSpawnWeight = ((BaseUnityPlugin)LethalMon.Instance).Config.Bind<int>("Items", "Tier1BallSpawnWeight", 20, "The spawn weight of the tier 1 ball (pokeball). Higher = more common").Value;
			values.Tier2BallSpawnWeight = ((BaseUnityPlugin)LethalMon.Instance).Config.Bind<int>("Items", "Tier2BallSpawnWeight", 10, "The spawn weight of the tier 2 ball (great ball). Higher = more common").Value;
			values.Tier3BallSpawnWeight = ((BaseUnityPlugin)LethalMon.Instance).Config.Bind<int>("Items", "Tier3BallSpawnWeight", 6, "The spawn weight of the tier 3 ball (ultra ball). Higher = more common").Value;
			values.Tier4BallSpawnWeight = ((BaseUnityPlugin)LethalMon.Instance).Config.Bind<int>("Items", "Tier4BallSpawnWeight", 2, "The spawn weight of the tier 4 ball (master ball). Higher = more common").Value;
			values.KeepBallsIfAllPlayersDead = ((BaseUnityPlugin)LethalMon.Instance).Config.Bind<ConfigValues.KeepBalls>("Items", "KeepBallsIfAllPlayersDead", ConfigValues.KeepBalls.No, "Make the balls don't despawn even if all the players are dead.").Value;
			values.FilledBallsPercentage = ((BaseUnityPlugin)LethalMon.Instance).Config.Bind<float>("Items", "FilledBallsPercentage", 0.5f, "Percentage of filled balls in the dungeon").Value;
			values.EnemyHPCaptureProbabilityMultiplier = ((BaseUnityPlugin)LethalMon.Instance).Config.Bind<float>("Items", "EnemyHPCaptureProbabilityMultiplier", 1f, "Lower enemy HP increases the capture probability. Set this to 0 to disable this feature").Value;
			values.DisabledMonsters = ((BaseUnityPlugin)LethalMon.Instance).Config.Bind<string>("Monsters", "DisabledMonsters", "", "Disabled monsters types. Separate with a comma and don't put spaces. Example: Monster1,Monster2. Available monsters: " + string.Join(", ", Enum.GetNames(typeof(Utils.Enemy)))).Value.Split(",");
			values.MonstersReactToFailedCaptures = ((BaseUnityPlugin)LethalMon.Instance).Config.Bind<bool>("Monsters", "MonstersReactToFailedCaptures", true, "Make the monsters react aggressively if a capture fails").Value;
			values.CaptureRateModifier = ((BaseUnityPlugin)LethalMon.Instance).Config.Bind<int>("Monsters", "CaptureRateModifier", 0, new ConfigDescription("Modifier for the capture rate. Each monster have a difficulty to catch between 1 and 10. You can modify all the monsters difficulty by adding this modifier to the base difficulty. Negative = easier to catch, positive = harder to catch", (AcceptableValueBase)(object)new AcceptableValueRange<int>(-10, 10), Array.Empty<object>())).Value;
			values.TamedNameFontSize = ((BaseUnityPlugin)LethalMon.Instance).Config.Bind<float>("Monsters", "TamedNameFontSize", 10f, new ConfigDescription("Font size of the text above tamed monsters, that shows the owner. Set this to 0 to disable the text.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 20f), Array.Empty<object>())).Value;
			string[] array = ((BaseUnityPlugin)LethalMon.Instance).Config.Bind<string>("Monsters", "DuplicationPrices", string.Join(",", Data.DuplicationPrices), "Prices for duplicating a monster. The first value is the price for a monster with a difficulty of 1, the second value for a monster with a difficulty of 2, etc. 10 difficulties in total").Value.Split(",");
			values.DuplicationPrices = new int[10];
			for (int i = 0; i < 10; i++)
			{
				try
				{
					values.DuplicationPrices[i] = int.Parse(array[i]);
				}
				catch
				{
					values.DuplicationPrices[i] = Data.DuplicationPrices[i];
				}
			}
			values.BrackenGrabCooldown = ((BaseUnityPlugin)LethalMon.Instance).Config.Bind<float>("Cooldowns", "BrackenGrabCooldown", 20f, "Grab cooldown time in seconds for the bracken").Value;
			values.DressGirlTeleportCooldown = ((BaseUnityPlugin)LethalMon.Instance).Config.Bind<float>("Cooldowns", "DressGirlTeleportCooldown", 60f, "Teleport cooldown time in seconds for the dress girl").Value;
			values.HoardingBugBringItemCooldown = ((BaseUnityPlugin)LethalMon.Instance).Config.Bind<float>("Cooldowns", "HoardingBugBringItemCooldown", 5f, "Bring item cooldown time in seconds for the hoarder bug").Value;
			values.FoxTongueHitCooldown = ((BaseUnityPlugin)LethalMon.Instance).Config.Bind<float>("Cooldowns", "FoxTongueHitCooldown", 5f, "Tongue hit cooldown time in seconds for the fox").Value;
			values.EyelessDogHowlCooldown = ((BaseUnityPlugin)LethalMon.Instance).Config.Bind<float>("Cooldowns", "EyelessDogHowlCooldown", 5f, "Howl cooldown time in seconds for the eyeless dog").Value;
			values.MaskedLendCooldown = ((BaseUnityPlugin)LethalMon.Instance).Config.Bind<float>("Cooldowns", "MaskedLendCooldown", 7f, "Mask lending cooldown time in seconds for the masked").Value;
			values.BeesStunCooldown = ((BaseUnityPlugin)LethalMon.Instance).Config.Bind<float>("Cooldowns", "BeesStunCooldown", 10f, "Stunning cooldown time in seconds for the bees").Value;
			values.SpiderWebCooldown = ((BaseUnityPlugin)LethalMon.Instance).Config.Bind<float>("Cooldowns", "SpiderWebCooldown", 8f, "Web shooting cooldown time in seconds for the spider").Value;
			values.BarberCutWallCooldown = ((BaseUnityPlugin)LethalMon.Instance).Config.Bind<float>("Cooldowns", "BarberCutWallCooldown", 30f, "Cutting wall cooldown time in seconds for the barber").Value;
			values.MaskedEffectDistance = ((BaseUnityPlugin)LethalMon.Instance).Config.Bind<float>("Behaviours", "MaskedEffectDistance", 20f, "Distance till which enemies can be seen through walls.").Value;
			values.BlobMaxItems = ((BaseUnityPlugin)LethalMon.Instance).Config.Bind<int>("Behaviours", "BlobMaxItems", 4, "Maximum amount of items a tamed blob can carry.").Value;
			originalValues = values;
		}

		public override void CreateInputActions(in InputActionMapBuilder builder)
		{
			//IL_001b: 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_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			ConfigFile config = ((BaseUnityPlugin)LethalMon.Instance).Config;
			KeyboardControl val = (KeyboardControl)36;
			string value = config.Bind<string>("Controls", "RetrieveBallKeyKeyboard", "<Keyboard>/" + ((object)(KeyboardControl)(ref val)).ToString(), "Key for retrieving the tamed enemy inside its ball. Requires a restart after changing.").Value;
			ConfigFile config2 = ((BaseUnityPlugin)LethalMon.Instance).Config;
			GamepadControl val2 = (GamepadControl)7;
			string value2 = config2.Bind<string>("Controls", "RetrieveBallKeyGamepad", "<Gamepad>/" + ((object)(GamepadControl)(ref val2)).ToString(), "Gamepad key for retrieving the tamed enemy inside its ball. Requires a restart after changing.").Value;
			builder.NewActionBinding().WithActionId("retreiveBallKey").WithActionType((InputActionType)1)
				.WithBindingName("RetrieveBallKey")
				.WithKbmPath(value)
				.WithGamepadPath(value2)
				.Finish();
			ConfigFile config3 = ((BaseUnityPlugin)LethalMon.Instance).Config;
			val = (KeyboardControl)22;
			string value3 = config3.Bind<string>("Controls", "ActionKey1Keyboard", "<Keyboard>/" + ((object)(KeyboardControl)(ref val)).ToString(), "Key for the first custom action on a tamed enemy. Requires a restart after changing.").Value;
			ConfigFile config4 = ((BaseUnityPlugin)LethalMon.Instance).Config;
			val2 = (GamepadControl)9;
			string value4 = config4.Bind<string>("Controls", "ActionKey1Gamepad", "<Gamepad>/" + ((object)(GamepadControl)(ref val2)).ToString(), "Gamepad key for the first custom action on a tamed enemy. Requires a restart after changing.").Value;
			builder.NewActionBinding().WithActionId("actionKey1").WithActionType((InputActionType)1)
				.WithBindingName("ActionKey1")
				.WithKbmPath(value3)
				.WithGamepadPath(value4)
				.Finish();
		}

		public static void ProcessValues()
		{
			LethalMon.Log("Processing config");
			if ((Object)(object)Pokeball.BallItem != (Object)null)
			{
				if (Instance.values.Tier1BallCost >= 0)
				{
					Items.UpdateShopItemPrice(Pokeball.BallItem, Instance.values.Tier1BallCost);
				}
				else
				{
					Items.RemoveShopItem(Pokeball.BallItem);
				}
			}
			if ((Object)(object)Greatball.BallItem != (Object)null)
			{
				if (Instance.values.Tier2BallCost >= 0)
				{
					Items.UpdateShopItemPrice(Greatball.BallItem, Instance.values.Tier2BallCost);
				}
				else
				{
					Items.RemoveShopItem(Greatball.BallItem);
				}
			}
			if ((Object)(object)Ultraball.BallItem != (Object)null)
			{
				if (Instance.values.Tier3BallCost >= 0)
				{
					Items.UpdateShopItemPrice(Ultraball.BallItem, Instance.values.Tier3BallCost);
				}
				else
				{
					Items.RemoveShopItem(Ultraball.BallItem);
				}
			}
			if ((Object)(object)Masterball.BallItem != (Object)null)
			{
				if (Instance.values.Tier4BallCost >= 0)
				{
					Items.UpdateShopItemPrice(Masterball.BallItem, Instance.values.Tier4BallCost);
				}
				else
				{
					Items.RemoveShopItem(Masterball.BallItem);
				}
			}
			string[] disabledMonsters = Instance.values.DisabledMonsters;
			foreach (string enemyTypeName in disabledMonsters)
			{
				Registry.RemoveEnemy(enemyTypeName);
			}
		}
	}
	public static class Data
	{
		public static readonly Random Random = new Random();

		public static readonly float[][] CaptureProbabilities = new float[4][]
		{
			new float[10] { 0.95f, 0.9f, 0.8f, 0.65f, 0.5f, 0.3f, 0.1f, 0.05f, 0.02f, 0.01f },
			new float[10] { 1f, 0.97f, 0.95f, 0.85f, 0.7f, 0.5f, 0.3f, 0.2f, 0.15f, 0.1f },
			new float[10] { 1f, 1f, 1f, 0.97f, 0.95f, 0.9f, 0.8f, 0.7f, 0.6f, 0.5f },
			new float[10] { 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f }
		};

		public static readonly int[] DuplicationPrices = new int[10] { 30, 70, 120, 180, 250, 330, 420, 520, 630, 750 };
	}
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("LethalMon", "LethalMon", "1.0.0")]
	public class LethalMon : BaseUnityPlugin
	{
		public enum LogType
		{
			Message,
			Warning,
			Error,
			Fatal,
			Debug
		}

		internal static GameObject? hudPrefab;

		public static LethalMon Instance { get; private set; }

		internal static ManualLogSource Logger { get; private set; }

		internal static Harmony? Harmony { get; set; }

		private void Awake()
		{
			Logger = ((BaseUnityPlugin)this).Logger;
			Instance = this;
			ModConfig.Instance.Setup();
			LoadAssetBundle();
			NetcodePatching();
			ApplyHarmonyPatches();
			PlayerControllerBPatch.InitializeRPCS();
			Logger.LogInfo((object)"LethalMon v1.0.0 has loaded!");
		}

		private void NetcodePatching()
		{
			Type[] types = Assembly.GetExecutingAssembly().GetTypes();
			Type[] array = types;
			foreach (Type type in array)
			{
				try
				{
					MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic);
					MethodInfo[] array2 = methods;
					foreach (MethodInfo methodInfo in array2)
					{
						object[] customAttributes = methodInfo.GetCustomAttributes(typeof(RuntimeInitializeOnLoadMethodAttribute), inherit: false);
						if (customAttributes.Length != 0)
						{
							methodInfo.Invoke(null, null);
						}
					}
				}
				catch (FileNotFoundException)
				{
				}
			}
		}

		private void LoadAssetBundle()
		{
			AssetBundle val = AssetBundle.LoadFromFile(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "lethalmon"));
			Pokeball.Setup(val);
			Greatball.Setup(val);
			Ultraball.Setup(val);
			Masterball.Setup(val);
			Utils.LoadSeeThroughShader(val);
			Utils.LoadWireframeMaterial(val);
			ClaySurgeonTamedBehaviour.LoadAssets(val);
			MaskedTamedBehaviour.LoadGhostAudio(val);
			BaboonHawkTamedBehaviour.LoadAudio(val);
			HoarderBugTamedBehaviour.LoadAudio(val);
			SpiderTamedBehaviour.LoadAudio(val);
			global::LethalMon.PC.PC.LoadAssets(val);
			PokeballItem.LoadAudio(val);
			hudPrefab = val.LoadAsset<GameObject>("Assets/UI/MonsterInfo.prefab");
			Registry.FallbackSprite = val.LoadAsset<Sprite>("assets/ui/monstersicons/Unknown.png");
			Registry.RegisterVanillaEnemies(val);
		}

		private void ApplyHarmonyPatches()
		{
			Harmony = Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), (string)null);
			Harmony.PatchAll(typeof(DebugPatches));
			Harmony.PatchAll(typeof(ModConfig.SyncHandshake));
			Harmony.PatchAll(typeof(PlayerControllerBPatch));
			Harmony.PatchAll(typeof(StartOfRoundPatch));
			Harmony.PatchAll(typeof(RoundManagerPatch));
			Harmony.PatchAll(typeof(HUDManagerPatch));
			Harmony.PatchAll(typeof(GameNetworkManagerPatch));
			Harmony.PatchAll(typeof(TerminalPatch));
			Harmony.PatchAll(typeof(AdvancedSavePatch));
			Harmony.PatchAll(typeof(DungeonGeneratorPatch));
			Harmony.PatchAll(typeof(EnemyAIPatch));
			Harmony.PatchAll(typeof(RedLocustBeesPatch));
			Harmony.PatchAll(typeof(MouthDogPatch));
			Harmony.PatchAll(typeof(FlowermanAIPatch));
			Harmony.PatchAll(typeof(BushWolfEnemyPatch));
			Harmony.PatchAll(typeof(MaskedPlayerEnemyPatch));
			Harmony.PatchAll(typeof(BaboonBirdAIPatch));
			Harmony.PatchAll(typeof(SandSpiderAIPatch));
			Harmony.PatchAll(typeof(TamedEnemyBehaviour));
			Harmony.PatchAll(typeof(KidnapperFoxTamedBehaviour));
			if (MirageCompatibility.Instance.Enabled)
			{
				Harmony.PatchAll(typeof(MirageCompatibility));
			}
			if (SnatchingBrackenCompatibility.Instance.Enabled)
			{
				Harmony.PatchAll(typeof(SnatchingBrackenCompatibility));
			}
			if (EnemySkinRegistryCompatibility.Instance.Enabled)
			{
				Harmony.PatchAll(typeof(EnemySkinRegistryCompatibility));
			}
			Harmony.PatchAll(typeof(ThrowableItem));
		}

		private static void Unpatch()
		{
			Logger.LogDebug((object)"Unpatching...");
			Harmony? harmony = Harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
			Logger.LogDebug((object)"Finished unpatching!");
		}

		internal static void Log(string message, LogType type = LogType.Debug)
		{
			switch (type)
			{
			case LogType.Debug:
				break;
			case LogType.Warning:
				Logger.LogWarning((object)message);
				break;
			case LogType.Error:
				Logger.LogError((object)message);
				break;
			case LogType.Fatal:
				Logger.LogFatal((object)message);
				break;
			default:
				Logger.LogMessage((object)message);
				break;
			}
		}
	}
	public static class Registry
	{
		private static readonly string EnemyTypesIdsKey = "LethalMon_EnemyTypesIds";

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

		internal static readonly Dictionary<string, global::LethalMon.CatchableEnemy.CatchableEnemy> CatchableEnemies = new Dictionary<string, global::LethalMon.CatchableEnemy.CatchableEnemy>();

		private static readonly Dictionary<string, Sprite> EnemiesSprites = new Dictionary<string, Sprite>();

		private static readonly Dictionary<Type, Type> EnemiesTamedBehaviours = new Dictionary<Type, Type>();

		internal static Sprite FallbackSprite = null;

		private static int _currentId;

		public static int? GetEnemyTypeId(string enemyType)
		{
			return _enemiesTypesIds.GetValueOrDefault(enemyType);
		}

		public static Sprite GetEnemySprite(string enemyType)
		{
			return EnemiesSprites.GetValueOrDefault(enemyType, FallbackSprite);
		}

		internal static Type GetTamedBehaviour(Type enemyType)
		{
			return EnemiesTamedBehaviours.GetValueOrDefault(enemyType, typeof(TamedEnemyBehaviour));
		}

		public static void RegisterEnemy(string enemyTypeName, global::LethalMon.CatchableEnemy.CatchableEnemy catchableEnemy, Type originalEnemyAiType, Type tamedBehaviourClassType, Sprite sprite)
		{
			if (CatchableEnemies.ContainsKey(enemyTypeName))
			{
				LethalMon.Log("Enemy type " + enemyTypeName + " is already registered", LethalMon.LogType.Warning);
			}
			else if (catchableEnemy.CatchDifficulty < 0 || catchableEnemy.CatchDifficulty >= Data.CaptureProbabilities[0].Length)
			{
				LethalMon.Log($"Catch difficulty for enemy type {enemyTypeName} is invalid. It must be between 0 and {Data.CaptureProbabilities[0].Length - 1}", LethalMon.LogType.Error);
			}
			else if (tamedBehaviourClassType.IsSubclassOf(typeof(TamedEnemyBehaviour)))
			{
				CatchableEnemies[enemyTypeName] = catchableEnemy;
				EnemiesSprites[enemyTypeName] = sprite;
				EnemiesTamedBehaviours[originalEnemyAiType] = tamedBehaviourClassType;
			}
			else
			{
				LethalMon.Log($"Tamed behaviour class {tamedBehaviourClassType} is not a subclass of TamedEnemyBehaviour", LethalMon.LogType.Error);
			}
		}

		public static bool IsEnemyRegistered(string enemyTypeName)
		{
			return CatchableEnemies.ContainsKey(enemyTypeName);
		}

		public static global::LethalMon.CatchableEnemy.CatchableEnemy? GetCatchableEnemy(string enemyTypeName)
		{
			return CatchableEnemies.GetValueOrDefault(enemyTypeName);
		}

		internal static global::LethalMon.CatchableEnemy.CatchableEnemy? GetCatchableEnemy(int enemyTypeId)
		{
			return CatchableEnemies.FirstOrDefault<KeyValuePair<string, global::LethalMon.CatchableEnemy.CatchableEnemy>>((KeyValuePair<string, global::LethalMon.CatchableEnemy.CatchableEnemy> cm) => _enemiesTypesIds.GetValueOrDefault(cm.Key) == enemyTypeId).Value;
		}

		internal static string GetEnemyTypeName(int enemyTypeId)
		{
			return CatchableEnemies.FirstOrDefault<KeyValuePair<string, global::LethalMon.CatchableEnemy.CatchableEnemy>>((KeyValuePair<string, global::LethalMon.CatchableEnemy.CatchableEnemy> cm) => _enemiesTypesIds.GetValueOrDefault(cm.Key) == enemyTypeId).Key;
		}

		internal static string[] GetEnemyTypes()
		{
			return CatchableEnemies.Keys.ToArray();
		}

		public static void RemoveEnemy(string enemyTypeName)
		{
			if (CatchableEnemies.ContainsKey(enemyTypeName))
			{
				CatchableEnemies.Remove(enemyTypeName);
			}
			if (EnemiesSprites.ContainsKey(enemyTypeName))
			{
				EnemiesSprites.Remove(enemyTypeName);
			}
		}

		internal static void RegisterVanillaEnemies(AssetBundle assetBundle)
		{
			RegisterEnemy(Utils.Enemy.BaboonHawk.ToString(), new CatchableBaboonHawk(), typeof(BaboonBirdAI), typeof(BaboonHawkTamedBehaviour), assetBundle.LoadAsset<Sprite>("assets/ui/monstersicons/BaboonHawk.png"));
			RegisterEnemy(Utils.Enemy.Blob.ToString(), new CatchableBlob(), typeof(BlobAI), typeof(BlobTamedBehaviour), assetBundle.LoadAsset<Sprite>("assets/ui/monstersicons/Blob.png"));
			RegisterEnemy(Utils.Enemy.BushWolf.ToString(), new CatchableKidnapperFox(), typeof(BushWolfEnemy), typeof(KidnapperFoxTamedBehaviour), assetBundle.LoadAsset<Sprite>("assets/ui/monstersicons/BushWolf.png"));
			RegisterEnemy(Utils.Enemy.Butler.ToString(), new CatchableButler(), typeof(ButlerEnemyAI), typeof(ButlerTamedBehaviour), assetBundle.LoadAsset<Sprite>("assets/ui/monstersicons/Butler.png"));
			RegisterEnemy(Utils.Enemy.ClaySurgeon.ToString(), new CatchableClaySurgeon(), typeof(ClaySurgeonAI), typeof(ClaySurgeonTamedBehaviour), assetBundle.LoadAsset<Sprite>("assets/ui/monstersicons/ClaySurgeon.png"));
			RegisterEnemy(Utils.Enemy.Crawler.ToString(), new CatchableCrawler(), typeof(CrawlerAI), typeof(CrawlerTamedBehaviour), assetBundle.LoadAsset<Sprite>("assets/ui/monstersicons/Crawler.png"));
			RegisterEnemy(Utils.Enemy.Flowerman.ToString(), new CatchableFlowerman(), typeof(FlowermanAI), typeof(FlowermanTamedBehaviour), assetBundle.LoadAsset<Sprite>("assets/ui/monstersicons/Flowerman.png"));
			RegisterEnemy(Utils.Enemy.DressGirl.ToString(), new CatchableGhostGirl(), typeof(DressGirlAI), typeof(GhostGirlTamedBehaviour), assetBundle.LoadAsset<Sprite>("assets/ui/monstersicons/DressGirl.png"));
			RegisterEnemy(Utils.Enemy.HoarderBug.ToString(), new CatchableHoarderBug(), typeof(HoarderBugAI), typeof(HoarderBugTamedBehaviour), assetBundle.LoadAsset<Sprite>("assets/ui/monstersicons/HoarderBug.png"));
			RegisterEnemy(Utils.Enemy.MaskedPlayerEnemy.ToString(), new CatchableMasked(), typeof(MaskedPlayerEnemy), typeof(MaskedTamedBehaviour), assetBundle.LoadAsset<Sprite>("assets/ui/monstersicons/MaskedPlayerEnemy.png"));
			RegisterEnemy(Utils.Enemy.MouthDog.ToString(), new CatchableMouthDog(), typeof(MouthDogAI), typeof(MouthDogTamedBehaviour), assetBundle.LoadAsset<Sprite>("assets/ui/monstersicons/MouthDog.png"));
			RegisterEnemy(Utils.Enemy.Nutcracker.ToString(), new CatchableNutcracker(), typeof(NutcrackerEnemyAI), typeof(NutcrackerTamedBehaviour), assetBundle.LoadAsset<Sprite>("assets/ui/monstersicons/Nutcracker.png"));
			RegisterEnemy(Utils.Enemy.RedLocustBees.ToString(), new CatchableRedLocustBees(), typeof(RedLocustBees), typeof(RedLocustBeesTamedBehaviour), assetBundle.LoadAsset<Sprite>("assets/ui/monstersicons/RedLocustBees.png"));
			RegisterEnemy(Utils.Enemy.SandSpider.ToString(), new CatchableSpider(), typeof(SandSpiderAI), typeof(SpiderTamedBehaviour), assetBundle.LoadAsset<Sprite>("assets/ui/monstersicons/SandSpider.png"));
			RegisterEnemy(Utils.Enemy.Puffer.ToString(), new CatchableSporeLizard(), typeof(PufferAI), typeof(SporeLizardTamedBehaviour), assetBundle.LoadAsset<Sprite>("assets/ui/monstersicons/Puffer.png"));
			RegisterEnemy(Utils.Enemy.FlowerSnake.ToString(), new CatchableTulipSnake(), typeof(FlowerSnakeEnemy), typeof(TulipSnakeTamedBehaviour), assetBundle.LoadAsset<Sprite>("assets/ui/monstersicons/FlowerSnake.png"));
		}

		private static int GetNextId()
		{
			return _currentId++;
		}

		internal static void LoadAndCalculateMissingIds()
		{
			if (ES3.KeyExists(EnemyTypesIdsKey, GameNetworkManager.Instance.currentSaveFileName))
			{
				_enemiesTypesIds.Clear();
				_enemiesTypesIds = ES3.Load<Dictionary<string, int>>(EnemyTypesIdsKey, GameNetworkManager.Instance.currentSaveFileName);
			}
			_currentId = ((_enemiesTypesIds.Count == 0) ? 1 : _enemiesTypesIds.Values.Max());
			foreach (KeyValuePair<string, global::LethalMon.CatchableEnemy.CatchableEnemy> catchableEnemy in CatchableEnemies)
			{
				if (!_enemiesTypesIds.ContainsKey(catchableEnemy.Key))
				{
					_enemiesTypesIds[catchableEnemy.Key] = GetNextId();
				}
			}
			ES3.Save<Dictionary<string, int>>(EnemyTypesIdsKey, _enemiesTypesIds, GameNetworkManager.Instance.currentSaveFileName);
		}
	}
	public class Utils
	{
		public enum Enemy
		{
			BaboonHawk,
			Blob,
			BushWolf,
			Butler,
			ButlerBees,
			CaveDweller,
			Centipede,
			ClaySurgeon,
			Crawler,
			DocileLocustBees,
			Doublewing,
			FlowerSnake,
			RedLocustBees,
			DressGirl,
			Flowerman,
			ForestGiant,
			HoarderBug,
			Jester,
			LassoMan,
			MaskedPlayerEnemy,
			MouthDog,
			Nutcracker,
			Puffer,
			RadMech,
			RedPillEnemyType,
			SandSpider,
			SandWorm,
			SpringMan
		}

		internal class LayerMasks
		{
			internal enum Mask
			{
				All = -1,
				Default,
				TransparentFX,
				Ignore_Raycast,
				Player,
				Water,
				UI,
				Props,
				HelmetVisor,
				Room,
				InteractableObject,
				Foliage,
				Colliders,
				PhysicsObject,
				Triggers,
				MapRadar,
				NavigationSurface,
				RoomLight,
				Anomaly,
				LineOfSight,
				Enemies,
				PlayerRagdoll,
				MapHazards,
				ScanNode,
				EnemiesNotRendered,
				MiscLevelGeometry,
				Terrain,
				PlaceableShipObjects,
				PlacementBlocker,
				Railing,
				DecalStickableSurface,
				CompanyCruiser
			}

			internal static int ToInt(Mask[] masks)
			{
				int num = 0;
				foreach (Mask mask in masks)
				{
					num |= 1 << (int)mask;
				}
				return num;
			}
		}

		public static readonly Random Random = new Random();

		private static readonly Dictionary<string, TerminalNode> infoNodes = new Dictionary<string, TerminalNode>();

		internal static List<AudioSource> diageticAudios = new List<AudioSource>();

		public static readonly float DefaultJumpForce = 13f;

		private static readonly List<string> NonEnemyRenderer = new List<string>(1) { "mapdot" };

		private static Item? _giftBoxItem;

		public static Shader? SeeThroughShader;

		public static readonly Color EnemyHighlightOutline = Color.red;

		public static readonly Color EnemyHighlightInline = new Color(0.8f, 0f, 0f, 0.8f);

		public static readonly Color ItemHighlightOutline = Color.yellow;

		public static readonly Color ItemHighlightInline = new Color(0.8f, 0.8f, 0f, 0.5f);

		public static readonly Color PlayerHighlightOutline = Color.green;

		public static readonly Color PlayerHighlightInline = new Color(0f, 0.8f, 0f, 0.6f);

		public static Material? WireframeMaterial;

		private static readonly string GlassName = "LethalMonGlass";

		private static Material? _glassMaterial = null;

		private static Material? _ghostMaterial = null;

		private static Material? _ghostEyesMaterial = null;

		public static List<PlayerControllerB>? AllPlayers => StartOfRound.Instance?.allPlayerScripts?.Where((PlayerControllerB pcb) => (Object)(object)pcb != (Object)null && (pcb.isPlayerControlled || pcb.isPlayerDead)).ToList();

		public static List<PlayerControllerB>? AlivePlayers => AllPlayers?.Where((PlayerControllerB pcb) => !pcb.isPlayerDead).ToList();

		public static PlayerControllerB CurrentPlayer => GameNetworkManager.Instance.localPlayerController;

		public static ulong? CurrentPlayerID => CurrentPlayer?.playerClientId;

		public static bool IsHost
		{
			get
			{
				if ((Object)(object)NetworkManager.Singleton != (Object)null)
				{
					if (!NetworkManager.Singleton.IsHost)
					{
						return NetworkManager.Singleton.IsServer;
					}
					return true;
				}
				if (CurrentPlayerID.HasValue)
				{
					return CurrentPlayerID.Value == 0;
				}
				return false;
			}
		}

		public static float DefaultPlayerSpeed
		{
			get
			{
				if (!CurrentPlayer.isSprinting)
				{
					return 1f;
				}
				return 2.25f;
			}
		}

		public static List<EnemyType> EnemyTypes => Resources.FindObjectsOfTypeAll<EnemyType>().ToList();

		public static Item? GiftBoxItem
		{
			get
			{
				if ((Object)(object)_giftBoxItem != (Object)null)
				{
					return _giftBoxItem;
				}
				_giftBoxItem = ((IEnumerable<Item>)Resources.FindObjectsOfTypeAll<Item>()).FirstOrDefault((Func<Item, bool>)((Item item) => item.itemName == "Gift"));
				return _giftBoxItem;
			}
		}

		public static Material Glass
		{
			get
			{
				//IL_0017: Unknown result type (might be due to invalid IL or missing references)
				//IL_001d: Expected O, but got Unknown
				//IL_0032: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)_glassMaterial == (Object)null)
				{
					Material val = new Material(Shader.Find("HDRP/Lit"));
					val.color = new Color(0.5f, 0.5f, 0.6f, 0.6f);
					val.renderQueue = 3300;
					val.shaderKeywords = new string[5] { "_SURFACE_TYPE_TRANSPARENT", "_DISABLE_SSR_TRANSPARENT", "_REFRACTION_THIN", "_NORMALMAP_TANGENT_SPACE", "_ENABLE_FOG_ON_TRANSPARENT" };
					((Object)val).name = GlassName;
					_glassMaterial = val;
				}
				return _glassMaterial;
			}
		}

		internal static Material GhostMaterial
		{
			get
			{
				//IL_0012: Unknown result type (might be due to invalid IL or missing references)
				//IL_001c: Expected O, but got Unknown
				//IL_003a: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)_ghostMaterial == (Object)null)
				{
					_ghostMaterial = new Material(WireframeMaterial);
					_ghostMaterial.SetColor("_EdgeColor", new Color(0.8f, 0.9f, 1f, 0.15f));
					_ghostMaterial.SetFloat("_WireframeVal", 1f);
					_ghostMaterial.SetFloat("_MaxVisibilityDistance", 15f);
				}
				return _ghostMaterial;
			}
		}

		internal static Material GhostEyesMaterial
		{
			get
			{
				//IL_0017: Unknown result type (might be due to invalid IL or missing references)
				//IL_001c: Unknown result type (might be due to invalid IL or missing references)
				//IL_002c: Unknown result type (might be due to invalid IL or missing references)
				//IL_003b: Expected O, but got Unknown
				if ((Object)(object)_ghostEyesMaterial == (Object)null)
				{
					_ghostEyesMaterial = new Material(Shader.Find("HDRP/Unlit"))
					{
						color = new Color(0.8f, 0.9f, 1f)
					};
				}
				return _ghostEyesMaterial;
			}
		}

		public static void CallNextFrame(Action action)
		{
			((MonoBehaviour)GameNetworkManager.Instance).StartCoroutine(CallNextFrameCoroutine(action));
		}

		public static IEnumerator CallNextFrameCoroutine(Action action)
		{
			yield return null;
			action();
		}

		public static void CallAfterTime(Action action, float time)
		{
			((MonoBehaviour)GameNetworkManager.Instance).StartCoroutine(CallAfterTimeCoroutine(action, time));
		}

		public static IEnumerator CallAfterTimeCoroutine(Action action, float time)
		{
			yield return (object)new WaitForSeconds(time);
			action();
		}

		public static Vector3 GetPositionInFrontOfPlayerEyes(PlayerControllerB player)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			return player.playerEye.position + player.playerEye.forward * 2.5f;
		}

		public static Vector3 GetPositionBehindPlayer(PlayerControllerB player)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			return ((Component)player).transform.position + ((Component)player).transform.forward * -2f;
		}

		public static EnemyAI? GetMostProbableAttackerEnemy(PlayerControllerB player, StackTrace stackTrace)
		{
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			StackFrame[] frames = stackTrace.GetFrames();
			StackFrame[] subArray = frames[1..];
			foreach (StackFrame stackFrame in subArray)
			{
				Type declaringType = stackFrame.GetMethod().DeclaringType;
				LethalMon.Log("Stackframe type: " + declaringType);
				if (!declaringType.IsSubclassOf(typeof(EnemyAI)))
				{
					continue;
				}
				LethalMon.Log("Class is assignable from EnemyAI");
				EnemyAI val = null;
				float? num = float.MaxValue;
				Collider[] array = Physics.OverlapSphere(((Component)player).transform.position, 10f);
				Collider[] array2 = array;
				foreach (Collider val2 in array2)
				{
					EnemyAI componentInParent = ((Component)val2).GetComponentInParent<EnemyAI>();
					if ((Object)(object)componentInParent != (Object)null && ((object)componentInParent).GetType() == declaringType)
					{
						float num2 = Vector3.Distance(((Component)player).transform.position, ((Component)componentInParent).transform.position);
						if (num > num2)
						{
							val = componentInParent;
							num = num2;
						}
					}
				}
				if ((Object)(object)val != (Object)null)
				{
					return val;
				}
			}
			return null;
		}

		public static TerminalNode CreateTerminalNode(string name, string description)
		{
			if (infoNodes.TryGetValue(name, out TerminalNode value))
			{
				return value;
			}
			TerminalNode val = ScriptableObject.CreateInstance<TerminalNode>();
			Object.DontDestroyOnLoad((Object)(object)val);
			val.clearPreviousText = true;
			((Object)val).name = name + "InfoNode";
			val.displayText = description + "\n\n";
			infoNodes.Add(name, val);
			return val;
		}

		public static Vector3 GetRandomNavMeshPositionOnRadius(Vector3 pos, float radius, NavMeshHit navHit = default(NavMeshHit))
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			float y = pos.y;
			pos = Random.onUnitSphere * radius + pos;
			pos.y = y;
			if (NavMesh.SamplePosition(pos, ref navHit, radius, -1))
			{
				return ((NavMeshHit)(ref navHit)).position;
			}
			return pos;
		}

		public static void EnableShotgunHeldByEnemyAi(EnemyAI enemyAI, bool enable)
		{
			ShotgunItem[] array = Object.FindObjectsOfType<ShotgunItem>();
			ShotgunItem[] array2 = array;
			foreach (ShotgunItem val in array2)
			{
				if ((Object)(object)val.heldByEnemy == (Object)(object)enemyAI)
				{
					((GrabbableObject)val).EnableItemMeshes(enable);
				}
			}
		}

		public static void DestroyShotgunHeldByEnemyAi(EnemyAI enemyAI)
		{
			ShotgunItem[] array = Object.FindObjectsOfType<ShotgunItem>();
			ShotgunItem[] array2 = array;
			foreach (ShotgunItem val in array2)
			{
				if ((Object)(object)val.heldByEnemy == (Object)(object)enemyAI)
				{
					((Component)val).GetComponent<NetworkObject>().Despawn(true);
				}
			}
		}

		internal static AudioSource CreateAudioSource(GameObject parent, float minDistance = 0f, float maxDistance = 25f)
		{
			AudioSource val = parent.AddComponent<AudioSource>();
			val.minDistance = minDistance;
			val.maxDistance = maxDistance;
			val.rolloffMode = (AudioRolloffMode)1;
			val.spatialBlend = 1f;
			val.priority = 127;
			val.outputAudioMixerGroup = SoundManager.Instance.tempAudio1.outputAudioMixerGroup;
			return val;
		}

		public static void PlaySoundAtPosition(Vector3 position, AudioClip clip, float volume = 1f)
		{
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			foreach (AudioSource diageticAudio in diageticAudios)
			{
				if (!((Object)(object)diageticAudio == (Object)null) && !diageticAudio.isPlaying)
				{
					((Component)diageticAudio).transform.position = position;
					diageticAudio.PlayOneShot(clip, volume);
					return;
				}
			}
			AudioSource val = CreateAudioSource(((Component)SoundManager.Instance).gameObject);
			diageticAudios.Add(val);
			((Component)val).transform.position = position;
			val.PlayOneShot(clip, volume);
		}

		public static EnemyType[] GetEnemyTypes(Enemy enemy)
		{
			string enemyName = enemy.ToString();
			return EnemyTypes.Where((EnemyType e) => ((Object)e).name == enemyName).ToArray();
		}

		public static EnemyType? GetFirstEnemyType(string enemy)
		{
			string enemy2 = enemy;
			return ((IEnumerable<EnemyType>)EnemyTypes).FirstOrDefault((Func<EnemyType, bool>)((EnemyType e) => ((Object)e).name == enemy2));
		}

		public static void OpenDoorsAsEnemyAroundPosition(Vector3 position)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			Collider[] array = Physics.OverlapSphere(position, 0.5f);
			Collider[] array2 = array;
			AnimatedObjectTrigger val2 = default(AnimatedObjectTrigger);
			foreach (Collider collider in array2)
			{
				DoorLock doorLockFromCollider = Cache.GetDoorLockFromCollider(collider);
				if ((Object)(object)doorLockFromCollider != (Object)null && doorLockFromCollider != null && !doorLockFromCollider.isDoorOpened && !doorLockFromCollider.isLocked)
				{
					Vector3 val = position;
					LethalMon.Log("Door opened at " + ((object)(Vector3)(ref val)).ToString());
					if (((Component)doorLockFromCollider).gameObject.TryGetComponent<AnimatedObjectTrigger>(ref val2))
					{
						val2.TriggerAnimationNonPlayer(false, true, false);
					}
					doorLockFromCollider.OpenDoorAsEnemyServerRpc();
				}
			}
		}

		public static bool TryGetRealEnemyBounds(EnemyAI enemy, out Bounds bounds)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			bounds = default(Bounds);
			if ((Object)(object)enemy == (Object)null)
			{
				return false;
			}
			Renderer[] componentsInChildren = ((Component)enemy).gameObject.GetComponentsInChildren<Renderer>();
			if (componentsInChildren == null)
			{
				return false;
			}
			bounds = componentsInChildren[0].bounds;
			for (int i = 1; i < componentsInChildren.Length; i++)
			{
				string @object = ((Object)componentsInChildren[i]).name.ToLower();
				if (!NonEnemyRenderer.Where(@object.StartsWith).Any())
				{
					Bounds bounds2 = componentsInChildren[i].bounds;
					LethalMon.Log("Encapsulated: " + (((Bounds)(ref bounds2)).max.y - ((Component)enemy).transform.position.y));
					((Bounds)(ref bounds)).Encapsulate(componentsInChildren[i].bounds);
				}
			}
			return true;
		}

		public static EnemyAI? SpawnEnemyAtPosition(Enemy enemy, Vector3 position)
		{
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			string enemyName = enemy.ToString();
			EnemyType val = EnemyTypes.Where((EnemyType e) => ((Object)e).name == enemyName).FirstOrDefault();
			if ((Object)(object)val?.enemyPrefab == (Object)null)
			{
				LethalMon.Log("Unable to spawn enemy with name \"" + enemyName + "\". Enemy prefab not found.");
				return null;
			}
			LethalMon.Logger.LogInfo((object)("Spawn enemy: " + enemyName));
			GameObject val2 = Object.Instantiate<GameObject>(val.enemyPrefab, position, Quaternion.Euler(new Vector3(0f, 0f, 0f)));
			val2.GetComponentInChildren<NetworkObject>().Spawn(true);
			EnemyAI component = val2.GetComponent<EnemyAI>();
			((Behaviour)component).enabled = (Object)(object)StartOfRound.Instance.testRoom == (Object)null;
			TamedEnemyBehaviour tamedEnemyBehaviour = default(TamedEnemyBehaviour);
			if (((Component)component).TryGetComponent<TamedEnemyBehaviour>(ref tamedEnemyBehaviour))
			{
				tamedEnemyBehaviour.IsOutside = IsEnemyOutside(component);
			}
			return component;
		}

		public static void CreateInteractionForEnemy(EnemyAI enemyAI, string hoverTip, float timeToHold, UnityAction<PlayerControllerB> callback, out InteractTrigger? interactTrigger, out GameObject? triggerObject)
		{
			//IL_0045: 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_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Expected O, but got Unknown
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Expected O, but got Unknown
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Expected O, but got Unknown
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Expected O, but got Unknown
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Expected O, but got Unknown
			interactTrigger = null;
			triggerObject = null;
			if (!TryGetRealEnemyBounds(enemyAI, out var bounds))
			{
				LethalMon.Log("Unable to get enemy bounds. No MeshRenderer found.", LethalMon.LogType.Error);
				return;
			}
			triggerObject = GameObject.CreatePrimitive((PrimitiveType)3);
			triggerObject.transform.SetParent(((Component)enemyAI).transform, false);
			triggerObject.transform.position = ((Bounds)(ref bounds)).center;
			triggerObject.transform.localScale = ((Bounds)(ref bounds)).size;
			Physics.IgnoreCollision((Collider)(object)triggerObject.GetComponent<BoxCollider>(), CurrentPlayer.playerCollider);
			triggerObject.tag = "InteractTrigger";
			triggerObject.layer = LayerMask.NameToLayer("InteractableObject");
			interactTrigger = triggerObject.AddComponent<InteractTrigger>();
			interactTrigger.interactable = true;
			InteractTrigger? obj = interactTrigger;
			GameObject obj2 = GameObject.Find("StartGameLever");
			obj.hoverIcon = ((obj2 == null) ? null : obj2.GetComponent<InteractTrigger>()?.hoverIcon);
			interactTrigger.hoverTip = hoverTip;
			interactTrigger.oneHandedItemAllowed = true;
			interactTrigger.twoHandedItemAllowed = true;
			interactTrigger.holdInteraction = timeToHold != 0f;
			interactTrigger.touchTrigger = false;
			interactTrigger.timeToHold = timeToHold;
			interactTrigger.timeToHoldSpeedMultiplier = 1f;
			interactTrigger.holdingInteractEvent = new InteractEventFloat();
			interactTrigger.onInteract = new InteractEvent();
			interactTrigger.onInteractEarly = new InteractEvent();
			interactTrigger.onStopInteract = new InteractEvent();
			interactTrigger.onCancelAnimation = new InteractEvent();
			((UnityEvent<PlayerControllerB>)(object)interactTrigger.onInteract).AddListener(callback);
			((Behaviour)interactTrigger).enabled = true;
		}

		public static bool IsEnemyOutside(EnemyAI enemyAI)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			return ((Component)enemyAI).transform.position.y > -50f;
		}

		private static GameObject? TrySpawnItemAtPosition(SpawnableItemWithRarity spawnableItemWithRarity, Vector3 position)
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			if (!IsHost)
			{
				LethalMon.Log("TrySpawnItemAtPosition: Not a valid item or not the host.");
				return null;
			}
			LethalMon.Log("Instantiating item " + ((Object)spawnableItemWithRarity.spawnableItem).name);
			GameObject val = Object.Instantiate<GameObject>(spawnableItemWithRarity.spawnableItem.spawnPrefab, position, Quaternion.identity, StartOfRound.Instance.elevatorTransform);
			NetworkObject component = val.GetComponent<NetworkObject>();
			if (component != null)
			{
				component.Spawn(false);
			}
			return val;
		}

		public static GameObject? TrySpawnRandomItemAtPosition(Vector3 position, out SpawnableItemWithRarity spawnableItemWithRarity)
		{
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			LethalMon.Log("Spawnable items: " + RoundManager.Instance.currentLevel.spawnableScrap.Count);
			spawnableItemWithRarity = RoundManager.Instance.currentLevel.spawnableScrap[Random.RandomRangeInt(0, RoundManager.Instance.currentLevel.spawnableScrap.Count)];
			return TrySpawnItemAtPosition(spawnableItemWithRarity, position);
		}

		public static void SpawnPoofCloudAt(Vector3 position)
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			Item giftBoxItem = GiftBoxItem;
			if ((Object)(object)giftBoxItem != (Object)null && (Object)(object)giftBoxItem.spawnPrefab != (Object)null)
			{
				GiftBoxItem component = giftBoxItem.spawnPrefab.GetComponent<GiftBoxItem>();
				ParticleSystem val = Object.Instantiate<ParticleSystem>(component.PoofParticle);
				((Component)val).transform.position = position;
				val.Play();
			}
		}

		public static void UnlockPCIfNotUnlocked()
		{
			try
			{
				if (!IsHost)
				{
					return;
				}
				if ((Object)(object)global::LethalMon.PC.PC.pcPrefab == (Object)null)
				{
					LethalMon.Log("PC prefab is null, returning", LethalMon.LogType.Error);
					return;
				}
				PlaceableShipObject componentInChildren = global::LethalMon.PC.PC.pcPrefab.GetComponentInChildren<PlaceableShipObject>();
				if ((Object)(object)componentInChildren == (Object)null)
				{
					LethalMon.Log("PC PlaceableShipObject is null, returning", LethalMon.LogType.Error);
					return;
				}
				UnlockableItem val = StartOfRound.Instance.unlockablesList.unlockables.Find((UnlockableItem u) => (Object)(object)u.prefabObject == (Object)(object)global::LethalMon.PC.PC.pcPrefab);
				if (val == null)
				{
					LethalMon.Log("PC Unlockable not found, returning", LethalMon.LogType.Error);
					return;
				}
				LethalMon.Log("Unlockable ID: " + componentInChildren.unlockableID);
				LethalMon.Log("Unlockable has been unlocked: " + val.hasBeenUnlockedByPlayer);
				if (!val.hasBeenUnlockedByPlayer)
				{
					StartOfRound.Instance.UnlockShipObject(componentInChildren.unlockableID);
				}
			}
			catch (Exception ex)
			{
				LethalMon.Log(ex.ToString(), LethalMon.LogType.Error);
			}
		}

		public static List<Renderer> GetRenderers(GameObject? g)
		{
			List<Renderer> list = new List<Renderer>();
			if ((Object)(object)g != (Object)null)
			{
				Renderer[] componentsInChildren = g.GetComponentsInChildren<Renderer>();
				foreach (Renderer item in componentsInChildren)
				{
					list.Add(item);
				}
			}
			return list;
		}

		public static void ReplaceAllMaterialsWith(GameObject g, Func<Material, Material> materialReplacer)
		{
			List<Renderer> renderers = GetRenderers(g);
			foreach (Renderer item in renderers)
			{
				ReplaceAllMaterialsWith(item, materialReplacer);
			}
		}

		public static Material[] ReplaceAllMaterialsWith(Renderer mr, Func<Material, Material> materialReplacer)
		{
			List<Material> list = new List<Material>();
			Material[] materials = mr.materials;
			foreach (Material arg in materials)
			{
				list.Add(materialReplacer(arg));
			}
			Material[] materials2 = mr.materials;
			mr.materials = list.ToArray();
			return materials2;
		}

		public static void LoadSeeThroughShader(AssetBundle assetBundle)
		{
			SeeThroughShader = assetBundle.LoadAsset<Shader>("Assets/SeeThrough/SeeThroughStencil.shader");
			if ((Object)(object)SeeThroughShader == (Object)null)
			{
				LethalMon.Log("Unable to load seethrough shader!", LethalMon.LogType.Error);
			}
		}

		public static void LoadWireframeMaterial(AssetBundle assetBundle)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			Shader val = assetBundle.LoadAsset<Shader>("Assets/SeeThrough/wireframe.shader");
			if ((Object)(object)val == (Object)null)
			{
				LethalMon.Log("Unable to load wireframe shader!", LethalMon.LogType.Error);
			}
			else
			{
				WireframeMaterial = new Material(val);
			}
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "LethalMon";

		public const string PLUGIN_NAME = "LethalMon";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}
namespace LethalMon.Throw
{
	public abstract class ThrowableItem : GrabbableObject
	{
		public PlayerControllerB? playerThrownBy;

		public PlayerControllerB? lastThrower;

		private float _totalFallTime;

		private float _throwTime;

		private Vector3 _initialVelocity;

		private int? _layerMask;

		private Vector3? _hitPointNormal;

		private bool _throwCorrectlyInitialized;

		private static ThrowableItem? _lastDroppedItem;

		private static List<ThrowableItem>? _dropAllHeldItems;

		protected virtual float MaxFallTime => 30f;

		protected virtual float TimeStep => 0.01f;

		protected virtual Vector3 Gravity => Physics.gravity * 1.5f;

		protected virtual float ItemRadius => base.itemProperties.verticalOffset;

		protected virtual int LayerMask
		{
			get
			{
				int valueOrDefault = _layerMask.GetValueOrDefault();
				if (!_layerMask.HasValue)
				{
					valueOrDefault = Utils.LayerMasks.ToInt(new Utils.LayerMasks.Mask[9]
					{
						Utils.LayerMasks.Mask.Default,
						Utils.LayerMasks.Mask.Room,
						Utils.LayerMasks.Mask.Colliders,
						Utils.LayerMasks.Mask.Railing,
						Utils.LayerMasks.Mask.MiscLevelGeometry,
						Utils.LayerMasks.Mask.CompanyCruiser,
						Utils.LayerMasks.Mask.MapHazards,
						Utils.LayerMasks.Mask.InteractableObject,
						Utils.LayerMasks.Mask.DecalStickableSurface
					});
					_layerMask = valueOrDefault;
					return valueOrDefault;
				}
				return valueOrDefault;
			}
		}

		protected virtual float BounceCoefficient => 0.15f;

		protected virtual float ThrowForce => 20f;

		[HarmonyPatch(typeof(PlayerControllerB), "DiscardHeldObject")]
		[HarmonyPrefix]
		private static void DiscardHeldObjectPrefix(PlayerControllerB __instance, bool placeObject = false)
		{
			if (__instance.currentlyHeldObjectServer is ThrowableItem lastDroppedItem && !placeObject)
			{
				_lastDroppedItem = lastDroppedItem;
			}
		}

		[HarmonyPatch(typeof(PlayerControllerB), "DiscardHeldObject")]
		[HarmonyPostfix]
		private static void DiscardHeldObjectPostfix(PlayerControllerB __instance, bool placeObject = false)
		{
			if (!placeObject)
			{
				_lastDroppedItem?.FallToGround();
			}
		}

		[HarmonyPatch(typeof(PlayerControllerB), "DropAllHeldItems")]
		[HarmonyPrefix]
		private static void DropAllHeldItemsPrefix(PlayerControllerB __instance, bool itemsFall = true)
		{
			if (itemsFall)
			{
				_dropAllHeldItems = __instance.ItemSlots.OfType<ThrowableItem>().ToList();
			}
		}

		[HarmonyPatch(typeof(PlayerControllerB), "DropAllHeldItems")]
		[HarmonyPostfix]
		private static void DropAllHeldItemsPostfix(PlayerControllerB __instance, bool itemsFall = true)
		{
			if (!itemsFall || _dropAllHeldItems == null)
			{
				return;
			}
			foreach (ThrowableItem dropAllHeldItem in _dropAllHeldItems)
			{
				dropAllHeldItem.FallToGround();
			}
		}

		[ServerRpc(RequireOwnership = false)]
		public void ThrowServerRpc(NetworkObjectReference playerThrownByReference, float totalFallTime, Vector3 initialVelocity, Vector3 hitPointNormal, Vector3 startPosition, Vector3 targetPosition, bool inElevator, bool isInShip)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
				{
					ServerRpcParams val = default(ServerRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(3676412531u, val, (RpcDelivery)0);
					((FastBufferWriter)(ref val2)).WriteValueSafe<NetworkObjectReference>(ref playerThrownByReference, default(ForNetworkSerializable));
					((FastBufferWriter)(ref val2)).WriteValueSafe<float>(ref totalFallTime, default(ForPrimitives));
					((FastBufferWriter)(ref val2)).WriteValueSafe(ref initialVelocity);
					((FastBufferWriter)(ref val2)).WriteValueSafe(ref hitPointNormal);
					((FastBufferWriter)(ref val2)).WriteValueSafe(ref startPosition);
					((FastBufferWriter)(ref val2)).WriteValueSafe(ref targetPosition);
					((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref inElevator, default(ForPrimitives));
					((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref isInShip, default(ForPrimitives));
					((NetworkBehaviour)this).__endSendServerRpc(ref val2, 3676412531u, val, (RpcDelivery)0);
				}
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost))
				{
					ThrowClientRpc(playerThrownByReference, totalFallTime, initialVelocity, hitPointNormal, startPosition, targetPosition, inElevator, isInShip);
				}
			}
		}

		[ClientRpc]
		public void ThrowClientRpc(NetworkObjectReference playerThrownByReference, float totalFallTime, Vector3 initialVelocity, Vector3 hitPointNormal, Vector3 startPosition, Vector3 targetPosition, bool inElevator, bool isInShip)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d0: 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)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
			{
				ClientRpcParams val = default(ClientRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(2687194980u, val, (RpcDelivery)0);
				((FastBufferWriter)(ref val2)).WriteValueSafe<NetworkObjectReference>(ref playerThrownByReference, default(ForNetworkSerializable));
				((FastBufferWriter)(ref val2)).WriteValueSafe<float>(ref totalFallTime, default(ForPrimitives));
				((FastBufferWriter)(ref val2)).WriteValueSafe(ref initialVelocity);
				((FastBufferWriter)(ref val2)).WriteValueSafe(ref hitPointNormal);
				((FastBufferWriter)(ref val2)).WriteValueSafe(ref startPosition);
				((FastBufferWriter)(ref val2)).WriteValueSafe(ref targetPosition);
				((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref inElevator, default(ForPrimitives));
				((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref isInShip, default(ForPrimitives));
				((NetworkBehaviour)this).__endSendClientRpc(ref val2, 2687194980u, val, (RpcDelivery)0);
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 2 || (!networkManager.IsClient && !networkManager.IsHost))
			{
				return;
			}
			LethalMon.Log("SendThrowRpc server rpc received");
			NetworkObject val3 = default(NetworkObject);
			if (!((NetworkObjectReference)(ref playerThrownByReference)).TryGet(ref val3, (NetworkManager)null))
			{
				LethalMon.Log(((Object)((Component)this).gameObject).name + ": Failed to get player component (SendThrowRpc)", LethalMon.LogType.Error);
				return;
			}
			_throwTime = 0f;
			_totalFallTime = totalFallTime;
			_initialVelocity = initialVelocity;
			_hitPointNormal = ((hitPointNormal == Vector3.zero) ? null : new Vector3?(hitPointNormal));
			base.startFallingPosition = startPosition;
			base.targetFloorPosition = targetPosition;
			_throwCorrectlyInitialized = true;
			UpdateParent(inElevator, isInShip);
			PlayerControllerB val4 = default(PlayerControllerB);
			if (((Component)val3).TryGetComponent<PlayerControllerB>(ref val4))
			{
				playerThrownBy = val4;
				lastThrower = playerThrownBy;
			}
			AudioSource val5 = default(AudioSource);
			if ((Object)(object)base.itemProperties.throwSFX != (Object)null && ((Component)this).gameObject.TryGetComponent<AudioSource>(ref val5))
			{
				val5.PlayOneShot(base.itemProperties.throwSFX);
				WalkieTalkie.TransmitOneShotAudio(val5, base.itemProperties.throwSFX, 1f);
			}
		}

		[ServerRpc(RequireOwnership = false)]
		public void FallToGroundServerRpc(float totalFallTime, Vector3 initialVelocity, Vector3 hitPointNormal, Vector3 startPosition, Vector3 targetPosition, bool inElevator, bool isInShip)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
				{
					ServerRpcParams val = default(ServerRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(3489132089u, val, (RpcDelivery)0);
					((FastBufferWriter)(ref val2)).WriteValueSafe<float>(ref totalFallTime, default(ForPrimitives));
					((FastBufferWriter)(ref val2)).WriteValueSafe(ref initialVelocity);
					((FastBufferWriter)(ref val2)).WriteValueSafe(ref hitPointNormal);
					((FastBufferWriter)(ref val2)).WriteValueSafe(ref startPosition);
					((FastBufferWriter)(ref val2)).WriteValueSafe(ref targetPosition);
					((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref inElevator, default(ForPrimitives));
					((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref isInShip, default(ForPrimitives));
					((NetworkBehaviour)this).__endSendServerRpc(ref val2, 3489132089u, val, (RpcDelivery)0);
				}
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost))
				{
					FallToGroundClientRpc(totalFallTime, initialVelocity, hitPointNormal, startPosition, targetPosition, inElevator, isInShip);
				}
			}
		}

		[ClientRpc]
		public void FallToGroundClientRpc(float totalFallTime, Vector3 initialVelocity, Vector3 hitPointNormal, Vector3 startPosition, Vector3 targetPosition, bool inElevator, bool isInShip)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_0188: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
				{
					ClientRpcParams val = default(ClientRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(2979563401u, val, (RpcDelivery)0);
					((FastBufferWriter)(ref val2)).WriteValueSafe<float>(ref totalFallTime, default(ForPrimitives));
					((FastBufferWriter)(ref val2)).WriteValueSafe(ref initialVelocity);
					((FastBufferWriter)(ref val2)).WriteValueSafe(ref hitPointNormal);
					((FastBufferWriter)(ref val2)).WriteValueSafe(ref startPosition);
					((FastBufferWriter)(ref val2)).WriteValueSafe(ref targetPosition);
					((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref inElevator, default(ForPrimitives));
					((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref isInShip, default(ForPrimitives));
					((NetworkBehaviour)this).__endSendClientRpc(ref val2, 2979563401u, val, (RpcDelivery)0);
				}
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
				{
					_throwTime = 0f;
					_totalFallTime = totalFallTime;
					_initialVelocity = initialVelocity;
					_hitPointNormal = ((hitPointNormal == Vector3.zero) ? null : new Vector3?(hitPointNormal));
					base.startFallingPosition = startPosition;
					base.targetFloorPosition = targetPosition;
					UpdateParent(inElevator, isInShip);
					_throwCorrectlyInitialized = true;
				}
			}
		}

		public override void ItemActivate(bool used, bool buttonDown = true)
		{
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			((GrabbableObject)this).ItemActivate(used, buttonDown);
			if (((NetworkBehaviour)this).IsOwner)
			{
				playerThrownBy = base.playerHeldBy;
				lastThrower = playerThrownBy;
				_throwTime = 0f;
				base.hasHitGround = true;
				base.playerHeldBy.DiscardHeldObject(true, (NetworkObject)null, GetItemThrowDestination(ThrowForce, out _initialVelocity, out _totalFallTime, out _hitPointNormal), true);
				ThrowServerRpc(NetworkObjectReference.op_Implicit(((Component)playerThrownBy).GetComponent<NetworkObject>()), _totalFallTime, _initialVelocity, (Vector3)(((??)_hitPointNormal) ?? Vector3.zero), base.startFallingPosition, base.targetFloorPosition, base.isInElevator, base.isInShipRoom);
			}
		}

		public override void FallWithCurve()
		{
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01df: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0208: Unknown result type (might be due to invalid IL or missing references)
			//IL_020d: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0243: Unknown result type (might be due to invalid IL or missing references)
			//IL_0248: Unknown result type (might be due to invalid IL or missing references)
			//IL_022c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0231: Unknown result type (might be due to invalid IL or missing references)
			//IL_024d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0259: Unknown result type (might be due to invalid IL or missing references)
			//IL_025e: Unknown result type (might be due to invalid IL or missing references)
			if (!_throwCorrectlyInitialized)
			{
				return;
			}
			if (_totalFallTime == 0f)
			{
				base.fallTime = 1f;
				StopMovingAfterHittingGround();
				return;
			}
			_throwTime += Time.deltaTime;
			if (_throwTime > _totalFallTime)
			{
				_throwTime = _totalFallTime;
			}
			Vector3 localPosition = ((Component)this).transform.localPosition;
			((Component)this).transform.localPosition = base.startFallingPosition + _initialVelocity * _throwTime + 0.5f * Gravity * _throwTime * _throwTime;
			base.fallTime = _throwTime / _totalFallTime;
			if (!(base.fallTime >= 1f))
			{
				return;
			}
			OnHitSurface();
			if (_hitPointNormal.HasValue)
			{
				Vector3 val = _initialVelocity + Gravity * _throwTime;
				Vector3 val2 = val - 2f * Vector3.Dot(val, _hitPointNormal.Value) * _hitPointNormal.Value;
				val2 *= BounceCoefficient;
				RaycastHit val3 = default(RaycastHit);
				if (Physics.Raycast(((Component)this).transform.position, Vector3.down, ref val3, 30f, LayerMask, (QueryTriggerInteraction)1) && Vector3.Distance(((RaycastHit)(ref val3)).point, ((Component)this).transform.position) <= ItemRadius + Mathf.Abs(TimeStep * Gravity.y) && ((Vector3)(ref val2)).magnitude < 0.5f)
				{
					StopMovingAfterHittingGround();
					return;
				}
				base.fallTime = 0f;
				_initialVelocity = val2;
				_throwTime = 0f;
				base.targetFloorPosition = GetSphereProjectileCollisionPoint(((Component)this).transform.position, _initialVelocity, Gravity, MaxFallTime, TimeStep, ItemRadius, out _totalFallTime, out _hitPointNormal);
				UpdateParent();
				base.targetFloorPosition = ((!base.isInElevator) ? StartOfRound.Instance.propsContainer.InverseTransformPoint(base.targetFloorPosition) : StartOfRound.Instance.elevatorTransform.InverseTransformPoint(base.targetFloorPosition));
				base.startFallingPosition = ((Component)this).transform.localPosition;
			}
			else
			{
				StopMovingAfterHittingGround();
			}
		}

		public void FallToGround(bool randomizePosition = false)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: 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_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			base.fallTime = 0f;
			_throwTime = 0f;
			base.startFallingPosition = ((Component)this).transform.localPosition;
			_initialVelocity = Vector3.zero;
			base.targetFloorPosition = GetSphereProjectileCollisionPoint(((Component)this).transform.position, Vector3.zero, Gravity, MaxFallTime, TimeStep, ItemRadius, out _totalFallTime, out _hitPointNormal);
			UpdateParent();
			base.targetFloorPosition = ((!base.isInElevator) ? StartOfRound.Instance.propsContainer.InverseTransformPoint(base.targetFloorPosition) : StartOfRound.Instance.elevatorTransform.InverseTransformPoint(base.targetFloorPosition));
			FallToGroundServerRpc(_totalFallTime, _initialVelocity, (Vector3)(((??)_hitPointNormal) ?? Vector3.zero), base.startFallingPosition, base.targetFloorPosition, base.isInElevator, base.isInShipRoom);
		}

		public override void DiscardItemFromEnemy()
		{
			((GrabbableObject)this).DiscardItemFromEnemy();
			FallToGround();
		}

		public void OnHitSurface()
		{
			((GrabbableObject)this).PlayDropSFX();
		}

		private void UpdateParent()
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			Bounds bounds = StartOfRound.Instance.shipBounds.bounds;
			bool flag = ((Bounds)(ref bounds)).Contains(((Component)this).transform.position);
			int inShipRoom;
			if (flag)
			{
				bounds = StartOfRound.Instance.shipInnerRoomBounds.bounds;
				inShipRoom = (((Bounds)(ref bounds)).Contains(((Component)this).transform.position) ? 1 : 0);
			}
			else
			{
				inShipRoom = 0;
			}
			UpdateParent(flag, (byte)inShipRoom != 0);
		}

		private void UpdateParent(bool inElevator, bool inShipRoom)
		{
			if (inElevator)
			{
				((Component)this).transform.SetParent(StartOfRound.Instance.elevatorTransform, true);
				base.isInElevator = true;
				base.isInShipRoom = inShipRoom;
			}
			else
			{
				((Component)this).transform.SetParent(StartOfRound.Instance.propsContainer, true);
				base.isInElevator = false;
				base.isInShipRoom = false;
			}
		}

		private void StopMovingAfterHittingGround()
		{
			LethalMon.Log("Stop moving");
			((GrabbableObject)this).OnHitGround();
			playerThrownBy = null;
			UpdateParent();
			GameNetworkManager.Instance.localPlayerController.SetItemInElevator(base.isInElevator, base.isInShipRoom, (GrabbableObject)(object)this);
			base.hasHitGround = true;
			_throwCorrectlyInitialized = false;
		}

		private Vector3 GetSphereProjectileCollisionPoint(Vector3 startPosition, Vector3 initialVelocity, Vector3 gravity, float maxTime, float timeStep, float radius, out float totalFallTime, out Vector3? hitPointNormal)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type