Decompiled source of PlayerBots v1.7.1

PlayerBots.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using EntityStates;
using EntityStates.AI.Walker;
using EntityStates.Railgunner.Reload;
using IL.RoR2;
using IL.RoR2.UI;
using Mono.Cecil.Cil;
using MonoMod.Cil;
using On.RoR2;
using On.RoR2.CharacterAI;
using On.RoR2.ExpansionManagement;
using PlayerBots.AI;
using PlayerBots.AI.SkillHelpers;
using PlayerBots.Custom;
using RoR2;
using RoR2.CharacterAI;
using RoR2.ExpansionManagement;
using RoR2.Navigation;
using UnityEngine;
using UnityEngine.Networking;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("PlayerBots")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("2.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("PlayerBots")]
[assembly: AssemblyTitle("PlayerBots")]
[assembly: AssemblyVersion("2.0.0.0")]
public class CommandHelper
{
	public static void RegisterCommands(Console self)
	{
		//IL_008c: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cf: Expected O, but got Unknown
		Type[] types = typeof(CommandHelper).Assembly.GetTypes();
		IDictionary fieldValue = self.GetFieldValue<IDictionary>("concommandCatalog");
		foreach (MethodInfo item in types.SelectMany((Type x) => x.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)))
		{
			foreach (ConCommandAttribute item2 in item.GetCustomAttributes(inherit: false).OfType<ConCommandAttribute>())
			{
				object obj = Reflection.GetNestedType<Console>("ConCommand").Instantiate();
				obj.SetFieldValue("flags", item2.flags);
				obj.SetFieldValue("helpText", item2.helpText);
				obj.SetFieldValue("action", (object)(ConCommandDelegate)Delegate.CreateDelegate(typeof(ConCommandDelegate), item));
				fieldValue[item2.commandName.ToLower()] = obj;
			}
		}
	}
}
public static class Reflection
{
	private static readonly BindingFlags _defaultFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy;

	public static TReturn GetFieldValue<TReturn>(this object instance, string fieldName)
	{
		return (TReturn)instance.GetType().GetField(fieldName, _defaultFlags | BindingFlags.Instance).GetValue(instance);
	}

	public static TReturn GetFieldValue<TClass, TReturn>(string fieldName)
	{
		return typeof(TClass).GetFieldValue<TReturn>(fieldName);
	}

	public static TReturn GetFieldValue<TReturn>(this Type type, string fieldName)
	{
		return (TReturn)type.GetField(fieldName, _defaultFlags | BindingFlags.Static).GetValue(null);
	}

	public static void SetFieldValue(this object instance, string fieldName, object value)
	{
		instance.GetType().GetField(fieldName, _defaultFlags | BindingFlags.Instance).SetValue(instance, value);
	}

	public static void SetFieldValue<TClass>(string fieldName, object value)
	{
		typeof(TClass).SetFieldValue(fieldName, value);
	}

	public static void SetFieldValue(this Type type, string fieldName, object value)
	{
		type.GetField(fieldName, _defaultFlags | BindingFlags.Static).SetValue(null, value);
	}

	public static TReturn GetPropertyValue<TReturn>(this object instance, string propName)
	{
		return (TReturn)instance.GetType().GetProperty(propName, _defaultFlags | BindingFlags.Instance).GetValue(instance);
	}

	public static TReturn GetPropertyValue<TClass, TReturn>(string propName)
	{
		return typeof(TClass).GetPropertyValue<TReturn>(propName);
	}

	public static TReturn GetPropertyValue<TReturn>(this Type type, string propName)
	{
		return (TReturn)type.GetProperty(propName, _defaultFlags | BindingFlags.Static).GetValue(null);
	}

	public static void SetPropertyValue(this object instance, string propName, object value)
	{
		instance.GetType().GetProperty(propName, _defaultFlags | BindingFlags.Instance).SetValue(instance, value);
	}

	public static void SetPropertyValue<TClass>(string propName, object value)
	{
		typeof(TClass).SetPropertyValue(propName, value);
	}

	public static void SetPropertyValue(this Type type, string propName, object value)
	{
		type.GetProperty(propName, _defaultFlags | BindingFlags.Static).SetValue(null, value);
	}

	public static TReturn InvokeMethod<TReturn>(this object instance, string methodName, params object[] methodParams)
	{
		return (TReturn)instance.GetType().GetMethod(methodName, _defaultFlags | BindingFlags.Instance).Invoke(instance, methodParams);
	}

	public static TReturn InvokeMethod<TClass, TReturn>(string methodName, params object[] methodParams)
	{
		return typeof(TClass).InvokeMethod<TReturn>(methodName, methodParams);
	}

	public static TReturn InvokeMethod<TReturn>(this Type type, string methodName, params object[] methodParams)
	{
		return (TReturn)type.GetMethod(methodName, _defaultFlags | BindingFlags.Static).Invoke(null, methodParams);
	}

	public static void InvokeMethod(this object instance, string methodName, params object[] methodParams)
	{
		instance.InvokeMethod<object>(methodName, methodParams);
	}

	public static void InvokeMethod<TClass>(string methodName, params object[] methodParams)
	{
		InvokeMethod<TClass, object>(methodName, methodParams);
	}

	public static void InvokeMethod(this Type type, string methodName, params object[] methodParams)
	{
		InvokeMethod<object>(methodName, methodParams);
	}

	public static Type GetNestedType<TParent>(string name)
	{
		return GetNestedType(typeof(TParent), name);
	}

	public static Type GetNestedType(this Type parentType, string name)
	{
		return parentType.GetNestedType(name, BindingFlags.Public | BindingFlags.NonPublic);
	}

	public static object Instantiate(this Type type)
	{
		return Activator.CreateInstance(type, nonPublic: true);
	}

	public static object InstantiateGeneric<TClass>(Type typeArgument)
	{
		return typeof(TClass).InstantiateGeneric(typeArgument);
	}

	public static object InstantiateGeneric(this Type genericType, Type typeArgument)
	{
		return genericType.MakeGenericType(typeArgument).Instantiate();
	}

	public static object InstantiateGeneric<TClass>(Type[] typeArguments)
	{
		return typeof(TClass).InstantiateGeneric(typeArguments);
	}

	public static object InstantiateGeneric(this Type genericType, Type[] typeArguments)
	{
		return genericType.MakeGenericType(typeArguments).Instantiate();
	}

	public static IList InstantiateList(this Type type)
	{
		return (IList)typeof(List<>).MakeGenericType(type).Instantiate();
	}
}
namespace PlayerBots
{
	internal class ItemManager : MonoBehaviour
	{
		private enum ChestTier
		{
			WHITE,
			GREEN,
			RED
		}

		public CharacterMaster master;

		private WeightedSelection<ChestTier> chestPicker;

		private ChestTier nextChestTier;

		private int nextChestPrice = 25;

		private int purchases;

		private int maxPurchases = 8;

		private FixedTimeStamp lastBuyCheck;

		private float buyingDelay;

		public void Awake()
		{
			master = ((Component)this).gameObject.GetComponent<CharacterMaster>();
			maxPurchases = PlayerBotManager.MaxBotPurchasesPerStage.Value;
			chestPicker = new WeightedSelection<ChestTier>(8);
			chestPicker.AddChoice(ChestTier.WHITE, PlayerBotManager.Tier1ChestBotWeight.Value);
			chestPicker.AddChoice(ChestTier.GREEN, PlayerBotManager.Tier2ChestBotWeight.Value);
			chestPicker.AddChoice(ChestTier.RED, PlayerBotManager.Tier3ChestBotWeight.Value);
			ResetPurchases();
			ResetBuyingDelay();
		}

		public void FixedUpdate()
		{
			if (((FixedTimeStamp)(ref lastBuyCheck)).timeSince >= buyingDelay)
			{
				CheckBuy();
				ResetBuyingDelay();
			}
		}

		public void ResetPurchases()
		{
			ResetChest();
			maxPurchases = GetMaxPurchases();
		}

		private void ResetBuyingDelay()
		{
			//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)
			lastBuyCheck = FixedTimeStamp.now;
			buyingDelay = Random.Range(PlayerBotManager.MinBuyingDelay.Value, PlayerBotManager.MaxBuyingDelay.Value);
		}

		public void ResetChest()
		{
			nextChestTier = chestPicker.Evaluate(Random.value);
			switch (nextChestTier)
			{
			case ChestTier.WHITE:
				nextChestPrice = Run.instance.GetDifficultyScaledCost(PlayerBotManager.Tier1ChestBotCost.Value);
				break;
			case ChestTier.GREEN:
				nextChestPrice = Run.instance.GetDifficultyScaledCost(PlayerBotManager.Tier2ChestBotCost.Value);
				break;
			case ChestTier.RED:
				nextChestPrice = Run.instance.GetDifficultyScaledCost(PlayerBotManager.Tier3ChestBotCost.Value);
				break;
			}
		}

		private int GetMaxPurchases()
		{
			return PlayerBotManager.MaxBotPurchasesPerStage.Value * (Run.instance.stageClearCount + 1);
		}

		private void CheckBuy()
		{
			if (!master.IsDeadAndOutOfLivesServer() && purchases < maxPurchases)
			{
				uint num = (uint)nextChestPrice;
				if (master.money >= num)
				{
					Buy(nextChestTier);
					CharacterMaster obj = master;
					obj.money -= num;
					purchases++;
					ResetChest();
				}
			}
		}

		private void Buy(ChestTier chestTier)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Invalid comparison between Unknown and I4
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Invalid comparison between Unknown and I4
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Invalid comparison between Unknown and I4
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Invalid comparison between Unknown and I4
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Expected O, but got Unknown
			List<PickupIndex> list = null;
			switch (chestTier)
			{
			case ChestTier.WHITE:
				list = (((int)master.inventory.currentEquipmentIndex != -1 || PlayerBotManager.EquipmentBuyChance.Value <= Random.Range(0, 100)) ? Run.instance.smallChestDropTierSelector.Evaluate(Random.value) : Run.instance.availableEquipmentDropList);
				break;
			case ChestTier.GREEN:
				list = Run.instance.mediumChestDropTierSelector.Evaluate(Random.value);
				break;
			case ChestTier.RED:
				list = Run.instance.largeChestDropTierSelector.Evaluate(Random.value);
				break;
			}
			if (list == null || list.Count <= 0)
			{
				return;
			}
			PickupIndex val = Run.instance.treasureRng.NextElementUniform<PickupIndex>(list);
			PickupDef pickupDef = PickupCatalog.GetPickupDef(val);
			if ((int)pickupDef.itemIndex != -1)
			{
				master.inventory.GiveItem(pickupDef.itemIndex, 1);
			}
			else
			{
				if ((int)pickupDef.equipmentIndex == -1)
				{
					return;
				}
				master.inventory.SetEquipmentIndex(pickupDef.equipmentIndex);
			}
			if (PlayerBotManager.ShowBuyMessages.Value)
			{
				PickupDef pickupDef2 = PickupCatalog.GetPickupDef(val);
				Chat.SendBroadcastChat((ChatMessageBase)new PlayerPickupChatMessage
				{
					subjectAsCharacterBody = master.GetBody(),
					baseToken = "PLAYER_PICKUP",
					pickupToken = (pickupDef2?.nameToken ?? PickupCatalog.invalidPickupToken),
					pickupColor = Color32.op_Implicit(pickupDef2?.baseColor ?? Color.black),
					pickupQuantity = (((int)pickupDef.itemIndex == -1) ? 1u : ((uint)master.inventory.GetItemCount(pickupDef.itemIndex)))
				});
			}
		}
	}
	internal class PlayerBotHooks
	{
		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static hook_OnBodyLost <>9__0_0;

			public static hook_OnServerMasterSummonGlobal <>9__0_1;

			public static Func<Instruction, bool> <>9__0_12;

			public static Manipulator <>9__0_2;

			public static hook_GiveTeamMoney_TeamIndex_uint <>9__0_3;

			public static hook_BeginStage <>9__0_4;

			public static hook_Start <>9__0_5;

			public static Func<PlayerCharacterMasterController, bool> <>9__0_15;

			public static Func<PlayerCharacterMasterController, bool> <>9__0_16;

			public static hook_PlaceTeleporter <>9__0_6;

			public static hook_PlayerCanUseBody <>9__0_7;

			public static hook_Update <>9__0_8;

			public static Func<Instruction, bool> <>9__0_17;

			public static Func<bool, bool> <>9__0_18;

			public static Manipulator <>9__0_9;

			public static hook_CanUserSpectateBody <>9__0_10;

			public static Func<Instruction, bool> <>9__0_19;

			public static Func<bool, bool> <>9__0_20;

			public static Manipulator <>9__0_11;

			internal void <AddHooks>b__0_0(orig_OnBodyLost orig, BaseAI self, CharacterBody body)
			{
				if (((Object)self).name.Equals("PlayerBot"))
				{
					self.stateMachine.SetNextState(EntityStateCatalog.InstantiateState(ref self.scanState));
				}
				else
				{
					orig.Invoke(self, body);
				}
			}

			internal void <AddHooks>b__0_1(orig_OnServerMasterSummonGlobal orig, CaptainDefenseMatrixController self, MasterSummonReport summonReport)
			{
				//IL_0016: Unknown result type (might be due to invalid IL or missing references)
				if (!((Object)(object)self.GetFieldValue<CharacterBody>("characterBody") == (Object)null))
				{
					orig.Invoke(self, summonReport);
				}
			}

			internal void <AddHooks>b__0_2(ILContext il)
			{
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				//IL_000d: Expected O, but got Unknown
				<>c__DisplayClass0_0 CS$<>8__locals0 = new <>c__DisplayClass0_0();
				ILCursor val = new ILCursor(il);
				val.GotoNext(new Func<Instruction, bool>[1]
				{
					(Instruction x) => ILPatternMatchingExt.MatchCallvirt<CharacterBody>(x, "get_isPlayerControlled")
				});
				CS$<>8__locals0.isPlayerBot = false;
				val.EmitDelegate<Func<CharacterBody, CharacterBody>>((Func<CharacterBody, CharacterBody>)delegate(CharacterBody x)
				{
					CS$<>8__locals0.isPlayerBot = ((Object)x.master).name.Equals("PlayerBot");
					return x;
				});
				val.Index += 1;
				val.EmitDelegate<Func<bool, bool>>((Func<bool, bool>)((bool x) => CS$<>8__locals0.isPlayerBot || x));
			}

			internal bool <AddHooks>b__0_12(Instruction x)
			{
				return ILPatternMatchingExt.MatchCallvirt<CharacterBody>(x, "get_isPlayerControlled");
			}

			internal void <AddHooks>b__0_3(orig_GiveTeamMoney_TeamIndex_uint orig, TeamManager self, TeamIndex teamIndex, uint money)
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_007a: Unknown result type (might be due to invalid IL or missing references)
				//IL_007f: Unknown result type (might be due to invalid IL or missing references)
				orig.Invoke(self, teamIndex, money);
				if (PlayerBotManager.playerbots.Count <= 0)
				{
					return;
				}
				int num = (Object.op_Implicit((Object)(object)Run.instance) ? Run.instance.livingPlayerCount : 0);
				if (num != 0)
				{
					money = (uint)Mathf.CeilToInt((float)money / (float)num);
				}
				foreach (GameObject playerbot in PlayerBotManager.playerbots)
				{
					if (Object.op_Implicit((Object)(object)playerbot))
					{
						CharacterMaster component = playerbot.GetComponent<CharacterMaster>();
						if (Object.op_Implicit((Object)(object)component) && !component.IsDeadAndOutOfLivesServer() && component.teamIndex == teamIndex)
						{
							component.GiveMoney(money);
						}
					}
				}
			}

			internal void <AddHooks>b__0_4(orig_BeginStage orig, Run self)
			{
				GameObject[] array = PlayerBotManager.playerbots.ToArray();
				foreach (GameObject val in array)
				{
					if (!Object.op_Implicit((Object)(object)val))
					{
						PlayerBotManager.playerbots.Remove(val);
						continue;
					}
					ItemManager component = val.GetComponent<ItemManager>();
					if (Object.op_Implicit((Object)(object)component))
					{
						component.ResetPurchases();
						component.master.money = 0u;
					}
				}
				orig.Invoke(self);
			}

			internal IEnumerator <AddHooks>b__0_5(orig_Start orig, Stage self)
			{
				//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
				IEnumerator result = orig.Invoke(self);
				if (NetworkServer.active)
				{
					if (PlayerBotManager.PlayerMode.Value)
					{
						GameObject[] array = PlayerBotManager.playerbots.ToArray();
						foreach (GameObject val in array)
						{
							if (!Object.op_Implicit((Object)(object)val))
							{
								PlayerBotManager.playerbots.Remove(val);
								continue;
							}
							CharacterMaster component = val.GetComponent<CharacterMaster>();
							if (Object.op_Implicit((Object)(object)component))
							{
								Stage.instance.RespawnCharacter(component);
							}
						}
					}
					if (Run.instance.stageClearCount == 0)
					{
						if (PlayerBotManager.InitialRandomBots.Value > 0)
						{
							PlayerBotManager.SpawnRandomPlayerbots(NetworkUser.readOnlyInstancesList[0].master, PlayerBotManager.InitialRandomBots.Value);
						}
						for (int j = 0; j < PlayerBotManager.InitialBots.Length; j++)
						{
							if (PlayerBotManager.InitialBots[j].Value > 0)
							{
								PlayerBotManager.SpawnPlayerbots(NetworkUser.readOnlyInstancesList[0].master, PlayerBotManager.RandomSurvivorsList[j], PlayerBotManager.InitialBots[j].Value);
							}
						}
					}
				}
				return result;
			}

			internal void <AddHooks>b__0_6(orig_PlaceTeleporter orig, SceneDirector self)
			{
				//IL_0073: Unknown result type (might be due to invalid IL or missing references)
				//IL_0078: Unknown result type (might be due to invalid IL or missing references)
				//IL_007a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0089: Unknown result type (might be due to invalid IL or missing references)
				//IL_0141: Unknown result type (might be due to invalid IL or missing references)
				//IL_0146: Unknown result type (might be due to invalid IL or missing references)
				//IL_0148: Unknown result type (might be due to invalid IL or missing references)
				//IL_0158: Unknown result type (might be due to invalid IL or missing references)
				if (PlayerBotManager.DontScaleInteractables.Value)
				{
					int num = PlayerCharacterMasterController.instances.Count((PlayerCharacterMasterController v) => Object.op_Implicit((Object)(object)v.networkUser));
					float num2 = 0.5f + (float)num * 0.5f;
					ClassicStageInfo component = ((Component)SceneInfo.instance).GetComponent<ClassicStageInfo>();
					int num3 = (int)((float)component.sceneDirectorInteractibleCredits * num2);
					if (component.bonusInteractibleCreditObjects != null)
					{
						for (int i = 0; i < component.bonusInteractibleCreditObjects.Length; i++)
						{
							BonusInteractibleCreditObject val = component.bonusInteractibleCreditObjects[i];
							if (val.objectThatGrantsPointsIfEnabled.activeSelf)
							{
								num3 += val.points;
							}
						}
					}
					self.interactableCredit = num3;
				}
				else if (Run.instance.stageClearCount == 0 && PlayerBotManager.GetInitialBotCount() > 0)
				{
					int num4 = PlayerCharacterMasterController.instances.Count((PlayerCharacterMasterController v) => Object.op_Implicit((Object)(object)v.networkUser));
					num4 += PlayerBotManager.GetInitialBotCount();
					float num5 = 0.5f + (float)num4 * 0.5f;
					ClassicStageInfo component2 = ((Component)SceneInfo.instance).GetComponent<ClassicStageInfo>();
					int num6 = (int)((float)component2.sceneDirectorInteractibleCredits * num5);
					if (component2.bonusInteractibleCreditObjects != null)
					{
						for (int j = 0; j < component2.bonusInteractibleCreditObjects.Length; j++)
						{
							BonusInteractibleCreditObject val2 = component2.bonusInteractibleCreditObjects[j];
							if (val2.objectThatGrantsPointsIfEnabled.activeSelf)
							{
								num6 += val2.points;
							}
						}
					}
					self.interactableCredit = num6;
				}
				orig.Invoke(self);
			}

			internal bool <AddHooks>b__0_15(PlayerCharacterMasterController v)
			{
				return Object.op_Implicit((Object)(object)v.networkUser);
			}

			internal bool <AddHooks>b__0_16(PlayerCharacterMasterController v)
			{
				return Object.op_Implicit((Object)(object)v.networkUser);
			}

			internal bool <AddHooks>b__0_7(orig_PlayerCanUseBody orig, ExpansionRequirementComponent self, PlayerCharacterMasterController master)
			{
				if (((Object)master).name.Equals("PlayerBot"))
				{
					return true;
				}
				return orig.Invoke(self, master);
			}

			internal void <AddHooks>b__0_8(orig_Update orig, PlayerCharacterMasterController self)
			{
				if (!((Object)self).name.Equals("PlayerBot"))
				{
					orig.Invoke(self);
				}
			}

			internal void <AddHooks>b__0_9(ILContext il)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0007: Expected O, but got Unknown
				ILCursor val = new ILCursor(il);
				val.GotoNext(new Func<Instruction, bool>[1]
				{
					(Instruction x) => ILPatternMatchingExt.MatchCallvirt<CharacterMaster>(x, "get_playerCharacterMasterController")
				});
				val.Index += 2;
				val.EmitDelegate<Func<bool, bool>>((Func<bool, bool>)((bool x) => false));
			}

			internal bool <AddHooks>b__0_17(Instruction x)
			{
				return ILPatternMatchingExt.MatchCallvirt<CharacterMaster>(x, "get_playerCharacterMasterController");
			}

			internal bool <AddHooks>b__0_18(bool x)
			{
				return false;
			}

			internal bool <AddHooks>b__0_10(orig_CanUserSpectateBody orig, NetworkUser viewer, CharacterBody body)
			{
				if (!body.isPlayerControlled)
				{
					return orig.Invoke(viewer, body);
				}
				return true;
			}

			internal void <AddHooks>b__0_11(ILContext il)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0007: Expected O, but got Unknown
				ILCursor val = new ILCursor(il);
				val.GotoNext(new Func<Instruction, bool>[1]
				{
					(Instruction x) => ILPatternMatchingExt.MatchCallvirt<PlayerCharacterMasterController>(x, "get_isConnected")
				});
				val.Index += 1;
				val.EmitDelegate<Func<bool, bool>>((Func<bool, bool>)((bool x) => true));
			}

			internal bool <AddHooks>b__0_19(Instruction x)
			{
				return ILPatternMatchingExt.MatchCallvirt<PlayerCharacterMasterController>(x, "get_isConnected");
			}

			internal bool <AddHooks>b__0_20(bool x)
			{
				return true;
			}
		}

		[CompilerGenerated]
		private sealed class <>c__DisplayClass0_0
		{
			public bool isPlayerBot;

			internal CharacterBody <AddHooks>b__13(CharacterBody x)
			{
				isPlayerBot = ((Object)x.master).name.Equals("PlayerBot");
				return x;
			}

			internal bool <AddHooks>b__14(bool x)
			{
				if (isPlayerBot)
				{
					return true;
				}
				return x;
			}
		}

		public static void AddHooks()
		{
			//IL_0014: 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: Expected O, but got Unknown
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Expected O, but got Unknown
			//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)
			//IL_007f: Expected O, but got Unknown
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Expected O, but got Unknown
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Expected O, but got Unknown
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Expected O, but got Unknown
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Expected O, but got Unknown
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Expected O, but got Unknown
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Expected O, but got Unknown
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_019b: Expected O, but got Unknown
			//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bf: Expected O, but got Unknown
			//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e3: Expected O, but got Unknown
			//IL_0208: Unknown result type (might be due to invalid IL or missing references)
			//IL_020d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0213: Expected O, but got Unknown
			object obj = <>c.<>9__0_0;
			if (obj == null)
			{
				hook_OnBodyLost val = delegate(orig_OnBodyLost orig, BaseAI self, CharacterBody body)
				{
					if (((Object)self).name.Equals("PlayerBot"))
					{
						self.stateMachine.SetNextState(EntityStateCatalog.InstantiateState(ref self.scanState));
					}
					else
					{
						orig.Invoke(self, body);
					}
				};
				<>c.<>9__0_0 = val;
				obj = (object)val;
			}
			BaseAI.OnBodyLost += (hook_OnBodyLost)obj;
			object obj2 = <>c.<>9__0_1;
			if (obj2 == null)
			{
				hook_OnServerMasterSummonGlobal val2 = delegate(orig_OnServerMasterSummonGlobal orig, CaptainDefenseMatrixController self, MasterSummonReport summonReport)
				{
					//IL_0016: Unknown result type (might be due to invalid IL or missing references)
					if (!((Object)(object)self.GetFieldValue<CharacterBody>("characterBody") == (Object)null))
					{
						orig.Invoke(self, summonReport);
					}
				};
				<>c.<>9__0_1 = val2;
				obj2 = (object)val2;
			}
			CaptainDefenseMatrixController.OnServerMasterSummonGlobal += (hook_OnServerMasterSummonGlobal)obj2;
			if (PlayerBotManager.ShowNameplates.Value && !PlayerBotManager.PlayerMode.Value)
			{
				object obj3 = <>c.<>9__0_2;
				if (obj3 == null)
				{
					Manipulator val3 = delegate(ILContext il)
					{
						//IL_0007: Unknown result type (might be due to invalid IL or missing references)
						//IL_000d: Expected O, but got Unknown
						ILCursor val19 = new ILCursor(il);
						val19.GotoNext(new Func<Instruction, bool>[1]
						{
							(Instruction x) => ILPatternMatchingExt.MatchCallvirt<CharacterBody>(x, "get_isPlayerControlled")
						});
						bool isPlayerBot = false;
						val19.EmitDelegate<Func<CharacterBody, CharacterBody>>((Func<CharacterBody, CharacterBody>)delegate(CharacterBody x)
						{
							isPlayerBot = ((Object)x.master).name.Equals("PlayerBot");
							return x;
						});
						val19.Index += 1;
						val19.EmitDelegate<Func<bool, bool>>((Func<bool, bool>)((bool x) => isPlayerBot || x));
					};
					<>c.<>9__0_2 = val3;
					obj3 = (object)val3;
				}
				TeamComponent.SetupIndicator += (Manipulator)obj3;
			}
			if (!PlayerBotManager.PlayerMode.Value && PlayerBotManager.AutoPurchaseItems.Value)
			{
				object obj4 = <>c.<>9__0_3;
				if (obj4 == null)
				{
					hook_GiveTeamMoney_TeamIndex_uint val4 = delegate(orig_GiveTeamMoney_TeamIndex_uint orig, TeamManager self, TeamIndex teamIndex, uint money)
					{
						//IL_0002: Unknown result type (might be due to invalid IL or missing references)
						//IL_007a: Unknown result type (might be due to invalid IL or missing references)
						//IL_007f: Unknown result type (might be due to invalid IL or missing references)
						orig.Invoke(self, teamIndex, money);
						if (PlayerBotManager.playerbots.Count > 0)
						{
							int num7 = (Object.op_Implicit((Object)(object)Run.instance) ? Run.instance.livingPlayerCount : 0);
							if (num7 != 0)
							{
								money = (uint)Mathf.CeilToInt((float)money / (float)num7);
							}
							foreach (GameObject playerbot in PlayerBotManager.playerbots)
							{
								if (Object.op_Implicit((Object)(object)playerbot))
								{
									CharacterMaster component5 = playerbot.GetComponent<CharacterMaster>();
									if (Object.op_Implicit((Object)(object)component5) && !component5.IsDeadAndOutOfLivesServer() && component5.teamIndex == teamIndex)
									{
										component5.GiveMoney(money);
									}
								}
							}
						}
					};
					<>c.<>9__0_3 = val4;
					obj4 = (object)val4;
				}
				TeamManager.GiveTeamMoney_TeamIndex_uint += (hook_GiveTeamMoney_TeamIndex_uint)obj4;
			}
			if (PlayerBotManager.AutoPurchaseItems.Value)
			{
				object obj5 = <>c.<>9__0_4;
				if (obj5 == null)
				{
					hook_BeginStage val5 = delegate(orig_BeginStage orig, Run self)
					{
						GameObject[] array2 = PlayerBotManager.playerbots.ToArray();
						foreach (GameObject val18 in array2)
						{
							if (!Object.op_Implicit((Object)(object)val18))
							{
								PlayerBotManager.playerbots.Remove(val18);
							}
							else
							{
								ItemManager component4 = val18.GetComponent<ItemManager>();
								if (Object.op_Implicit((Object)(object)component4))
								{
									component4.ResetPurchases();
									component4.master.money = 0u;
								}
							}
						}
						orig.Invoke(self);
					};
					<>c.<>9__0_4 = val5;
					obj5 = (object)val5;
				}
				Run.BeginStage += (hook_BeginStage)obj5;
			}
			object obj6 = <>c.<>9__0_5;
			if (obj6 == null)
			{
				hook_Start val6 = delegate(orig_Start orig, Stage self)
				{
					//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
					IEnumerator result = orig.Invoke(self);
					if (NetworkServer.active)
					{
						if (PlayerBotManager.PlayerMode.Value)
						{
							GameObject[] array = PlayerBotManager.playerbots.ToArray();
							foreach (GameObject val17 in array)
							{
								if (!Object.op_Implicit((Object)(object)val17))
								{
									PlayerBotManager.playerbots.Remove(val17);
								}
								else
								{
									CharacterMaster component3 = val17.GetComponent<CharacterMaster>();
									if (Object.op_Implicit((Object)(object)component3))
									{
										Stage.instance.RespawnCharacter(component3);
									}
								}
							}
						}
						if (Run.instance.stageClearCount == 0)
						{
							if (PlayerBotManager.InitialRandomBots.Value > 0)
							{
								PlayerBotManager.SpawnRandomPlayerbots(NetworkUser.readOnlyInstancesList[0].master, PlayerBotManager.InitialRandomBots.Value);
							}
							for (int l = 0; l < PlayerBotManager.InitialBots.Length; l++)
							{
								if (PlayerBotManager.InitialBots[l].Value > 0)
								{
									PlayerBotManager.SpawnPlayerbots(NetworkUser.readOnlyInstancesList[0].master, PlayerBotManager.RandomSurvivorsList[l], PlayerBotManager.InitialBots[l].Value);
								}
							}
						}
					}
					return result;
				};
				<>c.<>9__0_5 = val6;
				obj6 = (object)val6;
			}
			Stage.Start += (hook_Start)obj6;
			Target.GetBullseyePosition += new hook_GetBullseyePosition(Hook_GetBullseyePosition);
			if (!PlayerBotManager.PlayerMode.Value)
			{
				return;
			}
			object obj7 = <>c.<>9__0_6;
			if (obj7 == null)
			{
				hook_PlaceTeleporter val7 = delegate(orig_PlaceTeleporter orig, SceneDirector self)
				{
					//IL_0073: Unknown result type (might be due to invalid IL or missing references)
					//IL_0078: Unknown result type (might be due to invalid IL or missing references)
					//IL_007a: Unknown result type (might be due to invalid IL or missing references)
					//IL_0089: Unknown result type (might be due to invalid IL or missing references)
					//IL_0141: Unknown result type (might be due to invalid IL or missing references)
					//IL_0146: Unknown result type (might be due to invalid IL or missing references)
					//IL_0148: Unknown result type (might be due to invalid IL or missing references)
					//IL_0158: Unknown result type (might be due to invalid IL or missing references)
					if (PlayerBotManager.DontScaleInteractables.Value)
					{
						int num = PlayerCharacterMasterController.instances.Count((PlayerCharacterMasterController v) => Object.op_Implicit((Object)(object)v.networkUser));
						float num2 = 0.5f + (float)num * 0.5f;
						ClassicStageInfo component = ((Component)SceneInfo.instance).GetComponent<ClassicStageInfo>();
						int num3 = (int)((float)component.sceneDirectorInteractibleCredits * num2);
						if (component.bonusInteractibleCreditObjects != null)
						{
							for (int i = 0; i < component.bonusInteractibleCreditObjects.Length; i++)
							{
								BonusInteractibleCreditObject val15 = component.bonusInteractibleCreditObjects[i];
								if (val15.objectThatGrantsPointsIfEnabled.activeSelf)
								{
									num3 += val15.points;
								}
							}
						}
						self.interactableCredit = num3;
					}
					else if (Run.instance.stageClearCount == 0 && PlayerBotManager.GetInitialBotCount() > 0)
					{
						int num4 = PlayerCharacterMasterController.instances.Count((PlayerCharacterMasterController v) => Object.op_Implicit((Object)(object)v.networkUser));
						num4 += PlayerBotManager.GetInitialBotCount();
						float num5 = 0.5f + (float)num4 * 0.5f;
						ClassicStageInfo component2 = ((Component)SceneInfo.instance).GetComponent<ClassicStageInfo>();
						int num6 = (int)((float)component2.sceneDirectorInteractibleCredits * num5);
						if (component2.bonusInteractibleCreditObjects != null)
						{
							for (int j = 0; j < component2.bonusInteractibleCreditObjects.Length; j++)
							{
								BonusInteractibleCreditObject val16 = component2.bonusInteractibleCreditObjects[j];
								if (val16.objectThatGrantsPointsIfEnabled.activeSelf)
								{
									num6 += val16.points;
								}
							}
						}
						self.interactableCredit = num6;
					}
					orig.Invoke(self);
				};
				<>c.<>9__0_6 = val7;
				obj7 = (object)val7;
			}
			SceneDirector.PlaceTeleporter += (hook_PlaceTeleporter)obj7;
			object obj8 = <>c.<>9__0_7;
			if (obj8 == null)
			{
				hook_PlayerCanUseBody val8 = (orig_PlayerCanUseBody orig, ExpansionRequirementComponent self, PlayerCharacterMasterController master) => ((Object)master).name.Equals("PlayerBot") || orig.Invoke(self, master);
				<>c.<>9__0_7 = val8;
				obj8 = (object)val8;
			}
			ExpansionRequirementComponent.PlayerCanUseBody += (hook_PlayerCanUseBody)obj8;
			object obj9 = <>c.<>9__0_8;
			if (obj9 == null)
			{
				hook_Update val9 = delegate(orig_Update orig, PlayerCharacterMasterController self)
				{
					if (!((Object)self).name.Equals("PlayerBot"))
					{
						orig.Invoke(self);
					}
				};
				<>c.<>9__0_8 = val9;
				obj9 = (object)val9;
			}
			PlayerCharacterMasterController.Update += (hook_Update)obj9;
			object obj10 = <>c.<>9__0_9;
			if (obj10 == null)
			{
				Manipulator val10 = delegate(ILContext il)
				{
					//IL_0001: Unknown result type (might be due to invalid IL or missing references)
					//IL_0007: Expected O, but got Unknown
					ILCursor val14 = new ILCursor(il);
					val14.GotoNext(new Func<Instruction, bool>[1]
					{
						(Instruction x) => ILPatternMatchingExt.MatchCallvirt<CharacterMaster>(x, "get_playerCharacterMasterController")
					});
					val14.Index += 2;
					val14.EmitDelegate<Func<bool, bool>>((Func<bool, bool>)((bool x) => false));
				};
				<>c.<>9__0_9 = val10;
				obj10 = (object)val10;
			}
			AllyCardManager.PopulateCharacterDataSet += (Manipulator)obj10;
			object obj11 = <>c.<>9__0_10;
			if (obj11 == null)
			{
				hook_CanUserSpectateBody val11 = (orig_CanUserSpectateBody orig, NetworkUser viewer, CharacterBody body) => body.isPlayerControlled || orig.Invoke(viewer, body);
				<>c.<>9__0_10 = val11;
				obj11 = (object)val11;
			}
			CameraRigControllerSpectateControls.CanUserSpectateBody += (hook_CanUserSpectateBody)obj11;
			if (!PlayerBotManager.ContinueAfterDeath.Value)
			{
				return;
			}
			object obj12 = <>c.<>9__0_11;
			if (obj12 == null)
			{
				Manipulator val12 = delegate(ILContext il)
				{
					//IL_0001: Unknown result type (might be due to invalid IL or missing references)
					//IL_0007: Expected O, but got Unknown
					ILCursor val13 = new ILCursor(il);
					val13.GotoNext(new Func<Instruction, bool>[1]
					{
						(Instruction x) => ILPatternMatchingExt.MatchCallvirt<PlayerCharacterMasterController>(x, "get_isConnected")
					});
					val13.Index += 1;
					val13.EmitDelegate<Func<bool, bool>>((Func<bool, bool>)((bool x) => true));
				};
				<>c.<>9__0_11 = val12;
				obj12 = (object)val12;
			}
			Stage.FixedUpdate += (Manipulator)obj12;
		}

		public static bool Hook_GetBullseyePosition(orig_GetBullseyePosition orig, Target self, out Vector3 position)
		{
			orig.Invoke(self, ref position);
			return true;
		}
	}
	[BepInPlugin("com.meledy.PlayerBots", "PlayerBots", "1.7.1")]
	public class PlayerBotManager : BaseUnityPlugin
	{
		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static hook_Awake <>9__86_0;

			public static Func<PlayerCharacterMasterController, bool> <>9__99_0;

			internal void <Awake>b__86_0(orig_Awake orig, Console self)
			{
				CommandHelper.RegisterCommands(self);
				orig.Invoke(self);
			}

			internal bool <FixedUpdate>b__99_0(PlayerCharacterMasterController p)
			{
				if (p.preventGameOver)
				{
					return p.isConnected;
				}
				return false;
			}
		}

		public static Random random = new Random();

		public static List<GameObject> playerbots = new List<GameObject>();

		public static List<SurvivorIndex> RandomSurvivorsList = new List<SurvivorIndex>();

		public static Dictionary<string, SurvivorIndex> SurvivorDict = new Dictionary<string, SurvivorIndex>();

		public static ConfigEntry<int>[] InitialBots;

		public static bool allRealPlayersDead;

		public static ConfigEntry<int> InitialRandomBots { get; set; }

		public static ConfigEntry<int> MaxBotPurchasesPerStage { get; set; }

		public static ConfigEntry<bool> AutoPurchaseItems { get; set; }

		public static ConfigEntry<float> Tier1ChestBotWeight { get; set; }

		public static ConfigEntry<int> Tier1ChestBotCost { get; set; }

		public static ConfigEntry<float> Tier2ChestBotWeight { get; set; }

		public static ConfigEntry<int> Tier2ChestBotCost { get; set; }

		public static ConfigEntry<float> Tier3ChestBotWeight { get; set; }

		public static ConfigEntry<int> Tier3ChestBotCost { get; set; }

		public static ConfigEntry<int> EquipmentBuyChance { get; set; }

		public static ConfigEntry<float> MinBuyingDelay { get; set; }

		public static ConfigEntry<float> MaxBuyingDelay { get; set; }

		public static ConfigEntry<bool> ShowBuyMessages { get; set; }

		public static ConfigEntry<bool> HostOnlySpawnBots { get; set; }

		public static ConfigEntry<bool> ShowNameplates { get; set; }

		public static ConfigEntry<bool> PlayerMode { get; set; }

		public static ConfigEntry<bool> DontScaleInteractables { get; set; }

		public static ConfigEntry<bool> BotsUseInteractables { get; set; }

		public static ConfigEntry<bool> ContinueAfterDeath { get; set; }

		public static ConfigEntry<bool> RespawnAfterWave { get; set; }

		public void Awake()
		{
			//IL_02d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02de: Expected O, but got Unknown
			InitialRandomBots = ((BaseUnityPlugin)this).Config.Bind<int>("Starting Bots", "StartingBots.Random", 0, "Starting amount of bots to spawn at the start of a run. (Random)");
			AutoPurchaseItems = ((BaseUnityPlugin)this).Config.Bind<bool>("Bot Inventory", "AutoPurchaseItems", true, "Maximum amount of purchases a playerbot can do per stage. Items are purchased directly instead of from chests.");
			MaxBotPurchasesPerStage = ((BaseUnityPlugin)this).Config.Bind<int>("Bot Inventory", "MaxBotPurchasesPerStage", 10, "Maximum amount of putchases a playerbot can do per stage.");
			Tier1ChestBotWeight = ((BaseUnityPlugin)this).Config.Bind<float>("Bot Inventory", "Tier1ChestBotWeight", 0.8f, "Weight of a bot picking an item from a small chest's loot table.");
			Tier2ChestBotWeight = ((BaseUnityPlugin)this).Config.Bind<float>("Bot Inventory", "Tier2ChestBotWeight", 0.2f, "Weight of a bot picking an item from a large chest's loot table.");
			Tier3ChestBotWeight = ((BaseUnityPlugin)this).Config.Bind<float>("Bot Inventory", "Tier3ChestBotWeight", 0f, "Weight of a bot picking an item from a legendary chest's loot table.");
			Tier1ChestBotCost = ((BaseUnityPlugin)this).Config.Bind<int>("Bot Inventory", "Tier1ChestBotCost", 25, "Base price of a small chest for the bot.");
			Tier2ChestBotCost = ((BaseUnityPlugin)this).Config.Bind<int>("Bot Inventory", "Tier2ChestBotCost", 50, "Base price of a large chest for the bot.");
			Tier3ChestBotCost = ((BaseUnityPlugin)this).Config.Bind<int>("Bot Inventory", "Tier3ChestBotCost", 400, "Base price of a legendary chest for the bot.");
			EquipmentBuyChance = ((BaseUnityPlugin)this).Config.Bind<int>("Bot Inventory", "EquipmentBuyChance", 15, "Chance between 0 and 100 for a bot to buy from an equipment barrel instead of a tier 1 chest. Only active while the bot does not have a equipment item. (Default: 15)");
			MinBuyingDelay = ((BaseUnityPlugin)this).Config.Bind<float>("Bot Inventory", "MinBuyingDelay", 0f, "Minimum delay in seconds between the time it takes for a bot checks to buy an item.");
			MaxBuyingDelay = ((BaseUnityPlugin)this).Config.Bind<float>("Bot Inventory", "MaxBuyingDelay", 5f, "Maximum delay in seconds between the time it takes for a bot checks to buy an item.");
			ShowBuyMessages = ((BaseUnityPlugin)this).Config.Bind<bool>("Bot Inventory", "ShowBuyMessages", true, "Displays whenever a bot buys an item in chat.");
			HostOnlySpawnBots = ((BaseUnityPlugin)this).Config.Bind<bool>("Misc", "HostOnlySpawnBots", true, "Set true so that only the host may spawn bots");
			ShowNameplates = ((BaseUnityPlugin)this).Config.Bind<bool>("Misc", "ShowNameplates", true, "Show player nameplates on playerbots if PlayerMode is false. (Host only)");
			PlayerMode = ((BaseUnityPlugin)this).Config.Bind<bool>("Player Mode", "PlayerMode", false, "Makes the game treat playerbots like how regular players are treated. The bots now show up on the scoreboard, can pick up items, influence the map scaling, etc.");
			DontScaleInteractables = ((BaseUnityPlugin)this).Config.Bind<bool>("Player Mode", "DontScaleInteractables", true, "Prevents interactables spawn count from scaling with bots. Only active is PlayerMode is true.");
			BotsUseInteractables = ((BaseUnityPlugin)this).Config.Bind<bool>("Player Mode", "BotsUseInteractables", false, "[Experimental] Allow bots to use interactables, such as buying from a chest and picking up items on the ground. Only active is PlayerMode is true.");
			ContinueAfterDeath = ((BaseUnityPlugin)this).Config.Bind<bool>("Player Mode", "ContinueAfterDeath", false, "Bots will activate and use teleporters when all real players die. Only active is PlayerMode is true.");
			RespawnAfterWave = ((BaseUnityPlugin)this).Config.Bind<bool>("Simulacrum", "RespawnAfterWave", false, "Respawns bots after each wave in simulacrum");
			MaxBuyingDelay.Value = Math.Max(MaxBuyingDelay.Value, MinBuyingDelay.Value);
			object obj = <>c.<>9__86_0;
			if (obj == null)
			{
				hook_Awake val = delegate(orig_Awake orig, Console self)
				{
					CommandHelper.RegisterCommands(self);
					orig.Invoke(self);
				};
				<>c.<>9__86_0 = val;
				obj = (object)val;
			}
			Console.Awake += (hook_Awake)obj;
			RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, new Action(OnContentLoad));
			PlayerBotHooks.AddHooks();
		}

		public void OnContentLoad()
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: 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_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_0203: Unknown result type (might be due to invalid IL or missing references)
			//IL_021c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0235: Unknown result type (might be due to invalid IL or missing references)
			//IL_024e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0267: Unknown result type (might be due to invalid IL or missing references)
			//IL_0280: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b2: Unknown result type (might be due to invalid IL or missing references)
			SurvivorDict.Add("mult", SurvivorCatalog.FindSurvivorIndex("Toolbot"));
			SurvivorDict.Add("mul-t", SurvivorCatalog.FindSurvivorIndex("Toolbot"));
			SurvivorDict.Add("toolbot", SurvivorCatalog.FindSurvivorIndex("Toolbot"));
			SurvivorDict.Add("hunt", SurvivorCatalog.FindSurvivorIndex("Huntress"));
			SurvivorDict.Add("huntress", SurvivorCatalog.FindSurvivorIndex("Huntress"));
			SurvivorDict.Add("engi", SurvivorCatalog.FindSurvivorIndex("Engi"));
			SurvivorDict.Add("engineer", SurvivorCatalog.FindSurvivorIndex("Engi"));
			SurvivorDict.Add("mage", SurvivorCatalog.FindSurvivorIndex("Mage"));
			SurvivorDict.Add("arti", SurvivorCatalog.FindSurvivorIndex("Mage"));
			SurvivorDict.Add("artificer", SurvivorCatalog.FindSurvivorIndex("Mage"));
			SurvivorDict.Add("merc", SurvivorCatalog.FindSurvivorIndex("Merc"));
			SurvivorDict.Add("mercenary", SurvivorCatalog.FindSurvivorIndex("Merc"));
			SurvivorDict.Add("rex", SurvivorCatalog.FindSurvivorIndex("Treebot"));
			SurvivorDict.Add("treebot", SurvivorCatalog.FindSurvivorIndex("Treebot"));
			SurvivorDict.Add("croco", SurvivorCatalog.FindSurvivorIndex("Croco"));
			SurvivorDict.Add("capt", SurvivorCatalog.FindSurvivorIndex("Captain"));
			SurvivorDict.Add("captain", SurvivorCatalog.FindSurvivorIndex("Captain"));
			SurvivorDict.Add("railgunner", SurvivorCatalog.FindSurvivorIndex("Railgunner"));
			SurvivorDict.Add("rail", SurvivorCatalog.FindSurvivorIndex("Railgunner"));
			SurvivorDict.Add("void", SurvivorCatalog.FindSurvivorIndex("VoidSurvivor"));
			SurvivorDict.Add("voidfiend", SurvivorCatalog.FindSurvivorIndex("VoidSurvivor"));
			SurvivorDict.Add("voidsurvivor", SurvivorCatalog.FindSurvivorIndex("VoidSurvivor"));
			SurvivorDict.Add("seeker", SurvivorCatalog.FindSurvivorIndex("Seeker"));
			SurvivorDict.Add("chef", SurvivorCatalog.FindSurvivorIndex("Chef"));
			SurvivorDict.Add("son", SurvivorCatalog.FindSurvivorIndex("FalseSon"));
			SurvivorDict.Add("falseson", SurvivorCatalog.FindSurvivorIndex("FalseSon"));
			AiSkillHelperCatalog.Populate();
			InitialBots = new ConfigEntry<int>[RandomSurvivorsList.Count];
			for (int i = 0; i < RandomSurvivorsList.Count; i++)
			{
				string text = BodyCatalog.GetBodyName(SurvivorCatalog.GetBodyIndexFromSurvivorIndex(RandomSurvivorsList[i])).Replace("'", "");
				InitialBots[i] = ((BaseUnityPlugin)this).Config.Bind<int>("Starting Bots", "StartingBots." + text, 0, "Starting amount of bots to spawn at the start of a run. (" + text + ")");
			}
		}

		public static int GetInitialBotCount()
		{
			int num = InitialRandomBots.Value;
			for (int i = 0; i < InitialBots.Length; i++)
			{
				num += InitialBots[i].Value;
			}
			return num;
		}

		public static void SpawnPlayerbot(CharacterMaster owner, SurvivorIndex survivorIndex)
		{
			//IL_0015: 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)
			if (PlayerMode.Value)
			{
				SpawnPlayerbotAsPlayer(owner, survivorIndex);
			}
			else
			{
				SpawnPlayerbotAsSummon(owner, survivorIndex);
			}
		}

		private static void SpawnPlayerbotAsPlayer(CharacterMaster owner, SurvivorIndex survivorIndex)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Expected O, but got Unknown
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Expected O, but got Unknown
			SurvivorDef survivorDef = SurvivorCatalog.GetSurvivorDef(survivorIndex);
			if ((Object)(object)survivorDef == (Object)null)
			{
				return;
			}
			if (!survivorDef.CheckRequiredExpansionEnabled((NetworkUser)null))
			{
				Debug.Log((object)"You do not have the proper expansion enabled.");
				return;
			}
			GameObject bodyPrefab = survivorDef.bodyPrefab;
			if ((Object)(object)bodyPrefab == (Object)null)
			{
				return;
			}
			PlayerBotSpawnCard playerBotSpawnCard = ScriptableObject.CreateInstance<PlayerBotSpawnCard>();
			((SpawnCard)playerBotSpawnCard).hullSize = (HullClassification)0;
			((SpawnCard)playerBotSpawnCard).nodeGraphType = (GraphType)0;
			((SpawnCard)playerBotSpawnCard).occupyPosition = false;
			((SpawnCard)playerBotSpawnCard).sendOverNetwork = true;
			((SpawnCard)playerBotSpawnCard).forbiddenFlags = (NodeFlags)4;
			((SpawnCard)playerBotSpawnCard).prefab = LegacyResourcesAPI.Load<GameObject>("Prefabs/CharacterMasters/CommandoMaster");
			Transform randomSpawnPosition = GetRandomSpawnPosition(owner);
			if ((Object)(object)randomSpawnPosition == (Object)null)
			{
				Debug.LogError((object)"No spawn positions found for playerbot");
				return;
			}
			DirectorSpawnRequest val = new DirectorSpawnRequest((SpawnCard)(object)playerBotSpawnCard, new DirectorPlacementRule
			{
				placementMode = (PlacementMode)1,
				minDistance = 3f,
				maxDistance = 40f,
				spawnOnTarget = randomSpawnPosition
			}, RoR2Application.rng);
			val.ignoreTeamMemberLimit = true;
			val.teamIndexOverride = (TeamIndex)1;
			val.onSpawnedServer = delegate(SpawnResult result)
			{
				//IL_0000: 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_0066: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
				GameObject spawnedInstance = result.spawnedInstance;
				if (Object.op_Implicit((Object)(object)spawnedInstance))
				{
					spawnedInstance.AddComponent<PlayerBotStateMachine>();
					BaseAI ai = (BaseAI)(object)spawnedInstance.AddComponent<PlayerBotBaseAI>();
					spawnedInstance.AddComponent<AIOwnership>().ownerMaster = owner;
					CharacterMaster component = spawnedInstance.GetComponent<CharacterMaster>();
					((Object)spawnedInstance.GetComponent<PlayerCharacterMasterController>()).name = "PlayerBot";
					component.bodyPrefab = bodyPrefab;
					component.Respawn(((Component)component).transform.position, ((Component)component).transform.rotation, false);
					SetRandomSkin(component, bodyPrefab);
					component.SetFieldValue("aiComponents", spawnedInstance.GetComponents<BaseAI>());
					component.destroyOnBodyDeath = false;
					GiveStartingItems(owner, component);
					InjectSkillDrivers(spawnedInstance, ai, survivorIndex);
					if (AutoPurchaseItems.Value)
					{
						spawnedInstance.AddComponent<ItemManager>();
					}
					playerbots.Add(spawnedInstance);
				}
			};
			DirectorCore.instance.TrySpawnObject(val);
			Object.Destroy((Object)(object)playerBotSpawnCard);
		}

		private static void SpawnPlayerbotAsSummon(CharacterMaster owner, SurvivorIndex survivorIndex)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: 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_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Expected O, but got Unknown
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Expected O, but got Unknown
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			SurvivorDef survivorDef = SurvivorCatalog.GetSurvivorDef(survivorIndex);
			if ((Object)(object)survivorDef == (Object)null)
			{
				return;
			}
			if (!survivorDef.CheckRequiredExpansionEnabled((NetworkUser)null))
			{
				Debug.Log((object)"You do not have the proper expansion enabled.");
				return;
			}
			GameObject bodyPrefab = survivorDef.bodyPrefab;
			if ((Object)(object)bodyPrefab == (Object)null)
			{
				return;
			}
			PlayerBotSpawnCard playerBotSpawnCard = ScriptableObject.CreateInstance<PlayerBotSpawnCard>();
			((SpawnCard)playerBotSpawnCard).hullSize = (HullClassification)0;
			((SpawnCard)playerBotSpawnCard).nodeGraphType = (GraphType)0;
			((SpawnCard)playerBotSpawnCard).occupyPosition = false;
			((SpawnCard)playerBotSpawnCard).sendOverNetwork = true;
			((SpawnCard)playerBotSpawnCard).forbiddenFlags = (NodeFlags)4;
			((SpawnCard)playerBotSpawnCard).prefab = LegacyResourcesAPI.Load<GameObject>("Prefabs/CharacterMasters/CommandoMonsterMaster");
			playerBotSpawnCard.bodyPrefab = bodyPrefab;
			Transform randomSpawnPosition = GetRandomSpawnPosition(owner);
			if ((Object)(object)randomSpawnPosition == (Object)null)
			{
				Debug.LogError((object)"No spawn positions found for playerbot");
				return;
			}
			DirectorSpawnRequest val = new DirectorSpawnRequest((SpawnCard)(object)playerBotSpawnCard, new DirectorPlacementRule
			{
				placementMode = (PlacementMode)1,
				minDistance = 3f,
				maxDistance = 40f,
				spawnOnTarget = randomSpawnPosition
			}, RoR2Application.rng);
			val.ignoreTeamMemberLimit = true;
			val.teamIndexOverride = (TeamIndex)1;
			GameObject val2 = DirectorCore.instance.TrySpawnObject(val);
			if (Object.op_Implicit((Object)(object)val2))
			{
				CharacterMaster component = val2.GetComponent<CharacterMaster>();
				BaseAI component2 = val2.GetComponent<BaseAI>();
				val2.AddComponent<AIOwnership>().ownerMaster = owner;
				if (Object.op_Implicit((Object)(object)component))
				{
					((Object)component).name = "PlayerBot";
					component.teamIndex = (TeamIndex)1;
					SetRandomSkin(component, bodyPrefab);
					GiveStartingItems(owner, component);
					component.destroyOnBodyDeath = false;
					((Component)component).gameObject.AddComponent<SetDontDestroyOnLoad>();
				}
				InjectSkillDrivers(val2, component2, survivorIndex);
				if (AutoPurchaseItems.Value)
				{
					val2.AddComponent<ItemManager>();
				}
				playerbots.Add(val2);
			}
		}

		private static Transform GetRandomSpawnPosition(CharacterMaster owner)
		{
			if ((Object)(object)owner.GetBody() != (Object)null)
			{
				return ((Component)owner.GetBody()).transform;
			}
			SpawnPoint val = SpawnPoint.ConsumeSpawnPoint();
			if ((Object)(object)val != (Object)null)
			{
				val.consumed = false;
				return ((Component)val).transform;
			}
			return null;
		}

		private static void GiveStartingItems(CharacterMaster owner, CharacterMaster master)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			master.GiveMoney(owner.money);
			master.inventory.CopyItemsFrom(owner.inventory);
			master.inventory.RemoveItem(ItemCatalog.FindItemIndex("CaptainDefenseMatrix"), owner.inventory.GetItemCount(ItemCatalog.FindItemIndex("CaptainDefenseMatrix")));
			master.inventory.GiveItem(ItemCatalog.FindItemIndex("DrizzlePlayerHelper"), 1);
		}

		private static void SetRandomSkin(CharacterMaster master, GameObject bodyPrefab)
		{
			//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_001e: Unknown result type (might be due to invalid IL or missing references)
			BodyIndex bodyIndex = bodyPrefab.GetComponent<CharacterBody>().bodyIndex;
			SkinDef[] bodySkins = BodyCatalog.GetBodySkins(bodyIndex);
			master.loadout.bodyLoadoutManager.SetSkinIndex(bodyIndex, (uint)Random.Range(0, bodySkins.Length));
		}

		private static void InjectSkillDrivers(GameObject gameObject, BaseAI ai, SurvivorIndex survivorIndex)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			AiSkillHelper aiSkillHelper = AiSkillHelperCatalog.CreateSkillHelper(survivorIndex);
			if (aiSkillHelper.GetType() != typeof(DefaultSkillHelper))
			{
				AISkillDriver[] components = gameObject.GetComponents<AISkillDriver>();
				if (components != null)
				{
					StripSkills(components);
				}
				aiSkillHelper.InjectSkills(gameObject, ai);
				PropertyInfo? property = typeof(BaseAI).GetProperty("skillDrivers");
				property.DeclaringType.GetProperty("skillDrivers");
				property.SetValue(ai, gameObject.GetComponents<AISkillDriver>(), BindingFlags.Instance | BindingFlags.NonPublic, null, null, null);
			}
			else
			{
				aiSkillHelper.AddDefaultSkills(gameObject, ai, 0f);
			}
			if (Object.op_Implicit((Object)(object)ai))
			{
				((Object)ai).name = "PlayerBot";
				ai.neverRetaliateFriendlies = true;
				ai.fullVision = true;
				ai.aimVectorDampTime = 0.01f;
				ai.aimVectorMaxSpeed = 180f;
			}
			gameObject.AddComponent<PlayerBotController>().SetSkillHelper(aiSkillHelper);
		}

		public static void SpawnPlayerbots(CharacterMaster owner, SurvivorIndex characterType, int amount)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i < amount; i++)
			{
				SpawnPlayerbot(owner, characterType);
			}
		}

		public static void SpawnRandomPlayerbots(CharacterMaster owner, int amount)
		{
			//IL_0028: 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)
			int num = -1;
			for (int i = 0; i < amount; i++)
			{
				int num2 = -1;
				do
				{
					num2 = random.Next(0, RandomSurvivorsList.Count);
				}
				while ((num2 == num || !SurvivorCatalog.GetSurvivorDef(RandomSurvivorsList[num2]).CheckRequiredExpansionEnabled((NetworkUser)null)) && RandomSurvivorsList.Count > 1);
				SpawnPlayerbot(owner, RandomSurvivorsList[num2]);
				num = num2;
			}
		}

		private static void StripSkills(AISkillDriver[] skillDrivers)
		{
			for (int i = 0; i < skillDrivers.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)skillDrivers[i]);
			}
		}

		public void FixedUpdate()
		{
			allRealPlayersDead = !PlayerCharacterMasterController.instances.Any((PlayerCharacterMasterController p) => p.preventGameOver && p.isConnected);
		}

		[ConCommand(/*Could not decode attribute arguments.*/)]
		private static void CCAddBot(ConCommandArgs args)
		{
			//IL_0000: 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_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: 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_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Expected I4, but got Unknown
			NetworkUser val = args.sender;
			if ((HostOnlySpawnBots.Value && ((NetworkBehaviour)NetworkUser.readOnlyInstancesList[0]).netId != ((NetworkBehaviour)val).netId) || (Object)(object)Stage.instance == (Object)null)
			{
				return;
			}
			int result = 0;
			if (args.userArgs.Count > 0)
			{
				string text = args.userArgs[0];
				if (!int.TryParse(text, out result))
				{
					if (!SurvivorDict.TryGetValue(text.ToLower(), out var value))
					{
						result = 0;
						Debug.LogError((object)"No survivor with that name exists.");
						return;
					}
					result = (int)value;
				}
			}
			int result2 = 1;
			if (args.userArgs.Count > 1)
			{
				int.TryParse(args.userArgs[1], out result2);
			}
			if (args.userArgs.Count > 2)
			{
				int result3 = 0;
				if (!int.TryParse(args.userArgs[2], out result3))
				{
					return;
				}
				result3--;
				if (result3 >= 0 && result3 < NetworkUser.readOnlyInstancesList.Count)
				{
					val = NetworkUser.readOnlyInstancesList[result3];
				}
			}
			if (Object.op_Implicit((Object)(object)val) && !val.master.IsDeadAndOutOfLivesServer())
			{
				SpawnPlayerbots(val.master, (SurvivorIndex)result, result2);
				Debug.Log((object)(val.userName + " spawned " + result2 + " bots for " + val.userName));
			}
		}

		[ConCommand(/*Could not decode attribute arguments.*/)]
		private static void CCAddRandomBot(ConCommandArgs args)
		{
			//IL_0000: 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_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: 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_0073: Unknown result type (might be due to invalid IL or missing references)
			NetworkUser val = args.sender;
			if ((HostOnlySpawnBots.Value && ((NetworkBehaviour)NetworkUser.readOnlyInstancesList[0]).netId != ((NetworkBehaviour)val).netId) || (Object)(object)Stage.instance == (Object)null)
			{
				return;
			}
			int result = 1;
			if (args.userArgs.Count > 0)
			{
				int.TryParse(args.userArgs[0], out result);
			}
			if (args.userArgs.Count > 1)
			{
				int result2 = 0;
				if (!int.TryParse(args.userArgs[1], out result2))
				{
					return;
				}
				result2--;
				if (result2 >= 0 && result2 < NetworkUser.readOnlyInstancesList.Count)
				{
					val = NetworkUser.readOnlyInstancesList[result2];
				}
			}
			if (Object.op_Implicit((Object)(object)val) && !val.master.IsDeadAndOutOfLivesServer())
			{
				SpawnRandomPlayerbots(val.master, result);
				Debug.Log((object)(val.userName + " spawned " + result + " bots for " + val.userName));
			}
		}

		[ConCommand(/*Could not decode attribute arguments.*/)]
		private static void CCRemoveBots(ConCommandArgs args)
		{
			foreach (GameObject playerbot in playerbots)
			{
				CharacterMaster component = playerbot.GetComponent<CharacterMaster>();
				((Object)playerbot.GetComponent<BaseAI>()).name = "";
				component.TrueKill();
				Object.Destroy((Object)(object)playerbot);
			}
			playerbots.Clear();
		}

		[ConCommand(/*Could not decode attribute arguments.*/)]
		private static void CCKillBots(ConCommandArgs args)
		{
			foreach (GameObject playerbot in playerbots)
			{
				if (Object.op_Implicit((Object)(object)playerbot))
				{
					playerbot.GetComponent<CharacterMaster>().TrueKill();
				}
			}
		}

		[ConCommand(/*Could not decode attribute arguments.*/)]
		private static void CCTpBots(ConCommandArgs args)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			NetworkUser sender = args.sender;
			if ((Object)(object)Stage.instance == (Object)null || (Object)(object)sender.master == (Object)null || sender.master.IsDeadAndOutOfLivesServer())
			{
				return;
			}
			foreach (GameObject playerbot in playerbots)
			{
				if (Object.op_Implicit((Object)(object)playerbot))
				{
					CharacterMaster component = playerbot.GetComponent<CharacterMaster>();
					if (!component.IsDeadAndOutOfLivesServer())
					{
						TeleportHelper.TeleportGameObject(((Component)component.GetBody()).gameObject, new Vector3(((Component)sender.master.GetBody()).transform.position.x, ((Component)sender.master.GetBody()).transform.position.y, ((Component)sender.master.GetBody()).transform.position.z));
					}
				}
			}
		}

		[ConCommand(/*Could not decode attribute arguments.*/)]
		private static void CCInitialBot(ConCommandArgs args)
		{
			//IL_0002: 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_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Expected I4, but got Unknown
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			int result = 0;
			if (args.userArgs.Count > 0)
			{
				string text = args.userArgs[0];
				if (!int.TryParse(text, out result))
				{
					result = (SurvivorDict.TryGetValue(text.ToLower(), out var value) ? ((int)value) : 0);
				}
				result = Math.Max(Math.Min(result, RandomSurvivorsList.Count - 1), 0);
				int result2 = 0;
				if (args.userArgs.Count > 1)
				{
					int.TryParse(args.userArgs[1], out result2);
					InitialBots[result].Value = result2;
					SurvivorIndex val = RandomSurvivorsList[result];
					Debug.Log((object)("Set StartingBots." + ((object)(SurvivorIndex)(ref val)).ToString() + " to " + result2));
				}
			}
		}

		[ConCommand(/*Could not decode attribute arguments.*/)]
		private static void CCInitialRandomBot(ConCommandArgs args)
		{
			//IL_0002: 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)
			int result = 0;
			if (args.userArgs.Count > 0)
			{
				int.TryParse(args.userArgs[0], out result);
				InitialRandomBots.Value = result;
				Debug.Log((object)("Set StartingBots.Random to " + result));
			}
		}

		[ConCommand(/*Could not decode attribute arguments.*/)]
		private static void CCClearInitialBot(ConCommandArgs args)
		{
			InitialRandomBots.Value = 0;
			for (int i = 0; i < InitialBots.Length; i++)
			{
				InitialBots[i].Value = 0;
			}
			Debug.Log((object)"Reset all StartingBots values to 0");
		}

		[ConCommand(/*Could not decode attribute arguments.*/)]
		private static void CCSetMaxPurchases(ConCommandArgs args)
		{
			//IL_0002: 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)
			int result = 0;
			if (args.userArgs.Count > 0)
			{
				int.TryParse(args.userArgs[0], out result);
				MaxBotPurchasesPerStage.Value = result;
				Debug.Log((object)("Set MaxBotPurchasesPerStage to " + result));
			}
		}

		[ConCommand(/*Could not decode attribute arguments.*/)]
		private static void CCTestBots(ConCommandArgs args)
		{
			if ((Object)(object)Stage.instance == (Object)null)
			{
				return;
			}
			foreach (GameObject playerbot in playerbots)
			{
				CharacterMaster component = playerbot.GetComponent<CharacterMaster>();
				AIOwnership component2 = playerbot.GetComponent<AIOwnership>();
				string displayName = component.GetBody().GetDisplayName();
				if (Object.op_Implicit((Object)(object)component2.ownerMaster))
				{
					Debug.Log((object)(displayName + "'s master: " + component2.ownerMaster.GetBody().GetUserName()));
				}
				else
				{
					Debug.Log((object)(displayName + " has no master"));
				}
				Debug.Log((object)(displayName + "'s money: " + component.money));
			}
		}

		[ConCommand(/*Could not decode attribute arguments.*/)]
		private static void CCListSurvivors(ConCommandArgs args)
		{
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Expected I4, but got Unknown
			Debug.Log((object)"Listing all registered survivors and their indexes.");
			foreach (SurvivorDef allSurvivorDef in SurvivorCatalog.allSurvivorDefs)
			{
				Debug.Log((object)(allSurvivorDef.bodyPrefab.GetComponent<CharacterBody>().GetDisplayName() + " (" + ((Object)allSurvivorDef.bodyPrefab).name + ") : " + (int)allSurvivorDef.survivorIndex));
			}
		}
	}
	internal static class PlayerBotUtils
	{
		public static bool TryGetSurvivorIndexByBodyPrefabName(string bodyPrefabName, out SurvivorIndex index)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Expected I4, but got Unknown
			index = (SurvivorIndex)(-1);
			GameObject val = BodyCatalog.FindBodyPrefab(bodyPrefabName);
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			SurvivorDef val2 = SurvivorCatalog.FindSurvivorDefFromBody(val);
			if ((Object)(object)val2 == (Object)null)
			{
				return false;
			}
			index = (SurvivorIndex)(int)val2.survivorIndex;
			return true;
		}

		public static float GetFastDist(Vector3 pos1, Vector3 pos2)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = pos1 - pos2;
			return ((Vector3)(ref val)).sqrMagnitude;
		}
	}
}
namespace PlayerBots.Custom
{
	internal class PlayerBotBaseAI : BaseAI
	{
		private PlayerBotBaseAI()
		{
			//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)
			base.scanState = new SerializableEntityStateType(typeof(Wander));
			base.fullVision = true;
			base.aimVectorDampTime = 0.01f;
			base.aimVectorMaxSpeed = 180f;
			base.enemyAttentionDuration = 5f;
			base.selectedSkilldriverName = "";
			base.neverRetaliateFriendlies = true;
		}

		public override void OnBodyDeath(CharacterBody characterBody)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Expected O, but got Unknown
			if (Object.op_Implicit((Object)(object)((BaseAI)this).body))
			{
				string baseToken = "PLAYER_DEATH_QUOTE_" + Random.Range(0, 37);
				PlayerDeathChatMessage val = new PlayerDeathChatMessage();
				((SubjectChatMessage)val).subjectAsCharacterBody = ((BaseAI)this).body;
				((SubjectChatMessage)val).baseToken = baseToken;
				((SubjectFormatChatMessage)val).paramTokens = new string[1] { ((Object)((BaseAI)this).master).name };
				Chat.SendBroadcastChat((ChatMessageBase)(object)val);
			}
		}
	}
	internal class PlayerBotController : MonoBehaviour
	{
		public CharacterMaster master;

		public CharacterBody body;

		public EntityStateMachine stateMachine;

		public BaseAI ai;

		public Interactor bodyInteractor;

		public FixedTimeStamp lastEquipmentUse;

		public Stage currentStage;

		private AISkillDriver customTargetSkillDriver;

		private StageCache stageCache;

		private InfiniteTowerRun infiniteTowerRun;

		private int infiniteTowerWave;

		private AiSkillHelper skillHelper;

		public void SetSkillHelper(AiSkillHelper skillHelper)
		{
			this.skillHelper = skillHelper;
			skillHelper.controller = this;
		}

		public void Awake()
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Expected O, but got Unknown
			master = ((Component)this).GetComponent<CharacterMaster>();
			ai = ((Component)this).GetComponent<BaseAI>();
			stateMachine = ((Component)this).GetComponent<EntityStateMachine>();
			if (Run.instance is InfiniteTowerRun)
			{
				infiniteTowerRun = (InfiniteTowerRun)Run.instance;
			}
			if (ai is PlayerBotBaseAI)
			{
				customTargetSkillDriver = ai.skillDrivers.First((AISkillDriver driver) => driver.customName.Equals("CustomTargetLeash"));
				body = master.GetBody();
				bodyInteractor = ((Component)master.GetBody()).GetComponent<Interactor>();
				stageCache = new StageCache();
			}
		}

		public bool CanInteract()
		{
			if ((Object)(object)customTargetSkillDriver != (Object)null)
			{
				return PlayerBotManager.BotsUseInteractables.Value;
			}
			return false;
		}

		public void FixedUpdate()
		{
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Expected O, but got Unknown
			if (!Object.op_Implicit((Object)(object)master.GetBody()) || master.IsDeadAndOutOfLivesServer())
			{
				return;
			}
			ai.localNavigator.SetFieldValue("walkFrustration", 0f);
			if ((Object)(object)body != (Object)(object)master.GetBody())
			{
				body = master.GetBody();
				bodyInteractor = ((Component)master.GetBody()).GetComponent<Interactor>();
				skillHelper.OnBodyChange();
			}
			if (stateMachine.state is Combat)
			{
				((object)(Combat)stateMachine.state).SetFieldValue("aiUpdateTimer", 0);
			}
			if (Object.op_Implicit((Object)(object)infiniteTowerRun))
			{
				InfiniteTowerRunLogic();
			}
			else if (CanInteract())
			{
				if ((Object)(object)Stage.instance != (Object)(object)currentStage || (Object)(object)currentStage == (Object)null)
				{
					currentStage = Stage.instance;
					try
					{
						stageCache.Update();
					}
					catch (Exception ex)
					{
						Debug.LogError((object)ex);
					}
				}
				ai.customTarget.gameObject = null;
				customTargetSkillDriver.minDistance = 0f;
				PickupItems();
				CheckInteractables();
				ForceCustomSkillDriver();
			}
			else if (PlayerBotManager.allRealPlayersDead && PlayerBotManager.ContinueAfterDeath.Value)
			{
				ai.customTarget.gameObject = null;
				customTargetSkillDriver.minDistance = 0f;
				CheckTeleporter();
				ForceCustomSkillDriver();
			}
			ProcessEquipment();
			skillHelper.OnFixedUpdate();
		}

		public void InfiniteTowerRunLogic()
		{
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			InfiniteTowerSafeWardController fieldValue = infiniteTowerRun.GetFieldValue<InfiniteTowerSafeWardController>("safeWardController");
			if (infiniteTowerWave != infiniteTowerRun.waveIndex)
			{
				infiniteTowerWave = infiniteTowerRun.waveIndex;
				if (PlayerBotManager.RespawnAfterWave.Value && master.IsDeadAndOutOfLivesServer())
				{
					if (Object.op_Implicit((Object)(object)fieldValue))
					{
						master.Respawn(((Component)fieldValue).transform.position, ((Component)fieldValue).transform.rotation, false);
					}
					else
					{
						master.Respawn(((Component)master).transform.position, ((Component)master).transform.rotation, false);
					}
				}
			}
			ai.customTarget.gameObject = null;
			customTargetSkillDriver.minDistance = 0f;
			if (Object.op_Implicit((Object)(object)fieldValue))
			{
				ai.customTarget.gameObject = ((Component)fieldValue).gameObject;
			}
		}

		public void PickupItems()
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Invalid comparison between Unknown and I4
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Invalid comparison between Unknown and I4
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Invalid comparison between Unknown and I4
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Invalid comparison between Unknown and I4
			if (!Object.op_Implicit((Object)(object)master.inventory))
			{
				return;
			}
			List<GenericPickupController> instancesList = InstanceTracker.GetInstancesList<GenericPickupController>();
			for (int i = 0; i < instancesList.Count; i++)
			{
				GenericPickupController val = instancesList[i];
				if (PickupCatalog.GetPickupDef(val.pickupIndex).coinValue != 0)
				{
					continue;
				}
				ItemDef itemDef = ItemCatalog.GetItemDef(PickupCatalog.GetPickupDef(val.pickupIndex).itemIndex);
				if (!((Object)(object)itemDef != (Object)null) || (int)itemDef.tier != 3)
				{
					EquipmentIndex equipmentIndex = PickupCatalog.GetPickupDef(val.pickupIndex).equipmentIndex;
					if (((int)equipmentIndex == -1 || (!EquipmentCatalog.GetEquipmentDef(equipmentIndex).isLunar && (int)master.inventory.currentEquipmentIndex == -1)) && (int)val.GetInteractability(bodyInteractor) == 2 && PlayerBotUtils.GetFastDist(((Component)master.GetBody()).transform.position, ((Component)val).gameObject.transform.position) <= 3600f)
					{
						ai.customTarget.gameObject = ((Component)val).gameObject;
						break;
					}
				}
			}
		}

		private void CheckInteractables()
		{
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Invalid comparison between Unknown and I4
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)currentStage == (Object)null || !((Behaviour)master).isActiveAndEnabled || (Object)(object)ai.customTarget.gameObject != (Object)null)
			{
				return;
			}
			GameObject val = null;
			float num = 0f;
			for (int num2 = stageCache.interactablesItem.Count - 1; num2 >= 0; num2--)
			{
				BotInteractable<PurchaseInteraction> botInteractable = stageCache.interactablesItem[num2];
				Interactability interactability = botInteractable.Value.GetInteractability(bodyInteractor);
				if ((int)interactability == 2)
				{
					if (master.money >= botInteractable.Value.cost)
					{
						float num3 = Vector3.Distance(((Component)master.GetBody()).transform.position, botInteractable.gameObject.transform.position);
						if (num3 <= bodyInteractor.maxInteractionDistance)
						{
							bodyInteractor.AttemptInteraction(botInteractable.gameObject);
						}
						if ((Object)(object)val == (Object)null || num3 < num)
						{
							val = botInteractable.gameObject;
							num = num3;
						}
					}
				}
				else if ((int)interactability == 0)
				{
					stageCache.interactablesItem.RemoveAt(num2);
				}
			}
			if (!CheckTeleporter() && Object.op_Implicit((Object)(object)val))
			{
				ai.customTarget.gameObject = val;
				ai.customTarget.Update();
			}
		}

		private bool CheckTeleporter()
		{
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)TeleporterInteraction.instance))
			{
				if (CanInteract() && stageCache.interactablesItem.Count > 0)
				{
					return false;
				}
				if (TeleporterInteraction.instance.isCharging)
				{
					ai.customTarget.gameObject = ((Component)TeleporterInteraction.instance).gameObject;
					customTargetSkillDriver.minDistance = TeleporterInteraction.instance.holdoutZoneController.currentRadius;
				}
				if (TeleporterInteraction.instance.isIdle || (TeleporterInteraction.instance.isCharged && PlayerBotManager.allRealPlayersDead))
				{
					if (Vector3.Distance(((Component)master.GetBody()).transform.position, ((Component)TeleporterInteraction.instance).gameObject.transform.position) <= bodyInteractor.maxInteractionDistance)
					{
						bodyInteractor.AttemptInteraction(((Component)TeleporterInteraction.instance).gameObject);
					}
					ai.customTarget.gameObject = ((Component)TeleporterInteraction.instance).gameObject;
					return true;
				}
			}
			return false;
		}

		private void ForceCustomSkillDriver()
		{
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)master.GetBody() != (Object)null && master.GetBody().outOfCombat && master.GetBody().outOfDanger && (Object)(object)ai.customTarget.gameObject != (Object)null && (Object)(object)ai.skillDriverEvaluation.dominantSkillDriver != (Object)(object)customTargetSkillDriver)
			{
				ai.skillDriverEvaluation = new SkillDriverEvaluation
				{
					dominantSkillDriver = customTargetSkillDriver,
					target = ai.customTarget,
					aimTarget = ai.customTarget,
					separationSqrMagnitude = float.PositiveInfinity
				};
			}
		}

		private bool HasBuff(BuffIndex buff)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			return master.GetBody().HasBuff(buff);
		}

		private void ProcessEquipment()
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Invalid comparison between Unknown and I4
			//IL_04b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b7: 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_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_020c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0212: Unknown result type (might be due to invalid IL or missing references)
			//IL_025e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0264: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_026b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0271: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02af: Unknown result type (might be due to invalid IL or missing references)
			//IL_0278: Unknown result type (might be due to invalid IL or missing references)
			//IL_027e: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_0324: Unknown result type (might be due to invalid IL or missing references)
			//IL_032a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0363: Unknown result type (might be due to invalid IL or missing references)
			//IL_0369: Unknown result type (might be due to invalid IL or missing references)
			//IL_0337: Unknown result type (might be due to invalid IL or missing references)
			//IL_03cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0349: Unknown result type (might be due to invalid IL or missing references)
			//IL_0423: Unknown result type (might be due to invalid IL or missing references)
			//IL_0429: Unknown result type (might be due to invalid IL or missing references)
			if ((int)master.inventory.currentEquipmentIndex == -1 || master.GetBody().equipmentSlot.stock == 0)
			{
				return;
			}
			try
			{
				EquipmentIndex currentEquipmentIndex = master.inventory.currentEquipmentIndex;
				if (currentEquipmentIndex == Equipment.CommandMissile.equipmentIndex || currentEquipmentIndex == Equipment.Lightning.equipmentIndex || currentEquipmentIndex == Equipment.DeathProjectile.equipmentIndex)
				{
					if (ai.currentEnemy != null && ai.currentEnemy.hasLoS)
					{
						FireEquipment();
					}
				}
				else if (currentEquipmentIndex == Equipment.BFG.equipmentIndex)
				{
					if (ai.currentEnemy != null && (Object)(object)ai.currentEnemy.characterBody != (Object)null && ai.currentEnemy.hasLoS && (ai.currentEnemy.characterBody.isBoss || (master.GetBody().equipmentSlot.stock > 1 && ai.currentEnemy.characterBody.isElite)))
					{
						FireEquipment();
					}
				}
				else if (currentEquipmentIndex == Equipment.CritOnUse.equipmentIndex)
				{
					if (ai.currentEnemy != null && ai.currentEnemy.hasLoS && !HasBuff(Buffs.FullCrit.buffIndex))
					{
						if (master.GetBody().crit >= 100f)
						{
							master.inventory.SetEquipmentIndex((EquipmentIndex)(-1));
						}
						else
						{
							FireEquipment();
						}
					}
				}
				else if (currentEquipmentIndex == Equipment.TeamWarCry.equipmentIndex)
				{
					if (ai.currentEnemy != null && ai.currentEnemy.hasLoS && !HasBuff(Buffs.TeamWarCry.buffIndex))
					{
						FireEquipment();
					}
				}
				else if (currentEquipmentIndex == Equipment.Blackhole.equipmentIndex)
				{
					if (ai.currentEnemy != null && ai.currentEnemy.hasLoS && ((FixedTimeStamp)(ref lastEquipmentUse)).timeSince >= 10f)
					{
						FireEquipment();
					}
				}
				else if (currentEquipmentIndex == Equipment.LifestealOnHit.equipmentIndex || currentEquipmentIndex == Equipment.PassiveHealing.equipmentIndex || currentEquipmentIndex == Equipment.Fruit.equipmentIndex)
				{
					if ((double)master.GetBody().healthComponent.combinedHealthFraction <= 0.5 && !HasBuff(Buffs.HealingDisabled.buffIndex))
					{
						FireEquipment();
					}
				}
				else if (currentEquipmentIndex == Equipment.GainArmor.equipmentIndex)
				{
					if ((double)master.GetBody().healthComponent.combinedHealthFraction <= 0.35 && master.GetBody().healthComponent.timeSinceLastHit <= 1f)
					{
						FireEquipment();
					}
				}
				else if (currentEquipmentIndex == Equipment.Cleanse.equipmentIndex)
				{
					if (HasBuff(Buffs.OnFire.buffIndex) || HasBuff(Buffs.HealingDisabled.buffIndex))
					{
						FireEquipment();
					}
				}
				else if (currentEquipmentIndex == Equipment.Molotov.equipmentIndex)
				{
					if (ai.currentEnemy != null && ai.currentEnemy.hasLoS && !ai.currentEnemy.characterBody.isFlying && ((FixedTimeStamp)(ref lastEquipmentUse)).timeSince >= 10f)
					{
						FireEquipment();
					}
				}
				else if (currentEquipmentIndex == Equipment.BossHunter.equipmentIndex)
				{
					if (ai.currentEnemy != null && ai.currentEnemy.hasLoS && ai.currentEnemy.characterBody.isBoss)
					{
						FireEquipment();
					}
				}
				else if (currentEquipmentIndex == Equipment.GummyClone.equipmentIndex)
				{
					if (ai.currentEnemy != null && ai.currentEnemy.hasLoS && (double)master.GetBody().healthComponent.combinedHealthFraction <= 0.9 && ((FixedTimeStamp)(ref lastEquipmentUse)).timeSince >= 5f)
					{
						FireEquipment();
					}
				}
				else
				{
					master.inventory.SetEquipmentIndex((EquipmentIndex)(-1));
				}
			}
			catch (Exception ex)
			{
				Debug.LogError((object)ex);
				EquipmentIndex currentEquipmentIndex2 = master.inventory.currentEquipmentIndex;
				Debug.Log((object)("Error when bot is using: " + ((object)(EquipmentIndex)(ref currentEquipmentIndex2)).ToString()));
				master.inventory.SetEquipmentIndex((EquipmentIndex)(-1));
			}
		}

		private void FireEquipment()
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			if (master.GetBody().equipmentSlot.ExecuteIfReady())
			{
				lastEquipmentUse = FixedTimeStamp.now;
			}
		}
	}
	internal class PlayerBotSpawnCard : CharacterSpawnCard
	{
		public GameObject bodyPrefab;

		public PlayerBotSpawnCard()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			((CharacterSpawnCard)this).loadout = new SerializableLoadout();
			base.runtimeLoadout = new Loadout();
		}

		protected override Action<CharacterMaster> GetPreSpawnSetupCallback()
		{
			return delegate(CharacterMaster master)
			{
				master.bodyPrefab = bodyPrefab;
			};
		}
	}
	internal class PlayerBotStateMachine : EntityStateMachine
	{
		private PlayerBotStateMachine()
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			base.customName = "AI";
			base.initialStateType = new SerializableEntityStateType(typeof(Wander));
			base.mainStateType = new SerializableEntityStateType(typeof(Wander));
		}
	}
	internal class StageCache
	{
		public List<BotInteractable<PurchaseInteraction>> interactablesItem;

		public StageCache()
		{
			interactablesItem = new List<BotInteractable<PurchaseInteraction>>();
		}

		public void Update()
		{
			interactablesItem.Clear();
			MultiShopController[] array = Object.FindObjectsOfType<MultiShopController>();
			for (int i = 0; i < array.Length; i++)
			{
				GameObject[] fieldValue = array[i].GetFieldValue<GameObject[]>("_terminalGameObjects");
				if (fieldValue != null)
				{
					GameObject[] array2 = fieldValue;
					foreach (GameObject val in array2)
					{
						interactablesItem.Add(new BotInteractable<PurchaseInteraction>(val.gameObject));
					}
				}
			}
			ChestBehavior[] array3 = Object.FindObjectsOfType<ChestBehavior>();
			foreach (ChestBehavior val2 in array3)
			{
				interactablesItem.Add(new BotInteractable<PurchaseInteraction>(((Component)val2).gameObject));
			}
		}
	}
	public class BotInteractable<T> where T : IInteractable
	{
		public GameObject gameObject;

		public T Value;

		public BotInteractable(GameObject gameObject)
		{
			this.gameObject = gameObject;
			Value = gameObject.GetComponent<T>();
		}

		public BotInteractable(GameObject gameObject, T interactable)
		{
			this.gameObject = gameObject;
			Value = interactable;
		}
	}
}
namespace PlayerBots.AI
{
	internal abstract class AiSkillHelper
	{
		public PlayerBotController controller { get; set; }

		public virtual void OnBodyChange()
		{
		}

		public virtual void OnFixedUpdate()
		{
		}

		public abstract void InjectSkills(GameObject gameObject, BaseAI ai);

		public void AddDefaultSkills(GameObject gameObject, BaseAI ai, float minDistanceFromEnemy)
		{
			//IL_0013: 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_0053: 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_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01da: Unknown result type (might be due to invalid IL or missing references)
			//IL_020d: Unknown result type (might be due to invalid IL or missing references)
			//IL_021b: Unknown result type (might be due to invalid IL or missing references)
			//IL_024d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0254: Unknown result type (might be due to invalid IL or missing references)
			AISkillDriver obj = gameObject.AddComponent<AISkillDriver>();
			obj.customName = "CustomTargetLeash";
			obj.skillSlot = (SkillSlot)(-1);
			obj.requireSkillReady = false;
			obj.moveTargetType = (TargetType)3;
			obj.minDistance = 0f;
			obj.maxDistance = float.PositiveInfinity;
			obj.selectionRequiresTargetLoS = false;
			obj.activationRequiresTargetLoS = false;
			obj.activationRequiresAimConfirmation = false;
			obj.movementType = (MovementType)1;
			obj.aimType = (AimType)1;
			obj.ignoreNodeGraph = false;
			obj.resetCurrentEnemyOnNextDriverSelection = true;
			obj.driverUpdateTimerOverride = 3f;
			obj.noRepeat = false;
			obj.shouldSprint = true;
			AISkillDriver obj2 = gameObject.AddComponent<AISkillDriver>();
			obj2.customName = "ReturnToOwnerLeash";
			obj2.skillSlot = (SkillSlot)(-1);
			obj2.requireSkillReady = false;
			obj2.moveTargetType = (TargetType)2;
			obj2.minDistance = 60f;
			obj2.maxDistance = float.PositiveInfinity;
			obj2.selectionRequiresTargetLoS = false;
			obj2.activationRequiresTargetLoS = false;
			obj2.activationRequiresAimConfirmation = false;
			obj2.movementType = (MovementType)1;
			obj2.aimType = (AimType)1;
			obj2.ignoreNodeGraph = false;
			obj2.resetCurrentEnemyOnNextDriverSelection = true;
			obj2.driverUpdateTimerOverride = 3f;
			obj2.noRepeat = false;
			obj2.shouldSprint = true;
			AISkillDriver obj3 = gameObject.AddComponent<AISkillDriver>();
			obj3.customName = "ChaseEnemy";
			obj3.skillSlot = (SkillSlot)(-1);
			obj3.requireSkillReady = false;
			obj3.moveTargetType = (TargetType)0;
			obj3.minDistance = minDistanceFromEnemy;
			obj3.maxDistance = float.PositiveInfinity;
			obj3.selectionRequiresTargetLoS = false;
			obj3.activationRequiresTargetLoS = false;
			obj3.activationRequiresAimConfirmation = false;
			obj3.movementType = (MovementType)1;
			obj3.aimType = (AimType)4;
			obj3.ignoreNodeGraph = false;
			obj3.resetCurrentEnemyOnNextDriverSelection = false;
			obj3.noRepeat = false;
			obj3.shouldSprint = true;
			AISkillDriver obj4 = gameObject.AddComponent<AISkillDriver>();
			obj4.customName = "ReturnToLeader";
			obj4.skillSlot = (SkillSlot)(-1);
			obj4.requireSkillReady = false;
			obj4.moveTargetType = (TargetType)2;
			obj4.minDistance = 15f;
			obj4.maxDistance = float.PositiveInfinity;
			obj4.selectionRequiresTargetLoS = false;
			obj4.activationRequiresTargetLoS = false;
			obj4.activationRequiresAimConfirmation = false;
			obj4.movementType = (MovementType)1;
			obj4.aimType = (AimType)1;
			obj4.ignoreNodeGraph = false;
			obj4.resetCurrentEnemyOnNextDriverSelection = false;
			obj4.noRepeat = false;
			obj4.shouldSprint = true;
			AISkillDriver obj5 = gameObject.AddComponent<AISkillDriver>();
			obj5.customName = "WaitNearLeader";
			obj5.skillSlot