Decompiled source of LethalBots v13.0.0

plugins/TRizzle-LethalBot/LethalBots.dll

Decompiled a week ago
using System;
using System.CodeDom.Compiler;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Reflection.Emit;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Cryptography;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using BetterEmote.AssetScripts;
using BunkbedRevive;
using CSync.Extensions;
using CSync.Lib;
using CustomItemBehaviourLibrary.AbstractItems;
using Dawn.Internal;
using Dawn.Utils;
using Dissonance;
using Dissonance.Integrations.Unity_NFGO;
using DunGen;
using DunGen.Tags;
using FacilityMeltdown.API;
using GameNetcodeStuff;
using GeneralImprovements;
using HarmonyLib;
using LCAutoRevive;
using LCAutoRevive.Network;
using LCAutoRevive.Patches;
using LCAutoRevive.Utils;
using LCPeeper;
using LethalBots.AI;
using LethalBots.AI.AIStates;
using LethalBots.Configs;
using LethalBots.Constants;
using LethalBots.Enums;
using LethalBots.Inputs;
using LethalBots.Managers;
using LethalBots.NetcodePatcher;
using LethalBots.NetworkSerializers;
using LethalBots.Patches.EnemiesPatches;
using LethalBots.Patches.GameEnginePatches;
using LethalBots.Patches.MapHazardsPatches;
using LethalBots.Patches.MapPatches;
using LethalBots.Patches.ModPatches.AdditionalNetworking;
using LethalBots.Patches.ModPatches.AutoRevive;
using LethalBots.Patches.ModPatches.BetterEmotes;
using LethalBots.Patches.ModPatches.BetterLethalVRM;
using LethalBots.Patches.ModPatches.BunkbedRevive;
using LethalBots.Patches.ModPatches.DawnLib;
using LethalBots.Patches.ModPatches.LCVR;
using LethalBots.Patches.ModPatches.LethalPhones;
using LethalBots.Patches.ModPatches.LethalProgression;
using LethalBots.Patches.ModPatches.ModelRplcmntAPI;
using LethalBots.Patches.ModPatches.MoreEmotes;
using LethalBots.Patches.ModPatches.PathfindingLib;
using LethalBots.Patches.ModPatches.Peepers;
using LethalBots.Patches.ModPatches.ReviveCompany;
using LethalBots.Patches.ModPatches.SelfSortingStorage;
using LethalBots.Patches.ModPatches.ShowCapacity;
using LethalBots.Patches.ModPatches.TooManyEmotes;
using LethalBots.Patches.ModPatches.UsualScrap;
using LethalBots.Patches.ModPatches.Zaprillator;
using LethalBots.Patches.NpcPatches;
using LethalBots.Patches.ObjectsPatches;
using LethalBots.SaveAdapter;
using LethalBots.Utils;
using LethalBots.Utils.Helpers;
using LethalBots.Utils.Helpers.VehicleHelpers;
using LethalBots.Utils.Items.Weapons;
using LethalBots.Utils.Vehicles;
using LethalCompanyInputUtils.Api;
using LethalInternship.AI;
using LethalInternship.Managers;
using LethalLib.Modules;
using LethalMin;
using Microsoft.CodeAnalysis;
using ModelReplacement;
using ModelReplacement.Monobehaviors;
using ModelReplacement.Patches;
using MoreCompany;
using MoreCompany.Cosmetics;
using MoreEmotes.Patch;
using MoreEmotes.Scripts;
using NavMeshLib;
using NavMeshLib.Editor;
using NavMeshLib.Enums;
using Newtonsoft.Json;
using OPJosMod.ReviveCompany;
using OPJosMod.ReviveCompany.CustomRpc;
using OomJan.BetterLethalVRM;
using PathfindingLib.API;
using PathfindingLib.Utilities.Native;
using ReservedItemSlotCore.Data;
using Scoops.gameobjects;
using Scoops.misc;
using Scoops.patch;
using Scoops.service;
using SelfSortingStorage.Cupboard;
using SpeechRecognitionAPI;
using Steamworks;
using TMPro;
using TooManyEmotes;
using TooManyEmotes.Networking;
using TooManyEmotes.Patches;
using Unity.AI.Navigation;
using Unity.Collections;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.Animations.Rigging;
using UnityEngine.Audio;
using UnityEngine.Events;
using UnityEngine.InputSystem;
using UnityEngine.Networking;
using UnityEngine.Rendering;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using UsualScrap.Behaviors;
using UsualScrap.Patches;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp-firstpass")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: IgnoresAccessChecksTo("com.github.teamxiaolan.dawnlib.compatibility")]
[assembly: IgnoresAccessChecksTo("com.github.teamxiaolan.dawnlib")]
[assembly: IgnoresAccessChecksTo("com.github.teamxiaolan.dawnlib.dusk")]
[assembly: IgnoresAccessChecksTo("com.github.teamxiaolan.dawnlib.interfaces")]
[assembly: IgnoresAccessChecksTo("DunGen")]
[assembly: IgnoresAccessChecksTo("LethalPhones")]
[assembly: IgnoresAccessChecksTo("PathfindingLib")]
[assembly: IgnoresAccessChecksTo("SelfSortingStorage")]
[assembly: IgnoresAccessChecksTo("Tomatobird.AutoRevive")]
[assembly: IgnoresAccessChecksTo("Unity.AI.Navigation")]
[assembly: IgnoresAccessChecksTo("Unity.Netcode.Runtime")]
[assembly: IgnoresAccessChecksTo("UsualScrap")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("LethalBots")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("13.0.0.0")]
[assembly: AssemblyInformationalVersion("13.0.0+a6c80c1af4019cf0b76e023793fc9c93cd095433")]
[assembly: AssemblyProduct("LethalBots")]
[assembly: AssemblyTitle("LethalBots")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("13.0.0.0")]
[assembly: TypeForwardedTo(typeof(AllowNullAttribute))]
[assembly: TypeForwardedTo(typeof(DisallowNullAttribute))]
[assembly: TypeForwardedTo(typeof(MaybeNullAttribute))]
[assembly: TypeForwardedTo(typeof(MaybeNullWhenAttribute))]
[assembly: TypeForwardedTo(typeof(NotNullAttribute))]
[assembly: TypeForwardedTo(typeof(NotNullIfNotNullAttribute))]
[assembly: TypeForwardedTo(typeof(NotNullWhenAttribute))]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
[module: NetcodePatchedAssembly]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class IsUnmanagedAttribute : Attribute
	{
	}
	[CompilerGenerated]
	[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]
	[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]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace LethalBots
{
	[BepInPlugin("T-Rizzle.LethalBots", "LethalBots", "13.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		public const string ModGUID = "T-Rizzle.LethalBots";

		public static AssetBundle ModAssets;

		public static AssetBundle ShipOrbitNavMeshAssets;

		internal static string DirectoryName;

		internal static EnemyType LethalBotNPCPrefab;

		internal static GameObject ShipOrbitNavMeshPrefab;

		internal static int PluginIrlPlayersCount;

		internal static ManualLogSource Logger;

		internal static Config Config;

		internal static LethalBotsInputs InputActionsInstance;

		internal static bool IsModSpeechRecognitionAPILoaded;

		internal static bool IsModTooManyEmotesLoaded;

		internal static bool IsModModelReplacementAPILoaded;

		internal static bool IsModCustomItemBehaviourLibraryLoaded;

		internal static bool IsModMoreCompanyLoaded;

		internal static bool IsModReviveCompanyLoaded;

		internal static bool IsModBunkbedReviveLoaded;

		internal static bool IsModZaprillatorLoaded;

		internal static bool IsModLethalMinLoaded;

		internal static bool IsModLethalInternsLoaded;

		internal static bool IsModFacilityMeltdownLoaded;

		internal static bool IsModNavmeshInCompanyLoaded;

		internal static bool IsModReservedItemSlotCoreLoaded;

		internal static bool IsModLethalPhonesLoaded;

		internal static bool IsModGeneralImprovementsLoaded;

		internal static bool IsModDawnLibLoaded;

		internal static bool IsModUsualScrapLoaded;

		internal static bool IsModAutoReviveLoaded;

		internal static bool IsModSuperEclipseLoaded;

		internal static bool IsModNavmeshInCompanyReduxLoaded;

		internal static bool IsModSelfSortingStorageLoaded;

		internal static bool IsModPathfindingLibLoaded;

		private readonly Harmony _harmony = new Harmony("T-Rizzle.LethalBots");

		private void Awake()
		{
			DirectoryName = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location);
			Logger = ((BaseUnityPlugin)this).Logger;
			Config = new Config(((BaseUnityPlugin)this).Config);
			InputActionsInstance = new LethalBotsInputs();
			InitializeNetworkBehaviours();
			ModAssets = AssetBundle.LoadFromFile(Path.Combine(DirectoryName, "lethalbotnpcmodassets"));
			if ((Object)(object)ModAssets == (Object)null)
			{
				Logger.LogFatal((object)"Unknown to load custom assets.");
				return;
			}
			LethalBotNPCPrefab = ModAssets.LoadAsset<EnemyType>("LethalBotNPC");
			if ((Object)(object)LethalBotNPCPrefab == (Object)null)
			{
				Logger.LogInfo((object)"Failed to directly load LethalBotNPC, manually searching asset bundle instead!");
				Object[] array = ModAssets.LoadAllAssets();
				for (int i = 0; i < array.Length; i++)
				{
					Logger.LogInfo((object)$"Found {array[i]} in asset bundle");
					Object obj = array[i];
					EnemyType val = (EnemyType)(object)((obj is EnemyType) ? obj : null);
					if (val != null)
					{
						LethalBotNPCPrefab = val;
						break;
					}
				}
			}
			if ((Object)(object)LethalBotNPCPrefab == (Object)null)
			{
				Logger.LogFatal((object)"LethalBotNPC prefab failed to load.");
				return;
			}
			foreach (Transform item in (from x in LethalBotNPCPrefab.enemyPrefab.GetComponentsInChildren<Transform>()
				where (Object)(object)x.parent != (Object)null && ((Object)x.parent).name == "LethalBotNPCObj" && ((Object)x).name != "Collision" && ((Object)x).name != "TurnCompass" && ((Object)x).name != "CreatureSFX" && ((Object)x).name != "CreatureVoice"
				select x).ToList())
			{
				Object.DestroyImmediate((Object)(object)((Component)item).gameObject);
			}
			byte[] value = MD5.Create().ComputeHash(Encoding.UTF8.GetBytes(typeof(Plugin).Assembly.GetName().Name + ((Object)((Component)this).gameObject).name + "lethalbotnpcmodassets"));
			uint globalObjectIdHash = BitConverter.ToUInt32(value, 0);
			NetworkObject component = LethalBotNPCPrefab.enemyPrefab.GetComponent<NetworkObject>();
			component.GlobalObjectIdHash = globalObjectIdHash;
			ShipOrbitNavMeshAssets = AssetBundle.LoadFromFile(Path.Combine(DirectoryName, "ship_orbit_navmesh"));
			if ((Object)(object)ShipOrbitNavMeshAssets == (Object)null)
			{
				Logger.LogFatal((object)"Unknown to load custom ship navmesh assests.");
				return;
			}
			ShipOrbitNavMeshPrefab = ShipOrbitNavMeshAssets.LoadAsset<GameObject>("ShipNavMeshColliders");
			if ((Object)(object)ShipOrbitNavMeshPrefab == (Object)null)
			{
				Logger.LogFatal((object)"ShipOrbitNavMesh prefab failed to load.");
				return;
			}
			NetworkPrefabs.RegisterNetworkPrefab(LethalBotNPCPrefab.enemyPrefab);
			InitPluginManager();
			PatchBaseGame();
			PatchOtherMods();
			SceneManager.sceneLoaded += OnSceneLoaded;
			ModAssets.Unload(false);
			ShipOrbitNavMeshAssets.Unload(false);
			Logger.LogInfo((object)"Plugin T-Rizzle.LethalBots is loaded!");
		}

		private void PatchBaseGame()
		{
			_harmony.PatchAll(typeof(AudioMixerPatch));
			_harmony.PatchAll(typeof(AudioReverbTriggerPatch));
			_harmony.PatchAll(typeof(DebugPatch));
			_harmony.PatchAll(typeof(GameNetworkManagerPatch));
			_harmony.PatchAll(typeof(HUDManagerPatch));
			_harmony.PatchAll(typeof(NetworkSceneManagerPatch));
			_harmony.PatchAll(typeof(NfgoPlayerPatch));
			_harmony.PatchAll(typeof(NetworkObjectPatch));
			_harmony.PatchAll(typeof(RoundManagerPatch));
			_harmony.PatchAll(typeof(SoundManagerPatch));
			_harmony.PatchAll(typeof(StartOfRoundPatch));
			_harmony.PatchAll(typeof(EnemyAIPatch));
			_harmony.PatchAll(typeof(PlayerControllerBPatch));
			_harmony.PatchAll(typeof(EnemyAICollisionDetect));
			_harmony.PatchAll(typeof(BaboonBirdAIPatch));
			_harmony.PatchAll(typeof(BlobAIPatch));
			_harmony.PatchAll(typeof(BushWolfEnemyPatch));
			_harmony.PatchAll(typeof(ButlerBeesEnemyAIPatch));
			_harmony.PatchAll(typeof(ButlerEnemyAIPatch));
			_harmony.PatchAll(typeof(CadaverBloomAIPatch));
			_harmony.PatchAll(typeof(CadaverGrowthAIPatch));
			_harmony.PatchAll(typeof(CaveDwellerAIPatch));
			_harmony.PatchAll(typeof(CentipedeAIPatch));
			_harmony.PatchAll(typeof(CrawlerAIPatch));
			_harmony.PatchAll(typeof(DressGirlAIPatch));
			_harmony.PatchAll(typeof(FlowermanAIPatch));
			_harmony.PatchAll(typeof(FlowerSnakeEnemyPatch));
			_harmony.PatchAll(typeof(ForestGiantAIPatch));
			_harmony.PatchAll(typeof(GiantKiwiAIPatch));
			_harmony.PatchAll(typeof(JesterAIPatch));
			_harmony.PatchAll(typeof(MaskedPlayerEnemyPatch));
			_harmony.PatchAll(typeof(MouthDogAIPatch));
			_harmony.PatchAll(typeof(NutcrackerEnemyAIPatch));
			_harmony.PatchAll(typeof(PumaAIPatch));
			_harmony.PatchAll(typeof(RadMechAIPatch));
			_harmony.PatchAll(typeof(RadMechMissilePatch));
			_harmony.PatchAll(typeof(RedLocustBeesPatch));
			_harmony.PatchAll(typeof(SandSpiderAIPatch));
			_harmony.PatchAll(typeof(SandWormAIPatch));
			_harmony.PatchAll(typeof(SpringManAIPatch));
			_harmony.PatchAll(typeof(LandminePatch));
			_harmony.PatchAll(typeof(QuicksandTriggerPatch));
			_harmony.PatchAll(typeof(SpikeRoofTrapPatch));
			_harmony.PatchAll(typeof(TurretPatch));
			_harmony.PatchAll(typeof(AnimatedObjectFloatSetterPatch));
			_harmony.PatchAll(typeof(CompanyMonsterCollisionDetectPatch));
			_harmony.PatchAll(typeof(DoorLockPatch));
			_harmony.PatchAll(typeof(InteractTriggerPatch));
			_harmony.PatchAll(typeof(OutOfBoundsTriggerPatch));
			_harmony.PatchAll(typeof(PlayerPhysicsRegionPatch));
			_harmony.PatchAll(typeof(ShipTeleporterPatch));
			_harmony.PatchAll(typeof(VehicleControllerPatch));
			_harmony.PatchAll(typeof(DepositItemsDeskPatch));
			_harmony.PatchAll(typeof(CaveDwellerPhysicsPropPatch));
			_harmony.PatchAll(typeof(DeadBodyInfoPatch));
			_harmony.PatchAll(typeof(GrabbableObjectPatch));
			_harmony.PatchAll(typeof(RagdollGrabbableObjectPatch));
			_harmony.PatchAll(typeof(ShotgunItemPatch));
			_harmony.PatchAll(typeof(SprayPaintItemPatch));
			_harmony.PatchAll(typeof(StunGrenadeItemPatch));
			_harmony.PatchAll(typeof(TetraChemicalItemPatch));
		}

		private void PatchOtherMods()
		{
			//IL_0250: Unknown result type (might be due to invalid IL or missing references)
			//IL_025e: Expected O, but got Unknown
			//IL_028d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0299: Expected O, but got Unknown
			//IL_02c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d4: Expected O, but got Unknown
			//IL_03de: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ea: Expected O, but got Unknown
			//IL_041a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0428: Expected O, but got Unknown
			//IL_0494: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a2: Expected O, but got Unknown
			//IL_04d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e3: Expected O, but got Unknown
			//IL_0510: Unknown result type (might be due to invalid IL or missing references)
			//IL_051e: Expected O, but got Unknown
			//IL_054b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0559: Expected O, but got Unknown
			//IL_0586: Unknown result type (might be due to invalid IL or missing references)
			//IL_0594: Expected O, but got Unknown
			//IL_05c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_05cf: Expected O, but got Unknown
			//IL_061c: Unknown result type (might be due to invalid IL or missing references)
			//IL_062a: Expected O, but got Unknown
			//IL_0657: Unknown result type (might be due to invalid IL or missing references)
			//IL_0665: Expected O, but got Unknown
			//IL_0692: Unknown result type (might be due to invalid IL or missing references)
			//IL_06a0: Expected O, but got Unknown
			//IL_06cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_06db: Expected O, but got Unknown
			IsModSpeechRecognitionAPILoaded = IsModLoaded("JS03.SpeechRecognitionAPI");
			IsModTooManyEmotesLoaded = IsModLoaded("FlipMods.TooManyEmotes");
			IsModModelReplacementAPILoaded = IsModLoaded("meow.ModelReplacementAPI");
			IsModCustomItemBehaviourLibraryLoaded = IsModLoaded("com.github.WhiteSpike.CustomItemBehaviourLibrary");
			IsModMoreCompanyLoaded = IsModLoaded("me.swipez.melonloader.morecompany");
			IsModReviveCompanyLoaded = IsModLoaded("OpJosMod.ReviveCompany");
			IsModBunkbedReviveLoaded = IsModLoaded("viviko.BunkbedRevive");
			IsModZaprillatorLoaded = IsModLoaded("Zaprillator");
			IsModLethalMinLoaded = IsModLoaded("NoteBoxz.LethalMin");
			IsModLethalInternsLoaded = IsModLoaded("Szumi57.LethalInterns");
			IsModFacilityMeltdownLoaded = IsModLoaded("me.loaforc.facilitymeltdown");
			IsModNavmeshInCompanyLoaded = IsModLoaded("dev.kittenji.NavMeshInCompany");
			IsModReservedItemSlotCoreLoaded = IsModLoaded("FlipMods.ReservedItemSlotCore");
			IsModLethalPhonesLoaded = IsModLoaded("LethalPhones");
			IsModGeneralImprovementsLoaded = IsModLoaded("ShaosilGaming.GeneralImprovements");
			IsModDawnLibLoaded = IsModLoaded("com.github.teamxiaolan.dawnlib");
			IsModUsualScrapLoaded = IsModLoaded("Emil.UsualScrap");
			IsModAutoReviveLoaded = IsModLoaded("Tomatobird.AutoRevive");
			IsModSuperEclipseLoaded = IsModLoaded("Millie.SuperEclipse");
			IsModNavmeshInCompanyReduxLoaded = IsModLoaded("T-Rizzle.NavMeshInCompanyRedux");
			IsModSelfSortingStorageLoaded = IsModLoaded("zigzag.SelfSortingStorage");
			IsModPathfindingLibLoaded = IsModLoaded("Zaggy1024.PathfindingLib");
			bool flag = IsModLoaded("MoreEmotes");
			bool flag2 = IsModLoaded("BetterEmotes");
			bool flag3 = IsModLoaded("Piggy.ShowCapacity");
			bool flag4 = IsModLoaded("Stoneman.LethalProgression");
			bool flag5 = IsModLoaded("suskitech.LCAlwaysHearActiveWalkie");
			bool flag6 = IsModLoaded("butterystancakes.lethalcompany.butteryfixes");
			bool flag7 = IsModLoaded("x753.Peepers");
			bool flag8 = IsModLoaded("io.daxcess.lcvr");
			bool flag9 = IsModLoaded("OomJan.BetterLethalVRM");
			List<string> list = new List<string>();
			string[] files = Directory.GetFiles(Path.GetFullPath(Paths.PatcherPluginPath), "*.dll", SearchOption.AllDirectories);
			foreach (string path in files)
			{
				list.Add(Path.GetFileName(path));
			}
			bool flag10 = IsPreLoaderLoaded("AdditionalNetworking_Preloader.dll", list);
			if (flag)
			{
				_harmony.PatchAll(typeof(MoreEmotesPatch));
			}
			if (flag2)
			{
				_harmony.Patch((MethodBase)AccessTools.Method(AccessTools.TypeByName("BetterEmote.Patches.EmotePatch"), "StartPostfix", (Type[])null, (Type[])null), new HarmonyMethod(typeof(BetterEmotesPatch), "StartPostfix_Prefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				_harmony.Patch((MethodBase)AccessTools.Method(AccessTools.TypeByName("BetterEmote.Patches.EmotePatch"), "UpdatePostfix", (Type[])null, (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(typeof(BetterEmotesPatch), "UpdatePostfix_Transpiler", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null);
				_harmony.Patch((MethodBase)AccessTools.Method(AccessTools.TypeByName("BetterEmote.Patches.EmotePatch"), "PerformEmotePrefix", (Type[])null, (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(typeof(BetterEmotesPatch), "PerformEmotePrefix_Transpiler", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null);
				_harmony.PatchAll(typeof(BetterEmotesCustomAnimationObjectsPatch));
			}
			if (IsModTooManyEmotesLoaded)
			{
				_harmony.PatchAll(typeof(EmoteControllerPlayerPatch));
				_harmony.PatchAll(typeof(ThirdPersonEmoteControllerPatch));
			}
			if (IsModModelReplacementAPILoaded)
			{
				_harmony.PatchAll(typeof(ModelReplacementPlayerControllerBPatchPatch));
				_harmony.PatchAll(typeof(ModelReplacementAPIPatch));
			}
			if (IsModLethalPhonesLoaded)
			{
				_harmony.PatchAll(typeof(AudioSourceStoragePatch));
				_harmony.PatchAll(typeof(PhoneBehaviorPatch));
				_harmony.PatchAll(typeof(PlayerPhonePatch));
				_harmony.PatchAll(typeof(PlayerPhonePatchPatch));
				PhoneBehaviorPatch.SetupReflectionFields();
			}
			if (flag10)
			{
				_harmony.Patch((MethodBase)AccessTools.Method(AccessTools.TypeByName("AdditionalNetworking.Patches.Inventory.PlayerControllerBPatch"), "OnStart", (Type[])null, (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(typeof(AdditionalNetworkingPatch), "Start_Transpiler", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null);
			}
			if (flag3)
			{
				_harmony.Patch((MethodBase)AccessTools.Method(AccessTools.TypeByName("ShowCapacity.Patches.PlayerControllerBPatch"), "Update_PostFix", (Type[])null, (Type[])null), new HarmonyMethod(typeof(ShowCapacityPatch), "Update_PostFix_Prefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			if (IsModReviveCompanyLoaded)
			{
				_harmony.PatchAll(typeof(ReviveCompanyGeneralUtilPatch));
			}
			if (IsModBunkbedReviveLoaded)
			{
				_harmony.PatchAll(typeof(BunkbedControllerPatch));
			}
			if (IsModZaprillatorLoaded)
			{
				_harmony.Patch((MethodBase)AccessTools.Method(AccessTools.TypeByName("Zaprillator.Behaviors.RevivablePlayer"), "IShockableWithGun.StopShockingWithGun", (Type[])null, (Type[])null), new HarmonyMethod(typeof(RevivablePlayerPatch), "StopShockingWithGun_Prefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			if (flag4)
			{
				_harmony.Patch((MethodBase)AccessTools.Method(AccessTools.TypeByName("LethalProgression.Skills.HPRegen"), "HPRegenUpdate", (Type[])null, (Type[])null), new HarmonyMethod(typeof(HPRegenPatch), "HPRegenUpdate_Prefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				_harmony.Patch((MethodBase)AccessTools.Method(AccessTools.TypeByName("LethalProgression.Skills.Oxygen"), "EnteredWater", (Type[])null, (Type[])null), new HarmonyMethod(typeof(OxygenPatch), "EnteredWater_Prefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				_harmony.Patch((MethodBase)AccessTools.Method(AccessTools.TypeByName("LethalProgression.Skills.Oxygen"), "LeftWater", (Type[])null, (Type[])null), new HarmonyMethod(typeof(OxygenPatch), "LeftWater_Prefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				_harmony.Patch((MethodBase)AccessTools.Method(AccessTools.TypeByName("LethalProgression.Skills.Oxygen"), "ShouldDrown", (Type[])null, (Type[])null), new HarmonyMethod(typeof(OxygenPatch), "ShouldDrown_Prefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				_harmony.Patch((MethodBase)AccessTools.Method(AccessTools.TypeByName("LethalProgression.Skills.Oxygen"), "OxygenUpdate", (Type[])null, (Type[])null), new HarmonyMethod(typeof(OxygenPatch), "OxygenUpdate_Prefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			if (flag7)
			{
				_harmony.PatchAll(typeof(PeeperAttachHitboxPatch));
			}
			if (flag8)
			{
				_harmony.Patch((MethodBase)AccessTools.Method(AccessTools.TypeByName("LCVR.Patches.Spectating.SpectatorPlayerPatches"), "BeforePlayerDeath", (Type[])null, (Type[])null), new HarmonyMethod(typeof(LCVRPatchesPatch), "BeforePlayerDeath_Prefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				_harmony.Patch((MethodBase)AccessTools.Method(AccessTools.TypeByName("LCVR.Patches.Spectating.SpectatorPlayerPatches"), "OnPlayerDeath", (Type[])null, (Type[])null), new HarmonyMethod(typeof(LCVRPatchesPatch), "OnPlayerDeath_Prefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				_harmony.Patch((MethodBase)AccessTools.Method(AccessTools.TypeByName("LCVR.Patches.Items.ShotgunItemPatches"), "DisplaySafetyPatch", (Type[])null, (Type[])null), new HarmonyMethod(typeof(LCVRPatchesPatch), "DisplaySafetyPatch_Prefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				_harmony.Patch((MethodBase)AccessTools.Method(AccessTools.TypeByName("LCVR.Patches.PlayerControllerPatches"), "AfterDamagePlayer", (Type[])null, (Type[])null), new HarmonyMethod(typeof(LCVRPatchesPatch), "AfterDamagePlayer_Prefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			if (IsModDawnLibLoaded)
			{
				_harmony.PatchAll(typeof(DawnMoonNetworkerPatch));
				_harmony.PatchAll(typeof(PlayerNameplateUIPatch));
			}
			if (IsModUsualScrapLoaded)
			{
				_harmony.PatchAll(typeof(DefibrillatorScriptPatch));
				ItemsManager.RegisterWeapons.AddListener((UnityAction<ItemsManager>)UsualScrapWeaponsPatch.RegisterWeaponsForBots);
			}
			if (IsModAutoReviveLoaded)
			{
				_harmony.PatchAll(typeof(AutoRevivePlayerPatch));
				_harmony.PatchAll(typeof(LethalBotAutoReviveHelper));
			}
			if (IsModSelfSortingStorageLoaded)
			{
				SelfSortingStoragePatch.InitSingleton();
			}
			if (IsModPathfindingLibLoaded)
			{
				_harmony.PatchAll(typeof(PathfindingLibPatch));
				PathfindingLibPatch.AddCustomAreaMasks();
			}
			if (flag9)
			{
				_harmony.PatchAll(typeof(BetterLethalVRMPatch));
			}
		}

		private static bool IsModLoaded(string modGUID)
		{
			bool flag = Chainloader.PluginInfos.ContainsKey(modGUID);
			if (flag)
			{
				LogInfo("Mod compatibility loaded for mod : GUID " + modGUID);
			}
			return flag;
		}

		private static bool IsPreLoaderLoaded(string dllFileName, List<string> fileNames)
		{
			bool flag = fileNames.Contains(dllFileName);
			if (flag)
			{
				LogInfo("Mod compatibility loaded for preloader : " + dllFileName);
			}
			return flag;
		}

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

		private static void InitPluginManager()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			GameObject val = new GameObject("PluginManager");
			val.AddComponent<PluginManager>();
			PluginManager.Instance.InitManagers();
		}

		private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
		{
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			EnemyAINestSpawnObject[] array = Resources.FindObjectsOfTypeAll<EnemyAINestSpawnObject>();
			if (array == null || array.Length == 0)
			{
				return;
			}
			bool flag = false;
			try
			{
				RadMechAI arg = default(RadMechAI);
				foreach (EnemyAINestSpawnObject val in array)
				{
					if (!((Object)(object)val != (Object)null))
					{
						continue;
					}
					EnemyType enemyType = val.enemyType;
					if ((Object)(object)enemyType != (Object)null && enemyType.enemyPrefab.TryGetComponent<RadMechAI>(ref arg))
					{
						LogInfo($"Found Radmech Prefab {arg} with nest Prefab {val}");
						Transform val2 = ((Component)val).transform.FindChildWithName("Cube (4)");
						if ((Object)(object)val2 != (Object)null)
						{
							NavMeshObstacle val3 = ((Component)val2).gameObject.AddComponent<NavMeshObstacle>();
							val3.shape = (NavMeshObstacleShape)1;
							val3.carving = true;
							val3.carvingMoveThreshold = 0.1f;
							val3.carvingTimeToStationary = 0.5f;
							val3.carveOnlyStationary = true;
							val3.size = Vector3.one;
							val3.center = Vector3.zero;
							LogInfo("Added NavmeshObstacle to Left Arm");
						}
						Transform val4 = ((Component)val).transform.FindChildWithName("Cube (5)");
						if ((Object)(object)val4 != (Object)null)
						{
							NavMeshObstacle val5 = ((Component)val4).gameObject.AddComponent<NavMeshObstacle>();
							val5.shape = (NavMeshObstacleShape)1;
							val5.carving = true;
							val5.carvingMoveThreshold = 0.1f;
							val5.carvingTimeToStationary = 0.5f;
							val5.carveOnlyStationary = true;
							val5.size = Vector3.one;
							val5.center = Vector3.zero;
							LogInfo("Added NavmeshObstacle to Right Arm");
						}
						flag = true;
					}
				}
			}
			catch (Exception arg2)
			{
				LogError($"An error occured when attempting to edit RadMech Prefab. \n Error: {arg2}");
			}
			finally
			{
				if (flag)
				{
					SceneManager.sceneLoaded -= OnSceneLoaded;
				}
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal static void LogDebug(string debugLog)
		{
			if (Config.EnableDebugLog.Value)
			{
				Logger.LogDebug((object)debugLog);
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal static void LogInfo(string infoLog)
		{
			Logger.LogInfo((object)infoLog);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal static void LogWarning(string warningLog)
		{
			Logger.LogWarning((object)warningLog);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal static void LogError(string errorLog)
		{
			Logger.LogError((object)errorLog);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal static void LogFatal(string fatalLog)
		{
			Logger.LogFatal((object)fatalLog);
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "LethalBots";

		public const string PLUGIN_NAME = "LethalBots";

		public const string PLUGIN_VERSION = "13.0.0";
	}
}
namespace LethalBots.Utils
{
	internal static class ComponentUtil
	{
		public static void ListAllComponents(GameObject gameObject)
		{
			if ((Object)(object)gameObject == (Object)null)
			{
				return;
			}
			Plugin.LogDebug(" ");
			Plugin.LogDebug("List of components :");
			Component[] components = gameObject.GetComponents(typeof(Component));
			Component[] array = components;
			foreach (Component val in array)
			{
				if (!((Object)(object)val == (Object)null))
				{
					Plugin.LogDebug(((object)val).ToString());
				}
			}
			Plugin.LogDebug("Child components :");
			components = gameObject.GetComponentsInChildren(typeof(Component));
			Component[] array2 = components;
			foreach (Component val2 in array2)
			{
				if (!((Object)(object)val2 == (Object)null))
				{
					Plugin.LogDebug(((object)val2).ToString());
				}
			}
			Plugin.LogDebug("Parent components :");
			components = gameObject.GetComponentsInParent(typeof(Component));
			Component[] array3 = components;
			foreach (Component val3 in array3)
			{
				if (!((Object)(object)val3 == (Object)null))
				{
					Plugin.LogDebug(((object)val3).ToString());
				}
			}
		}

		public static void ListAllColliders(GameObject gameObject)
		{
			if ((Object)(object)gameObject == (Object)null)
			{
				return;
			}
			Plugin.LogDebug(" ");
			Plugin.LogDebug("List of Colliders: ");
			Component[] components = gameObject.GetComponents(typeof(Collider));
			Component[] array = components;
			foreach (Component val in array)
			{
				if (!((Object)(object)val == (Object)null))
				{
					Plugin.LogDebug(((object)val).ToString());
				}
			}
			Plugin.LogDebug("Child Colliders: ");
			components = gameObject.GetComponentsInChildren(typeof(Collider));
			Component[] array2 = components;
			foreach (Component val2 in array2)
			{
				if (!((Object)(object)val2 == (Object)null))
				{
					Plugin.LogDebug(((object)val2).ToString());
				}
			}
			Plugin.LogDebug("Parent Colliders: ");
			components = gameObject.GetComponentsInParent(typeof(Collider));
			Component[] array3 = components;
			foreach (Component val3 in array3)
			{
				if (!((Object)(object)val3 == (Object)null))
				{
					Plugin.LogDebug(((object)val3).ToString());
				}
			}
		}

		public static void SetFieldValue(object obj, string fieldName, object value)
		{
			Type type = obj.GetType();
			FieldInfo field = type.GetField(fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			field.SetValue(obj, value);
		}

		public static void SetPropertyValue(object obj, string propertyName, object value)
		{
			Type type = obj.GetType();
			PropertyInfo property = type.GetProperty(propertyName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			property.SetValue(obj, value);
		}

		public static T GetCopyOf<T>(this Component comp, T other) where T : Component
		{
			Type type = ((object)comp).GetType();
			if (type != ((object)other).GetType())
			{
				return default(T);
			}
			BindingFlags bindingAttr = BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
			PropertyInfo[] properties = type.GetProperties(bindingAttr);
			PropertyInfo[] array = properties;
			foreach (PropertyInfo propertyInfo in array)
			{
				if (propertyInfo.CanWrite && propertyInfo.CanRead && !(propertyInfo.Name == "name"))
				{
					try
					{
						propertyInfo.SetValue(comp, propertyInfo.GetValue(other, null), null);
					}
					catch
					{
					}
				}
			}
			FieldInfo[] allFields = PropertiesAndFieldsUtils.GetAllFields(type);
			FieldInfo[] array2 = allFields;
			foreach (FieldInfo fieldInfo in array2)
			{
				if (!fieldInfo.IsStatic)
				{
					fieldInfo.SetValue(comp, fieldInfo.GetValue(other));
				}
			}
			return (T)(object)((comp is T) ? comp : null);
		}

		public static T AddCopyOfComponent<T>(this GameObject go, T toAdd) where T : Component
		{
			return ((Component)(object)go.AddComponent<T>()).GetCopyOf(toAdd);
		}

		public static T CopyComponent<T>(T original, GameObject destination) where T : Component
		{
			Type type = ((object)original).GetType();
			Component component = destination.GetComponent(type);
			T val = (T)(object)((component is T) ? component : null);
			if (!Object.op_Implicit((Object)(object)val))
			{
				Component obj = destination.AddComponent(type);
				val = (T)(object)((obj is T) ? obj : null);
			}
			FieldInfo[] allFields = PropertiesAndFieldsUtils.GetAllFields(type);
			FieldInfo[] array = allFields;
			foreach (FieldInfo fieldInfo in array)
			{
				if (!fieldInfo.IsStatic)
				{
					fieldInfo.SetValue(val, fieldInfo.GetValue(original));
				}
			}
			PropertyInfo[] properties = type.GetProperties();
			PropertyInfo[] array2 = properties;
			foreach (PropertyInfo propertyInfo in array2)
			{
				if (propertyInfo.CanWrite && propertyInfo.CanWrite && !(propertyInfo.Name == "name"))
				{
					propertyInfo.SetValue(val, propertyInfo.GetValue(original, null), null);
				}
			}
			return val;
		}

		public static Transform? FindChildWithName(this Transform parent, string name)
		{
			for (int i = 0; i < parent.childCount; i++)
			{
				Transform child = parent.GetChild(i);
				if (((Object)child).name == name)
				{
					return child;
				}
				Transform val = child.FindChildWithName(name);
				if ((Object)(object)val != (Object)null)
				{
					return val;
				}
			}
			return null;
		}
	}
	internal static class DrawUtil
	{
		public static void DrawWhiteLine(LineRenderer? lr, Ray ray, float length)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			DrawLine(lr, ray, length, Color.white);
		}

		public static void DrawLine(LineRenderer? lr, Ray ray, float length, Color color)
		{
			//IL_0003: 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_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			Vector3 origin = ((Ray)(ref ray)).origin;
			Vector3 origin2 = ((Ray)(ref ray)).origin;
			Vector3 direction = ((Ray)(ref ray)).direction;
			DrawLine(lr, origin, origin2 + ((Vector3)(ref direction)).normalized * length, color);
		}

		public static void DrawLine(LineRenderer? lr, Vector3 start, Vector3 end, Color color)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Expected O, but got Unknown
			//IL_0020: 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_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)lr == (Object)null))
			{
				((Renderer)lr).material = new Material(Shader.Find("Legacy Shaders/Particles/Alpha Blended Premultiply"));
				lr.startColor = color;
				lr.endColor = color;
				lr.startWidth = 0.1f;
				lr.endWidth = 0.1f;
				lr.SetPosition(0, start);
				lr.SetPosition(1, end);
			}
		}
	}
	public class LineRendererUtil
	{
		private LineRenderer[] _listLineRenderers;

		private Transform _transformToParent;

		private int _index;

		public LineRendererUtil(int nbMaxLineRenderer, Transform transformToParent)
		{
			_listLineRenderers = (LineRenderer[])(object)new LineRenderer[nbMaxLineRenderer];
			_transformToParent = transformToParent;
		}

		public LineRenderer? GetLineRenderer()
		{
			return null;
		}

		private LineRenderer CreateLineRenderer()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			LineRenderer lineRenderer = new GameObject().AddComponent<LineRenderer>();
			return InitLineRenderer(ref lineRenderer);
		}

		private LineRenderer InitLineRenderer(ref LineRenderer lineRenderer)
		{
			//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)
			((Component)lineRenderer).gameObject.transform.SetParent(((Component)_transformToParent).transform, false);
			((Component)lineRenderer).gameObject.transform.SetPositionAndRotation(Vector3.zero, Quaternion.identity);
			return lineRenderer;
		}
	}
	internal static class PatchesUtil
	{
		public static readonly FieldInfo FieldInfoTargetPlayer = AccessTools.Field(typeof(EnemyAI), "targetPlayer");

		public static readonly FieldInfo FieldInfoDraggingPlayer = AccessTools.Field(typeof(BushWolfEnemy), "draggingPlayer");

		public static readonly MethodInfo AllEntitiesCountMethod = SymbolExtensions.GetMethodInfo((Expression<Action>)(() => AllEntitiesCount()));

		public static readonly MethodInfo AllRealPlayersCountMethod = SymbolExtensions.GetMethodInfo((Expression<Action>)(() => AllRealPlayersCount()));

		public static readonly MethodInfo IsPlayerLocalOrLethalBotOwnerLocalMethod = SymbolExtensions.GetMethodInfo(Expression.Lambda<Action>(Expression.Call(null, (MethodInfo)MethodBase.GetMethodFromHandle((RuntimeMethodHandle)/*OpCode not supported: LdMemberToken*/), Expression.New(typeof(PlayerControllerB))), Array.Empty<ParameterExpression>()));

		public static readonly MethodInfo IsPlayerLocalOrLethalBotMethod = SymbolExtensions.GetMethodInfo(Expression.Lambda<Action>(Expression.Call(null, (MethodInfo)MethodBase.GetMethodFromHandle((RuntimeMethodHandle)/*OpCode not supported: LdMemberToken*/), Expression.New(typeof(PlayerControllerB))), Array.Empty<ParameterExpression>()));

		public static readonly MethodInfo IsColliderFromLocalOrLethalBotOwnerLocalMethod = SymbolExtensions.GetMethodInfo(Expression.Lambda<Action>(Expression.Call(null, (MethodInfo)MethodBase.GetMethodFromHandle((RuntimeMethodHandle)/*OpCode not supported: LdMemberToken*/), Expression.New(typeof(Collider))), Array.Empty<ParameterExpression>()));

		public static readonly MethodInfo IsPlayerLethalBotMethod = SymbolExtensions.GetMethodInfo(Expression.Lambda<Action>(Expression.Call(null, (MethodInfo)MethodBase.GetMethodFromHandle((RuntimeMethodHandle)/*OpCode not supported: LdMemberToken*/), Expression.New(typeof(PlayerControllerB))), Array.Empty<ParameterExpression>()));

		public static readonly MethodInfo IsPlayerLocalMethod = SymbolExtensions.GetMethodInfo(Expression.Lambda<Action>(Expression.Call(null, (MethodInfo)MethodBase.GetMethodFromHandle((RuntimeMethodHandle)/*OpCode not supported: LdMemberToken*/), Expression.New(typeof(PlayerControllerB))), Array.Empty<ParameterExpression>()));

		public static readonly MethodInfo IsIdPlayerLethalBotMethod = SymbolExtensions.GetMethodInfo((Expression<Action>)(() => IsIdPlayerLethalBot(0)));

		public static readonly MethodInfo IsRagdollPlayerIdLethalBotMethod = SymbolExtensions.GetMethodInfo(Expression.Lambda<Action>(Expression.Call(null, (MethodInfo)MethodBase.GetMethodFromHandle((RuntimeMethodHandle)/*OpCode not supported: LdMemberToken*/), Expression.New(typeof(RagdollGrabbableObject))), Array.Empty<ParameterExpression>()));

		public static readonly MethodInfo IsPlayerLethalBotOwnerLocalMethod = SymbolExtensions.GetMethodInfo(Expression.Lambda<Action>(Expression.Call(null, (MethodInfo)MethodBase.GetMethodFromHandle((RuntimeMethodHandle)/*OpCode not supported: LdMemberToken*/), Expression.New(typeof(PlayerControllerB))), Array.Empty<ParameterExpression>()));

		public static readonly MethodInfo IsAnLethalBotAiOwnerOfObjectMethod = SymbolExtensions.GetMethodInfo((Expression<Action>)(() => IsAnLethalBotAiOwnerOfObject((GrabbableObject)new object())));

		public static readonly MethodInfo DisableOriginalGameDebugLogsMethod = SymbolExtensions.GetMethodInfo((Expression<Action>)(() => DisableOriginalGameDebugLogs()));

		public static readonly MethodInfo IsPlayerLethalBotControlledAndOwnerMethod = SymbolExtensions.GetMethodInfo(Expression.Lambda<Action>(Expression.Call(null, (MethodInfo)MethodBase.GetMethodFromHandle((RuntimeMethodHandle)/*OpCode not supported: LdMemberToken*/), Expression.New(typeof(PlayerControllerB))), Array.Empty<ParameterExpression>()));

		public static readonly MethodInfo GetDamageFromSlimeIfLethalBotMethod = SymbolExtensions.GetMethodInfo(Expression.Lambda<Action>(Expression.Call(null, (MethodInfo)MethodBase.GetMethodFromHandle((RuntimeMethodHandle)/*OpCode not supported: LdMemberToken*/), Expression.New(typeof(PlayerControllerB))), Array.Empty<ParameterExpression>()));

		public static readonly MethodInfo SyncJumpMethod = SymbolExtensions.GetMethodInfo((Expression<Action>)(() => SyncJump(0uL)));

		public static readonly MethodInfo SyncLandFromJumpMethod = SymbolExtensions.GetMethodInfo((Expression<Action>)(() => SyncLandFromJump(0uL, fallHard: false)));

		public static List<CodeInstruction> InsertIsPlayerLethalBotInstructions(List<CodeInstruction> codes, ILGenerator generator, int startIndex, int indexToJumpTo)
		{
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Expected O, but got Unknown
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Expected O, but got Unknown
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Expected O, but got Unknown
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Expected O, but got Unknown
			List<Label> labels = codes[startIndex].labels;
			List<Label> labels2 = codes[startIndex + indexToJumpTo].labels;
			Label label = generator.DefineLabel();
			labels2.Add(label);
			if (labels.Count > 0)
			{
				codes.Insert(startIndex + 1, new CodeInstruction(codes[startIndex].opcode, codes[startIndex].operand));
				codes[startIndex].opcode = OpCodes.Nop;
				codes[startIndex].operand = null;
				startIndex++;
			}
			List<CodeInstruction> collection = new List<CodeInstruction>
			{
				new CodeInstruction(OpCodes.Ldarg_0, (object)null),
				new CodeInstruction(OpCodes.Call, (object)IsPlayerLethalBotMethod),
				new CodeInstruction(OpCodes.Brtrue_S, (object)label)
			};
			codes.InsertRange(startIndex, collection);
			return codes;
		}

		public static List<CodeInstruction> InsertLogOfFieldOfThis(string logWithZeroParameter, FieldInfo fieldInfo, Type fieldType)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Expected O, but got Unknown
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Expected O, but got Unknown
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Expected O, but got Unknown
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Expected O, but got Unknown
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Expected O, but got Unknown
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Expected O, but got Unknown
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Expected O, but got Unknown
			List<CodeInstruction> list = new List<CodeInstruction>();
			list.Add(new CodeInstruction(OpCodes.Ldsfld, (object)AccessTools.Field(typeof(Plugin), "Logger")));
			list.Add(new CodeInstruction(OpCodes.Ldstr, (object)logWithZeroParameter));
			list.Add(new CodeInstruction(OpCodes.Ldarg_0, (object)null));
			list.Add(new CodeInstruction(OpCodes.Ldfld, (object)fieldInfo));
			list.Add(new CodeInstruction(OpCodes.Box, (object)fieldType));
			list.Add(new CodeInstruction(OpCodes.Call, (object)SymbolExtensions.GetMethodInfo((Expression<Action>)(() => string.Format(new string(new char[0]), new object())))));
			list.Add(new CodeInstruction(OpCodes.Callvirt, (object)SymbolExtensions.GetMethodInfo((Expression<Action>)(() => Plugin.LogDebug(new string(new char[0]))))));
			return list;
		}

		public static List<CodeInstruction> InsertLogWithoutParameters(string log)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Expected O, but got Unknown
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Expected O, but got Unknown
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Expected O, but got Unknown
			List<CodeInstruction> list = new List<CodeInstruction>();
			list.Add(new CodeInstruction(OpCodes.Ldsfld, (object)AccessTools.Field(typeof(Plugin), "Logger")));
			list.Add(new CodeInstruction(OpCodes.Ldstr, (object)log));
			list.Add(new CodeInstruction(OpCodes.Callvirt, (object)SymbolExtensions.GetMethodInfo((Expression<Action>)(() => Plugin.LogDebug(new string(new char[0]))))));
			return list;
		}

		public static List<CodeInstruction> InsertIsBypass(List<CodeInstruction> codes, ILGenerator generator, int startIndex, int indexToJumpTo)
		{
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Expected O, but got Unknown
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Expected O, but got Unknown
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Expected O, but got Unknown
			List<Label> labels = codes[startIndex].labels;
			List<Label> labels2 = codes[startIndex + indexToJumpTo].labels;
			Label label = generator.DefineLabel();
			labels2.Add(label);
			if (labels.Count > 0)
			{
				codes.Insert(startIndex + 1, new CodeInstruction(codes[startIndex].opcode, codes[startIndex].operand));
				codes[startIndex].opcode = OpCodes.Nop;
				codes[startIndex].operand = null;
				startIndex++;
			}
			List<CodeInstruction> collection = new List<CodeInstruction>
			{
				new CodeInstruction(OpCodes.Call, (object)DisableOriginalGameDebugLogsMethod),
				new CodeInstruction(OpCodes.Brtrue_S, (object)label)
			};
			codes.InsertRange(startIndex, collection);
			return codes;
		}

		public static bool IsGrabbableObjectEqualsToNull(GrabbableObject grabbableObject)
		{
			return (Object)(object)grabbableObject == (Object)null;
		}

		private static bool DisableOriginalGameDebugLogs()
		{
			return false;
		}

		private static bool IsPlayerLocal(PlayerControllerB player)
		{
			return LethalBotManager.IsPlayerLocal(player);
		}

		private static bool IsPlayerLocalOrLethalBot(PlayerControllerB player)
		{
			return LethalBotManager.Instance.IsPlayerLocalOrLethalBot(player);
		}

		private static bool IsPlayerLocalOrLethalBotOwnerLocal(PlayerControllerB player)
		{
			return LethalBotManager.Instance.IsPlayerLocalOrLethalBotOwnerLocal(player);
		}

		private static int AllEntitiesCount()
		{
			return LethalBotManager.Instance.AllEntitiesCount;
		}

		private static int AllRealPlayersCount()
		{
			return Math.Clamp(LethalBotManager.Instance.AllRealPlayersCount - 1, 0, AllEntitiesCount());
		}

		private static bool IsColliderFromLocalOrLethalBotOwnerLocal(Collider collider)
		{
			return LethalBotManager.Instance.IsColliderFromLocalOrLethalBotOwnerLocal(collider);
		}

		private static bool IsPlayerLethalBot(PlayerControllerB player)
		{
			return LethalBotManager.Instance.IsPlayerLethalBot(player);
		}

		private static bool IsIdPlayerLethalBot(int id)
		{
			return LethalBotManager.Instance.IsPlayerLethalBot(id);
		}

		private static bool IsRagdollPlayerIdLethalBot(RagdollGrabbableObject ragdollGrabbableObject)
		{
			return LethalBotManager.Instance.IsPlayerLethalBot((int)ragdollGrabbableObject.ragdoll.playerScript.playerClientId);
		}

		private static bool IsPlayerLethalBotOwnerLocal(PlayerControllerB player)
		{
			return LethalBotManager.Instance.IsPlayerLethalBotOwnerLocal(player);
		}

		private static bool IsPlayerLethalBotControlledAndOwner(PlayerControllerB player)
		{
			return LethalBotManager.Instance.IsPlayerLethalBotControlledAndOwner(player);
		}

		private static int GetDamageFromSlimeIfLethalBot(PlayerControllerB player)
		{
			return LethalBotManager.Instance.GetDamageFromSlimeIfLethalBot(player);
		}

		private static bool IsAnLethalBotAiOwnerOfObject(GrabbableObject grabbableObject)
		{
			return LethalBotManager.Instance.IsAnLethalBotAiOwnerOfObject(grabbableObject);
		}

		private static void SyncJump(ulong playerClientId)
		{
			LethalBotManager.Instance.GetLethalBotAI((int)playerClientId)?.SyncJump();
		}

		private static void SyncLandFromJump(ulong playerClientId, bool fallHard)
		{
			LethalBotManager.Instance.GetLethalBotAI((int)playerClientId)?.SyncLandFromJump(fallHard);
		}
	}
	internal static class PropertiesAndFieldsUtils
	{
		public static void ListNamesOfObjectsArray<T>(T[] array)
		{
			Type typeFromHandle = typeof(T);
			Plugin.LogDebug(" ");
			if (array == null)
			{
				Plugin.LogDebug($"Array of type {typeFromHandle} is null");
				return;
			}
			if (array.Length == 0)
			{
				Plugin.LogDebug($"Array of type {typeFromHandle} is empty");
				return;
			}
			PropertyInfo[] readablePropertiesOf = GetReadablePropertiesOf(typeFromHandle);
			Plugin.LogDebug($"- List of type : {typeFromHandle}");
			for (int i = 0; i < array.Length; i++)
			{
				T val = array[i];
				if (val != null)
				{
					Plugin.LogDebug($" Object {i}: \"{NameOfObject(val, readablePropertiesOf)}\"");
				}
			}
		}

		public static void ListPropertiesAndFieldsOfArray<T>(T[] array, bool hasToListProperties = true, bool hasToListFields = true)
		{
			Type typeFromHandle = typeof(T);
			if (array == null)
			{
				Plugin.LogDebug($"Array of type {typeFromHandle} is null");
				return;
			}
			if (array.Length == 0)
			{
				Plugin.LogDebug($"Array of type {typeFromHandle} is empty");
				return;
			}
			PropertyInfo[] readablePropertiesOf = GetReadablePropertiesOf(typeFromHandle);
			FieldInfo[] allFields = GetAllFields(typeFromHandle);
			for (int i = 0; i < array.Length; i++)
			{
				if (hasToListProperties)
				{
					LogProperties(array[i], typeFromHandle, readablePropertiesOf);
				}
				Plugin.LogDebug(" ");
				Plugin.LogDebug($"- Fields of \"{NameOfObject(array[i], readablePropertiesOf)}\" of type \"{typeFromHandle}\" :");
				if (hasToListFields)
				{
					LogFields(array[i], typeFromHandle, allFields);
				}
			}
		}

		public static void ListPropertiesAndFields<T>(T obj, bool hasToListProperties = true, bool hasToListFields = true)
		{
			Type typeFromHandle = typeof(T);
			PropertyInfo[] readablePropertiesOf = GetReadablePropertiesOf(typeFromHandle);
			if (hasToListProperties)
			{
				LogProperties(obj, typeFromHandle, readablePropertiesOf);
			}
			Plugin.LogDebug(" ");
			Plugin.LogDebug($"- Fields of \"{NameOfObject(obj, readablePropertiesOf)}\" of type \"{typeFromHandle}\" :");
			FieldInfo[] allFields = GetAllFields(typeFromHandle);
			if (hasToListFields)
			{
				LogFields(obj, typeFromHandle, allFields);
			}
		}

		public static NetworkObject? GetNetworkObjectByHash(uint hashID)
		{
			FieldInfo field = typeof(NetworkObject).GetField("GlobalObjectIdHash", BindingFlags.Instance | BindingFlags.NonPublic);
			if (field == null)
			{
				Plugin.LogError("GlobalObjectIdHash field is null.");
				return null;
			}
			NetworkObject[] array = Resources.FindObjectsOfTypeAll<NetworkObject>();
			foreach (NetworkObject val in array)
			{
				uint num = (uint)field.GetValue(val);
				if (num == hashID)
				{
					return val;
				}
			}
			return null;
		}

		private static void LogProperties<T>(T obj, Type typeObj, PropertyInfo[] arrObjProperties)
		{
			if (obj == null)
			{
				Plugin.LogDebug($"Object of type {typeObj} is null");
				return;
			}
			Plugin.LogDebug(" ");
			Plugin.LogDebug($"- Properties of \"{NameOfObject(obj, arrObjProperties)}\" of type \"{typeObj}\" :");
			foreach (PropertyInfo propertyInfo in arrObjProperties)
			{
				Plugin.LogDebug($" {propertyInfo.Name} = {GetValueOfProperty(obj, propertyInfo)}");
			}
		}

		private static string NameOfObject<T>(T obj, PropertyInfo[] propertyInfos)
		{
			object valueOfProperty = GetValueOfProperty(obj, propertyInfos.FirstOrDefault((PropertyInfo x) => x.Name == "name"));
			if (valueOfProperty != null)
			{
				return valueOfProperty.ToString();
			}
			return "name null";
		}

		private static void LogFields<T>(T obj, Type typeObj, FieldInfo[] arrObjFields)
		{
			if (obj == null)
			{
				Plugin.LogDebug($"Object of type {typeObj} is null");
				return;
			}
			Plugin.LogDebug(" ");
			foreach (FieldInfo fieldInfo in arrObjFields)
			{
				Plugin.LogDebug($" {fieldInfo.Name} = {GetValueOfField(obj, fieldInfo)}");
			}
		}

		public static FieldInfo[] GetAllFields(Type t)
		{
			if (t == null)
			{
				return new FieldInfo[0];
			}
			BindingFlags bindingAttr = BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
			return t.GetFields(bindingAttr).Concat(GetAllFields(t.BaseType)).ToArray();
		}

		private static PropertyInfo[] GetReadablePropertiesOf(Type type)
		{
			return (from x in type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy)
				where x.CanRead
				select x).ToArray();
		}

		private static object? GetValueOfProperty<T>(T obj, PropertyInfo propertyInfo)
		{
			if (propertyInfo == null)
			{
				return null;
			}
			if (!propertyInfo.GetAccessors(nonPublic: true)[0].IsStatic)
			{
				return propertyInfo.GetValue(obj, null);
			}
			return propertyInfo.GetValue(null);
		}

		private static object? GetValueOfField<T>(T obj, FieldInfo fieldInfo)
		{
			if (fieldInfo == null)
			{
				return null;
			}
			if (!fieldInfo.IsStatic)
			{
				return fieldInfo.GetValue(obj);
			}
			return fieldInfo.GetValue(null);
		}
	}
	public class RayUtil
	{
		public static void RayCastAndDrawFromPointWithColor(LineRenderer? lr, Vector3 origin, Vector3 endPoint, Color color)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			Ray ray = default(Ray);
			((Ray)(ref ray))..ctor(origin, endPoint - origin);
			float length = Vector3.Distance(endPoint, origin);
			DrawUtil.DrawLine(lr, ray, length, color);
		}

		public static bool RayCastAndDraw(LineRenderer? lr, Vector3 origin, Vector3 directionOrigin, float angle, float length)
		{
			//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_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: 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_0021: 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_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: 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_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = Vector3.Cross(directionOrigin, Vector3.up);
			if (val == Vector3.zero)
			{
				val = Vector3.right;
			}
			Ray val2 = default(Ray);
			((Ray)(ref val2))..ctor(origin, Quaternion.AngleAxis(angle, val) * directionOrigin);
			if (Physics.Raycast(val2, length, StartOfRound.Instance.walkableSurfacesMask, (QueryTriggerInteraction)1))
			{
				DrawUtil.DrawLine(lr, val2, length, Color.red);
				return true;
			}
			DrawUtil.DrawWhiteLine(lr, val2, length);
			return false;
		}

		public static bool RayCastForwardAndDraw(LineRenderer? lr, Vector3 origin, Vector3 directionForward, float length)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			Ray val = default(Ray);
			((Ray)(ref val))..ctor(origin, directionForward);
			if (Physics.Raycast(val, length, StartOfRound.Instance.walkableSurfacesMask, (QueryTriggerInteraction)1))
			{
				DrawUtil.DrawLine(lr, val, length, Color.red);
				return true;
			}
			DrawUtil.DrawWhiteLine(lr, val, length);
			return false;
		}

		public static bool RayCastDownAndDraw(LineRenderer? lr, Vector3 origin, float length)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: 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_0031: 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_0024: Unknown result type (might be due to invalid IL or missing references)
			Ray val = default(Ray);
			((Ray)(ref val))..ctor(origin, Vector3.down);
			if (Physics.Raycast(val, length, StartOfRound.Instance.walkableSurfacesMask, (QueryTriggerInteraction)1))
			{
				DrawUtil.DrawLine(lr, val, length, Color.red);
				return true;
			}
			DrawUtil.DrawWhiteLine(lr, val, length);
			return false;
		}
	}
	internal static class TreesUtils
	{
		public static void PrintTransformTree(Transform[] tree, string? parent = null)
		{
			if (tree == null)
			{
				Plugin.LogDebug("Tree of transform is null");
				return;
			}
			if (tree.Length == 0)
			{
				Plugin.LogDebug("Tree of transform is empty");
				return;
			}
			if (Utility.IsNullOrWhiteSpace(parent))
			{
				Transform? obj = tree.FirstOrDefault();
				object obj2;
				if (obj == null)
				{
					obj2 = null;
				}
				else
				{
					Transform parent2 = obj.parent;
					if (parent2 == null)
					{
						obj2 = null;
					}
					else
					{
						Transform root = parent2.root;
						obj2 = ((root != null) ? ((Object)root).name : null);
					}
				}
				parent = (string?)obj2;
			}
			TransformTreeTraversal(tree, parent, 0);
		}

		private static void TransformTreeTraversal(Transform[] tree, string? parent, int depth)
		{
			StringBuilder stringBuilder = new StringBuilder();
			foreach (Transform val in tree)
			{
				if ((string.IsNullOrWhiteSpace(parent) && ((Object)(object)val.parent == (Object)null || string.IsNullOrWhiteSpace(((Object)val.parent).name))) || ((Object)(object)val.parent != (Object)null && ((Object)val.parent).name == parent))
				{
					for (int j = 1; j <= depth - 1; j++)
					{
						stringBuilder.Append("│   ");
					}
					if (depth > 0)
					{
						stringBuilder.Append("├──");
					}
					Plugin.LogDebug(stringBuilder.ToString() + ((Object)val).name);
					stringBuilder.Clear();
					TransformTreeTraversal(tree, ((Object)val).name, depth + 1);
				}
			}
		}

		public static void PrintComponentsTreeOfGameObject(GameObject gameObject)
		{
			if ((Object)(object)gameObject == (Object)null)
			{
				Plugin.LogDebug("GameObject is null");
				return;
			}
			Component[] array = (from x in gameObject.GetComponentsInChildren(typeof(Component))
				where (Object)(object)x != (Object)null
				select x).ToArray();
			if (array.Length == 0)
			{
				Plugin.LogDebug("GameObject has no components");
			}
			else
			{
				ComponentTreeTraversal(array);
			}
		}

		private static int ComponentTreeTraversal(Component[] tree, string? parent = null, int index = 0, int depth = 0, string lastTransformName = "")
		{
			StringBuilder stringBuilder = new StringBuilder();
			for (int i = index; i < tree.Length; i++)
			{
				Component val = tree[i];
				Transform val2 = (Transform)(object)((val is Transform) ? val : null);
				bool flag = (Object)(object)val2 != (Object)null;
				if ((Object)(object)val2 == (Object)null)
				{
					val2 = val.transform;
				}
				if (string.IsNullOrWhiteSpace(parent))
				{
					Transform parent2 = val2.parent;
					if (string.IsNullOrWhiteSpace((parent2 != null) ? ((Object)parent2).name : null))
					{
						Plugin.LogDebug((flag ? ((Object)val2).name : ((object)val).ToString()) ?? "");
					}
				}
				if (string.IsNullOrWhiteSpace(parent))
				{
					Transform parent3 = val2.parent;
					if (!string.IsNullOrWhiteSpace((parent3 != null) ? ((Object)parent3).name : null))
					{
						parent = ((Object)val2.parent).name;
					}
				}
				if (parent == ((Object)val2).name)
				{
					for (int j = 1; j <= depth - 1; j++)
					{
						stringBuilder.Append("│   ");
					}
					if (depth > 0)
					{
						stringBuilder.Append("├──");
					}
					Plugin.LogDebug($"{stringBuilder}{(flag ? ((Object)val2).name : ((object)val).ToString())}");
					stringBuilder.Clear();
					continue;
				}
				Transform parent4 = val2.parent;
				if (((parent4 != null) ? ((Object)parent4).name : null) == parent && flag)
				{
					for (int k = 1; k <= depth - 1; k++)
					{
						stringBuilder.Append("│   ");
					}
					if (depth > 0)
					{
						stringBuilder.Append("├──");
					}
					if (!(((Object)val2).name == lastTransformName))
					{
						lastTransformName = ((Object)val2).name;
						Plugin.LogDebug($"{stringBuilder}{((Object)val2).name}");
						stringBuilder.Clear();
						i = ComponentTreeTraversal(tree, ((Object)val2).name, i + 1, depth + 1, lastTransformName);
						index = i;
					}
				}
			}
			return index;
		}
	}
}
namespace LethalBots.Utils.Vehicles
{
	public class CompanyCruiserInfo : VehicleAdapter<VehicleController, CompanyCruiserGearRequest>
	{
		private const string CRUISER_ANIMATION_STRING = "SA_CarAnim";

		public override bool IsSeatOccupied(VehicleController vehicleController, InteractTrigger seatTrigger, [NotNullWhen(true)] out PlayerControllerB? playerInSeat)
		{
			playerInSeat = null;
			if ((Object)(object)vehicleController.driverSeatTrigger == (Object)(object)seatTrigger)
			{
				playerInSeat = vehicleController.driverSeatTrigger.playerScriptInSpecialAnimation;
			}
			else if ((Object)(object)vehicleController.passengerSeatTrigger == (Object)(object)seatTrigger)
			{
				playerInSeat = vehicleController.passengerSeatTrigger.playerScriptInSpecialAnimation;
			}
			return (Object)(object)playerInSeat != (Object)null;
		}

		public override bool IsPlayerInVehicle(VehicleController vehicleController, PlayerControllerB playerToCheck, out InteractTrigger? seatTrigger)
		{
			seatTrigger = null;
			InteractTrigger driverSeatTrigger = vehicleController.driverSeatTrigger;
			if ((Object)(object)driverSeatTrigger != (Object)null && (Object)(object)driverSeatTrigger.playerScriptInSpecialAnimation == (Object)(object)playerToCheck)
			{
				seatTrigger = driverSeatTrigger;
				return true;
			}
			driverSeatTrigger = vehicleController.passengerSeatTrigger;
			if ((Object)(object)driverSeatTrigger != (Object)null && (Object)(object)driverSeatTrigger.playerScriptInSpecialAnimation == (Object)(object)playerToCheck)
			{
				seatTrigger = driverSeatTrigger;
				return true;
			}
			if ((Object)(object)playerToCheck.overridePhysicsParent == (Object)null && (Object)(object)vehicleController.physicsRegion.physicsTransform == (Object)(object)playerToCheck.physicsParent)
			{
				return true;
			}
			return false;
		}

		public override IEnumerator StartCar(VehicleController vehicleController, LethalBotAI lethalBotAI)
		{
			if (IsIgnitionStarted(vehicleController))
			{
				EndCoroutine(lethalBotAI);
				yield break;
			}
			PlayerControllerB lethalBotController = lethalBotAI.NpcController.Npc;
			while (!IsIgnitionStarted(vehicleController))
			{
				float startTime = Time.timeSinceLevelLoad;
				if (vehicleController.keyIgnitionCoroutine != null)
				{
					((MonoBehaviour)vehicleController).StopCoroutine(vehicleController.keyIgnitionCoroutine);
				}
				vehicleController.keyIgnitionCoroutine = ((MonoBehaviour)vehicleController).StartCoroutine(vehicleController.TryIgnition(true));
				vehicleController.TryIgnitionServerRpc((int)GameNetworkManager.Instance.localPlayerController.playerClientId, vehicleController.keyIsInIgnition);
				float startMaxWaitTime = Random.Range(2.7f, 3.2f);
				yield return (object)new WaitUntil((Func<bool>)(() => IsIgnitionStarted(vehicleController) || Time.timeSinceLevelLoad - startTime > startMaxWaitTime));
				if (!IsIgnitionStarted(vehicleController))
				{
					if (vehicleController.keyIsInIgnition)
					{
						lethalBotController.playerBodyAnimator.SetInteger("SA_CarAnim", 3);
					}
					else
					{
						lethalBotController.playerBodyAnimator.SetInteger("SA_CarAnim", 0);
					}
					vehicleController.carEngine1AudioActive = false;
					vehicleController.CancelIgnitionAnimation();
					vehicleController.CancelTryIgnitionServerRpc((int)GameNetworkManager.Instance.localPlayerController.playerClientId, vehicleController.keyIsInIgnition);
					float num = Random.Range(0.5f, 1f);
					yield return (object)new WaitForSeconds(num);
				}
			}
			EndCoroutine(lethalBotAI);
		}

		public override IEnumerator ChangeGear(VehicleController vehicleController, CompanyCruiserGearRequest changeGearInfo, LethalBotAI lethalBotAI)
		{
			CarGearShift desiredGear = changeGearInfo.DesiredGear;
			if (desiredGear == vehicleController.gear)
			{
				EndCoroutine(lethalBotAI);
				yield break;
			}
			vehicleController.ShiftToGearAndSync((int)desiredGear);
			yield return null;
			EndCoroutine(lethalBotAI);
		}

		public override InteractTrigger? FindOpenPassengerSeat(VehicleController vehicleController, LethalBotAI lethalBotAI)
		{
			InteractTrigger passengerSeatTrigger = vehicleController.passengerSeatTrigger;
			if (!((Object)(object)passengerSeatTrigger != (Object)null) || !passengerSeatTrigger.interactable || !((Object)(object)vehicleController.currentPassenger == (Object)null))
			{
				return null;
			}
			return passengerSeatTrigger;
		}

		public override Vector3? FindOpenTrunkPosition(VehicleController vehicleController, LethalBotAI lethalBotAI)
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			float num = Random.Range(Const.FIRST_CORNER_LETHALBOT_IN_CRUISER.x, Const.SECOND_CORNER_LETHALBOT_IN_CRUISER.x);
			float num2 = Random.Range(Const.FIRST_CORNER_LETHALBOT_IN_CRUISER.y, Const.SECOND_CORNER_LETHALBOT_IN_CRUISER.y);
			float num3 = Random.Range(Const.FIRST_CORNER_LETHALBOT_IN_CRUISER.z, Const.SECOND_CORNER_LETHALBOT_IN_CRUISER.z);
			return new Vector3(num, num2, num3);
		}

		public override InteractTrigger? GetDriverSeat(VehicleController vehicleController, LethalBotAI lethalBotAI)
		{
			return vehicleController.driverSeatTrigger;
		}

		public override IEnumerator OpenTrunk(VehicleController vehicleController, LethalBotAI lethalBotAI)
		{
			if (IsTrunkOpen(vehicleController, lethalBotAI))
			{
				EndCoroutine(lethalBotAI);
				yield break;
			}
			Transform val = vehicleController.backDoorContainer.transform.Find("OpenTrigger");
			if ((Object)(object)val != (Object)null)
			{
				float startTime = Time.timeSinceLevelLoad;
				((Component)val).GetComponent<InteractTrigger>().Interact(lethalBotAI.NpcController.Npc.thisPlayerBody);
				yield return (object)new WaitUntil((Func<bool>)(() => IsTrunkOpen(vehicleController, lethalBotAI) || Time.timeSinceLevelLoad - startTime > 5f));
			}
			EndCoroutine(lethalBotAI);
		}

		public override IEnumerator CloseTrunk(VehicleController vehicleController, LethalBotAI lethalBotAI)
		{
			if (!IsTrunkOpen(vehicleController, lethalBotAI))
			{
				EndCoroutine(lethalBotAI);
				yield break;
			}
			Transform val = vehicleController.backDoorContainer.transform.Find("ClosedTrigger");
			if ((Object)(object)val != (Object)null)
			{
				float startTime = Time.timeSinceLevelLoad;
				((Component)val).GetComponent<InteractTrigger>().Interact(lethalBotAI.NpcController.Npc.thisPlayerBody);
				yield return (object)new WaitUntil((Func<bool>)(() => !IsTrunkOpen(vehicleController, lethalBotAI) || Time.timeSinceLevelLoad - startTime > 5f));
			}
			EndCoroutine(lethalBotAI);
		}

		public override IEnumerator DriveVehicle(VehicleController vehicleController, LethalBotAI lethalBotAI, NavMeshAgent vehicleAgent)
		{
			lethalBotAI.NpcController.vehicleInput.Reset();
			while ((Object)(object)vehicleController != (Object)null && (Object)(object)lethalBotAI != (Object)null && (Object)(object)vehicleAgent != (Object)null)
			{
				if (!IsIgnitionStarted(vehicleController))
				{
					yield return StartCar(vehicleController, lethalBotAI);
				}
				SetAreaCostsForCruiser(vehicleAgent, vehicleController);
				Vector3 velocity = vehicleController.mainRigidbody.velocity;
				float magnitude = ((Vector3)(ref velocity)).magnitude;
				vehicleAgent.speed = Mathf.Max(MaxDrivingSpeed, magnitude);
				ref VehicleInputHelper vehicleInput = ref lethalBotAI.NpcController.vehicleInput;
				UpdateVehicleInput(vehicleController, lethalBotAI, vehicleAgent, ref vehicleInput);
				CarGearShift gear = vehicleController.gear;
				if (vehicleInput.WantsForward && (int)gear != 1)
				{
					vehicleInput.Throttle = 0f;
					if (magnitude <= ChangeGearSpeed)
					{
						yield return ChangeGear(vehicleController, new CompanyCruiserGearRequest
						{
							DesiredGear = (CarGearShift)1
						}, lethalBotAI);
					}
					else
					{
						vehicleInput.Brake = 1f;
					}
				}
				else if (vehicleInput.WantsReverse && (int)gear != 2)
				{
					vehicleInput.Throttle = 0f;
					if (magnitude <= ChangeGearSpeed)
					{
						yield return ChangeGear(vehicleController, new CompanyCruiserGearRequest
						{
							DesiredGear = (CarGearShift)2
						}, lethalBotAI);
					}
					else
					{
						vehicleInput.Brake = 1f;
					}
				}
				else if (vehicleInput.Brake > 0f && (int)gear != 3 && vehicleInput.IsStopping && magnitude <= ChangeGearSpeed)
				{
					yield return ChangeGear(vehicleController, new CompanyCruiserGearRequest
					{
						DesiredGear = (CarGearShift)3
					}, lethalBotAI);
				}
				yield return null;
			}
		}

		public override IEnumerator EnterVehicle(VehicleController vehicleController, LethalBotAI lethalBotAI, InteractTrigger seatTrigger)
		{
			if ((Object)(object)seatTrigger == (Object)null)
			{
				EndCoroutine(lethalBotAI);
				yield break;
			}
			InteractTrigger driverSeat = GetDriverSeat(vehicleController, lethalBotAI);
			if ((Object)(object)driverSeat == (Object)null)
			{
				Plugin.LogWarning("[CompanyCruiserInfo] No driver seat found for vehicle " + ((Object)vehicleController).name + ". Cannot enter vehicle.");
				EndCoroutine(lethalBotAI);
				yield break;
			}
			PlayerControllerB lethalBotController = lethalBotAI.NpcController.Npc;
			if ((Object)(object)seatTrigger == (Object)(object)driverSeat)
			{
				if ((Object)(object)vehicleController.currentDriver != (Object)null)
				{
					Plugin.LogWarning("[CompanyCruiserInfo] Driver seat is already occupied for vehicle " + ((Object)vehicleController).name + ". Cannot enter vehicle.");
					EndCoroutine(lethalBotAI);
					yield break;
				}
				if (!vehicleController.driverSideDoor.boolValue)
				{
					float startTime = Time.timeSinceLevelLoad;
					vehicleController.driverSideDoorTrigger.Interact(lethalBotController.thisPlayerBody);
					yield return (object)new WaitForSeconds(1.5f);
					yield return (object)new WaitUntil((Func<bool>)(() => vehicleController.driverSideDoor.boolValue || Time.timeSinceLevelLoad - startTime > 5f));
				}
				if ((Object)(object)vehicleController.currentDriver != (Object)null)
				{
					Plugin.LogWarning("[CompanyCruiserInfo] Driver seat is already occupied for vehicle " + ((Object)vehicleController).name + ". Cannot enter vehicle.");
					EndCoroutine(lethalBotAI);
					yield break;
				}
				driverSeat.Interact(lethalBotController.thisPlayerBody);
				if (vehicleController.driverSideDoor.boolValue)
				{
					vehicleController.driverSideDoor.TriggerAnimation(lethalBotController);
				}
				vehicleController.currentDriver = lethalBotController;
				lethalBotController.playerBodyAnimator.SetFloat("animationSpeed", 0.5f);
				if (vehicleController.ignitionStarted)
				{
					lethalBotController.playerBodyAnimator.SetInteger("SA_CarAnim", 1);
				}
				else
				{
					lethalBotController.playerBodyAnimator.SetInteger("SA_CarAnim", 0);
				}
				vehicleController.SetVehicleCollisionForPlayer(false, lethalBotController);
				vehicleController.SetPlayerInControlOfVehicleServerRpc((int)lethalBotController.playerClientId);
			}
			else
			{
				if ((Object)(object)vehicleController.currentPassenger != (Object)null)
				{
					Plugin.LogWarning("[CompanyCruiserInfo] Passenger seat is already occupied for vehicle " + ((Object)vehicleController).name + ". Cannot enter vehicle.");
					EndCoroutine(lethalBotAI);
					yield break;
				}
				if (!vehicleController.passengerSideDoor.boolValue)
				{
					float startTime2 = Time.timeSinceLevelLoad;
					vehicleController.passengerSideDoorTrigger.Interact(lethalBotController.thisPlayerBody);
					yield return (object)new WaitForSeconds(1.5f);
					yield return (object)new WaitUntil((Func<bool>)(() => vehicleController.passengerSideDoor.boolValue || Time.timeSinceLevelLoad - startTime2 > 5f));
				}
				if ((Object)(object)vehicleController.currentPassenger != (Object)null)
				{
					Plugin.LogWarning("[CompanyCruiserInfo] Passenger seat is already occupied for vehicle " + ((Object)vehicleController).name + ". Cannot enter vehicle.");
					EndCoroutine(lethalBotAI);
					yield break;
				}
				vehicleController.SetVehicleCollisionForPlayer(false, lethalBotController);
				seatTrigger.Interact(lethalBotController.thisPlayerBody);
			}
			EndCoroutine(lethalBotAI);
		}

		public override IEnumerator ExitVehicle(VehicleController vehicleController, LethalBotAI lethalBotAI)
		{
			InteractTrigger driverSeat = GetDriverSeat(vehicleController, lethalBotAI);
			if ((Object)(object)driverSeat == (Object)null)
			{
				Plugin.LogWarning("[CompanyCruiserInfo] No driver seat found for vehicle " + ((Object)vehicleController).name + ". Cannot leave vehicle.");
				EndCoroutine(lethalBotAI);
				yield break;
			}
			PlayerControllerB lethalBotController = lethalBotAI.NpcController.Npc;
			if ((Object)(object)driverSeat.playerScriptInSpecialAnimation == (Object)(object)lethalBotController)
			{
				VehicleInputHelper vehicleInput = lethalBotAI.NpcController.vehicleInput;
				vehicleInput.Zero();
				vehicleInput.Brake = 1f;
				float startTime = Time.timeSinceLevelLoad;
				yield return null;
				yield return (object)new WaitUntil((Func<bool>)delegate
				{
					//IL_0010: Unknown result type (might be due to invalid IL or missing references)
					//IL_0015: Unknown result type (might be due to invalid IL or missing references)
					Vector3 velocity = vehicleController.mainRigidbody.velocity;
					return ((Vector3)(ref velocity)).magnitude < ChangeGearSpeed || Time.timeSinceLevelLoad - startTime > 5f;
				});
				if ((int)vehicleController.gear != 3)
				{
					yield return ChangeGear(vehicleController, new CompanyCruiserGearRequest
					{
						DesiredGear = (CarGearShift)3
					}, lethalBotAI);
				}
				if (IsIgnitionStarted(vehicleController))
				{
					if (vehicleController.keyIgnitionCoroutine != null)
					{
						((MonoBehaviour)vehicleController).StopCoroutine(vehicleController.keyIgnitionCoroutine);
					}
					startTime = Time.timeSinceLevelLoad;
					vehicleController.keyIgnitionCoroutine = ((MonoBehaviour)vehicleController).StartCoroutine(vehicleController.RemoveKey());
					lethalBotController.playerBodyAnimator.SetInteger("SA_CarAnim", 6);
					vehicleController.RemoveKeyFromIgnitionServerRpc((int)GameNetworkManager.Instance.localPlayerController.playerClientId);
					yield return (object)new WaitUntil((Func<bool>)(() => vehicleController.keyIgnitionCoroutine == null || Time.timeSinceLevelLoad - startTime > 5f));
				}
				lethalBotController.playerBodyAnimator.SetInteger("SA_CarAnim", 0);
				int num = CanExitCar(vehicleController, lethalBotController, passengerSide: true);
				if (num != -1)
				{
					lethalBotController.TeleportPlayer(vehicleController.driverSideExitPoints[num].position, false, 0f, false, true);
				}
				else
				{
					if (!vehicleController.driverSideDoor.boolValue)
					{
						vehicleController.driverSideDoor.TriggerAnimation(lethalBotController);
					}
					lethalBotController.TeleportPlayer(vehicleController.driverSideExitPoints[1].position, false, 0f, false, true);
				}
				yield return (object)new WaitForSeconds(1f);
				if (vehicleController.driverSideDoor.boolValue)
				{
					startTime = Time.timeSinceLevelLoad;
					vehicleController.driverSideDoorTrigger.Interact(lethalBotController.thisPlayerBody);
					yield return (object)new WaitUntil((Func<bool>)(() => !vehicleController.driverSideDoor.boolValue || Time.timeSinceLevelLoad - startTime > 5f));
				}
			}
			else if ((Object)(object)vehicleController.passengerSeatTrigger.playerScriptInSpecialAnimation == (Object)(object)lethalBotController)
			{
				if (!vehicleController.passengerSideDoor.boolValue)
				{
					float startTime2 = Time.timeSinceLevelLoad;
					vehicleController.passengerSideDoorTrigger.Interact(lethalBotController.thisPlayerBody);
					yield return (object)new WaitForSeconds(1.5f);
					yield return (object)new WaitUntil((Func<bool>)(() => vehicleController.passengerSideDoor.boolValue || Time.timeSinceLevelLoad - startTime2 > 5f));
				}
				int num2 = CanExitCar(vehicleController, lethalBotController, passengerSide: false);
				if (num2 != -1)
				{
					lethalBotController.TeleportPlayer(vehicleController.passengerSideExitPoints[num2].position, false, 0f, false, true);
				}
				else
				{
					lethalBotController.TeleportPlayer(vehicleController.passengerSideExitPoints[1].position, false, 0f, false, true);
				}
				vehicleController.passengerSeatTrigger.interactable = true;
				vehicleController.currentPassenger = null;
				vehicleController.SetVehicleCollisionForPlayer(false, lethalBotController);
				yield return (object)new WaitForSeconds(1f);
				if (vehicleController.passengerSideDoor.boolValue)
				{
					float startTime3 = Time.timeSinceLevelLoad;
					vehicleController.passengerSideDoorTrigger.Interact(lethalBotController.thisPlayerBody);
					yield return (object)new WaitUntil((Func<bool>)(() => !vehicleController.passengerSideDoor.boolValue || Time.timeSinceLevelLoad - startTime3 > 5f));
				}
			}
			EndCoroutine(lethalBotAI);
		}

		private static int CanExitCar(VehicleController vehicleController, PlayerControllerB lethalbotController, bool passengerSide)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			Vector3 position = ((Component)lethalbotController.gameplayCamera).transform.position;
			if (passengerSide)
			{
				for (int i = 0; i < vehicleController.driverSideExitPoints.Length; i++)
				{
					if (!Physics.Linecast(position, vehicleController.driverSideExitPoints[i].position, vehicleController.exitCarLayerMask, (QueryTriggerInteraction)1))
					{
						return i;
					}
				}
				return -1;
			}
			for (int j = 0; j < vehicleController.passengerSideExitPoints.Length; j++)
			{
				if (!Physics.Linecast(position, vehicleController.passengerSideExitPoints[j].position, vehicleController.exitCarLayerMask, (QueryTriggerInteraction)1))
				{
					return j;
				}
			}
			return -1;
		}
	}
}
namespace LethalBots.Utils.Items.Weapons
{
	public class KnifeInfo : WeaponInfo
	{
		public override float GetAttackRangeForWeapon(GrabbableObject weapon)
		{
			return 1f;
		}

		public override float GetWeaponAttackInterval(GrabbableObject weapon)
		{
			return 0.43f;
		}

		public override void GetWeaponAttackInfo(GrabbableObject weapon, PlayerControllerB lethalBotController, out Ray ray, out float maxFOV, out float radius, out float maxRange, out LayerMask hitMask)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			KnifeItem val = (KnifeItem)(object)((weapon is KnifeItem) ? weapon : null);
			if (val != null)
			{
				ray = new Ray(((Component)lethalBotController.gameplayCamera).transform.position + ((Component)lethalBotController.gameplayCamera).transform.right * 0.1f, ((Component)lethalBotController.gameplayCamera).transform.forward);
				maxFOV = 45f;
				radius = 0.3f;
				maxRange = 0.75f;
				hitMask = LayerMask.op_Implicit(val.knifeMask);
			}
			else
			{
				base.GetWeaponAttackInfo(weapon, lethalBotController, out ray, out maxFOV, out radius, out maxRange, out hitMask);
			}
		}
	}
	public class ShotgunInfo : WeaponInfo
	{
		public ShotgunInfo()
		{
			enemyColliders = (RaycastHit[])(object)new RaycastHit[10];
		}

		public override bool IsRanged(GrabbableObject weapon)
		{
			return true;
		}

		public override bool NeedsToReload(GrabbableObject weapon)
		{
			ShotgunItem val = (ShotgunItem)(object)((weapon is ShotgunItem) ? weapon : null);
			if (val != null)
			{
				return val.shellsLoaded < 2;
			}
			return false;
		}

		public override bool ShouldEquip(GrabbableObject weapon, PlayerControllerB lethalBotController)
		{
			ShotgunItem val = (ShotgunItem)(object)((weapon is ShotgunItem) ? weapon : null);
			if (val != null)
			{
				if (val.safetyOn)
				{
					if (NeedsToReload(weapon))
					{
						return HasAmmo(lethalBotController, (GrabbableObject)(object)val, spareOnly: true);
					}
					return false;
				}
				return true;
			}
			return false;
		}

		public override bool HasAmmo(PlayerControllerB lethalBotController, GrabbableObject weapon, bool spareOnly = false)
		{
			ShotgunItem val = (ShotgunItem)(object)((weapon is ShotgunItem) ? weapon : null);
			if (val != null)
			{
				if (!spareOnly && val.shellsLoaded > 0)
				{
					return true;
				}
				GrabbableObject itemOnlySlot = lethalBotController.ItemOnlySlot;
				if ((Object)(object)itemOnlySlot != (Object)null)
				{
					GunAmmo val2 = (GunAmmo)(object)((itemOnlySlot is GunAmmo) ? itemOnlySlot : null);
					if ((Object)(object)val2 != (Object)null && val2.ammoType == val.gunCompatibleAmmoID)
					{
						return true;
					}
				}
				GrabbableObject[] itemSlots = lethalBotController.ItemSlots;
				for (int i = 0; i < itemSlots.Length; i++)
				{
					GrabbableObject val3 = itemSlots[i];
					if ((Object)(object)val3 != (Object)null)
					{
						GunAmmo val4 = (GunAmmo)(object)((val3 is GunAmmo) ? val3 : null);
						Plugin.LogDebug($"Ammo null in slot #{i}?: {(Object)(object)val4 == (Object)null}");
						if ((Object)(object)val4 != (Object)null)
						{
							Plugin.LogDebug($"Ammo in slot #{i} id: {val4.ammoType}");
						}
						if ((Object)(object)val4 != (Object)null && val4.ammoType == val.gunCompatibleAmmoID)
						{
							return true;
						}
					}
				}
				return false;
			}
			return true;
		}

		public override float GetAttackRangeForWeapon(GrabbableObject weapon)
		{
			return 4f;
		}

		public override float GetWeaponAttackInterval(GrabbableObject weapon)
		{
			return 0.1f;
		}

		public override void GetWeaponAttackInfo(GrabbableObject weapon, PlayerControllerB lethalBotController, out Ray ray, out float maxFOV, out float radius, out float maxRange, out LayerMask hitMask)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_003a: 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_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			if (weapon is ShotgunItem)
			{
				Vector3 val = ((Component)lethalBotController.gameplayCamera).transform.position - ((Component)lethalBotController.gameplayCamera).transform.up * 0.45f;
				Vector3 forward = ((Component)lethalBotController.gameplayCamera).transform.forward;
				ray = new Ray(val - forward * 10f, forward);
				maxFOV = 30f;
				radius = 5f;
				maxRange = 15f;
				hitMask = LayerMask.op_Implicit(524288);
			}
			else
			{
				base.GetWeaponAttackInfo(weapon, lethalBotController, out ray, out maxFOV, out radius, out maxRange, out hitMask);
			}
		}

		public override bool CanHitWithWeapon(PlayerControllerB lethalBotController, EnemyAI currentEnemy, Collider? enemyCollider, Ray ray, float radius, float maxRange, LayerMask hitMask)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			if (enemyColliders == null)
			{
				enemyColliders = (RaycastHit[])(object)new RaycastHit[10];
			}
			int num = Physics.SphereCastNonAlloc(ray, radius, enemyColliders, maxRange, LayerMask.op_Implicit(hitMask), (QueryTriggerInteraction)2);
			IHittable val2 = default(IHittable);
			EnemyAICollisionDetect val3 = default(EnemyAICollisionDetect);
			for (int i = 0; i < num; i++)
			{
				RaycastHit val = enemyColliders[i];
				if (((RaycastHit)(ref val)).distance == 0f || ((RaycastHit)(ref val)).point == Vector3.zero || !((Component)((RaycastHit)(ref val)).transform).TryGetComponent<IHittable>(ref val2) || Physics.Linecast(((Component)lethalBotController.gameplayCamera).transform.position, ((RaycastHit)(ref val)).point, StartOfRound.Instance.collidersAndRoomMaskAndDefault, (QueryTriggerInteraction)1))
				{
					continue;
				}
				if (!((Object)(object)((RaycastHit)(ref val)).collider == (Object)(object)enemyCollider))
				{
					if (!((Component)((RaycastHit)(ref val)).transform).gameObject.TryGetComponent<EnemyAICollisionDetect>(ref val3))
					{
						continue;
					}
					EnemyAI mainScript = val3.mainScript;
					if (mainScript == null || !((Object)(object)mainScript == (Object)(object)currentEnemy))
					{
						continue;
					}
				}
				return true;
			}
			return false;
		}

		public override IEnumerator AttackWithWeapon(PlayerControllerB lethalBotController, GrabbableObject weapon, EnemyAI currentEnemy, Collider? enemyCollider, bool canHitTarget, Action<bool> setSkipCooldown)
		{
			if (!canHitTarget)
			{
				yield return null;
				setSkipCooldown(obj: true);
				yield break;
			}
			ShotgunItem val = (ShotgunItem)(object)((weapon is ShotgunItem) ? weapon : null);
			if (val != null)
			{
				if (val.isReloading)
				{
					yield return null;
					setSkipCooldown(obj: true);
				}
				else if (val.safetyOn)
				{
					((GrabbableObject)val).ItemInteractLeftRightOnClient(false);
					yield return null;
					setSkipCooldown(obj: true);
				}
				else if (val.shellsLoaded <= 0)
				{
					((GrabbableObject)val).ItemInteractLeftRightOnClient(true);
					yield return null;
					setSkipCooldown(obj: true);
				}
				else
				{
					weapon.UseItemOnClient(true);
				}
			}
		}

		public override void UseHeldWeapon(PlayerControllerB lethalBotController, GrabbableObject weapon, ref bool canUseLethalPhones)
		{
			ShotgunItem val = (ShotgunItem)(object)((weapon is ShotgunItem) ? weapon : null);
			if (val != null)
			{
				if (!val.safetyOn)
				{
					canUseLethalPhones = false;
					((GrabbableObject)val).ItemInteractLeftRightOnClient(false);
				}
				else if (NeedsToReload(weapon) && HasAmmo(lethalBotController, weapon, spareOnly: true))
				{
					canUseLethalPhones = false;
					((GrabbableObject)val).ItemInteractLeftRightOnClient(true);
				}
			}
		}
	}
	public class ShovelInfo : WeaponInfo
	{
		public override float GetAttackRangeForWeapon(GrabbableObject weapon)
		{
			return 2f;
		}

		public override float GetWeaponAttackInterval(GrabbableObject weapon)
		{
			return 0.78f;
		}

		public override void GetWeaponAttackInfo(GrabbableObject weapon, PlayerControllerB lethalBotController, out Ray ray, out float maxFOV, out float radius, out float maxRange, out LayerMask hitMask)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			Shovel val = (Shovel)(object)((weapon is Shovel) ? weapon : null);
			if (val != null)
			{
				ray = new Ray(((Component)lethalBotController.gameplayCamera).transform.position + ((Component)lethalBotController.gameplayCamera).transform.right * -0.35f, ((Component)lethalBotController.gameplayCamera).transform.forward);
				maxFOV = 75f;
				radius = 0.8f;
				maxRange = 1.5f;
				hitMask = LayerMask.op_Implicit(val.shovelMask);
			}
			else
			{
				base.GetWeaponAttackInfo(weapon, lethalBotController, out ray, out maxFOV, out radius, out maxRange, out hitMask);
			}
		}
	}
	public class ZapGunInfo : WeaponInfo
	{
		public ZapGunInfo()
		{
			if (enemyColliders == null)
			{
				enemyColliders = (RaycastHit[])(object)new RaycastHit[12];
			}
		}

		public override bool IsRanged(GrabbableObject weapon)
		{
			return true;
		}

		public override bool HasAmmo(PlayerControllerB lethalBotController, GrabbableObject weapon, bool spareOnly = false)
		{
			return ItemsManager.HasRequiredCharge(weapon);
		}

		public override float GetAttackRangeForWeapon(GrabbableObject weapon)
		{
			return 5f;
		}

		public override float GetWeaponAttackInterval(GrabbableObject weapon)
		{
			return 0.1f;
		}

		public override void GetWeaponAttackInfo(GrabbableObject weapon, PlayerControllerB lethalBotController, out Ray ray, out float maxFOV, out float radius, out float maxRange, out LayerMask hitMask)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_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_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: 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_006c: Unknown result type (might be due to invalid IL or missing references)
			PatcherTool val = (PatcherTool)(object)((weapon is PatcherTool) ? weapon : null);
			if (val != null)
			{
				Vector3 forward = ((Component)lethalBotController.gameplayCamera).transform.forward;
				ray = new Ray(((Component)lethalBotController.gameplayCamera).transform.position - forward * 3f, forward);
				maxFOV = 60f;
				radius = 5f;
				maxRange = 5f;
				hitMask = LayerMask.op_Implicit(val.anomalyMask);
			}
			else
			{
				base.GetWeaponAttackInfo(weapon, lethalBotController, out ray, out maxFOV, out radius, out maxRange, out hitMask);
			}
		}

		public override bool CanHitWithWeapon(PlayerControllerB lethalBotController, EnemyAI currentEnemy, Collider? enemyCollider, Ray ray, float radius, float maxRange, LayerMask hitMask)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			if (enemyColliders == null)
			{
				enemyColliders = (RaycastHit[])(object)new RaycastHit[10];
			}