Decompiled source of RoundWithBots v4.0.1

plugins/RoundsWithBots.dll

Decompiled 2 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using CardChoiceSpawnUniqueCardPatch.CustomCategories;
using HarmonyLib;
using InControl;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using ModdingUtils.AIMinion;
using ModdingUtils.AIMinion.Extensions;
using ModdingUtils.GameModes;
using ModdingUtils.Utils;
using Photon.Pun;
using PickPhaseImprovements;
using RWF;
using RWF.UI;
using RarityLib.Utils;
using RoundsWithBots.AI;
using RoundsWithBots.AI.Movement;
using RoundsWithBots.CardPickerAIs;
using RoundsWithBots.CardPickerAIs.Weighted;
using RoundsWithBots.CardPickerAIs.Weighted.CardsProcessesors;
using RoundsWithBots.Extensions;
using RoundsWithBots.Handlers;
using RoundsWithBots.Menu;
using RoundsWithBots.Mods.Compatibility;
using RoundsWithBots.Pacthes.Storage;
using RoundsWithBots.Patches;
using RoundsWithBots.Pathfinding.Core;
using RoundsWithBots.Pathfinding.Nodes;
using RoundsWithBots.Pathfinding.Nodes.Lines;
using RoundsWithBots.Pathfinding.Scanning;
using RoundsWithBots.UI;
using RoundsWithBots.Utils;
using RoundsWithBots.Utils.Debug;
using TMPro;
using UnboundLib;
using UnboundLib.Extensions;
using UnboundLib.GameModes;
using UnboundLib.Networking;
using UnboundLib.Utils;
using UnboundLib.Utils.UI;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.1", FrameworkDisplayName = ".NET Framework 4.7.1")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace RoundsWithBots
{
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInProcess("Rounds.exe")]
	[BepInPlugin("com.aalund13.rounds.roundswithbots", "Rounds With Bots", "4.0.1")]
	public class RoundsWithBots : BaseUnityPlugin
	{
		private const string ModId = "com.aalund13.rounds.roundswithbots";

		private const string ModName = "Rounds With Bots";

		public const string Version = "4.0.1";

		public const string ModInitials = "RWB";

		public AssetBundle Assets;

		internal static List<BaseUnityPlugin> Plugins { get; private set; }

		internal static RoundsWithBots Instance { get; private set; }

		internal static ManualLogSource ModLogger { get; private set; }

		private void Awake()
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			Instance = this;
			ModLogger = ((BaseUnityPlugin)this).Logger;
			Assets = AssetUtils.LoadAssetBundleFromResources("rwb_assets", typeof(RoundsWithBots).Assembly);
			((Component)this).gameObject.AddComponent<DebugVisualizer>();
			RWBMenu.BindConfigs("Rounds With Bots", ((BaseUnityPlugin)this).Config);
			new Harmony("com.aalund13.rounds.roundswithbots").PatchAll();
		}

		private void Start()
		{
			Plugins = (List<BaseUnityPlugin>)typeof(Chainloader).GetField("_plugins", BindingFlags.Static | BindingFlags.NonPublic).GetValue(null);
			RWBMenu.RegisterMenu("Rounds With Bots");
			Cards.instance.AddCardValidationFunction((Func<Player, CardInfo, bool>)((Player player, CardInfo card) => (!player.data.GetAdditionalData().IsBot || !card.blacklistedCategories.Contains(CustomCardCategories.instance.CardCategory("NotForBots"))) ? true : false));
			CardExclusiveUtils.ExcludeCardsFromBots(CardManager.GetCardInfoWithName("Remote"));
			((Component)this).gameObject.AddComponent<BotsManager>();
			((Component)this).gameObject.AddComponent<BotCardPickerHandler>();
			((Component)this).gameObject.AddComponent<BotStalemateHandler>();
			((Component)this).gameObject.AddComponent<MapScanner>();
		}
	}
}
namespace RoundsWithBots.Utils
{
	public class CardExclusiveUtils
	{
		public static CardCategory NotBotCategory = CustomCardCategories.instance.CardCategory("NotForBots");

		public static void ExcludeCardsFromBots(CardInfo card)
		{
			card.blacklistedCategories = CollectionExtensions.AddToArray<CardCategory>(card.blacklistedCategories, NotBotCategory);
		}
	}
	public class DaryHeap<T> where T : IHeapItem<T>
	{
		private const float GROWTH_FACTOR = 2f;

		private T[] items;

		private readonly int d;

		private int currentItemCount;

		public int Capacity => items.Length;

		public int Count => currentItemCount;

		public DaryHeap(int d, int initialCapacity = 4)
		{
			if (d < 2)
			{
				throw new ArgumentOutOfRangeException("d", "Arity must be at least 2");
			}
			this.d = d;
			items = new T[initialCapacity];
			currentItemCount = 0;
		}

		public void Clear()
		{
			for (int i = 0; i < currentItemCount; i++)
			{
				items[i].HeapIndex = -1;
				items[i] = default(T);
			}
			currentItemCount = 0;
		}

		public void Add(T item)
		{
			if (item == null)
			{
				throw new ArgumentNullException("item");
			}
			if (item.HeapIndex >= 0 && item.HeapIndex < currentItemCount && Contains(item))
			{
				UpdateItem(item);
				return;
			}
			EnsureCapacity();
			int heapIndex = currentItemCount;
			item.HeapIndex = heapIndex;
			items[currentItemCount] = item;
			SortUp(item);
			currentItemCount++;
		}

		public T RemoveFirst()
		{
			if (currentItemCount == 0)
			{
				throw new InvalidOperationException("Heap is empty");
			}
			T result = items[0];
			currentItemCount--;
			if (currentItemCount > 0)
			{
				items[0] = items[currentItemCount];
				items[0].HeapIndex = 0;
				SortDown(items[0]);
			}
			result.HeapIndex = -1;
			return result;
		}

		public void UpdateItem(T item)
		{
			SortUp(item);
			SortDown(item);
		}

		public bool Contains(T item)
		{
			int heapIndex = item.HeapIndex;
			if (heapIndex >= 0 && heapIndex < currentItemCount)
			{
				return (object)items[heapIndex] == (object)item;
			}
			return false;
		}

		private void EnsureCapacity()
		{
			if (currentItemCount >= items.Length)
			{
				int num = (int)((float)items.Length * 2f);
				if (num < 4)
				{
					num = 4;
				}
				Array.Resize(ref items, num);
			}
		}

		private void SortDown(T item)
		{
			int num = item.HeapIndex;
			while (true)
			{
				int num2 = d * num + 1;
				if (num2 >= currentItemCount)
				{
					break;
				}
				int num3 = num2;
				for (int i = 1; i < d; i++)
				{
					int num4 = num2 + i;
					if (num4 < currentItemCount && items[num4].CompareTo(items[num3]) < 0)
					{
						num3 = num4;
					}
				}
				ref readonly T reference = ref items[num3];
				T other = item;
				if (reference.CompareTo(other) < 0)
				{
					Swap(item, items[num3]);
					num = num3;
					continue;
				}
				break;
			}
		}

		private void SortUp(T item)
		{
			int num = item.HeapIndex;
			int num2 = (num - 1) / d;
			while (num > 0 && item.CompareTo(items[num2]) < 0)
			{
				Swap(item, items[num2]);
				num = num2;
				num2 = (num - 1) / d;
			}
		}

		private void Swap(T a, T b)
		{
			items[a.HeapIndex] = b;
			items[b.HeapIndex] = a;
			int heapIndex = a.HeapIndex;
			a.HeapIndex = b.HeapIndex;
			b.HeapIndex = heapIndex;
		}
	}
	public interface IHeapItem<T> : IComparable<T>
	{
		int HeapIndex { get; set; }
	}
	public static class EaseUtils
	{
		public enum EaseType
		{
			easeInSine,
			easeOutSine,
			easeInOutSine,
			easeInQuad,
			easeOutQuad,
			easeInOutQuad
		}

		public static float Ease(float time, float start, float end, float duration, EaseType easeType)
		{
			switch (easeType)
			{
			case EaseType.easeInSine:
				return 0f - Mathf.Cos(time / duration * ((float)Math.PI / 2f)) + 1f * (end - start) + start;
			case EaseType.easeOutSine:
				return Mathf.Sin(time / duration * ((float)Math.PI / 2f)) * (end - start) + start;
			case EaseType.easeInOutSine:
				return -0.5f * (Mathf.Cos((float)Math.PI * time / duration) - 1f) * (end - start) + start;
			case EaseType.easeInQuad:
				return (end - start) * (time /= duration) * time + start;
			case EaseType.easeOutQuad:
				return (0f - (end - start)) * (time /= duration) * (time - 2f) + start;
			case EaseType.easeInOutQuad:
				if (!((time /= duration / 2f) < 1f))
				{
					return (0f - (end - start)) / 2f * ((time -= 1f) * (time - 2f) - 1f) + start;
				}
				return (end - start) / 2f * time * time + start;
			default:
				return 0f;
			}
		}

		public static IEnumerator EaseCoroutine(float duration, EaseType easeType, Action<float> action, Action onComplete = null, float min = 0f, float max = 1f)
		{
			float time = 0f;
			while (time < duration)
			{
				action(Ease(time, min, max, duration, easeType));
				time += Time.deltaTime;
				yield return null;
			}
			action(Ease(duration, min, max, duration, easeType));
			onComplete?.Invoke();
		}
	}
	public static class MathUtils
	{
		public static float CalculatePointsStraightness(Vector2 pointOne, Vector2 pointTwo, Vector2 pointThree)
		{
			//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)
			//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_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: 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_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			Vector2 val = pointThree - pointOne;
			if (((Vector2)(ref val)).sqrMagnitude < Mathf.Epsilon)
			{
				return Vector2.Distance(pointTwo, pointOne);
			}
			return Mathf.Abs((pointTwo.x - pointOne.x) * val.y - (pointTwo.y - pointOne.y) * val.x) / ((Vector2)(ref val)).magnitude;
		}
	}
	public class MoveTransformSimulator
	{
		public Vector2 Start;

		public Vector2 Velocity;

		public Vector2 Position;

		public float Gravity;

		public float Drag;

		public float DragMinSpeed;

		public float Multiplier;

		public MoveTransformSimulator(Vector2 start, Vector2 velocity, float gravity, float drag, float dragMinSpeed, float multiplier)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0016: Unknown result type (might be due to invalid IL or missing references)
			Start = start;
			Position = start;
			Velocity = velocity;
			Gravity = gravity;
			Drag = drag;
			DragMinSpeed = dragMinSpeed;
			Multiplier = multiplier;
		}

		public void Step(float simulationStep)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: 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: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: 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_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			if (Gravity != 0f)
			{
				Velocity += Gravity * Vector2.down * simulationStep * Multiplier;
			}
			if (((Vector2)(ref Velocity)).magnitude > 2f && ((Vector2)(ref Velocity)).magnitude > DragMinSpeed)
			{
				Velocity -= Velocity * Mathf.Clamp(Drag * simulationStep * Mathf.Clamp(Multiplier, 0f, 1f), 0f, 1f);
			}
			Position += Velocity * simulationStep * Multiplier;
		}
	}
	public static class ProjectileAimUtils
	{
		public static bool TryGetAimDirection(Vector2 start, Vector2 target, float speed, float gravity, float drag, float dragMinSpeed, float multiplier, float maxTime, float simulationStep, out Vector2 direction)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: 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_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			direction = Vector2.zero;
			Vector2 val = target - start;
			if (((Vector2)(ref val)).sqrMagnitude < 0.0001f)
			{
				return false;
			}
			float num = Mathf.Atan2(val.y, val.x) * 57.29578f;
			float num2 = num;
			float num3 = float.PositiveInfinity;
			int num4 = Mathf.CeilToInt(maxTime / simulationStep);
			for (int i = 0; i < 180; i++)
			{
				float num5 = num + (float)((i % 2 == 0) ? (i / 2) : (-(i + 1) / 2));
				float num6 = num5 * ((float)Math.PI / 180f);
				Vector2 velocity = new Vector2(Mathf.Cos(num6), Mathf.Sin(num6)) * speed;
				MoveTransformSimulator moveTransformSimulator = new MoveTransformSimulator(start, velocity, gravity, drag, dragMinSpeed, multiplier);
				Vector2 position = moveTransformSimulator.Position;
				for (int j = 0; j < num4; j++)
				{
					moveTransformSimulator.Step(simulationStep);
					float num7 = DistanceToSegmentSquared(target, position, moveTransformSimulator.Position);
					if (num7 < num3)
					{
						num3 = num7;
						num2 = num5;
					}
					position = moveTransformSimulator.Position;
				}
				if (num3 < 0.25f)
				{
					break;
				}
			}
			if (num3 >= 0.25f)
			{
				return false;
			}
			float num8 = num2 * ((float)Math.PI / 180f);
			direction = new Vector2(Mathf.Cos(num8), Mathf.Sin(num8));
			return true;
		}

		private static float DistanceToSegmentSquared(Vector2 point, Vector2 segmentStart, Vector2 segmentEnd)
		{
			//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)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: 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_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: 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_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			Vector2 val = segmentEnd - segmentStart;
			float sqrMagnitude = ((Vector2)(ref val)).sqrMagnitude;
			Vector2 val2;
			if (sqrMagnitude < 1E-06f)
			{
				val2 = point - segmentStart;
				return ((Vector2)(ref val2)).sqrMagnitude;
			}
			float num = Vector2.Dot(point - segmentStart, val) / sqrMagnitude;
			num = Mathf.Clamp01(num);
			Vector2 val3 = segmentStart + val * num;
			val2 = point - val3;
			return ((Vector2)(ref val2)).sqrMagnitude;
		}
	}
}
namespace RoundsWithBots.Utils.Debug
{
	internal class DebugVisualizer : MonoBehaviour
	{
		[Flags]
		public enum VisualizerCategory
		{
			None = 0,
			MapScanner = 1,
			Bots = 2
		}

		private class DebugObject
		{
			public GameObject gameObject;

			public bool callLastFrame;
		}

		private static DebugVisualizer instance;

		private readonly Dictionary<string, DebugObject> debugSphereObjects = new Dictionary<string, DebugObject>();

		private readonly Dictionary<string, DebugObject> debugLineObjects = new Dictionary<string, DebugObject>();

		private readonly Dictionary<string, DebugObject> debugTextObjects = new Dictionary<string, DebugObject>();

		private Material debugSphereMaterial;

		private Material debugLineMaterial;

		public static VisualizerCategory EnableCategory => RWBMenu.GetEnableVisualizer();

		private void Awake()
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Expected O, but got Unknown
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Expected O, but got Unknown
			if ((Object)(object)instance != (Object)null)
			{
				Object.Destroy((Object)(object)this);
				return;
			}
			instance = this;
			debugSphereMaterial = new Material(Shader.Find("Unlit/Color"));
			debugLineMaterial = new Material(Shader.Find("Sprites/Default"));
		}

		private void LateUpdate()
		{
			RemoveNonCallObject(debugSphereObjects);
			RemoveNonCallObject(debugLineObjects);
			RemoveNonCallObject(debugTextObjects);
		}

		private List<string> RemoveNonCallObject(Dictionary<string, DebugObject> dictionary)
		{
			List<string> list = new List<string>();
			foreach (KeyValuePair<string, DebugObject> item in dictionary)
			{
				if (!item.Value.callLastFrame)
				{
					Object.Destroy((Object)(object)item.Value.gameObject);
					list.Add(item.Key);
				}
				else
				{
					item.Value.callLastFrame = false;
				}
			}
			foreach (string item2 in list)
			{
				dictionary.Remove(item2);
			}
			return list;
		}

		private GameObject InternalCreateDebugSphere(string name, Color color, Vector2 position, float size = 0.5f)
		{
			//IL_0081: 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_009b: 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_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: 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_004c: Unknown result type (might be due to invalid IL or missing references)
			if (debugSphereObjects.ContainsKey(name))
			{
				DebugObject debugObject = debugSphereObjects[name];
				debugObject.gameObject.GetComponent<Renderer>().material.color = color;
				debugObject.gameObject.transform.localPosition = new Vector3(position.x, position.y, -5f);
				debugObject.callLastFrame = true;
				return debugObject.gameObject;
			}
			GameObject val = GameObject.CreatePrimitive((PrimitiveType)0);
			Renderer component = val.GetComponent<Renderer>();
			component.material = debugSphereMaterial;
			component.material.color = color;
			((Object)val).name = name;
			val.transform.localScale = Vector3.one * size;
			val.transform.localPosition = new Vector3(position.x, position.y, -5f);
			DebugObject value = new DebugObject
			{
				gameObject = val,
				callLastFrame = true
			};
			debugSphereObjects.Add(name, value);
			return val;
		}

		private GameObject InternalCreateDebugLine(string name, Color color, Vector2 firstPoint, Vector2 secondPoint)
		{
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Expected O, but got Unknown
			//IL_00a9: 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_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_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: 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_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			if (debugLineObjects.ContainsKey(name))
			{
				DebugObject debugObject = debugLineObjects[name];
				LineRenderer component = debugObject.gameObject.GetComponent<LineRenderer>();
				component.SetPositions((Vector3[])(object)new Vector3[2]
				{
					new Vector3(firstPoint.x, firstPoint.y, -5f),
					new Vector3(secondPoint.x, secondPoint.y, -5f)
				});
				component.startColor = color;
				component.endColor = color;
				debugObject.callLastFrame = true;
				return debugObject.gameObject;
			}
			GameObject val = new GameObject(name);
			LineRenderer val2 = val.AddComponent<LineRenderer>();
			val2.SetPositions((Vector3[])(object)new Vector3[2]
			{
				new Vector3(firstPoint.x, firstPoint.y, -5f),
				new Vector3(secondPoint.x, secondPoint.y, -5f)
			});
			((Renderer)val2).material = debugLineMaterial;
			val2.startColor = color;
			val2.endColor = color;
			val2.startWidth = 0.25f;
			val2.endWidth = 0.25f;
			DebugObject value = new DebugObject
			{
				gameObject = val,
				callLastFrame = true
			};
			debugLineObjects.Add(name, value);
			return val;
		}

		private GameObject InternalCreateDebugText(string name, Vector2 position, Color color, string text)
		{
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Expected O, but got Unknown
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			if (debugTextObjects.TryGetValue(name, out var value))
			{
				TextMeshPro component = value.gameObject.GetComponent<TextMeshPro>();
				component.sortingOrder = 1000;
				((TMP_Text)component).text = text;
				((Graphic)component).color = color;
				value.gameObject.transform.position = new Vector3(position.x, position.y, -5f);
				value.callLastFrame = true;
				return value.gameObject;
			}
			GameObject val = new GameObject(name);
			TextMeshPro obj = val.AddComponent<TextMeshPro>();
			obj.sortingOrder = 1000;
			((TMP_Text)obj).text = text;
			((Graphic)obj).color = color;
			((TMP_Text)obj).fontSize = 6f;
			((TMP_Text)obj).alignment = (TextAlignmentOptions)513;
			((TMP_Text)obj).enableWordWrapping = false;
			val.transform.position = new Vector3(position.x, position.y, -5f);
			DebugObject value2 = new DebugObject
			{
				gameObject = val,
				callLastFrame = true
			};
			debugTextObjects.Add(name, value2);
			return val;
		}

		public static GameObject RenderDebugSphere(VisualizerCategory category, string name, Color color, Vector2 position, float size = 0.5f)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)instance == (Object)null || !EnableCategory.HasFlag(category))
			{
				return null;
			}
			return instance.InternalCreateDebugSphere(name, color, position, size);
		}

		public static GameObject RenderDebugLine(VisualizerCategory category, string name, Color color, Vector2 firstPoint, Vector2 secondPoint)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)instance == (Object)null || !EnableCategory.HasFlag(category))
			{
				return null;
			}
			return instance.InternalCreateDebugLine(name, color, firstPoint, secondPoint);
		}

		public static GameObject RenderDebugText(VisualizerCategory category, string name, Vector2 position, Color color, string text)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)instance == (Object)null || !EnableCategory.HasFlag(category))
			{
				return null;
			}
			return instance.InternalCreateDebugText(name, position, color, text);
		}
	}
	public static class LoggerUtils
	{
		private static void Loginternal(LogLevel level, string message, bool bypassCheck = false)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Invalid comparison between I4 and Unknown
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			if (32 > (int)level || RWBMenu.EnableDebugLogging.Value || bypassCheck)
			{
				string name = new StackFrame(2).GetMethod().DeclaringType.Name;
				RoundsWithBots.ModLogger.Log(level, (object)("[" + name + "] " + message));
			}
		}

		public static void Log(LogLevel level, string message, bool bypassCheck = false)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			Loginternal(level, message, bypassCheck);
		}

		public static void LogInfo(string message, bool bypassCheck = false)
		{
			Loginternal((LogLevel)16, message, bypassCheck);
		}

		public static void LogWarn(string message)
		{
			Loginternal((LogLevel)4, message, bypassCheck: true);
		}

		public static void LogError(string message)
		{
			Loginternal((LogLevel)2, message, bypassCheck: true);
		}
	}
	public static class Profiler
	{
		private class ProfilerSection
		{
			public string Name;

			public Stopwatch Stopwatch;

			public List<ProfilerSection> Children;

			public ProfilerSection(string name)
			{
				Name = name;
				Stopwatch = Stopwatch.StartNew();
				Children = new List<ProfilerSection>();
			}
		}

		private static readonly Stack<ProfilerSection> sectionStack = new Stack<ProfilerSection>();

		private static readonly List<ProfilerSection> rootSections = new List<ProfilerSection>();

		public static void Start(string name)
		{
			if (RWBMenu.EnableProfiler.Value)
			{
				ProfilerSection item = new ProfilerSection(name);
				if (sectionStack.Count > 0)
				{
					sectionStack.Peek().Children.Add(item);
				}
				else
				{
					rootSections.Add(item);
				}
				sectionStack.Push(item);
			}
		}

		public static void End(string name)
		{
			if (!RWBMenu.EnableProfiler.Value)
			{
				return;
			}
			if (sectionStack.Count == 0)
			{
				LoggerUtils.Log((LogLevel)4, "Profiler.End(\"" + name + "\") called without a matching Start().");
				return;
			}
			ProfilerSection profilerSection = sectionStack.Pop();
			if (profilerSection.Name != name)
			{
				LoggerUtils.Log((LogLevel)4, "Profiler section mismatch. Expected End(\"" + profilerSection.Name + "\"), got End(\"" + name + "\").");
			}
			profilerSection.Stopwatch.Stop();
		}

		public static void Log()
		{
			if (!RWBMenu.EnableProfiler.Value)
			{
				return;
			}
			foreach (ProfilerSection rootSection in rootSections)
			{
				LogSection(rootSection, 0);
			}
			rootSections.Clear();
		}

		private static void LogSection(ProfilerSection section, int depth)
		{
			string text = new string(' ', depth * 2);
			LoggerUtils.Log((LogLevel)32, text + section.Name + ": " + $"{section.Stopwatch.Elapsed.TotalMilliseconds:F2} ms");
			foreach (ProfilerSection child in section.Children)
			{
				LogSection(child, depth + 1);
			}
		}
	}
}
namespace RoundsWithBots.UI
{
	internal class BotMenuUIHandler : MonoBehaviour
	{
		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static UnityAction <>9__13_0;

			internal void <Start>b__13_0()
			{
				UnityEvent onPlayerTeamChange = OnPlayerTeamChange;
				if (onPlayerTeamChange != null)
				{
					onPlayerTeamChange.Invoke();
				}
			}
		}

		public static GameObject Prefab;

		public static BotMenuUIHandler CurrentActiveInstance;

		public static UnityEvent OnPlayerTeamChange;

		[Header("References")]
		public GameObject MenuObject;

		public List<Graphic> TeamColorGraphics = new List<Graphic>();

		[HideInInspector]
		public UnityEvent OnTeamChange = new UnityEvent();

		[HideInInspector]
		public UnityEvent OnFaceChange = new UnityEvent();

		private bool isOpened;

		[HideInInspector]
		public CharacterSelectionInstance CharacterSelectionInstance { get; private set; }

		internal static BotMenuUIHandler CreateInstance(CharacterSelectionInstance characterSelection)
		{
			BotMenuUIHandler component = Object.Instantiate<GameObject>(Prefab).GetComponent<BotMenuUIHandler>();
			component.CharacterSelectionInstance = characterSelection;
			component.MenuObject.SetActive(false);
			return component;
		}

		private void Start()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			//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_0042: Expected O, but got Unknown
			SetTeamColors();
			OnTeamChange.AddListener(new UnityAction(SetTeamColors));
			UnityEvent onTeamChange = OnTeamChange;
			object obj = <>c.<>9__13_0;
			if (obj == null)
			{
				UnityAction val = delegate
				{
					UnityEvent onPlayerTeamChange2 = OnPlayerTeamChange;
					if (onPlayerTeamChange2 != null)
					{
						onPlayerTeamChange2.Invoke();
					}
				};
				<>c.<>9__13_0 = val;
				obj = (object)val;
			}
			onTeamChange.AddListener((UnityAction)obj);
			UnityEvent onPlayerTeamChange = OnPlayerTeamChange;
			if (onPlayerTeamChange != null)
			{
				onPlayerTeamChange.Invoke();
			}
		}

		private void Update()
		{
			//IL_004b: 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_0051: 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_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			if (((Object)(object)CharacterSelectionInstance == (Object)null || (Object)(object)CharacterSelectionInstance.currentPlayer == (Object)null) && isOpened)
			{
				HideMenu();
			}
			if ((Object)(object)CharacterSelectionInstance != (Object)null)
			{
				Vector3 localScale = ((Component)CharacterSelectionInstance).transform.localScale;
				float num = ((localScale.x == 0f) ? 1f : (1f / localScale.x));
				float num2 = ((localScale.y == 0f) ? 1f : (1f / localScale.y));
				float num3 = ((localScale.z == 0f) ? 1f : (1f / localScale.z));
				((Transform)((Component)this).GetComponent<RectTransform>()).localScale = new Vector3(num, num2, num3);
			}
		}

		public void OpenMenu()
		{
			if ((Object)(object)CurrentActiveInstance != (Object)null && (Object)(object)CurrentActiveInstance != (Object)(object)this)
			{
				CurrentActiveInstance.HideMenu();
			}
			CurrentActiveInstance = this;
			isOpened = true;
			MenuObject.SetActive(true);
		}

		public void HideMenu()
		{
			if (isOpened)
			{
				isOpened = false;
				if ((Object)(object)CurrentActiveInstance == (Object)(object)this)
				{
					CurrentActiveInstance = null;
				}
				MenuObject.SetActive(false);
			}
		}

		public void Refresh()
		{
			UnityEvent onFaceChange = OnFaceChange;
			if (onFaceChange != null)
			{
				onFaceChange.Invoke();
			}
			UnityEvent onTeamChange = OnTeamChange;
			if (onTeamChange != null)
			{
				onTeamChange.Invoke();
			}
		}

		public void RemovePlayer()
		{
			PlayerManager.instance.RemovePlayer(CharacterSelectionInstance.currentPlayer);
			UnityEvent onPlayerTeamChange = OnPlayerTeamChange;
			if (onPlayerTeamChange != null)
			{
				onPlayerTeamChange.Invoke();
			}
			HideMenu();
		}

		private void SetTeamColors()
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			foreach (Graphic teamColorGraphic in TeamColorGraphics)
			{
				PlayerSkin playerSkinColors = PlayerSkinBank.GetPlayerSkinColors(PlayerExtensions.GetAdditionalData(CharacterSelectionInstance.currentPlayer).colorID);
				teamColorGraphic.color = playerSkinColors.color;
			}
		}

		static BotMenuUIHandler()
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected O, but got Unknown
			RoundsWithBots instance = RoundsWithBots.Instance;
			object prefab;
			if (instance == null)
			{
				prefab = null;
			}
			else
			{
				AssetBundle assets = instance.Assets;
				prefab = ((assets != null) ? assets.LoadAsset<GameObject>("Bot Menu") : null);
			}
			Prefab = (GameObject)prefab;
			OnPlayerTeamChange = new UnityEvent();
		}
	}
	internal class FaceUIButton : MonoBehaviour
	{
		[Header("References")]
		[SerializeField]
		private BotMenuUIHandler BotMenuUIHandler;

		[SerializeField]
		private CharacterCreatorItemEquipper CharacterCreatorItemEquipper;

		[SerializeField]
		private Graphic ColorGraphic;

		[SerializeField]
		private Graphic SelectionGraphic;

		[SerializeField]
		private Button ChangeFaceButton;

		[Header("Selection Colors")]
		public Color SelectionColor = Color.white * 0.8f;

		public Color DeselectionColor = Color.white * 0.2f;

		[Header("Color Id")]
		public int FaceId;

		private void Start()
		{
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Expected O, but got Unknown
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Expected O, but got Unknown
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Expected O, but got Unknown
			CharacterCreatorItemEquipper component = (from x in ((Component)((Component)BotMenuUIHandler.CharacterSelectionInstance).transform.GetChild(0).GetChild(0)).GetComponentsInChildren<HoverEvent>(true)
				select ((Component)x).gameObject).ToArray()[0].GetComponent<CharacterCreatorItemEquipper>();
			CharacterCreatorItemEquipper.defaultEyes = component.defaultEyes;
			CharacterCreatorItemEquipper.defaultMouth = component.defaultMouth;
			CharacterCreatorItemEquipper.EquipFace(CharacterCreatorHandler.instance.GetFacePreset(FaceId));
			SetSelectionColor();
			SetFaceColor();
			BotMenuUIHandler.OnFaceChange.AddListener(new UnityAction(SetSelectionColor));
			BotMenuUIHandler.OnTeamChange.AddListener(new UnityAction(SetFaceColor));
			((UnityEvent)ChangeFaceButton.onClick).AddListener(new UnityAction(ChangeFace));
		}

		private void SetSelectionColor()
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			if (BotMenuUIHandler.CharacterSelectionInstance.currentlySelectedFace == FaceId)
			{
				SelectionGraphic.color = SelectionColor;
			}
			else
			{
				SelectionGraphic.color = DeselectionColor;
			}
		}

		private void SetFaceColor()
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			PlayerSkin playerSkinColors = PlayerSkinBank.GetPlayerSkinColors(PlayerExtensions.GetAdditionalData(BotMenuUIHandler.CharacterSelectionInstance.currentPlayer).colorID);
			ColorGraphic.color = playerSkinColors.color;
		}

		private void ChangeFace()
		{
			BotMenuUIHandler.CharacterSelectionInstance.currentlySelectedFace = FaceId;
			UnityEvent onFaceChange = BotMenuUIHandler.OnFaceChange;
			if (onFaceChange != null)
			{
				onFaceChange.Invoke();
			}
		}
	}
	public class TeamUIButton : MonoBehaviour
	{
		[Header("References")]
		[SerializeField]
		private BotMenuUIHandler BotMenuUIHandler;

		[SerializeField]
		private Graphic ColorGraphic;

		[SerializeField]
		private Graphic SelectionGraphic;

		[SerializeField]
		private Button ChangeTeamButton;

		[Header("Selection Colors")]
		public Color SelectionColor = Color.white * 0.8f;

		public Color DeselectionColor = Color.white * 0.2f;

		[Header("Colors")]
		public int ColorId;

		public float LockedColorMult = 0.6f;

		private void Start()
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Expected O, but got Unknown
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Expected O, but got Unknown
			SetSelectionColor();
			SetTeamColor();
			BotMenuUIHandler.OnTeamChange.AddListener(new UnityAction(SetSelectionColor));
			((UnityEvent)ChangeTeamButton.onClick).AddListener(new UnityAction(ChangeTeam));
			BotMenuUIHandler.OnPlayerTeamChange.AddListener(new UnityAction(SetTeamColor));
		}

		private void OnDestroy()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			BotMenuUIHandler.OnPlayerTeamChange.RemoveListener(new UnityAction(SetTeamColor));
		}

		private void SetSelectionColor()
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			if (PlayerExtensions.GetAdditionalData(BotMenuUIHandler.CharacterSelectionInstance.currentPlayer).colorID == ColorId)
			{
				SelectionGraphic.color = SelectionColor;
			}
			else
			{
				SelectionGraphic.color = DeselectionColor;
			}
		}

		private void ChangeTeam()
		{
			PlayerExtensions.AssignColorID(BotMenuUIHandler.CharacterSelectionInstance.currentPlayer, ColorId);
			BotMenuUIHandler.CharacterSelectionInstance.currentPlayer.SetColors();
			CharacterSelectionInstancePatch.RequestColorChange[BotMenuUIHandler.CharacterSelectionInstance] = true;
			UnityEvent onTeamChange = BotMenuUIHandler.OnTeamChange;
			if (onTeamChange != null)
			{
				onTeamChange.Invoke();
			}
		}

		private void SetTeamColor()
		{
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			PlayerSkin playerSkinColors = PlayerSkinBank.GetPlayerSkinColors(ColorId);
			if (PlayerManager.instance.players.Where((Player p) => (Object)(object)p != (Object)null && (Object)(object)p != (Object)(object)BotMenuUIHandler.CharacterSelectionInstance.currentPlayer).ToArray().Any((Player p) => PlayerExtensions.colorID(p) == ColorId) && !GameModeManager.CurrentHandler.AllowTeams)
			{
				ColorGraphic.color = playerSkinColors.color * LockedColorMult;
				((Selectable)ChangeTeamButton).interactable = false;
			}
			else
			{
				ColorGraphic.color = playerSkinColors.color;
				((Selectable)ChangeTeamButton).interactable = true;
			}
		}
	}
}
namespace RoundsWithBots.Pathfinding.Scanning
{
	public sealed class LineScanner
	{
		private const float MIN_DISTANCE_BETWEEN_NODES = 1f;

		private const float AIR_NODES_RANGE = 15f;

		public LineScanner PreviousLineScanner;

		public LineScanner NextLineScanner;

		public NodeLine NodeLine;

		public PathLine PathLine;

		public readonly float x;

		public readonly int LineIndex;

		private readonly float metherPerLine;

		private Vector2 verticalLine;

		private Vector2 bound;

		private int mask;

		public LineScanner(float x, int LineIndex, float metherPerLine, Vector2 verticalLine, Vector2 bound, int mask)
		{
			//IL_001c: 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_0026: Unknown result type (might be due to invalid IL or missing references)
			this.x = x;
			this.LineIndex = LineIndex;
			this.metherPerLine = metherPerLine;
			this.verticalLine = verticalLine;
			this.bound = bound;
			this.mask = mask;
		}

		public void InitializeNeighborScanners(LineScanner previousLineScanner, LineScanner nextLineScanner)
		{
			if (previousLineScanner != null)
			{
				PreviousLineScanner = previousLineScanner;
			}
			if (nextLineScanner != null)
			{
				NextLineScanner = nextLineScanner;
			}
		}

		public void BuildNodeLine()
		{
			//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_0049: 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)
			new List<Node>();
			new List<Node>();
			Vector2 val = default(Vector2);
			((Vector2)(ref val))..ctor(x, verticalLine.x);
			Vector2 val2 = default(Vector2);
			((Vector2)(ref val2))..ctor(x, verticalLine.y);
			RaycastHit2D[] first = Physics2D.LinecastAll(val, val2, mask);
			RaycastHit2D[] second = Physics2D.LinecastAll(val2, val, mask);
			RaycastHit2D[] hits = (from r in first.Concat(second)
				orderby ((RaycastHit2D)(ref r)).point.y descending
				select r).ToArray();
			List<Node> nodes = ProcessCollisions(hits);
			NodeLine = new NodeLine(x, verticalLine.x, verticalLine.y, nodes);
			PathLine = new PathLine(NodeLine);
		}

		public void BuildNodeEdge()
		{
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01de: Unknown result type (might be due to invalid IL or missing references)
			if (PreviousLineScanner != null)
			{
				foreach (Node node in PreviousLineScanner.NodeLine.Nodes)
				{
					if (node.Vaild && !(node is EdgeNode))
					{
						Node nodeAboveY = NodeLine.GetNodeAboveY(node.Position.y);
						if (!NodeLine.Nodes.Exists((Node n) => !(n is EdgeNode) && Mathf.Abs(n.Position.y - node.Position.y) < 1f) && (!(node is CeilingNode) || nodeAboveY is EdgeNode))
						{
							EdgeNode node2 = new EdgeNode(LineIndex, new Vector2(x, node.Position.y), EdgeNode.Direction.Right, node is CeilingNode);
							NodeLine.AddNode(node2);
						}
					}
				}
			}
			if (NextLineScanner == null)
			{
				return;
			}
			foreach (Node node3 in NextLineScanner.NodeLine.Nodes)
			{
				if (node3.Vaild && !(node3 is EdgeNode))
				{
					Node nodeAboveY2 = NodeLine.GetNodeAboveY(node3.Position.y);
					if (!NodeLine.Nodes.Exists((Node n) => !(n is EdgeNode) && Mathf.Abs(n.Position.y - node3.Position.y) < 1f) && (!(node3 is CeilingNode) || nodeAboveY2 is EdgeNode))
					{
						Node node4 = new EdgeNode(LineIndex, new Vector2(x, node3.Position.y), EdgeNode.Direction.Left, node3 is CeilingNode);
						NodeLine.AddNode(node4);
					}
				}
			}
		}

		public void BuildAirNodes()
		{
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			foreach (Node node in NodeLine.Nodes)
			{
				if (!node.Vaild || !(node is EdgeNode { EdgeDirection: var edgeDirection }))
				{
					continue;
				}
				LineScanner lineScanner = ((edgeDirection == EdgeNode.Direction.Left) ? PreviousLineScanner : NextLineScanner);
				Dictionary<LineScanner, List<AirNode>> dictionary = new Dictionary<LineScanner, List<AirNode>>();
				int num = Mathf.CeilToInt(15f / metherPerLine);
				bool flag = false;
				bool isEdgeAirNode = false;
				while (lineScanner != null)
				{
					Node nodeAtY = lineScanner.NodeLine.GetNodeAtY(node.Position.y);
					if (nodeAtY != null && (nodeAtY is EdgeNode || nodeAtY is AirNode))
					{
						break;
					}
					AirNode item = new AirNode(lineScanner.LineIndex, new Vector2(lineScanner.x, node.Position.y), isEdgeAirNode);
					if (!dictionary.ContainsKey(lineScanner))
					{
						dictionary.Add(lineScanner, new List<AirNode>());
					}
					dictionary[lineScanner].Add(item);
					lineScanner = ((edgeDirection == EdgeNode.Direction.Left) ? lineScanner.PreviousLineScanner : lineScanner.NextLineScanner);
					if (lineScanner == null)
					{
						break;
					}
					Node nodeAboveY = lineScanner.NodeLine.GetNodeAboveY(node.Position.y, typeof(AirNode));
					Node nodeBelowY = lineScanner.NodeLine.GetNodeBelowY(node.Position.y, typeof(AirNode));
					if (flag || num == 0 || (nodeAboveY is GroundNode && nodeBelowY is CeilingNode))
					{
						break;
					}
					if (nodeAboveY is EdgeNode edgeNode2 && edgeNode2.EdgeDirection != edgeDirection)
					{
						isEdgeAirNode = true;
						flag = true;
					}
					else if (nodeBelowY is EdgeNode edgeNode3 && edgeNode3.EdgeDirection != edgeDirection)
					{
						isEdgeAirNode = true;
						flag = true;
					}
					num--;
				}
				if (lineScanner == null || num == 0)
				{
					break;
				}
				foreach (KeyValuePair<LineScanner, List<AirNode>> item2 in dictionary)
				{
					foreach (AirNode item3 in item2.Value)
					{
						item2.Key.NodeLine.AddNode(item3);
					}
				}
			}
		}

		public void BuildPathLine()
		{
			List<PathNode> list = new List<PathNode>();
			List<Node> vaildNodes = NodeLine.VaildNodes;
			PathLine pathLine = PreviousLineScanner?.PathLine;
			for (int num = vaildNodes.Count - 1; num >= 0; num--)
			{
				Node node = vaildNodes[num];
				PathNode nodeBelowY = PathLine.GetNodeBelowY(node.Position.y);
				if (node is GroundNode)
				{
					PathNode pathNode = new PathNode(node);
					PathLine.AddNode(pathNode);
					PathNode pathNode2 = pathLine?.GetNodeAtY(node.Position.y, 1f, typeof(GroundNode), typeof(EdgeNode));
					if (pathNode2 != null)
					{
						pathNode.ConnectNode(pathNode2);
					}
					list.Add(pathNode);
				}
				else if (node is EdgeNode)
				{
					PathNode pathNode3 = new PathNode(node);
					PathLine.AddNode(pathNode3);
					PathNode pathNode4 = pathLine?.GetNodeAtY(node.Position.y, 1f, typeof(GroundNode), typeof(AirNode));
					if (pathNode4 != null)
					{
						pathNode3.ConnectNode(pathNode4);
					}
					if (nodeBelowY?.Node is GroundNode || nodeBelowY?.Node is EdgeNode)
					{
						pathNode3.ConnectNode(nodeBelowY);
					}
					list.Add(pathNode3);
				}
				else if (node is AirNode airNode)
				{
					PathNode pathNode5 = new PathNode(node);
					PathLine.AddNode(pathNode5);
					PathNode pathNode6 = pathLine?.GetNodeAtY(node.Position.y, 1f, typeof(AirNode), typeof(EdgeNode));
					if (pathNode6 != null)
					{
						pathNode5.ConnectNode(pathNode6);
					}
					if (nodeBelowY?.Node is EdgeNode || nodeBelowY?.Node is AirNode || (nodeBelowY?.Node is GroundNode && airNode.IsEdgeAirNode))
					{
						pathNode5.ConnectNode(nodeBelowY);
					}
					list.Add(pathNode5);
				}
			}
		}

		private List<Node> ProcessCollisions(RaycastHit2D[] hits)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			List<Node> list = new List<Node>();
			bool flag = false;
			bool flag2 = true;
			HashSet<Collider2D> hashSet = new HashSet<Collider2D>();
			for (int i = 0; i < hits.Length; i++)
			{
				RaycastHit2D val = hits[i];
				Vector2 point = ((RaycastHit2D)(ref val)).point;
				bool flag3 = ((RaycastHit2D)(ref val)).normal.y > 0f;
				float spaceAbove = float.MaxValue;
				int instanceID = ((Object)((RaycastHit2D)(ref val)).collider).GetInstanceID();
				bool flag4 = true;
				if (flag3)
				{
					if (hashSet.Count > 0)
					{
						flag4 = false;
					}
					hashSet.Add(((RaycastHit2D)(ref val)).collider);
				}
				else
				{
					if (hashSet.Count != 1)
					{
						flag4 = false;
					}
					hashSet.Remove(((RaycastHit2D)(ref val)).collider);
				}
				if (point.y >= bound.x || point.y <= bound.y)
				{
					flag4 = false;
				}
				else if (!flag2 && flag3 == flag)
				{
					flag4 = false;
				}
				if (list.Count > 0)
				{
					spaceAbove = Mathf.Abs(list[list.Count - 1].Position.y - point.y);
				}
				Node item = (flag3 ? ((Node)new GroundNode(instanceID, LineIndex, flag4, point, spaceAbove)) : ((Node)new CeilingNode(instanceID, LineIndex, flag4, point)));
				list.Add(item);
				if (flag4)
				{
					flag = flag3;
					flag2 = false;
				}
			}
			return list;
		}
	}
	public sealed class MapScanner : MonoBehaviour
	{
		public class ClosestNodeResult
		{
			public PathNode Node;

			public float DistanceSquared = float.MaxValue;
		}

		public int layerMask = LayerMask.GetMask(new string[2] { "Default", "IgnorePlayer" });

		public float ScanlineSpacing = 0.95f;

		public float MapWidthZeroScale = 3.556f;

		public float MapHeightZeroScale = 2f;

		public float RayYOffsetMultiplier = 1.5f;

		private float actualScanlineSpacing;

		public static MapScanner Instance { get; private set; }

		public static float MapSize
		{
			get
			{
				MapManager instance = MapManager.instance;
				float? obj;
				if (instance == null)
				{
					obj = null;
				}
				else
				{
					MapWrapper currentMap = instance.currentMap;
					obj = ((currentMap == null) ? ((float?)null) : currentMap.Map?.size);
				}
				return obj ?? 20f;
			}
		}

		public LineScanner[] LineScanners { get; private set; }

		private void Awake()
		{
			if ((Object)(object)Instance != (Object)null && (Object)(object)Instance != (Object)(object)this)
			{
				Object.Destroy((Object)(object)this);
			}
			else
			{
				Instance = this;
			}
		}

		private void FixedUpdate()
		{
			ScanMap();
		}

		private void Update()
		{
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0219: Unknown result type (might be due to invalid IL or missing references)
			//IL_022a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0239: Unknown result type (might be due to invalid IL or missing references)
			//IL_0245: Unknown result type (might be due to invalid IL or missing references)
			//IL_0251: Unknown result type (might be due to invalid IL or missing references)
			if (!DebugVisualizer.EnableCategory.HasFlag(DebugVisualizer.VisualizerCategory.MapScanner))
			{
				return;
			}
			List<PathNode> list = new List<PathNode>();
			LineScanner[] lineScanners = LineScanners;
			foreach (LineScanner lineScanner in lineScanners)
			{
				if (lineScanner == null || lineScanner.NodeLine == null)
				{
					continue;
				}
				foreach (Node node in lineScanner.NodeLine.Nodes)
				{
					if (node.Vaild)
					{
						if (node is GroundNode)
						{
							DebugVisualizer.RenderDebugSphere(DebugVisualizer.VisualizerCategory.MapScanner, $"Node [Ground] | x: {node.Position.x} y: {node.Position.y}", Color.green, node.Position, 0.25f);
						}
						else if (node is CeilingNode)
						{
							DebugVisualizer.RenderDebugSphere(DebugVisualizer.VisualizerCategory.MapScanner, $"Node [Ceiling] | x: {node.Position.x} y: {node.Position.y}", Color.red, node.Position, 0.25f);
						}
						else if (node is EdgeNode)
						{
							DebugVisualizer.RenderDebugSphere(DebugVisualizer.VisualizerCategory.MapScanner, $"Node [Edge] | x: {node.Position.x} y: {node.Position.y}", Color.cyan, node.Position, 0.25f);
						}
						else if (node is AirNode)
						{
							DebugVisualizer.RenderDebugSphere(DebugVisualizer.VisualizerCategory.MapScanner, $"Node [Air] | x: {node.Position.x} y: {node.Position.y}", Color.yellow, node.Position, 0.25f);
						}
					}
				}
				foreach (PathNode path in lineScanner.PathLine.Paths)
				{
					foreach (PathNode connetedNode in path.ConnetedNodes)
					{
						if (!list.Contains(connetedNode))
						{
							DebugVisualizer.RenderDebugLine(DebugVisualizer.VisualizerCategory.MapScanner, $"Path from: {path.Node.Position} to {connetedNode.Node.Position}", Color.black, path.Node.Position, connetedNode.Node.Position);
						}
					}
					list.Add(path);
				}
			}
		}

		public void ScanMap()
		{
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			Profiler.Start("Map Scanning");
			float num = MapWidthZeroScale * MapSize;
			int num2 = Mathf.CeilToInt(num / ScanlineSpacing);
			actualScanlineSpacing = num / (float)(num2 - 1);
			LineScanners = new LineScanner[num2];
			Profiler.Start("Create LineScanners");
			for (int i = 0; i < LineScanners.Length; i++)
			{
				float x = (0f - MapSize) * MapWidthZeroScale / 2f + (float)i * actualScanlineSpacing;
				float num3 = MapSize * MapHeightZeroScale / 2f;
				LineScanners[i] = new LineScanner(x, i, actualScanlineSpacing, new Vector2(num3 * RayYOffsetMultiplier, 0f - num3), new Vector2(num3, 0f - num3), layerMask);
			}
			Profiler.End("Create LineScanners");
			Profiler.Start("Initialize Neighbors");
			for (int j = 0; j < LineScanners.Length; j++)
			{
				LineScanner previousLineScanner = ((j > 0) ? LineScanners[j - 1] : null);
				LineScanner nextLineScanner = ((j < LineScanners.Length - 1) ? LineScanners[j + 1] : null);
				LineScanners[j].InitializeNeighborScanners(previousLineScanner, nextLineScanner);
			}
			Profiler.End("Initialize Neighbors");
			Profiler.Start("Building");
			Profiler.Start("Build Node Lines");
			LineScanner[] lineScanners = LineScanners;
			for (int k = 0; k < lineScanners.Length; k++)
			{
				lineScanners[k].BuildNodeLine();
			}
			Profiler.End("Build Node Lines");
			Profiler.Start("Build Edge Nodes");
			lineScanners = LineScanners;
			for (int k = 0; k < lineScanners.Length; k++)
			{
				lineScanners[k].BuildNodeEdge();
			}
			Profiler.End("Build Edge Nodes");
			Profiler.Start("Build Air Nodes");
			int num4 = LineScanners.Length;
			int num5 = num4 / 2;
			for (int l = 0; l < num5; l++)
			{
				LineScanners[l].BuildAirNodes();
			}
			for (int num6 = num4 - 1; num6 >= num5; num6--)
			{
				LineScanners[num6].BuildAirNodes();
			}
			Profiler.End("Build Air Nodes");
			Profiler.Start("Build Path Lines");
			lineScanners = LineScanners;
			for (int k = 0; k < lineScanners.Length; k++)
			{
				lineScanners[k].BuildPathLine();
			}
			Profiler.End("Build Path Lines");
			Profiler.End("Building");
			Profiler.End("Map Scanning");
			Profiler.Log();
		}

		public LineScanner GetLineScanner(int index)
		{
			if (LineScanners == null || index < 0 || index >= LineScanners.Length)
			{
				return null;
			}
			return LineScanners[index];
		}

		public LineScanner GetLineScannerAtX(float x)
		{
			for (int i = 0; i < LineScanners.Length; i++)
			{
				LineScanner lineScanner = LineScanners[i];
				if (lineScanner.x >= x)
				{
					return lineScanner;
				}
			}
			return null;
		}

		public PathNode[] GetVaildNodeInRange(Vector2 target, Func<PathNode, LineScanner, bool> selector, float range = 1f)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			if (LineScanners == null)
			{
				return new PathNode[0];
			}
			List<PathNode> list = new List<PathNode>();
			for (int i = 0; i < LineScanners.Length; i++)
			{
				if (!(LineScanners[i].x >= target.x))
				{
					continue;
				}
				int num = Mathf.CeilToInt((range - 1f) / actualScanlineSpacing);
				int num2 = Mathf.Max(i - num, 0);
				int num3 = Mathf.Min(i + num, LineScanners.Length - 1);
				for (int j = num2; j <= num3; j++)
				{
					LineScanner lineScanner = LineScanners[j];
					foreach (PathNode path in lineScanner.PathLine.Paths)
					{
						if (selector(path, lineScanner))
						{
							list.Add(path);
						}
					}
				}
				break;
			}
			return list.ToArray();
		}

		public ClosestNodeResult GetClosestPathNode(Vector2 target, Func<LineScanner, PathNode, bool> selector)
		{
			//IL_0032: 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_008d: 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_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			ClosestNodeResult closestNodeResult = new ClosestNodeResult();
			int num = 0;
			if (LineScanners == null || LineScanners.Length == 0)
			{
				return closestNodeResult;
			}
			for (int i = 0; i < LineScanners.Length; i++)
			{
				LineScanner lineScanner = LineScanners[i];
				if (lineScanner.x >= target.x)
				{
					num = i;
					closestNodeResult = GetClosetPathNodeInLine(target, lineScanner, selector);
					break;
				}
			}
			int num2 = num - 1;
			int num3 = num + 1;
			bool flag = false;
			bool flag2 = false;
			while (!flag && !flag2)
			{
				if (!flag)
				{
					if (num2 < 0)
					{
						flag = true;
					}
					else
					{
						LineScanner lineScanner2 = LineScanners[num2];
						float num4 = lineScanner2.x - target.x;
						float num5 = num4 * num4;
						ClosestNodeResult closetPathNodeInLine = GetClosetPathNodeInLine(target, lineScanner2, selector);
						if (closetPathNodeInLine.DistanceSquared < closestNodeResult.DistanceSquared)
						{
							closestNodeResult = closetPathNodeInLine;
						}
						if (num5 > closestNodeResult.DistanceSquared)
						{
							flag = true;
						}
						num2--;
					}
				}
				if (flag2)
				{
					continue;
				}
				if (num3 >= LineScanners.Length)
				{
					flag2 = true;
					continue;
				}
				LineScanner lineScanner3 = LineScanners[num3];
				float num6 = lineScanner3.x - target.x;
				float num7 = num6 * num6;
				ClosestNodeResult closetPathNodeInLine2 = GetClosetPathNodeInLine(target, lineScanner3, selector);
				if (closetPathNodeInLine2.DistanceSquared < closestNodeResult.DistanceSquared)
				{
					closestNodeResult = closetPathNodeInLine2;
				}
				if (num7 > closestNodeResult.DistanceSquared)
				{
					flag2 = true;
				}
				num3++;
			}
			return closestNodeResult;
		}

		public ClosestNodeResult GetClosetPathNodeInLine(Vector2 target, LineScanner lineScanner, Func<LineScanner, PathNode, bool> selector)
		{
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: 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_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)
			ClosestNodeResult closestNodeResult = new ClosestNodeResult();
			foreach (PathNode path in lineScanner.PathLine.Paths)
			{
				Node nodeBelowY = lineScanner.NodeLine.GetNodeBelowY(path.Node.Position.y);
				bool flag = nodeBelowY != null && nodeBelowY is CeilingNode && nodeBelowY.Position.y > target.y;
				if (path.Node is GroundNode && flag)
				{
					continue;
				}
				PathNode[] verticalNodes = path.GetVerticalNodes();
				foreach (PathNode pathNode in verticalNodes)
				{
					Vector2 val = target - pathNode.Node.Position;
					float sqrMagnitude = ((Vector2)(ref val)).sqrMagnitude;
					if (sqrMagnitude < closestNodeResult.DistanceSquared && (selector == null || selector(lineScanner, pathNode)))
					{
						closestNodeResult.Node = pathNode;
						closestNodeResult.DistanceSquared = sqrMagnitude;
					}
				}
			}
			return closestNodeResult;
		}
	}
}
namespace RoundsWithBots.Pathfinding.Nodes
{
	public class AirNode : Node
	{
		public bool IsEdgeAirNode;

		public AirNode(int LineIndex, Vector2 position, bool isEdgeAirNode)
			: base(-1, LineIndex, vaild: true, position)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			IsEdgeAirNode = isEdgeAirNode;
		}
	}
	public class CeilingNode : Node
	{
		public CeilingNode(int id, int LineIndex, bool vaild, Vector2 position)
			: base(id, LineIndex, vaild, position)
		{
		}//IL_0004: Unknown result type (might be due to invalid IL or missing references)

	}
	public class EdgeNode : Node
	{
		public enum Direction
		{
			Left,
			Right
		}

		public Direction EdgeDirection;

		public bool IsCeilingEdge;

		public EdgeNode(int LineIndex, Vector2 position, Direction edgeDirection, bool isCeilingEdge)
			: base(-1, LineIndex, vaild: true, position)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			EdgeDirection = edgeDirection;
			IsCeilingEdge = isCeilingEdge;
		}
	}
	public class GroundNode : Node
	{
		public float spaceAbove;

		public GroundNode(int id, int LineIndex, bool vaild, Vector2 position, float spaceAbove)
			: base(id, LineIndex, vaild, position)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			this.spaceAbove = spaceAbove;
		}
	}
	public abstract class Node
	{
		public int ObjectId;

		public int LineIndex;

		public bool Vaild;

		public Vector2 Position;

		public Node(int id, int lineIndex, bool vaild, Vector2 position)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			ObjectId = id;
			LineIndex = lineIndex;
			Position = position;
			Vaild = vaild;
		}
	}
	public class PathNode
	{
		public Node Node;

		public List<PathNode> ConnetedNodes = new List<PathNode>();

		public PathNode(Node node)
		{
			Node = node;
		}

		public void ConnectNode(PathNode node)
		{
			ConnetedNodes.Add(node);
			node.ConnetedNodes.Add(this);
		}

		public PathNode[] GetVerticalNodes()
		{
			List<PathNode> list = new List<PathNode> { this };
			foreach (PathNode connetedNode in ConnetedNodes)
			{
				if (connetedNode.Node is EdgeNode && connetedNode.Node.LineIndex == Node.LineIndex)
				{
					list.Add(connetedNode);
				}
			}
			return list.ToArray();
		}
	}
}
namespace RoundsWithBots.Pathfinding.Nodes.Lines
{
	public class NodeLine
	{
		public float X;

		public float StartY;

		public float EndY;

		public List<Node> Nodes;

		public List<Node> VaildNodes => Nodes.Where((Node n) => n.Vaild).ToList();

		public NodeLine(float x, float startY, float endY, List<Node> nodes)
		{
			X = x;
			StartY = startY;
			EndY = endY;
			Nodes = nodes.OrderByDescending((Node n) => n.Position.y).ToList();
		}

		public void AddNode(Node node)
		{
			int num = Nodes.FindIndex((Node n) => n.Position.y < node.Position.y);
			if (num == -1)
			{
				Nodes.Add(node);
			}
			else
			{
				Nodes.Insert(num, node);
			}
		}

		public Node GetNodeAboveY(float y, params Type[] blacklistNodeType)
		{
			if (blacklistNodeType.Any((Type t) => !t.IsSubclassOf(typeof(Node))))
			{
				throw new ArgumentException("All types in blacklistNodeType must inherit from Node.", "blacklistNodeType");
			}
			for (int num = Nodes.Count - 1; num >= 0; num--)
			{
				if (Nodes[num].Vaild && Nodes[num].Position.y > y && !blacklistNodeType.Contains(Nodes[num].GetType()))
				{
					return Nodes[num];
				}
			}
			return null;
		}

		public Node GetNodeBelowY(float y, params Type[] blacklistNodeType)
		{
			if (blacklistNodeType.Any((Type t) => !t.IsSubclassOf(typeof(Node))))
			{
				throw new ArgumentException("All types in blacklistNodeType must inherit from Node.", "blacklistNodeType");
			}
			for (int num = 0; num < Nodes.Count; num++)
			{
				if (Nodes[num].Vaild && Nodes[num].Position.y < y && !blacklistNodeType.Contains(Nodes[num].GetType()))
				{
					return Nodes[num];
				}
			}
			return null;
		}

		public Node GetNodeAtY(float y, float minDist = 1f)
		{
			foreach (Node node in Nodes)
			{
				if (Mathf.Abs(node.Position.y - y) < minDist && node.Vaild)
				{
					return node;
				}
			}
			return null;
		}

		public Node GetNodeAtY(float y, float minDist = 1f, params Type[] whitelistedNodeTypes)
		{
			if (whitelistedNodeTypes.Any((Type t) => !t.IsSubclassOf(typeof(Node))))
			{
				throw new ArgumentException("All types in blacklistNodeType must inherit from Node.", "whitelistedNodeTypes");
			}
			foreach (Node node in Nodes)
			{
				if (Mathf.Abs(node.Position.y - y) < minDist && node.Vaild && (whitelistedNodeTypes.Length == 0 || whitelistedNodeTypes.Contains(node.GetType())))
				{
					return node;
				}
			}
			return null;
		}
	}
	public class PathLine
	{
		public NodeLine NodeLine;

		public List<PathNode> Paths = new List<PathNode>();

		public PathLine(NodeLine nodeLine)
		{
			NodeLine = nodeLine;
		}

		public void AddNode(PathNode node)
		{
			int num = Paths.FindIndex((PathNode n) => n.Node.Position.y < node.Node.Position.y);
			if (num == -1)
			{
				Paths.Add(node);
			}
			else
			{
				Paths.Insert(num, node);
			}
		}

		public PathNode GetNodeAboveY(float y, params Type[] blacklistNodeType)
		{
			if (blacklistNodeType.Any((Type t) => !t.IsSubclassOf(typeof(Node))))
			{
				throw new ArgumentException("All types in blacklistNodeType must inherit from Node.", "blacklistNodeType");
			}
			for (int num = Paths.Count - 1; num >= 0; num--)
			{
				if (Paths[num].Node.Vaild && Paths[num].Node.Position.y > y && !blacklistNodeType.Contains(Paths[num].Node.GetType()))
				{
					return Paths[num];
				}
			}
			return null;
		}

		public PathNode GetNodeBelowY(float y, params Type[] blacklistNodeType)
		{
			if (blacklistNodeType.Any((Type t) => !t.IsSubclassOf(typeof(Node))))
			{
				throw new ArgumentException("All types in blacklistNodeType must inherit from Node.", "blacklistNodeType");
			}
			for (int num = 0; num < Paths.Count; num++)
			{
				if (Paths[num].Node.Vaild && Paths[num].Node.Position.y < y && !blacklistNodeType.Contains(Paths[num].Node.GetType()))
				{
					return Paths[num];
				}
			}
			return null;
		}

		public PathNode GetNodeAtY(float y, float minDist = 1f)
		{
			foreach (PathNode path in Paths)
			{
				if (Mathf.Abs(path.Node.Position.y - y) < minDist && path.Node.Vaild)
				{
					return path;
				}
			}
			return null;
		}

		public PathNode GetNodeAtY(float y, float minDist = 1f, params Type[] whitelistedNodeTypes)
		{
			if (whitelistedNodeTypes.Any((Type t) => !t.IsSubclassOf(typeof(Node))))
			{
				throw new ArgumentException("All types in blacklistNodeType must inherit from Node.", "whitelistedNodeTypes");
			}
			foreach (PathNode path in Paths)
			{
				if (Mathf.Abs(path.Node.Position.y - y) < minDist && path.Node.Vaild && (whitelistedNodeTypes.Length == 0 || whitelistedNodeTypes.Contains(path.Node.GetType())))
				{
					return path;
				}
			}
			return null;
		}
	}
}
namespace RoundsWithBots.Pathfinding.Core
{
	public class PathfindAgent
	{
		public PathfindRequest CurrentPathRequest;

		public void Pathfind(PathNode startNode, PathNode endNode, PathfindingOptions pathfindingOptions)
		{
			CurrentPathRequest = new PathfindRequest(startNode, endNode, pathfindingOptions);
			CurrentPathRequest.Pathfind();
		}
	}
	public struct PathfindingOptions
	{
		public float JumpPenaltyPow;

		public float JumpMeters;

		public float AirNodePenaltyMult;

		public float MinSpaceRequire;

		public PathfindingOptions(float jumpPenaltyPow, float airNodePenaltyMult, float jumpMeters, float minSpaceRequire)
		{
			JumpPenaltyPow = jumpPenaltyPow;
			AirNodePenaltyMult = airNodePenaltyMult;
			JumpMeters = jumpMeters;
			MinSpaceRequire = minSpaceRequire;
		}
	}
	public class PathfindRequest
	{
		private const int MAX_ITERATIONS = 10000;

		public PathNode StartNode;

		public PathNode EndNode;

		public PathfindingOptions PathfindingOptions;

		public List<VisitedNode> Path = new List<VisitedNode>();

		private readonly Dictionary<PathNode, VisitedNode> visitedNodes = new Dictionary<PathNode, VisitedNode>();

		private readonly HashSet<PathNode> closedSet = new HashSet<PathNode>();

		private readonly DaryHeap<VisitedNode> openSet = new DaryHeap<VisitedNode>(4);

		public bool PathfindFinishes { get; private set; }

		public PathfindRequest(PathNode startNode, PathNode endNode, PathfindingOptions penaltyOption)
		{
			StartNode = startNode;
			EndNode = endNode;
			PathfindingOptions = penaltyOption;
			VisitedNode visitedNode = new VisitedNode(StartNode);
			visitedNode.G = 0f;
			visitedNode.H = visitedNode.GetDistance(EndNode);
			visitedNodes.Add(StartNode, visitedNode);
			openSet.Add(visitedNode);
		}

		public void CondensePath()
		{
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			if (Path.Count <= 2)
			{
				return;
			}
			Type type = Path[0].PathNode.Node.GetType();
			List<VisitedNode> list = new List<VisitedNode>();
			list.Add(Path[0]);
			for (int i = 1; i < Path.Count - 1; i++)
			{
				VisitedNode visitedNode = Path[i - 1];
				VisitedNode visitedNode2 = Path[i];
				if (MathUtils.CalculatePointsStraightness(pointThree: Path[i + 1].PathNode.Node.Position, pointOne: visitedNode.PathNode.Node.Position, pointTwo: visitedNode2.PathNode.Node.Position) > 0.1f || visitedNode2.PathNode.Node.GetType() != type)
				{
					list.Add(visitedNode2);
					type = visitedNode2.PathNode.Node.GetType();
				}
			}
			list.Add(Path[Path.Count - 1]);
			Path = list;
		}

		public void Pathfind()
		{
			if (PathfindFinishes)
			{
				return;
			}
			int num = 0;
			while (openSet.Count > 0)
			{
				if (++num > 10000)
				{
					LoggerUtils.LogWarn($"A* exceeded {10000} iterations!");
					break;
				}
				VisitedNode visitedNode = openSet.RemoveFirst();
				closedSet.Add(visitedNode.PathNode);
				if (visitedNode.PathNode == EndNode)
				{
					Path = BuildPath(visitedNode);
					break;
				}
				foreach (PathNode connetedNode in visitedNode.PathNode.ConnetedNodes)
				{
					if (!visitedNodes.TryGetValue(connetedNode, out var value))
					{
						value = new VisitedNode(connetedNode);
						value.H = value.GetDistance(EndNode);
						visitedNodes.Add(connetedNode, value);
					}
					float num2 = visitedNode.G + visitedNode.GetDistance(connetedNode);
					if ((connetedNode.Node is GroundNode groundNode && groundNode.spaceAbove < PathfindingOptions.MinSpaceRequire) || (connetedNode.Node.LineIndex == visitedNode.PathNode.Node.LineIndex && connetedNode.Node.Position.y > visitedNode.PathNode.Node.Position.y && (connetedNode.Node is AirNode || connetedNode.Node is EdgeNode { IsCeilingEdge: not false }) && !(visitedNode.PathNode.Node is EdgeNode) && (value.JumpDist = visitedNode.JumpDist + Mathf.Abs(connetedNode.Node.Position.y - visitedNode.PathNode.Node.Position.y)) > PathfindingOptions.JumpMeters))
					{
						continue;
					}
					float num3 = num2 + value.GetPenalty(PathfindingOptions);
					if (!(num3 >= value.G))
					{
						value.G = num3;
						value.Parent = visitedNode;
						if (openSet.Contains(value))
						{
							openSet.UpdateItem(value);
						}
						else
						{
							openSet.Add(value);
						}
					}
				}
			}
			PathfindFinishes = true;
		}

		public List<VisitedNode> BuildPath(VisitedNode visitedNode)
		{
			List<VisitedNode> list = new List<VisitedNode>();
			HashSet<PathNode> hashSet = new HashSet<PathNode>();
			for (VisitedNode visitedNode2 = visitedNode; visitedNode2 != null; visitedNode2 = visitedNode2.Parent)
			{
				if (!hashSet.Add(visitedNode2.PathNode))
				{
					LoggerUtils.Log((LogLevel)2, "Cycle detected in parent chain!");
					return new List<VisitedNode>();
				}
				list.Add(visitedNode2);
			}
			list.Reverse();
			return list;
		}
	}
	public class VisitedNode : IHeapItem<VisitedNode>, IComparable<VisitedNode>
	{
		public PathNode PathNode;

		public VisitedNode Parent;

		public float G = float.PositiveInfinity;

		public float H = float.PositiveInfinity;

		public float JumpDist;

		public int HeapIndex { get; set; }

		public float F => G + H;

		public VisitedNode(PathNode node, VisitedNode parent)
		{
			PathNode = node;
			Parent = parent;
		}

		public VisitedNode(PathNode node)
			: this(node, null)
		{
		}

		public float GetPenalty(PathfindingOptions penaltyOption)
		{
			if (Parent == null)
			{
				return 0f;
			}
			float num = 0f;
			num += Mathf.Pow(JumpDist, penaltyOption.JumpPenaltyPow);
			if (PathNode.Node is AirNode)
			{
				num += GetDistance(Parent.PathNode) * penaltyOption.AirNodePenaltyMult;
			}
			return num;
		}

		public float GetDistance(PathNode b)
		{
			//IL_000b: 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)
			return Vector2.Distance(PathNode.Node.Position, b.Node.Position);
		}

		public int CompareTo(VisitedNode other)
		{
			int num = F.CompareTo(other.F);
			if (num != 0)
			{
				return num;
			}
			return H.CompareTo(other.H);
		}
	}
}
namespace RoundsWithBots.Pacthes
{
	[HarmonyPatch(typeof(PlayerAPI), "GetAllBullets")]
	public class PlayerAPIGetAllBulletsPatch
	{
		private static readonly FieldRef<ProjectileHit, MoveTransform> MoveRef = AccessTools.FieldRefAccess<ProjectileHit, MoveTransform>("move");

		private static bool Prefix(ref List<BulletWrapper> __result)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: 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_0055: 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_0064: Expected O, but got Unknown
			List<ProjectileHit> bullets = StoreBullets.Bullets;
			List<BulletWrapper> list = new List<BulletWrapper>(bullets.Count);
			foreach (ProjectileHit item in bullets)
			{
				MoveTransform val = MoveRef.Invoke(item);
				list.Add(new BulletWrapper
				{
					projectileHit = item,
					projectileMovement = val,
					damage = item.damage,
					velocity = Vector2.op_Implicit(val.velocity)
				});
			}
			__result = list;
			return false;
		}
	}
}
namespace RoundsWithBots.Pacthes.Storage
{
	[HarmonyPatch(typeof(ProjectileHit))]
	public class StoreBullets
	{
		private static readonly List<ProjectileHit> bullets = new List<ProjectileHit>();

		public static List<ProjectileHit> Bullets
		{
			get
			{
				bullets.RemoveAll((ProjectileHit b) => (Object)(object)b == (Object)null);
				return bullets;
			}
		}

		[HarmonyPatch("Start")]
		[HarmonyPrefix]
		public static void BulletStartPrefix(ProjectileHit __instance)
		{
			bullets.Add(__instance);
		}
	}
	[HarmonyPatch(typeof(OutOfBoundsHandler), "Start")]
	public class StoreOutOfBoundsHandler
	{
		public static Dictionary<Player, OutOfBoundsHandler> outOfBoundsHandlers = new Dictionary<Player, OutOfBoundsHandler>();

		private static void Postfix(OutOfBoundsHandler __instance)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			outOfBoundsHandlers.Add(((CharacterData)ExtensionMethods.GetFieldValue((object)__instance, "data")).player, __instance);
		}
	}
}
namespace RoundsWithBots.Pacthes.RWF
{
	[HarmonyPatch(/*Could not decode attribute arguments.*/)]
	public class RoundEndHandlerPatch
	{
		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator il)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Expected O, but got Unknown
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Expected O, but got Unknown
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Expected O, but got Unknown
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Expected O, but got Unknown
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Expected O, but got Unknown
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: Expected O, but got Unknown
			//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01be: Expected O, but got Unknown
			try
			{
				LoggerUtils.Log((LogLevel)32, "RoundEndHandlerPatch.Transpiler called");
				List<CodeInstruction> list = new List<CodeInstruction>(instructions);
				LoggerUtils.Log((LogLevel)32, $"Transpiler received {list.Count} instructions");
				CodeMatcher val = new CodeMatcher(instructions, il);
				LoggerUtils.Log((LogLevel)32, "Created CodeMatcher - attempting MatchForward for PopUpMenu.Open");
				val.MatchForward(false, (CodeMatch[])(object)new CodeMatch[2]
				{
					new CodeMatch((OpCode?)OpCodes.Callvirt, (object)AccessTools.Method(typeof(PopUpMenu), "Open", new Type[2]
					{
						typeof(List<string>),
						typeof(Action<string>)
					}, (Type[])null), (string)null),
					new CodeMatch((OpCode?)OpCodes.Br, (object)null, (string)null)
				}).Advance(1);
				Label label = (Label)val.Instruction.operand;
				LoggerUtils.Log((LogLevel)32, "Matched PopUpMenu.Open and Br_S; extracted target label");
				Label label2 = default(Label);
				val.Advance(1).Insert((CodeInstruction[])(object)new CodeInstruction[2]
				{
					new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(RoundEndHandlerPatch), "Rematch", (Type[])null, (Type[])null)),
					new CodeInstruction(OpCodes.Br_S, (object)label)
				}).CreateLabel(ref label2);
				LoggerUtils.Log((LogLevel)32, "Inserted Rematch call and branch; created botsRoundsEndLabel");
				val.MatchBack(false, (CodeMatch[])(object)new CodeMatch[1]
				{
					new CodeMatch((OpCode?)OpCodes.Newobj, (object)AccessTools.Constructor(typeof(List<string>), Type.EmptyTypes, false), (string)null)
				});
				List<Label> labels = new List<Label>(val.Instruction.labels);
				val.Insert((CodeInstruction[])(object)new CodeInstruction[2]
				{
					new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(RoundEndHandlerPatch), "ShouldDoBotsRematch", (Type[])null, (Type[])null))
					{
						labels = labels
					},
					new CodeInstruction(OpCodes.Brtrue_S, (object)label2)
				});
				LoggerUtils.Log((LogLevel)32, "Inserted ShouldDoBotsRematch check before List<string> construction");
				List<CodeInstruction> list2 = val.Instructions().ToList();
				LoggerUtils.Log((LogLevel)32, $"Transpiler finished, returning {list2.Count} instructions");
				return list2;
			}
			catch (Exception arg)
			{
				LoggerUtils.LogError($"RoundEndHandlerPatch.Transpiler failed: {arg}");
				return instructions;
			}
		}

		private static bool ShouldDoBotsRematch()
		{
			return PlayerManager.instance.players.All((Player p) => p.data.GetAdditionalData().IsBot || CharacterDataExtension.GetAdditionalData(p.data).isAIMinion);
		}

		private static void Rematch()
		{
			RoundEndHandler.instance.OnGameOverChoose("REMATCH");
		}
	}
}
namespace RoundsWithBots.Patches
{
	[HarmonyPatch(typeof(CharacterSelectionInstance))]
	internal class CharacterSelectionInstancePatch
	{
		public static Dictionary<CharacterSelectionInstance, bool> RequestColorChange = new Dictionary<CharacterSelectionInstance, bool>();

		public static Dictionary<CharacterSelectionInstance, BotMenuUIHandler> BotMenuMap = new Dictionary<CharacterSelectionInstance, BotMenuUIHandler>();

		public static GameObject BotMenusCanvas;

		[HarmonyPatch("StartPicking")]
		[HarmonyBefore(new string[] { "io.olavim.rounds.rwf" })]
		[HarmonyPostfix]
		public static void StartPickingPostfix(CharacterSelectionInstance __instance, HoverEvent[] ___buttons)
		{
			if (__instance.currentPlayer.data.GetAdditionalData().IsBot)
			{
				if (RWBMenu.RandomizationFace.Value)
				{
					__instance.currentlySelectedFace = Random.Range(0, 7);
				}
				else
				{
					__instance.currentlySelectedFace = RWBMenu.SelectedFace.Value;
				}
				if (!BotMenuMap.ContainsKey(__instance))
				{
					BotMenuUIHandler botMenuUIHandler = BotMenuUIHandler.CreateInstance(__instance);
					((Component)botMenuUIHandler).transform.SetParent(((Component)__instance).transform, false);
					RectTransform rect = ((Component)botMenuUIHandler).GetComponent<RectTransform>();
					ExtensionMethods.ExecuteAfterFrames((MonoBehaviour)(object)botMenuUIHandler, 1, (Action)delegate
					{
						//IL_0010: Unknown result type (might be due to invalid IL or missing references)
						rect.anchoredPosition = new Vector2(0f, 95f);
					});
					BotMenuMap.Add(__instance, botMenuUIHandler);
				}
				else
				{
					BotMenuUIHandler botMenuUIHandler2 = BotMenuMap[__instance];
					botMenuUIHandler2.HideMenu();
					botMenuUIHandler2.Refresh();
				}
			}
			else if (BotMenuMap.ContainsKey(__instance))
			{
				Object.Destroy((Object)(object)BotMenuMap[__instance]);
				BotMenuMap.Remove(__instance);
			}
			ExtensionMethods.ExecuteAfterFrames((MonoBehaviour)(object)__instance, 1, (Action)delegate
			{
				((Component)((Component)__instance).transform.GetChild(0).GetChild(1)).gameObject.SetActive(false);
				SetupButton(__instance, ___buttons);
			});
		}

		private static void SetupButton(CharacterSelectionInstance __instance, HoverEvent[] ___buttons)
		{
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: 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_009d: Expected O, but got Unknown
			//IL_00a2: Expected O, but got Unknown
			UnityAction val2 = default(UnityAction);
			foreach (HoverEvent val in ___buttons)
			{
				if (__instance.currentPlayer.data.GetAdditionalData().IsBot)
				{
					GameObject gameObject = ((Component)((Component)val).transform.Find("Tooltip")).gameObject;
					Button orAddComponent = ExtensionMethods.GetOrAddComponent<Button>(gameObject, false);
					Image componentInChildren = gameObject.GetComponentInChildren<Image>(true);
					TextMeshProUGUI componentInChildren2 = gameObject.GetComponentInChildren<TextMeshProUGUI>();
					ControllerImageToggler component = ((Component)componentInChildren).GetComponent<ControllerImageToggler>();
					((UnityEventBase)orAddComponent.onClick).RemoveAllListeners();
					ButtonClickedEvent onClick = orAddComponent.onClick;
					UnityAction obj = val2;
					if (obj == null)
					{
						UnityAction val3 = delegate
						{
							//IL_0000: Unknown result type (might be due to invalid IL or missing references)
							//IL_0005: Unknown result type (might be due to invalid IL or missing references)
							Vector2.op_Implicit(Input.mousePosition);
							if (BotMenuMap.TryGetValue(__instance, out var value))
							{
								value.OpenMenu();
							}
						};
						UnityAction val4 = val3;
						val2 = val3;
						obj = val4;
					}
					((UnityEvent)onClick).AddListener(obj);
					((Selectable)orAddComponent).targetGraphic = (Graphic)(object)componentInChildren2;
					componentInChildren.overrideSprite = component.MKSprite;
					((Component)componentInChildren).transform.localEulerAngles = new Vector3(0f, 180f, 0f);
					((TMP_Text)componentInChildren2).text = "TO EDIT";
					((Selectable)orAddComponent).interactable = true;
				}
				else
				{
					GameObject gameObject2 = ((Component)((Component)val).transform.Find("Tooltip")).gameObject;
					Button orAddComponent2 = ExtensionMethods.GetOrAddComponent<Button>(gameObject2, false);
					Image componentInChildren3 = gameObject2.GetComponentInChildren<Image>(true);
					((Component)componentInChildren3).transform.localEulerAngles = new Vector3(0f, 0f, 0f);
					componentInChildren3.overrideSprite = null;
					((Selectable)orAddComponent2).interactable = false;
					((Selectable)orAddComponent2).targetGraphic = null;
				}
				((Component)val).GetComponent<SimulatedSelection>().Select();
			}
		}

		[HarmonyPatch("Update")]
		[HarmonyBefore(new string[] { "io.olavim.rounds.rwf" })]
		[HarmonyPrefix]
		public static bool UpdatePrefix(CharacterSelectionInstance __instance, HoverEvent[] ___buttons)
		{
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)__instance.currentPlayer == (Object)null)
			{
				return false;
			}
			if (RequestColorChange.ContainsKey(__instance) && RequestColorChange[__instance])
			{
				foreach (HoverEvent obj in ___buttons)
				{
					((Component)((Component)obj).transform.GetChild(2).GetChild(0)).GetComponent<SpriteRenderer>().color = __instance.currentPlayer.GetTeamColors().color;
					((TMP_Text)((Component)((Component)obj).transform.GetChild(4).GetChild(2)).GetComponent<TextMeshProUGUI>()).text = (GameModeManager.CurrentHandler.AllowTeams ? "TEAM " : "") + ExtraPlayerSkins.GetTeamColorName(PlayerExtensions.colorID(__instance.currentPlayer)).ToUpper();
				}
				if (RequestColorChange.ContainsKey(__instance))
				{
					RequestColorChange[__instance] = false;
				}
				else
				{
					RequestColorChange.Add(__instance, value: false);
				}
			}
			if (__instance.currentPlayer.data.GetAdditionalData().IsBot)
			{
				ExtensionMethods.SetFieldValue((object)__instance.currentPlayer.data.playerVel, "simulated", (object)false);
				if (Input.GetKeyDown((KeyCode)114))
				{
					AccessTools.Method(typeof(CharacterSelectionInstance), "ReadyUp", (Type[])null, (Type[])null).Invoke(__instance, null);
					return false;
				}
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(PlayerAssigner))]
	internal class PlayerAssignerPatch
	{
		[HarmonyPatch("CreatePlayer")]
		public static bool Prefix(bool isAI, ref IEnumerator __result)
		{
			if (GameManager.instance.isPlaying && !AIMinionHandler.sandbox)
			{
				__result = EmptyEnumerator();
				return false;
			}
			return true;
		}

		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator il)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Expected O, but got Unknown
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Expected O, but got Unknown
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Expected O, but got Unknown
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Expected O, but got Unknown
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Expected O, but got Unknown
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Expected O, but got Unknown
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Expected O, but got Unknown
			LoggerUtils.Log((LogLevel)32, "PlayerAssignerPatch.Transpiler called");
			List<CodeInstruction> list = new List<CodeInstruction>(instructions);
			LoggerUtils.Log((LogLevel)32, $"Transpiler received {list.Count} instructions");
			CodeMatcher val = new CodeMatcher(instructions, il);
			LoggerUtils.Log((LogLevel)32, "Created CodeMatcher - attempting MatchForward for PlayerAssigner.CreatePlayeer");
			val.MatchForward(false, (CodeMatch[])(object)new CodeMatch[4]
			{
				new CodeMatch((OpCode?)OpCodes.Ldloc_3, (object)null, (string)null),
				new CodeMatch((OpCode?)OpCodes.Callvirt, (object)AccessTools.Method(typeof(Component), "GetComponent", Type.EmptyTypes, (Type[])null).MakeGenericMethod(typeof(CharacterData)), (string)null),
				new CodeMatch((OpCode?)OpCodes.Ldnull, (object)null, (string)null),
				new CodeMatch((OpCode?)OpCodes.Callvirt, (object)AccessTools.Method(typeof(CharacterData), "SetAI", (Type[])null, (Type[])null), (string)null)
			}).MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
			{
				new CodeMatch((OpCode?)OpCodes.Pop, (object)null, (string)null)
			}).Insert((CodeInstruction[])(object)new CodeInstruction[2]
			{
				new CodeInstruction(OpCodes.Ldloc_3, (object)null),
				new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(PlayerAssignerPatch), "CreateAdvacnedAI", (Type[])null, (Type[])null))
			});
			LoggerUtils.Log((LogLevel)32, "Inserted CreateAdvacnedAI call");
			List<CodeInstruction> list2 = val.Instructions().ToList();
			LoggerUtils.Log((LogLevel)32, $"Transpiler finished, returning {list2.Count} instructions");
			return list2;
		}

		private static void CreateAdvacnedAI(CharacterData data)
		{
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Expected O, but got Unknown
			PlayerAI componentInChildren = ((Component)data).GetComponentInChildren<PlayerAI>();
			PlayerAIZorro componentInChildren2 = ((Component)data).GetComponentInChildren<PlayerAIZorro>();
			if ((Object)(object)componentInChildren != (Object)null)
			{
				((Component)componentInChildren).gameObject.AddComponent<PlayerAIBase>();
				Object.Destroy((Object)(object)componentInChildren);
			}
			else if ((Object)(object)componentInChildren2 != (Object)null)
			{
				((Component)componentInChildren2).gameObject.AddComponent<PlayerAIBase>();
				HealthHandler healthHandler = data.healthHandler;
				healthHandler.delayedReviveAction = (Action)Delegate.Remove(healthHandler.delayedReviveAction, new Action(componentInChildren2.Init));
				Object.Destroy((Object)(object)componentInChildren2);
			}
			data.playerActions = new PlayerActions();
			((PlayerActionSet)data.playerActions).Device = InputDevice.Null;
			data.GetAdditionalData().IsBot = true;
			LoggerUtils.Log((LogLevel)32, "Created advanced bot");
		}

		private static IEnumerator EmptyEnumerator()
		{
			yield break;
		}
	}
}
namespace RoundsWithBots.Patches.RWF
{
	[HarmonyPatch(typeof(KeybindHints))]
	internal class KeybindHintsPatch
	{
		[HarmonyPatch("CreateLocalHints")]
		public static void Postfix()
		{
			if (PlayerPrefs.GetInt(RWFMod.GetCustomPropertyKey("ShowKeybinds"), 1) != 0)
			{
				KeybindHints.AddHint("to ready up all bots", "[R]", (Vector2?)null);
			}
		}
	}
	[HarmonyPatch(typeof(PlayerSpotlight))]
	internal class PlayerSpotlightPatch
	{
		[HarmonyPatch("AddSpotToPlayer")]
		public static bool Prefix(Player player)
		{
			return !((Behaviour)((Component)player).GetComponent<PlayerAPI>()).enabled;
		}
	}
}
namespace RoundsWithBots.Menu
{
	internal static class RWBMenu
	{
		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static UnityAction <>9__4_0;

			public static UnityAction<float> <>9__4_1;

			public static UnityAction<float> <>9__4_2;

			public static UnityAction<float> <>9__4_3;

			public static UnityAction<float> <>9__4_4;

			public static UnityAction <>9__9_0;

			public static UnityAction<bool> <>9__9_1;

			public static UnityAction<bool> <>9__9_2;

			public static UnityAction<bool> <>9__9_3;

			public static UnityAction<bool> <>9__9_4;

			public static UnityAction <>9__14_0;

			public static UnityAction<bool> <>9__14_1;

			public static UnityAction<float> <>9__14_2;

			public static UnityAction <>9__16_0;

			public static UnityAction <>9__22_0;

			public static UnityAction<float> <>9__22_1;

			public static UnityAction<float> <>9__22_2;

			public static UnityAction<float> <>9__22_3;

			internal void <CreateCardsPickerMenu>b__4_0()
			{
			}

			internal void <CreateCardsPickerMenu>b__4_1(float value)
			{
				CycleDelay.Value = value;
			}

			internal void <CreateCardsPickerMenu>b__4_2(float value)
			{
				PreCycleDelay.Value = value;
			}

			internal void <CreateCardsPickerMenu>b__4_3(float value)
			{
				GoToCardDelay.Value = value;
			}

			internal void <CreateCardsPickerMenu>b__4_4(float value)
			{
				PickDelay.Value = value;
			}

			internal void <CreateDebugMenu>b__9_0()
			{
			}

			internal void <CreateDebugMenu>b__9_1(bool value)
			{
				EnableMapScannerVisualizer.Value = value;
			}

			internal void <CreateDebugMenu>b__9_2(bool value)
			{
				EnableBotsPathfindingVisualizer.Value = value;
			}

			internal void <CreateDebugMenu>b__9_3(bool value)
			{
				EnableDebugLogging.Value = value;
			}

			internal void <CreateDebugMenu>b__9_4(bool value)
			{
				EnableProfiler.Value = value;
			}

			internal void <CreateDetailsMenu>b__14_0()
			{
			}

			internal void <CreateDetailsMenu>b__14_1(bool value)
			{
				RandomizationFace.Value = value;
				SelectedFaceObject.SetActive(!value);
			}

			internal void <CreateDetailsMenu>b__14_2(float value)
			{
				SelectedFace.Value = (int)value;
			}

			internal void <RegisterMenu>b__16_0()
			{
			}

			internal void <CreateStalemateMenu>b__22_0()
			{
			}

			internal void <CreateStalemateMenu>b__22_1(float value)
			{
				StalemateTimer.Value = value;
			}

			internal void <CreateStalemateMenu>b__22_2(float value)
			{
				StalemateDamageCooldown.Value = value;
			}

			internal void <CreateStalemateMenu>b__22_3(float value)
			{
				StalemateDamageDuration.Value = value;
			}
		}

		public static ConfigEntry<float> CycleDelay;

		public static ConfigEntry<float> PreCycleDelay;

		public static ConfigEntry<float> GoToCardDelay;

		public static ConfigEntry<float> PickDelay;

		public static ConfigEntry<bool> EnableMapScannerVisualizer;

		public static ConfigEntry<bool> EnableBotsPathfindingVisualizer;

		public static ConfigEntry<bool> EnableDebugLogging;

		public static ConfigEntry<bool> EnableProfiler;

		public static GameObject SelectedFaceObject;

		public static ConfigEntry<bool> RandomizationFace;

		public static ConfigEntry<int> SelectedFace;

		public static ConfigEntry<float> StalemateTimer;

		public static ConfigEntry<float> StalemateDamageCooldown;

		public static ConfigEntry<float> StalemateDamageDuration;

		private static void CreateCardsPickerMenu(GameObject mainMenu)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Expected O, but got Unknown
			object obj = <>c.<>9__4_0;
			if (obj == null)
			{
				UnityAction val = delegate
				{
				};
				<>c.<>9__4_0 = val;
				obj = (object)val;
			}
			GameObject val2 = MenuHandler.CreateMenu("Cards Picker", (UnityAction)obj, mainMenu, 40, true, tru