Decompiled source of FreeAim v1.0.0

FreeAim.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using DM;
using GamepadUI.StateManager.Core;
using HarmonyLib;
using InControl;
using Landfall.TABS;
using Landfall.TABS.AI;
using Landfall.TABS.AI.Components;
using Landfall.TABS.GameState;
using Landfall.TABS_Input;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using TFBGames;
using Unity.Mathematics;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace FreeAim
{
	internal static class AimExclusionIcons
	{
		private static readonly Dictionary<string, Sprite> UnitIconCache = new Dictionary<string, Sprite>();

		internal static Sprite GetUnitIcon(UnitBlueprint blueprint)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			if (((blueprint != null) ? blueprint.Entity : null) == null)
			{
				return null;
			}
			string text = AimExclusionStore.Key(blueprint.Entity.GUID);
			if (string.IsNullOrEmpty(text))
			{
				return TryGetLoadedSprite(blueprint.Entity);
			}
			if (UnitIconCache.TryGetValue(text, out var value))
			{
				return value;
			}
			Sprite val = TryGetLoadedSprite(blueprint.Entity);
			if ((Object)(object)val != (Object)null)
			{
				UnitIconCache[text] = val;
			}
			return val;
		}

		internal static Sprite TryGetLoadedSprite(object entity)
		{
			if (entity == null)
			{
				return null;
			}
			try
			{
				object? obj = entity.GetType().GetProperty("SpriteIcon", BindingFlags.Instance | BindingFlags.Public)?.GetValue(entity, null);
				return (Sprite)((obj is Sprite) ? obj : null);
			}
			catch
			{
				return null;
			}
		}
	}
	internal static class AimExclusionMenu
	{
		private enum SourceFilter
		{
			All,
			BuiltIn,
			Custom
		}

		private enum CombatFilter
		{
			All,
			Melee,
			Ranged
		}

		private enum TextAlignment
		{
			Left = 513,
			Center
		}

		private class VirtualRow
		{
			internal GameObject Row;

			internal Image RowImage;

			internal Image IconImage;

			internal Component TextComponent;

			internal Button ExcludeButton;

			internal Button RangeButton;

			internal Button SpreadButton;

			internal Button VerticalButton;

			internal Button DashButton;

			internal AimExclusionStore.UnitEntry BoundEntry;

			internal int DataIndex = -1;
		}

		private class PanelLayoutMarker : MonoBehaviour
		{
			internal int Version;
		}

		private class SearchInputBehaviour : MonoBehaviour
		{
			private void Update()
			{
				HandleSearchInput();
			}
		}

		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static UnityAction <>9__47_0;

			public static UnityAction<Vector2> <>9__58_0;

			public static Action <>9__61_0;

			public static Action <>9__61_1;

			public static Action <>9__61_2;

			public static Action <>9__61_3;

			public static Action <>9__61_4;

			public static Action <>9__61_5;

			public static Action <>9__61_6;

			public static Action <>9__61_7;

			public static Action <>9__61_8;

			public static Action <>9__61_9;

			public static Action <>9__61_10;

			public static Action <>9__62_0;

			public static Action <>9__62_1;

			public static Action <>9__63_0;

			public static Action <>9__63_1;

			public static Func<AimExclusionStore.UnitEntry, string> <>9__72_1;

			public static Func<AimExclusionStore.UnitEntry, bool> <>9__84_0;

			public static UnityAction <>9__116_0;

			internal void <TryAddButton>b__47_0()
			{
				try
				{
					Open();
				}
				catch (Exception arg)
				{
					Plugin.LogWarning($"Aim exclusions: menu open failed: {arg}");
				}
			}

			internal void <EnsureScrollListener>b__58_0(Vector2 _)
			{
				BindVisibleRows();
			}

			internal void <BuildPanel>b__61_0()
			{
				AimExclusionStore.SetAllExcluded(excluded: true);
				Refresh(resetScroll: true);
			}

			internal void <BuildPanel>b__61_1()
			{
				AimExclusionStore.SetAllExcluded(excluded: false);
				Refresh(resetScroll: true);
			}

			internal void <BuildPanel>b__61_2()
			{
				AimExclusionStore.SetAllRangeGate(enabled: false);
				Refresh(resetScroll: true);
			}

			internal void <BuildPanel>b__61_3()
			{
				AimExclusionStore.SetAllRangeGate(enabled: true);
				Refresh(resetScroll: true);
			}

			internal void <BuildPanel>b__61_4()
			{
				AimExclusionStore.SetAllVolleySpread(enabled: false);
				Refresh(resetScroll: true);
			}

			internal void <BuildPanel>b__61_5()
			{
				AimExclusionStore.SetAllVolleySpread(enabled: true);
				Refresh(resetScroll: true);
			}

			internal void <BuildPanel>b__61_6()
			{
				AimExclusionStore.SetAllMeleeDash(enabled: false);
				Refresh(resetScroll: true);
			}

			internal void <BuildPanel>b__61_7()
			{
				AimExclusionStore.SetAllMeleeDash(enabled: true);
				Refresh(resetScroll: true);
			}

			internal void <BuildPanel>b__61_8()
			{
				AimExclusionStore.ResetToDefaults();
				Refresh(resetScroll: true);
			}

			internal void <BuildPanel>b__61_9()
			{
				AimExclusionStore.SetAllVerticalAim(enabled: false);
				Refresh(resetScroll: true);
			}

			internal void <BuildPanel>b__61_10()
			{
				AimExclusionStore.SetAllVerticalAim(enabled: true);
				Refresh(resetScroll: true);
			}

			internal void <BuildBattleDashKeySettingsRow>b__62_0()
			{
			}

			internal void <BuildBattleDashKeySettingsRow>b__62_1()
			{
				SetMenuInputEnabled(enabled: true);
				_listeningForBattleDashKey = true;
				UpdateBattleDashKeyButtonLabel();
			}

			internal void <BuildAutoShootKeySettingsRow>b__63_0()
			{
			}

			internal void <BuildAutoShootKeySettingsRow>b__63_1()
			{
				SetMenuInputEnabled(enabled: true);
				_listeningForAutoShootKey = true;
				UpdateAutoShootKeyButtonLabel();
			}

			internal string <RebuildFilteredEntries>b__72_1(AimExclusionStore.UnitEntry u)
			{
				return u.name;
			}

			internal bool <UpdateSummaryText>b__84_0(AimExclusionStore.UnitEntry u)
			{
				return u.excluded;
			}

			internal void <CreateSearchBox>b__116_0()
			{
				_searchFocused = true;
				UpdateSearchLabel();
			}
		}

		private const int PanelLayoutVersion = 16;

		private const float HeaderHeight = 448f;

		private const int RowPoolExtra = 4;

		private const int MinRowPoolSize = 12;

		private static readonly FieldInfo MainMenuButtonsContainerField = AccessTools.Field(typeof(MainMenuButtons), "m_ButtonsContainer");

		private const float RowHeight = 56f;

		private const float IconSize = 40f;

		private const float TextLeft = 56f;

		private const float ActionButtonWidth = 84f;

		private static readonly Color RowEven = new Color(0.11f, 0.11f, 0.11f, 0.92f);

		private static readonly Color RowOdd = new Color(0.145f, 0.145f, 0.145f, 0.92f);

		private static readonly Color RowExcluded = new Color(0.26f, 0.12f, 0.12f, 0.96f);

		private static readonly Color ActionOn = new Color(0.2f, 0.48f, 0.28f, 0.98f);

		private static readonly Color ActionOff = new Color(0.18f, 0.18f, 0.18f, 0.96f);

		private static readonly Color SubtitleColor = new Color(0.62f, 0.66f, 0.7f, 1f);

		private static GameObject _canvasRoot;

		private static Canvas _canvas;

		private static GameObject _panel;

		private static Transform _listRoot;

		private static ScrollRect _scroll;

		private static Component _searchText;

		private static Component _summaryText;

		private static Component _textTemplate;

		private static GameObject _menuButtonSource;

		private static GameObject _rowButtonTemplate;

		private static SearchInputBehaviour _searchInputBehaviour;

		private static bool _listeningForBattleDashKey;

		private static Button _battleDashKeyButton;

		private static Component _battleDashKeyLabel;

		private static bool _listeningForAutoShootKey;

		private static Button _autoShootKeyButton;

		private static Component _autoShootKeyLabel;

		private static string _search = "";

		private static bool _searchFocused;

		private static SourceFilter _sourceFilter = SourceFilter.All;

		private static CombatFilter _combatFilter = CombatFilter.All;

		private static bool _scrollListenerRegistered;

		private static int _firstVisibleIndex = -1;

		private static readonly List<AimExclusionStore.UnitEntry> FilteredEntries = new List<AimExclusionStore.UnitEntry>();

		private static readonly List<(Button button, SourceFilter filter)> SourceFilterChips = new List<(Button, SourceFilter)>();

		private static readonly List<(Button button, CombatFilter filter)> CombatFilterChips = new List<(Button, CombatFilter)>();

		private static readonly List<VirtualRow> RowPool = new List<VirtualRow>();

		internal static bool IsOpen
		{
			get
			{
				if ((Object)(object)_panel != (Object)null)
				{
					return _panel.activeSelf;
				}
				return false;
			}
		}

		internal static void MainMenuButtons_Start_Postfix(MainMenuButtons __instance)
		{
			TryAddButton(__instance);
		}

		private static void TryAddButton(MainMenuButtons menu)
		{
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Expected O, but got Unknown
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Expected O, but got Unknown
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Expected O, but got Unknown
			if ((Object)(object)menu == (Object)null)
			{
				return;
			}
			object? obj = MainMenuButtonsContainerField?.GetValue(menu);
			Transform val = (Transform)((obj is Transform) ? obj : null);
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			Transform val2 = FindMenuButtonRow(val);
			bool flag = false;
			if ((Object)(object)val2 == (Object)null)
			{
				RemoveStaleMenuButtons(((Component)menu).transform);
				Transform val3 = null;
				foreach (Transform item in val)
				{
					Transform val4 = item;
					if ((Object)(object)((Component)val4).GetComponentInChildren<Button>(true) != (Object)null)
					{
						val3 = val4;
						break;
					}
				}
				if ((Object)(object)val3 == (Object)null)
				{
					return;
				}
				GameObject val5 = Object.Instantiate<GameObject>(((Component)val3).gameObject, val, false);
				((Object)val5).name = "StayCombatFixAimButton";
				val5.SetActive(true);
				val2 = val5.transform;
				Button componentInChildren = ((Component)val2).GetComponentInChildren<Button>(true);
				if ((Object)(object)componentInChildren == (Object)null)
				{
					Object.Destroy((Object)(object)val5);
					return;
				}
				_menuButtonSource = ((Component)componentInChildren).gameObject;
				if ((Object)(object)_textTemplate == (Object)null)
				{
					_textTemplate = FindTmpText(val5);
				}
				DisableLocalization(val5);
				SetTmpText(val5, "Aim Exclusions");
				((UnityEventBase)componentInChildren.onClick).RemoveAllListeners();
				ButtonClickedEvent onClick = componentInChildren.onClick;
				object obj2 = <>c.<>9__47_0;
				if (obj2 == null)
				{
					UnityAction val6 = delegate
					{
						try
						{
							Open();
						}
						catch (Exception arg)
						{
							Plugin.LogWarning($"Aim exclusions: menu open failed: {arg}");
						}
					};
					<>c.<>9__47_0 = val6;
					obj2 = (object)val6;
				}
				((UnityEvent)onClick).AddListener((UnityAction)obj2);
				flag = true;
			}
			int num = val.childCount - 1;
			int num2 = -1;
			foreach (Transform item2 in val)
			{
				Transform val7 = item2;
				if (!((Object)(object)((Component)val7).GetComponentInChildren<MainMenuQuitGame>(true) == (Object)null))
				{
					num2 = val7.GetSiblingIndex();
					num = num2;
					break;
				}
			}
			int num3;
			if (!flag)
			{
				num3 = ((val2.GetSiblingIndex() != num) ? 1 : 0);
				if (num3 == 0)
				{
					goto IL_01de;
				}
			}
			else
			{
				num3 = 1;
			}
			val2.SetSiblingIndex(num);
			goto IL_01de;
			IL_01de:
			if (num3 != 0)
			{
				RectTransform val8 = (RectTransform)(object)((val is RectTransform) ? val : null);
				if ((Object)(object)val8 != (Object)null)
				{
					LayoutRebuilder.ForceRebuildLayoutImmediate(val8);
				}
				RebuildMainMenuNavigation(menu);
			}
			if (flag)
			{
				Plugin.LogInfo($"Aim exclusions: main menu button at index {val2.GetSiblingIndex()} " + $"(quit={num2}, children={val.childCount})");
			}
		}

		private static Transform FindMenuButtonRow(Transform buttonsContainer)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			if ((Object)(object)buttonsContainer == (Object)null)
			{
				return null;
			}
			foreach (Transform item in buttonsContainer)
			{
				Transform val = item;
				if (((Object)val).name == "StayCombatFixAimButton")
				{
					return val;
				}
			}
			return null;
		}

		private static void RemoveStaleMenuButtons(Transform menuRoot)
		{
			if ((Object)(object)menuRoot == (Object)null)
			{
				return;
			}
			List<Transform> list = new List<Transform>();
			Transform[] componentsInChildren = ((Component)menuRoot).GetComponentsInChildren<Transform>(true);
			foreach (Transform val in componentsInChildren)
			{
				if (((Object)val).name == "StayCombatFixAimButton")
				{
					list.Add(val);
				}
			}
			foreach (Transform item in list)
			{
				Object.Destroy((Object)(object)((Component)item).gameObject);
			}
		}

		private static void RebuildMainMenuNavigation(MainMenuButtons menu)
		{
			try
			{
				AccessTools.Method(typeof(MainMenuButtons), "RebuildNavigation", (Type[])null, (Type[])null)?.Invoke(menu, null);
			}
			catch (Exception ex)
			{
				Plugin.LogWarning("Aim exclusions: failed to rebuild main menu navigation: " + ex.Message);
			}
		}

		internal static void NotifyContentChanged()
		{
			if (!IsOpen)
			{
				return;
			}
			try
			{
				Refresh();
			}
			catch (Exception arg)
			{
				Plugin.LogWarning($"Aim exclusions: refresh after content change failed: {arg}");
			}
		}

		internal static void Open()
		{
			AimExclusionStore.EnsureDiscovered(force: true);
			EnsurePanelReady();
			if ((Object)(object)_canvas != (Object)null)
			{
				((Behaviour)_canvas).enabled = true;
			}
			_panel.SetActive(true);
			SetMenuInputEnabled(enabled: true);
			try
			{
				Refresh(resetScroll: true);
				SyncScrollAreaBelowHeader();
			}
			catch (Exception arg)
			{
				Plugin.LogWarning($"Aim exclusions: refresh failed: {arg}");
			}
			Plugin.LogInfo("Aim exclusions: menu opened with " + AimExclusionStore.DiscoverySummary);
		}

		private static void CloseMenu()
		{
			_searchFocused = false;
			_listeningForBattleDashKey = false;
			_listeningForAutoShootKey = false;
			SetMenuInputEnabled(enabled: false);
			if ((Object)(object)_panel != (Object)null)
			{
				_panel.SetActive(false);
			}
			if ((Object)(object)_canvas != (Object)null)
			{
				((Behaviour)_canvas).enabled = false;
			}
		}

		private static void SetMenuInputEnabled(bool enabled)
		{
			if ((Object)(object)_searchInputBehaviour != (Object)null)
			{
				((Behaviour)_searchInputBehaviour).enabled = enabled;
			}
		}

		private static void SyncScrollAreaBelowHeader()
		{
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_panel == (Object)null)
			{
				return;
			}
			Transform obj = _panel.transform.Find("Header");
			RectTransform val = (RectTransform)(object)((obj is RectTransform) ? obj : null);
			Transform obj2 = _panel.transform.Find("Scroll");
			RectTransform val2 = (RectTransform)(object)((obj2 is RectTransform) ? obj2 : null);
			if (!((Object)(object)val == (Object)null) && !((Object)(object)val2 == (Object)null))
			{
				Canvas.ForceUpdateCanvases();
				LayoutRebuilder.ForceRebuildLayoutImmediate(val);
				float preferredHeight = LayoutUtility.GetPreferredHeight(val);
				float[] obj3 = new float[3] { 448f, preferredHeight, 0f };
				Rect rect = val.rect;
				obj3[2] = ((Rect)(ref rect)).height;
				float num = Mathf.Max(obj3);
				rect = val.rect;
				if (preferredHeight > ((Rect)(ref rect)).height)
				{
					val.sizeDelta = new Vector2(0f, preferredHeight);
				}
				val2.offsetMin = new Vector2(24f, 28f);
				val2.offsetMax = new Vector2(-24f, 0f - (num + 6f));
			}
		}

		private static void EnsurePanelReady()
		{
			if ((Object)(object)_panel != (Object)null && TryResolvePanelReferences())
			{
				return;
			}
			if ((Object)(object)_panel != (Object)null)
			{
				PanelLayoutMarker component = _panel.GetComponent<PanelLayoutMarker>();
				if ((Object)(object)component != (Object)null && component.Version != 16)
				{
					DestroyPanelRoot();
				}
				else if (!TryResolvePanelReferences())
				{
					DestroyPanelRoot();
				}
			}
			if ((Object)(object)_panel == (Object)null)
			{
				BuildPanel();
			}
			else
			{
				TryResolvePanelReferences();
			}
		}

		private static bool TryResolvePanelReferences()
		{
			if ((Object)(object)_panel == (Object)null)
			{
				return false;
			}
			PanelLayoutMarker component = _panel.GetComponent<PanelLayoutMarker>();
			if ((Object)(object)component == (Object)null || component.Version != 16)
			{
				return false;
			}
			Transform obj = _panel.transform.Find("Scroll");
			_scroll = ((obj != null) ? ((Component)obj).GetComponent<ScrollRect>() : null);
			_listRoot = _panel.transform.Find("Scroll/Viewport/Content");
			if ((Object)(object)_scroll == (Object)null || (Object)(object)_listRoot == (Object)null)
			{
				return false;
			}
			if ((Object)(object)_scroll.content == (Object)null)
			{
				? val = _scroll;
				Transform listRoot = _listRoot;
				((ScrollRect)val).content = (RectTransform)(object)((listRoot is RectTransform) ? listRoot : null);
			}
			Transform val2 = _panel.transform.Find("Header");
			if ((Object)(object)val2 != (Object)null)
			{
				Transform obj2 = val2.Find("Summary");
				_summaryText = FindTmpText((obj2 != null) ? ((Component)obj2).gameObject : null);
			}
			if ((Object)(object)_canvasRoot != (Object)null)
			{
				_canvas = _canvasRoot.GetComponent<Canvas>();
				_searchInputBehaviour = _canvasRoot.GetComponent<SearchInputBehaviour>();
			}
			EnsureScrollListener();
			return true;
		}

		private static void EnsureScrollListener()
		{
			if (!((Object)(object)_scroll == (Object)null) && !_scrollListenerRegistered)
			{
				((UnityEvent<Vector2>)(object)_scroll.onValueChanged).AddListener((UnityAction<Vector2>)delegate
				{
					BindVisibleRows();
				});
				_scrollListenerRegistered = true;
			}
		}

		private static void DestroyPanelRoot()
		{
			ClearRowPool();
			_scrollListenerRegistered = false;
			if ((Object)(object)_canvasRoot != (Object)null)
			{
				Object.Destroy((Object)(object)_canvasRoot);
			}
			_canvasRoot = null;
			_canvas = null;
			_panel = null;
			_listRoot = null;
			_scroll = null;
			_summaryText = null;
			_searchText = null;
			_rowButtonTemplate = null;
			_searchInputBehaviour = null;
			_firstVisibleIndex = -1;
			SourceFilterChips.Clear();
			CombatFilterChips.Clear();
		}

		private static void ClearRowPool()
		{
			foreach (VirtualRow item in RowPool)
			{
				if ((Object)(object)item?.Row != (Object)null)
				{
					Object.Destroy((Object)(object)item.Row);
				}
			}
			RowPool.Clear();
		}

		private static void BuildPanel()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			//IL_0016: 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_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: 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_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c5: Expected O, but got Unknown
			//IL_0261: Unknown result type (might be due to invalid IL or missing references)
			//IL_0296: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02be: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0325: Unknown result type (might be due to invalid IL or missing references)
			//IL_0334: Unknown result type (might be due to invalid IL or missing references)
			//IL_0370: Unknown result type (might be due to invalid IL or missing references)
			//IL_037f: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_0405: Unknown result type (might be due to invalid IL or missing references)
			//IL_0414: Unknown result type (might be due to invalid IL or missing references)
			//IL_0465: Unknown result type (might be due to invalid IL or missing references)
			//IL_0474: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_04bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_04fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_050a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0546: Unknown result type (might be due to invalid IL or missing references)
			//IL_0555: Unknown result type (might be due to invalid IL or missing references)
			//IL_0590: Unknown result type (might be due to invalid IL or missing references)
			//IL_059f: Unknown result type (might be due to invalid IL or missing references)
			//IL_05f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_063a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0649: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("StayCombatFix Aim Exclusions");
			_canvasRoot = val;
			Object.DontDestroyOnLoad((Object)val);
			_canvas = val.AddComponent<Canvas>();
			_canvas.renderMode = (RenderMode)0;
			_canvas.sortingOrder = 20000;
			((Behaviour)_canvas).enabled = false;
			CanvasScaler obj = val.AddComponent<CanvasScaler>();
			obj.uiScaleMode = (ScaleMode)1;
			obj.referenceResolution = new Vector2(1280f, 720f);
			val.AddComponent<GraphicRaycaster>();
			_searchInputBehaviour = val.AddComponent<SearchInputBehaviour>();
			((Behaviour)_searchInputBehaviour).enabled = false;
			_panel = CreatePanel(val.transform, "Panel", new Color(0.03f, 0.03f, 0.03f, 0.94f));
			_panel.AddComponent<PanelLayoutMarker>().Version = 16;
			RectTransform component = _panel.GetComponent<RectTransform>();
			component.anchorMin = new Vector2(0.06f, 0.04f);
			component.anchorMax = new Vector2(0.94f, 0.96f);
			component.offsetMin = Vector2.zero;
			component.offsetMax = Vector2.zero;
			BuildScrollArea();
			GameObject obj2 = CreatePanel(_panel.transform, "Header", new Color(0.03f, 0.03f, 0.03f, 0.98f));
			RectTransform component2 = obj2.GetComponent<RectTransform>();
			component2.anchorMin = new Vector2(0f, 1f);
			component2.anchorMax = new Vector2(1f, 1f);
			component2.pivot = new Vector2(0.5f, 1f);
			component2.anchoredPosition = Vector2.zero;
			component2.sizeDelta = new Vector2(0f, 448f);
			((Graphic)obj2.GetComponent<Image>()).raycastTarget = false;
			VerticalLayoutGroup obj3 = obj2.AddComponent<VerticalLayoutGroup>();
			((LayoutGroup)obj3).padding = new RectOffset(12, 12, 8, 6);
			((HorizontalOrVerticalLayoutGroup)obj3).spacing = 6f;
			((HorizontalOrVerticalLayoutGroup)obj3).childControlWidth = true;
			((HorizontalOrVerticalLayoutGroup)obj3).childControlHeight = true;
			((HorizontalOrVerticalLayoutGroup)obj3).childForceExpandWidth = true;
			((HorizontalOrVerticalLayoutGroup)obj3).childForceExpandHeight = false;
			CreateLayoutTextRow(obj2.transform, "Aim Exclusions", 32f, 26f, TextAlignment.Center);
			_summaryText = CreateLayoutTextRow(obj2.transform, string.Empty, 22f, 14f, TextAlignment.Center, null, "Summary");
			CreateLayoutTextRow(obj2.transform, "Exclude: disables crosshair aim and ballistic overrides while possessed.\nRange ON/OFF: out-of-range attack blocking (independent of Exclude).\nSpread ON/OFF: volley-style random projectile spread (requires crosshair aim).\nVert ON/OFF: mod weapon hold (crosshair tilt/PID on held weapons). Vert OFF: vanilla assigned hold positions only; crosshair attack aim and ballistic correction stay on.\nDash ON/OFF: melee body dash/lunge in first person (requires crosshair aim).\nSpread/Dash row buttons depend on unit combat type (Melee/Ranged/Mixed). Vert applies to every unit.\nIn-battle dash hotkey toggles dash for the possessed unit instance until the battle ends.\nBulk buttons apply to every discovered unit. Search supports tag:custom tag:melee etc.", 104f, 12f, TextAlignment.Left, SubtitleColor, "Guide");
			Transform parent = CreateHeaderLayoutRow(obj2.transform, "Toolbar", 36f);
			CreateSearchBox(parent, new Vector2(0f, 0f), new Vector2(520f, 34f));
			CreateButton(parent, "Close", new Vector2(-24f, 0f), new Vector2(120f, 36f), CloseMenu, anchorRight: true);
			BuildFilterToolbar(obj2.transform);
			Transform parent2 = CreateHeaderLayoutRow(obj2.transform, "BulkToolbar1", 36f);
			CreateButton(parent2, "Exclude All", new Vector2(0f, 0f), new Vector2(150f, 34f), delegate
			{
				AimExclusionStore.SetAllExcluded(excluded: true);
				Refresh(resetScroll: true);
			});
			CreateButton(parent2, "Unexclude All", new Vector2(158f, 0f), new Vector2(150f, 34f), delegate
			{
				AimExclusionStore.SetAllExcluded(excluded: false);
				Refresh(resetScroll: true);
			});
			CreateButton(parent2, "Range Off All", new Vector2(316f, 0f), new Vector2(150f, 34f), delegate
			{
				AimExclusionStore.SetAllRangeGate(enabled: false);
				Refresh(resetScroll: true);
			});
			CreateButton(parent2, "Range On All", new Vector2(474f, 0f), new Vector2(150f, 34f), delegate
			{
				AimExclusionStore.SetAllRangeGate(enabled: true);
				Refresh(resetScroll: true);
			});
			Transform parent3 = CreateHeaderLayoutRow(obj2.transform, "BulkToolbar2", 36f);
			CreateButton(parent3, "Spread Off All", new Vector2(0f, 0f), new Vector2(150f, 34f), delegate
			{
				AimExclusionStore.SetAllVolleySpread(enabled: false);
				Refresh(resetScroll: true);
			});
			CreateButton(parent3, "Spread On All", new Vector2(158f, 0f), new Vector2(150f, 34f), delegate
			{
				AimExclusionStore.SetAllVolleySpread(enabled: true);
				Refresh(resetScroll: true);
			});
			CreateButton(parent3, "Dash Off All", new Vector2(316f, 0f), new Vector2(150f, 34f), delegate
			{
				AimExclusionStore.SetAllMeleeDash(enabled: false);
				Refresh(resetScroll: true);
			});
			CreateButton(parent3, "Dash On All", new Vector2(474f, 0f), new Vector2(150f, 34f), delegate
			{
				AimExclusionStore.SetAllMeleeDash(enabled: true);
				Refresh(resetScroll: true);
			});
			CreateButton(parent3, "Reset Defaults", new Vector2(632f, 0f), new Vector2(150f, 34f), delegate
			{
				AimExclusionStore.ResetToDefaults();
				Refresh(resetScroll: true);
			});
			Transform parent4 = CreateHeaderLayoutRow(obj2.transform, "BulkToolbar3", 36f);
			CreateButton(parent4, "Vert Off All", new Vector2(0f, 0f), new Vector2(150f, 34f), delegate
			{
				AimExclusionStore.SetAllVerticalAim(enabled: false);
				Refresh(resetScroll: true);
			});
			CreateButton(parent4, "Vert On All", new Vector2(158f, 0f), new Vector2(150f, 34f), delegate
			{
				AimExclusionStore.SetAllVerticalAim(enabled: true);
				Refresh(resetScroll: true);
			});
			BuildBattleDashKeySettingsRow(obj2.transform);
			BuildAutoShootKeySettingsRow(obj2.transform);
			obj2.transform.SetAsLastSibling();
			EnsureRowButtonTemplate(val.transform);
			EnsureScrollListener();
			SyncScrollAreaBelowHeader();
			_panel.SetActive(false);
		}

		private static void BuildBattleDashKeySettingsRow(Transform header)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: 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_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: 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)
			Transform parent = CreateHeaderLayoutRow(header, "SettingsToolbar", 36f);
			_battleDashKeyLabel = CreateLabel(parent, "In-battle dash toggle key:", 14f, TextAlignment.Left, new Vector2(0f, 0f), new Vector2(220f, 34f), stretch: false, layoutChild: false, SubtitleColor);
			_battleDashKeyButton = CreateButton(parent, AimExclusionStore.FormatKeyName(AimExclusionStore.GetBattleDashToggleKey()), new Vector2(228f, 0f), new Vector2(120f, 34f), delegate
			{
			});
			CreateButton(parent, "Change Key", new Vector2(356f, 0f), new Vector2(120f, 34f), delegate
			{
				SetMenuInputEnabled(enabled: true);
				_listeningForBattleDashKey = true;
				UpdateBattleDashKeyButtonLabel();
			});
			UpdateBattleDashKeyButtonLabel();
		}

		private static void BuildAutoShootKeySettingsRow(Transform header)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: 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_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: 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)
			Transform parent = CreateHeaderLayoutRow(header, "AutoShootSettingsToolbar", 36f);
			_autoShootKeyLabel = CreateLabel(parent, "In-battle auto-shoot toggle key:", 14f, TextAlignment.Left, new Vector2(0f, 0f), new Vector2(220f, 34f), stretch: false, layoutChild: false, SubtitleColor);
			_autoShootKeyButton = CreateButton(parent, AimExclusionStore.FormatKeyName(AimExclusionStore.GetAutoShootToggleKey()), new Vector2(228f, 0f), new Vector2(120f, 34f), delegate
			{
			});
			CreateButton(parent, "Change Key", new Vector2(356f, 0f), new Vector2(120f, 34f), delegate
			{
				SetMenuInputEnabled(enabled: true);
				_listeningForAutoShootKey = true;
				UpdateAutoShootKeyButtonLabel();
			});
			UpdateAutoShootKeyButtonLabel();
		}

		private static void UpdateAutoShootKeyButtonLabel()
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_autoShootKeyButton == (Object)null))
			{
				string value = (_listeningForAutoShootKey ? "Press key..." : AimExclusionStore.FormatKeyName(AimExclusionStore.GetAutoShootToggleKey()));
				SetTmpText(((Component)_autoShootKeyButton).gameObject, value);
			}
		}

		private static void UpdateBattleDashKeyButtonLabel()
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_battleDashKeyButton == (Object)null))
			{
				string value = (_listeningForBattleDashKey ? "Press key..." : AimExclusionStore.FormatKeyName(AimExclusionStore.GetBattleDashToggleKey()));
				SetTmpText(((Component)_battleDashKeyButton).gameObject, value);
			}
		}

		private static void GetCombatToggleVisibility(bool? isRanged, out bool showSpread, out bool showVertical, out bool showDash)
		{
			showSpread = isRanged != false;
			showVertical = true;
			showDash = !isRanged.GetValueOrDefault();
		}

		private static float ActionButtonRightOffset(int slotFromRight)
		{
			return 0f - (84f * (float)(slotFromRight + 1) + 8f * (float)slotFromRight + 4f);
		}

		private static void LayoutRowActionButtons(VirtualRow virtualRow, AimExclusionStore.UnitEntry entry, out float textRightMargin)
		{
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			GetCombatToggleVisibility(entry?.isRanged, out var showSpread, out var showVertical, out var showDash);
			((Component)virtualRow.SpreadButton).gameObject.SetActive(showSpread);
			((Component)virtualRow.VerticalButton).gameObject.SetActive(showVertical);
			((Component)virtualRow.DashButton).gameObject.SetActive(showDash);
			List<Button> list = new List<Button> { virtualRow.ExcludeButton, virtualRow.RangeButton };
			if (showSpread)
			{
				list.Add(virtualRow.SpreadButton);
			}
			if (showVertical)
			{
				list.Add(virtualRow.VerticalButton);
			}
			if (showDash)
			{
				list.Add(virtualRow.DashButton);
			}
			for (int i = 0; i < list.Count; i++)
			{
				((Component)list[list.Count - 1 - i]).GetComponent<RectTransform>().anchoredPosition = new Vector2(ActionButtonRightOffset(i), -8f);
			}
			int count = list.Count;
			textRightMargin = 0f - (84f * (float)count + 8f * (float)Mathf.Max(0, count - 1) + 36f);
		}

		private static void BuildScrollArea()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: 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_003d: 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_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: 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_00b3: 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_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: 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_015c: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("Scroll");
			val.transform.SetParent(_panel.transform, false);
			val.transform.SetAsFirstSibling();
			RectTransform obj = val.AddComponent<RectTransform>();
			obj.anchorMin = Vector2.zero;
			obj.anchorMax = Vector2.one;
			obj.offsetMin = new Vector2(24f, 28f);
			obj.offsetMax = new Vector2(-24f, -454f);
			ScrollRect val2 = val.AddComponent<ScrollRect>();
			GameObject val3 = CreatePanel(val.transform, "Viewport", new Color(0f, 0f, 0f, 0.22f));
			RectTransform component = val3.GetComponent<RectTransform>();
			component.anchorMin = Vector2.zero;
			component.anchorMax = Vector2.one;
			component.offsetMin = Vector2.zero;
			component.offsetMax = Vector2.zero;
			val3.AddComponent<RectMask2D>();
			GameObject val4 = new GameObject("Content");
			val4.transform.SetParent(val3.transform, false);
			_listRoot = val4.transform;
			RectTransform val5 = val4.AddComponent<RectTransform>();
			val5.anchorMin = new Vector2(0f, 1f);
			val5.anchorMax = new Vector2(1f, 1f);
			val5.pivot = new Vector2(0.5f, 1f);
			val5.anchoredPosition = Vector2.zero;
			val5.sizeDelta = new Vector2(0f, 56f);
			val2.viewport = component;
			val2.content = val5;
			val2.horizontal = false;
			val2.vertical = true;
			val2.movementType = (MovementType)2;
			val2.scrollSensitivity = 30f;
			_scroll = val2;
		}

		private static void EnsureRowButtonTemplate(Transform parent)
		{
			if (!((Object)(object)_rowButtonTemplate != (Object)null) && !((Object)(object)_menuButtonSource == (Object)null))
			{
				_rowButtonTemplate = Object.Instantiate<GameObject>(_menuButtonSource, parent, false);
				((Object)_rowButtonTemplate).name = "RowButtonTemplate";
				_rowButtonTemplate.SetActive(false);
				DisableLocalization(_rowButtonTemplate);
				if ((Object)(object)_textTemplate == (Object)null)
				{
					_textTemplate = FindTmpText(_rowButtonTemplate);
				}
			}
		}

		private static void Refresh(bool resetScroll = false)
		{
			if (!TryResolvePanelReferences())
			{
				Plugin.LogWarning("Aim exclusions: list root missing; rebuilding panel");
				DestroyPanelRoot();
				BuildPanel();
				TryResolvePanelReferences();
				if ((Object)(object)_listRoot == (Object)null)
				{
					return;
				}
			}
			RebuildFilteredEntries();
			UpdateContentHeight(FilteredEntries.Count);
			UpdateSummaryText();
			UpdateFilterChipVisuals();
			if (resetScroll && (Object)(object)_scroll != (Object)null)
			{
				_scroll.verticalNormalizedPosition = 1f;
			}
			_firstVisibleIndex = -1;
			BindVisibleRows(force: true);
		}

		private static void RebuildFilteredEntries()
		{
			FilteredEntries.Clear();
			SourceFilter sourceFilter = _sourceFilter;
			CombatFilter combatFilter = _combatFilter;
			string textFilter = ParseSearchTags(ref sourceFilter, ref combatFilter);
			FilteredEntries.AddRange(from u in AimExclusionStore.Units
				where MatchesSource(u, sourceFilter) && MatchesCombat(u, combatFilter) && MatchesTextSearch(textFilter, u)
				orderby u.name
				select u);
		}

		private static string ParseSearchTags(ref SourceFilter sourceFilter, ref CombatFilter combatFilter)
		{
			string text = (_search ?? string.Empty).Trim();
			if (string.IsNullOrEmpty(text))
			{
				return string.Empty;
			}
			string[] array = text.Split(new char[1] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
			List<string> list = new List<string>(array.Length);
			string[] array2 = array;
			foreach (string text2 in array2)
			{
				if (!text2.StartsWith("tag:", StringComparison.OrdinalIgnoreCase))
				{
					list.Add(text2);
					continue;
				}
				switch (text2.Substring(4).Trim().ToLowerInvariant())
				{
				case "builtin":
				case "vanilla":
				case "built-in":
				case "official":
				case "mod":
					sourceFilter = SourceFilter.BuiltIn;
					break;
				case "custom":
					sourceFilter = SourceFilter.Custom;
					break;
				case "melee":
					combatFilter = CombatFilter.Melee;
					break;
				case "ranged":
					combatFilter = CombatFilter.Ranged;
					break;
				case "all":
					sourceFilter = SourceFilter.All;
					combatFilter = CombatFilter.All;
					break;
				default:
					list.Add(text2);
					break;
				}
			}
			return string.Join(" ", list).Trim().ToLowerInvariant();
		}

		private static bool MatchesSource(AimExclusionStore.UnitEntry entry, SourceFilter filter)
		{
			if (filter == SourceFilter.All)
			{
				return true;
			}
			bool flag = (entry?.source ?? "Built-in") == "Custom";
			return filter switch
			{
				SourceFilter.BuiltIn => !flag, 
				SourceFilter.Custom => flag, 
				_ => true, 
			};
		}

		private static bool MatchesCombat(AimExclusionStore.UnitEntry entry, CombatFilter filter)
		{
			switch (filter)
			{
			case CombatFilter.All:
				return true;
			case CombatFilter.Ranged:
				return entry?.isRanged.GetValueOrDefault() ?? false;
			default:
				if (entry == null)
				{
					return false;
				}
				return entry.isRanged == false;
			}
		}

		private static bool MatchesTextSearch(string filter, AimExclusionStore.UnitEntry entry)
		{
			if (string.IsNullOrEmpty(filter))
			{
				return true;
			}
			string text = AimExclusionStore.FormatCombatTag(entry?.isRanged);
			return Matches(filter, entry?.name, entry?.source, text);
		}

		private static void BuildFilterToolbar(Transform header)
		{
			//IL_0034: 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_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: 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)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			SourceFilterChips.Clear();
			CombatFilterChips.Clear();
			Transform parent = CreateHeaderLayoutRow(header, "FilterToolbar", 36f);
			RegisterSourceFilterChip(parent, "All", new Vector2(0f, 0f), SourceFilter.All);
			RegisterSourceFilterChip(parent, "Built-in", new Vector2(58f, 0f), SourceFilter.BuiltIn);
			RegisterSourceFilterChip(parent, "Custom", new Vector2(150f, 0f), SourceFilter.Custom);
			RegisterCombatFilterChip(parent, "Any", new Vector2(230f, 0f), CombatFilter.All);
			RegisterCombatFilterChip(parent, "Melee", new Vector2(290f, 0f), CombatFilter.Melee);
			RegisterCombatFilterChip(parent, "Ranged", new Vector2(358f, 0f), CombatFilter.Ranged);
			UpdateFilterChipVisuals();
		}

		private static void RegisterSourceFilterChip(Transform parent, string label, Vector2 position, SourceFilter filter)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			Button val = CreateFilterChip(parent, label, position, delegate
			{
				SetSourceFilter(filter);
			});
			if ((Object)(object)val != (Object)null)
			{
				SourceFilterChips.Add((val, filter));
			}
		}

		private static void RegisterCombatFilterChip(Transform parent, string label, Vector2 position, CombatFilter filter)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			Button val = CreateFilterChip(parent, label, position, delegate
			{
				SetCombatFilter(filter);
			});
			if ((Object)(object)val != (Object)null)
			{
				CombatFilterChips.Add((val, filter));
			}
		}

		private static void UpdateFilterChipVisuals()
		{
			foreach (var (button, sourceFilter) in SourceFilterChips)
			{
				SetActionButtonActive(button, _sourceFilter == sourceFilter);
			}
			foreach (var (button2, combatFilter) in CombatFilterChips)
			{
				SetActionButtonActive(button2, _combatFilter == combatFilter);
			}
		}

		private static void SetSourceFilter(SourceFilter filter)
		{
			_sourceFilter = filter;
			Refresh(resetScroll: true);
		}

		private static void SetCombatFilter(CombatFilter filter)
		{
			_combatFilter = filter;
			Refresh(resetScroll: true);
		}

		private static Button CreateFilterChip(Transform parent, string label, Vector2 position, Action onClick)
		{
			//IL_0002: 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)
			return CreateButton(parent, label, position, new Vector2(72f, 30f), onClick);
		}

		private static void UpdateSummaryText()
		{
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			int num = FilteredEntries.Count((AimExclusionStore.UnitEntry u) => u.excluded);
			int count = AimExclusionStore.Units.Count;
			SetText(_summaryText, $"Showing {FilteredEntries.Count} of {count} units · {num} excluded in list · {AimExclusionStore.DiscoverySummary}", (float?)14f, TextAlignment.Center, (Color?)new Color(0.78f, 0.8f, 0.84f, 1f), richText: false);
		}

		private static float GetViewportHeight()
		{
			//IL_0023: 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)
			ScrollRect scroll = _scroll;
			if ((Object)(object)((scroll != null) ? scroll.viewport : null) != (Object)null)
			{
				Rect rect = _scroll.viewport.rect;
				return ((Rect)(ref rect)).height;
			}
			return 600f;
		}

		private static int GetRequiredPoolSize()
		{
			int num = Mathf.CeilToInt(GetViewportHeight() / 56f) + 4;
			return Mathf.Max(12, num);
		}

		private static void EnsureRowPool()
		{
			int requiredPoolSize = GetRequiredPoolSize();
			while (RowPool.Count < requiredPoolSize)
			{
				VirtualRow virtualRow = CreateVirtualRowShell();
				((Object)virtualRow.Row).name = "Row";
				virtualRow.Row.transform.SetParent(_listRoot, false);
				virtualRow.Row.SetActive(false);
				RowPool.Add(virtualRow);
			}
		}

		private static int GetFirstVisibleIndex()
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			Transform listRoot = _listRoot;
			RectTransform val = (RectTransform)(object)((listRoot is RectTransform) ? listRoot : null);
			if ((Object)(object)val == (Object)null)
			{
				return 0;
			}
			return Mathf.Max(0, Mathf.FloorToInt(val.anchoredPosition.y / 56f));
		}

		private static void BindVisibleRows(bool force = false)
		{
			if ((Object)(object)_listRoot == (Object)null)
			{
				return;
			}
			if (FilteredEntries.Count == 0)
			{
				foreach (VirtualRow item in RowPool)
				{
					if ((Object)(object)item?.Row != (Object)null)
					{
						item.Row.SetActive(false);
					}
				}
				_firstVisibleIndex = 0;
				return;
			}
			EnsureRowPool();
			int firstVisibleIndex = GetFirstVisibleIndex();
			if (!force && firstVisibleIndex == _firstVisibleIndex)
			{
				return;
			}
			_firstVisibleIndex = firstVisibleIndex;
			for (int i = 0; i < RowPool.Count; i++)
			{
				int num = firstVisibleIndex + i;
				VirtualRow virtualRow = RowPool[i];
				if (num >= FilteredEntries.Count)
				{
					virtualRow.DataIndex = -1;
					virtualRow.BoundEntry = null;
					virtualRow.Row.SetActive(false);
				}
				else
				{
					virtualRow.Row.SetActive(true);
					BindVirtualRow(virtualRow, FilteredEntries[num], num);
				}
			}
		}

		private static VirtualRow CreateVirtualRowShell()
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: 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_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Expected O, but got Unknown
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0200: Unknown result type (might be due to invalid IL or missing references)
			//IL_0241: Unknown result type (might be due to invalid IL or missing references)
			//IL_0250: Unknown result type (might be due to invalid IL or missing references)
			//IL_0291: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0331: Unknown result type (might be due to invalid IL or missing references)
			//IL_0340: Unknown result type (might be due to invalid IL or missing references)
			VirtualRow virtualRow = new VirtualRow();
			virtualRow.Row = CreatePanel(_listRoot, "Row", RowEven);
			virtualRow.RowImage = virtualRow.Row.GetComponent<Image>();
			GameObject val = CreatePanel(virtualRow.Row.transform, "IconFrame", new Color(0.07f, 0.07f, 0.07f, 1f));
			RectTransform component = val.GetComponent<RectTransform>();
			component.anchorMin = new Vector2(0f, 1f);
			component.anchorMax = new Vector2(0f, 1f);
			component.pivot = new Vector2(0f, 1f);
			component.anchoredPosition = new Vector2(8f, -8f);
			component.sizeDelta = new Vector2(40f, 40f);
			GameObject val2 = new GameObject("Icon");
			val2.transform.SetParent(val.transform, false);
			RectTransform obj = val2.AddComponent<RectTransform>();
			obj.anchorMin = Vector2.zero;
			obj.anchorMax = Vector2.one;
			obj.offsetMin = new Vector2(3f, 3f);
			obj.offsetMax = new Vector2(-3f, -3f);
			virtualRow.IconImage = val2.AddComponent<Image>();
			virtualRow.IconImage.preserveAspect = true;
			((Graphic)virtualRow.IconImage).raycastTarget = false;
			virtualRow.TextComponent = CreateRowText(virtualRow.Row.transform, string.Empty, 18f, new Vector2(56f, 6f), new Vector2(-464f, -6f), richText: true);
			virtualRow.ExcludeButton = CreateRowActionButton(virtualRow.Row.transform, "Exclude", active: false, new Vector2(-456f, -8f), new Vector2(84f, 40f), delegate
			{
				OnExcludeClicked(virtualRow);
			});
			virtualRow.RangeButton = CreateRowActionButton(virtualRow.Row.transform, "Range ON", active: true, new Vector2(-364f, -8f), new Vector2(84f, 40f), delegate
			{
				OnRangeClicked(virtualRow);
			});
			virtualRow.SpreadButton = CreateRowActionButton(virtualRow.Row.transform, "Spread ON", active: true, new Vector2(-272f, -8f), new Vector2(84f, 40f), delegate
			{
				OnSpreadClicked(virtualRow);
			});
			virtualRow.VerticalButton = CreateRowActionButton(virtualRow.Row.transform, "Vert ON", active: true, new Vector2(-180f, -8f), new Vector2(84f, 40f), delegate
			{
				OnVerticalClicked(virtualRow);
			});
			virtualRow.DashButton = CreateRowActionButton(virtualRow.Row.transform, "Dash ON", active: true, new Vector2(-88f, -8f), new Vector2(84f, 40f), delegate
			{
				OnDashClicked(virtualRow);
			});
			return virtualRow;
		}

		private static void OnExcludeClicked(VirtualRow virtualRow)
		{
			AimExclusionStore.UnitEntry boundEntry = virtualRow.BoundEntry;
			if (boundEntry != null)
			{
				AimExclusionStore.SetUnitExcluded(boundEntry, !boundEntry.excluded);
				BindVirtualRow(virtualRow, boundEntry, virtualRow.DataIndex);
				UpdateSummaryText();
			}
		}

		private static void OnRangeClicked(VirtualRow virtualRow)
		{
			AimExclusionStore.UnitEntry boundEntry = virtualRow.BoundEntry;
			if (boundEntry != null)
			{
				AimExclusionStore.SetUnitRangeGate(boundEntry, !boundEntry.rangeGateEnabled);
				BindVirtualRow(virtualRow, boundEntry, virtualRow.DataIndex);
				UpdateSummaryText();
			}
		}

		private static void OnSpreadClicked(VirtualRow virtualRow)
		{
			AimExclusionStore.UnitEntry boundEntry = virtualRow.BoundEntry;
			if (boundEntry != null)
			{
				AimExclusionStore.SetUnitVolleySpread(boundEntry, !boundEntry.volleySpreadEnabled);
				BindVirtualRow(virtualRow, boundEntry, virtualRow.DataIndex);
				UpdateSummaryText();
			}
		}

		private static void OnVerticalClicked(VirtualRow virtualRow)
		{
			AimExclusionStore.UnitEntry boundEntry = virtualRow.BoundEntry;
			if (boundEntry != null)
			{
				AimExclusionStore.SetUnitVerticalAim(boundEntry, !boundEntry.verticalAimEnabled);
				BindVirtualRow(virtualRow, boundEntry, virtualRow.DataIndex);
				UpdateSummaryText();
			}
		}

		private static void OnDashClicked(VirtualRow virtualRow)
		{
			AimExclusionStore.UnitEntry boundEntry = virtualRow.BoundEntry;
			if (boundEntry != null)
			{
				AimExclusionStore.SetUnitMeleeDash(boundEntry, !boundEntry.meleeDashEnabled);
				BindVirtualRow(virtualRow, boundEntry, virtualRow.DataIndex);
				UpdateSummaryText();
			}
		}

		private static void BindVirtualRow(VirtualRow virtualRow, AimExclusionStore.UnitEntry entry, int dataIndex)
		{
			//IL_01c2: 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)
			virtualRow.BoundEntry = entry;
			virtualRow.DataIndex = dataIndex;
			ConfigureListRowRect(virtualRow.Row, dataIndex);
			ApplyRowHighlight(virtualRow.Row, entry.excluded, dataIndex);
			AimExclusionStore.EnsureEntryIcon(entry);
			if ((Object)(object)virtualRow.IconImage != (Object)null)
			{
				virtualRow.IconImage.sprite = entry.iconSprite;
				((Behaviour)virtualRow.IconImage).enabled = (Object)(object)entry.iconSprite != (Object)null;
			}
			SetActionButtonActive(virtualRow.ExcludeButton, entry.excluded);
			SetActionButtonActive(virtualRow.RangeButton, entry.rangeGateEnabled);
			SetTmpText(((Component)virtualRow.RangeButton).gameObject, entry.rangeGateEnabled ? "Range ON" : "Range OFF");
			GetCombatToggleVisibility(entry.isRanged, out var showSpread, out var showVertical, out var showDash);
			if (showSpread)
			{
				SetActionButtonActive(virtualRow.SpreadButton, entry.volleySpreadEnabled);
				SetTmpText(((Component)virtualRow.SpreadButton).gameObject, entry.volleySpreadEnabled ? "Spread ON" : "Spread OFF");
			}
			if (showVertical)
			{
				SetActionButtonActive(virtualRow.VerticalButton, entry.verticalAimEnabled);
				SetTmpText(((Component)virtualRow.VerticalButton).gameObject, entry.verticalAimEnabled ? "Vert ON" : "Vert OFF");
			}
			if (showDash)
			{
				SetActionButtonActive(virtualRow.DashButton, entry.meleeDashEnabled);
				SetTmpText(((Component)virtualRow.DashButton).gameObject, entry.meleeDashEnabled ? "Dash ON" : "Dash OFF");
			}
			LayoutRowActionButtons(virtualRow, entry, out var textRightMargin);
			if ((Object)(object)virtualRow.TextComponent != (Object)null)
			{
				RectTransform component = virtualRow.TextComponent.GetComponent<RectTransform>();
				if ((Object)(object)component != (Object)null)
				{
					component.offsetMax = new Vector2(textRightMargin, -6f);
				}
			}
			SetText(virtualRow.TextComponent, FormatUnitRichText(entry), 18f, TextAlignment.Left, Color.white, richText: true);
		}

		private static bool Matches(string filter, params string[] values)
		{
			if (!string.IsNullOrEmpty(filter))
			{
				return values.Any((string v) => (v ?? string.Empty).ToLowerInvariant().Contains(filter));
			}
			return true;
		}

		private static void UpdateContentHeight(int rowCount)
		{
			//IL_0033: 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)
			Transform listRoot = _listRoot;
			RectTransform val = (RectTransform)(object)((listRoot is RectTransform) ? listRoot : null);
			if (!((Object)(object)val == (Object)null))
			{
				val.sizeDelta = new Vector2(0f, Mathf.Max(56f, (float)rowCount * 56f + 16f));
				val.anchoredPosition = Vector2.zero;
			}
		}

		private static Button CreateRowActionButton(Transform parent, string label, bool active, Vector2 anchoredPosition, Vector2 size, Action onClick)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			Button obj = CreateRowButton(parent, label, anchoredPosition, size, onClick, anchorRight: true);
			SetActionButtonActive(obj, active);
			return obj;
		}

		private static void SetActionButtonActive(Button button, bool active)
		{
			//IL_0025: 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)
			if (!((Object)(object)button == (Object)null))
			{
				Image component = ((Component)button).GetComponent<Image>();
				if ((Object)(object)component != (Object)null)
				{
					((Graphic)component).color = (active ? ActionOn : ActionOff);
				}
			}
		}

		private static void ApplyRowHighlight(GameObject row, bool excluded, int rowIndex)
		{
			//IL_0031: 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_0023: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)row == (Object)null))
			{
				Image component = row.GetComponent<Image>();
				if ((Object)(object)component != (Object)null)
				{
					((Graphic)component).color = (excluded ? RowExcluded : ((rowIndex % 2 == 0) ? RowEven : RowOdd));
				}
			}
		}

		private static void ConfigureListRowRect(GameObject row, int rowIndex)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			RectTransform component = row.GetComponent<RectTransform>();
			component.anchorMin = new Vector2(0f, 1f);
			component.anchorMax = new Vector2(1f, 1f);
			component.pivot = new Vector2(0.5f, 1f);
			component.anchoredPosition = new Vector2(0f, (float)(-rowIndex) * 56f);
			component.sizeDelta = new Vector2(0f, 56f);
		}

		private static string FormatUnitRichText(AimExclusionStore.UnitEntry entry)
		{
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			string value = HumanizeName(string.IsNullOrWhiteSpace(entry.name) ? entry.guid : entry.name);
			string value2 = (string.IsNullOrWhiteSpace(entry.source) ? "Unknown" : entry.source);
			string value3 = AimExclusionStore.FormatCombatTag(entry.isRanged);
			string text = (entry.rangeGateEnabled ? string.Empty : " · range gate off");
			GetCombatToggleVisibility(entry.isRanged, out var showSpread, out var showVertical, out var showDash);
			if (showSpread && !entry.volleySpreadEnabled)
			{
				text += " · spread off";
			}
			if (showVertical && !entry.verticalAimEnabled)
			{
				text += " · vert off";
			}
			if (showDash && !entry.meleeDashEnabled)
			{
				text += " · dash off";
			}
			return "<size=18>" + EscapeRichText(value) + "</size>\n<size=13><color=#" + ColorToHex(SubtitleColor) + ">" + EscapeRichText(value2) + " · " + EscapeRichText(value3) + text + "</color></size>";
		}

		private static string HumanizeName(string value)
		{
			if (string.IsNullOrWhiteSpace(value))
			{
				return "Unknown";
			}
			string text = value;
			if (text.StartsWith("UNIT_", StringComparison.OrdinalIgnoreCase))
			{
				text = text.Substring(5);
			}
			return text.Replace('_', ' ');
		}

		private static string EscapeRichText(string value)
		{
			return (value ?? string.Empty).Replace("<", "\\<").Replace(">", "\\>");
		}

		private static string ColorToHex(Color color)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			return ColorUtility.ToHtmlStringRGB(color);
		}

		private static Button CreateRowButton(Transform parent, string label, Vector2 anchoredPosition, Vector2 size, Action onClick, bool anchorRight = false)
		{
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: 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_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Expected O, but got Unknown
			if ((Object)(object)_rowButtonTemplate != (Object)null)
			{
				GameObject obj = Object.Instantiate<GameObject>(_rowButtonTemplate, parent, false);
				obj.SetActive(true);
				DisableLocalization(obj);
				RectTransform component = obj.GetComponent<RectTransform>();
				if (anchorRight)
				{
					component.anchorMin = new Vector2(1f, 1f);
					component.anchorMax = new Vector2(1f, 1f);
					component.pivot = new Vector2(1f, 1f);
				}
				else
				{
					component.anchorMin = new Vector2(0f, 1f);
					component.anchorMax = new Vector2(0f, 1f);
					component.pivot = new Vector2(0f, 1f);
				}
				component.anchoredPosition = anchoredPosition;
				component.sizeDelta = size;
				Button component2 = obj.GetComponent<Button>();
				((UnityEventBase)component2.onClick).RemoveAllListeners();
				if (onClick != null)
				{
					((UnityEvent)component2.onClick).AddListener((UnityAction)delegate
					{
						onClick();
					});
				}
				SetTmpText(obj, label);
				ConfigureRowButtonHitArea(obj);
				return component2;
			}
			return CreateButton(parent, label, anchoredPosition, size, onClick, anchorRight);
		}

		private static void ConfigureRowButtonHitArea(GameObject buttonObject)
		{
			if ((Object)(object)buttonObject == (Object)null)
			{
				return;
			}
			Image component = buttonObject.GetComponent<Image>();
			if ((Object)(object)component != (Object)null)
			{
				((Graphic)component).raycastTarget = true;
			}
			Component[] componentsInChildren = buttonObject.GetComponentsInChildren<Component>(true);
			foreach (Component val in componentsInChildren)
			{
				if (!((Object)(object)val == (Object)null))
				{
					string name = ((object)val).GetType().Name;
					if (!(name != "TextMeshProUGUI") || !(name != "TMP_Text"))
					{
						StretchTextRect(val);
						((object)val).GetType().GetProperty("raycastTarget")?.SetValue(val, false, null);
					}
				}
			}
		}

		private static Component CreateRowText(Transform parent, string value, float size, Vector2 offsetMin, Vector2 offsetMax, bool richText = false)
		{
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: 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_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: 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_0080: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_textTemplate != (Object)null)
			{
				GameObject obj = Object.Instantiate<GameObject>(_textTemplate.gameObject, parent, false);
				obj.SetActive(true);
				DisableLocalization(obj);
				RectTransform component = obj.GetComponent<RectTransform>();
				component.anchorMin = Vector2.zero;
				component.anchorMax = Vector2.one;
				component.pivot = new Vector2(0.5f, 0.5f);
				component.offsetMin = offsetMin;
				component.offsetMax = offsetMax;
				Component val = FindTmpText(obj);
				SetText(val, value, size, TextAlignment.Left, Color.white, richText);
				if ((Object)(object)val != (Object)null)
				{
					((object)val).GetType().GetProperty("raycastTarget")?.SetValue(val, false, null);
				}
				return val;
			}
			return CreateLabel(parent, value, size, TextAlignment.Left);
		}

		private static GameObject CreatePanel(Transform parent, string name, Color color)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: 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_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Expected O, but got Unknown
			GameObject val = new GameObject(name);
			val.transform.SetParent(parent, false);
			val.AddComponent<RectTransform>();
			((Graphic)val.AddComponent<Image>()).color = color;
			return val;
		}

		private static Transform CreateHeaderLayoutRow(Transform parent, string name, float height)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name);
			val.transform.SetParent(parent, false);
			LayoutElement obj = val.AddComponent<LayoutElement>();
			obj.preferredHeight = height;
			obj.minHeight = height;
			obj.flexibleWidth = 1f;
			return val.transform;
		}

		private static Component CreateLayoutTextRow(Transform parent, string value, float height, float fontSize, TextAlignment alignment, Color? color = null, string name = null)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			//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_005f: 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_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: 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_00a9: Expected O, but got Unknown
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(string.IsNullOrEmpty(name) ? "TextRow" : name);
			val.transform.SetParent(parent, false);
			LayoutElement obj = val.AddComponent<LayoutElement>();
			obj.preferredHeight = height;
			obj.minHeight = height;
			obj.flexibleWidth = 1f;
			GameObject val2 = new GameObject("Text");
			val2.transform.SetParent(val.transform, false);
			RectTransform obj2 = val2.AddComponent<RectTransform>();
			obj2.anchorMin = Vector2.zero;
			obj2.anchorMax = Vector2.one;
			obj2.offsetMin = new Vector2(4f, 0f);
			obj2.offsetMax = new Vector2(-4f, 0f);
			Component val3 = AddTmpText(val2);
			ConfigureLabelText(val3, fontSize, alignment);
			SetText(val3, value, fontSize, alignment, (Color)(((??)color) ?? Color.white), value.Contains("\n"));
			StretchTextRect(val3);
			if ((Object)(object)val3 != (Object)null)
			{
				((object)val3).GetType().GetProperty("raycastTarget")?.SetValue(val3, false, null);
			}
			return val3;
		}

		private static void ConfigureLabelText(Component tmp, float size, TextAlignment alignment)
		{
			if (!((Object)(object)tmp == (Object)null))
			{
				Type type = ((object)tmp).GetType();
				type.GetProperty("enableAutoSizing")?.SetValue(tmp, false, null);
				type.GetProperty("fontSize")?.SetValue(tmp, size, null);
				type.GetProperty("enableWordWrapping")?.SetValue(tmp, true, null);
				PropertyInfo property = type.GetProperty("alignment");
				if (property != null)
				{
					property.SetValue(tmp, Enum.ToObject(property.PropertyType, (int)alignment), null);
				}
			}
		}

		private static Component CreateLabel(Transform parent, string value, float size, TextAlignment alignment, Vector2 pos = default(Vector2), Vector2 sizeDelta = default(Vector2), bool stretch = false, bool layoutChild = false, Color? color = null)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: 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_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: 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_00e1: Expected O, but got Unknown
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("Label");
			val.transform.SetParent(parent, false);
			RectTransform val2 = val.AddComponent<RectTransform>();
			if (layoutChild)
			{
				ConfigureLayoutChildRect(val2, -1f, 36f, flexibleWidth: true);
			}
			else if (stretch)
			{
				val2.anchorMin = new Vector2(0f, 1f);
				val2.anchorMax = new Vector2(1f, 1f);
				val2.pivot = new Vector2(0.5f, 1f);
				val2.anchoredPosition = pos;
				val2.sizeDelta = sizeDelta;
			}
			else
			{
				val2.anchorMin = new Vector2(0f, 1f);
				val2.anchorMax = new Vector2(0f, 1f);
				val2.pivot = new Vector2(0f, 1f);
				val2.anchoredPosition = pos;
				val2.sizeDelta = sizeDelta;
			}
			Component val3 = AddTmpText(val);
			SetText(val3, value, size, alignment, (Color)(((??)color) ?? Color.white));
			StretchTextRect(val3);
			if ((Object)(object)val3 != (Object)null)
			{
				((object)val3).GetType().GetProperty("raycastTarget")?.SetValue(val3, false, null);
			}
			return val3;
		}

		private static Button CreateButton(Transform parent, string label, Vector2 pos, Vector2 size, Action click, bool anchorRight = false, bool layoutChild = false)
		{
			//IL_002e: 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_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: 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_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Expected O, but got Unknown
			//IL_00a6: 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_00d0: 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_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = CreatePanel(parent, label + "Button", new Color(0.18f, 0.18f, 0.18f, 0.96f));
			RectTransform component = val.GetComponent<RectTransform>();
			if (layoutChild)
			{
				ConfigureLayoutChildRect(component, size.x, size.y);
			}
			else
			{
				component.anchorMin = (anchorRight ? new Vector2(1f, 1f) : new Vector2(0f, 1f));
				component.anchorMax = (anchorRight ? new Vector2(1f, 1f) : new Vector2(0f, 1f));
				component.pivot = (anchorRight ? new Vector2(1f, 1f) : new Vector2(0f, 1f));
				component.anchoredPosition = pos;
				component.sizeDelta = size;
			}
			Button val2 = val.AddComponent<Button>();
			if (click != null)
			{
				((UnityEvent)val2.onClick).AddListener((UnityAction)delegate
				{
					click();
				});
			}
			CreateLabel(val.transform, label, 18f, TextAlignment.Center, Vector2.zero, Vector2.zero, stretch: true);
			Component val3 = FindTmpText(val);
			RectTransform val4 = (((Object)(object)val3 != (Object)null) ? val3.GetComponent<RectTransform>() : null);
			if ((Object)(object)val4 != (Object)null && (Object)(object)((Component)val4).gameObject != (Object)(object)val)
			{
				val4.anchorMin = Vector2.zero;
				val4.anchorMax = Vector2.one;
				val4.offsetMin = Vector2.zero;
				val4.offsetMax = Vector2.zero;
			}
			return val2;
		}

		private static void CreateSearchBox(Transform parent, Vector2 pos, Vector2 size)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: 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_00a5: 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_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Expected O, but got Unknown
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Expected O, but got Unknown
			GameObject val = CreatePanel(parent, "Search", new Color(0.14f, 0.14f, 0.14f, 1f));
			RectTransform component = val.GetComponent<RectTransform>();
			component.anchorMin = new Vector2(0f, 1f);
			component.anchorMax = new Vector2(0f, 1f);
			component.pivot = new Vector2(0f, 1f);
			component.anchoredPosition = pos;
			component.sizeDelta = size;
			GameObject val2 = new GameObject("Text");
			val2.transform.SetParent(val.transform, false);
			RectTransform obj = val2.AddComponent<RectTransform>();
			obj.anchorMin = Vector2.zero;
			obj.anchorMax = Vector2.one;
			obj.offsetMin = new Vector2(8f, 2f);
			obj.offsetMax = new Vector2(-8f, -2f);
			_searchText = AddTmpText(val2);
			UpdateSearchLabel();
			ButtonClickedEvent onClick = val.AddComponent<Button>().onClick;
			object obj2 = <>c.<>9__116_0;
			if (obj2 == null)
			{
				UnityAction val3 = delegate
				{
					_searchFocused = true;
					UpdateSearchLabel();
				};
				<>c.<>9__116_0 = val3;
				obj2 = (object)val3;
			}
			((UnityEvent)onClick).AddListener((UnityAction)obj2);
		}

		private static Component AddTmpText(GameObject obj)
		{
			Type type = AccessTools.TypeByName("TMPro.TextMeshProUGUI");
			if (type == null)
			{
				throw new MissingMemberException("TextMeshProUGUI type not found");
			}
			Component obj2 = obj.AddComponent(type);
			CopyTextTemplate(obj2);
			return obj2;
		}

		private static Component FindTmpText(GameObject root)
		{
			Component[] componentsInChildren = root.GetComponentsInChildren<Component>(true);
			foreach (Component val in componentsInChildren)
			{
				if (!((Object)(object)val == (Object)null))
				{
					string name = ((object)val).GetType().Name;
					if (name == "TextMeshProUGUI" || name == "TMP_Text")
					{
						return val;
					}
				}
			}
			return null;
		}

		private static void SetTmpText(GameObject root, string value)
		{
			Component[] componentsInChildren = root.GetComponentsInChildren<Component>(true);
			foreach (Component val in componentsInChildren)
			{
				if (!((Object)(object)val == (Object)null))
				{
					string name = ((object)val).GetType().Name;
					if (name == "TextMeshProUGUI" || name == "TMP_Text")
					{
						SetText(val, value, null, TextAlignment.Center);
					}
				}
			}
		}

		private static void DisableLocalization(GameObject root)
		{
			Component[] componentsInChildren = root.GetComponentsInChildren<Component>(true);
			foreach (Component val in componentsInChildren)
			{
				if (!((Object)(object)val == (Object)null) && !(((object)val).GetType().Name != "LocalizeText"))
				{
					Type type = ((object)val).GetType();
					type.GetProperty("Localized")?.SetValue(val, false, null);
					type.GetProperty("LocaleID")?.SetValue(val, "", null);
					Behaviour val2 = (Behaviour)(object)((val is Behaviour) ? val : null);
					if (val2 != null)
					{
						val2.enabled = false;
					}
				}
			}
		}

		private static void SetText(Component component, string value, float? size, TextAlignment alignment, Color? color = null, bool richText = false)
		{
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)component == (Object)null))
			{
				Type type = ((object)component).GetType();
				if (richText)
				{
					type.GetProperty("richText")?.SetValue(component, true, null);
				}
				type.GetProperty("text")?.SetValue(component, value, null);
				if (size.HasValue)
				{
					type.GetProperty("fontSize")?.SetValue(component, size.Value, null);
				}
				PropertyInfo property = type.GetProperty("alignment");
				if (property != null)
				{
					object value2 = Enum.ToObject(property.PropertyType, (int)alignment);
					property.SetValue(component, value2, null);
				}
				if (color.HasValue)
				{
					type.GetProperty("color")?.SetValue(component, color.Value, null);
				}
				ForceMeshUpdate(component);
			}
		}

		private static void ConfigureLayoutChildRect(RectTransform rect, float preferredWidth = -1f, float preferredHeight = -1f, bool flexibleWidth = false)
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			LayoutElement val = ((Component)rect).gameObject.AddComponent<LayoutElement>();
			if (preferredWidth > 0f)
			{
				val.preferredWidth = preferredWidth;
			}
			if (preferredHeight > 0f)
			{
				val.preferredHeight = preferredHeight;
			}
			if (flexibleWidth)
			{
				val.flexibleWidth = 1f;
			}
			rect.anchorMin = Vector2.zero;
			rect.anchorMax = Vector2.one;
			rect.pivot = new Vector2(0.5f, 0.5f);
			rect.offsetMin = Vector2.zero;
			rect.offsetMax = Vector2.zero;
		}

		private static void StretchTextRect(Component textComponent)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: 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)
			if (!((Object)(object)textComponent == (Object)null))
			{
				RectTransform component = textComponent.GetComponent<RectTransform>();
				if (!((Object)(object)component == (Object)null))
				{
					component.anchorMin = Vector2.zero;
					component.anchorMax = Vector2.one;
					component.pivot = new Vector2(0.5f, 0.5f);
					component.offsetMin = Vector2.zero;
					component.offsetMax = Vector2.zero;
				}
			}
		}

		private static void ForceMeshUpdate(Component textComponent)
		{
			if (!((Object)(object)textComponent == (Object)null))
			{
				Type type = ((object)textComponent).GetType();
				type.GetMethod("ForceMeshUpdate", Type.EmptyTypes)?.Invoke(textComponent, null);
				type.GetMethod("UpdateMeshPadding", Type.EmptyTypes)?.Invoke(textComponent, null);
			}
		}

		private static void CopyTextTemplate(Component component)
		{
			if (!((Object)(object)component == (Object)null) && !((Object)(object)_textTemplate == (Object)null))
			{
				CopyProperty(_textTemplate, component, "font");
				CopyProperty(_textTemplate, component, "fontSharedMaterial");
				CopyProperty(_textTemplate, component, "material");
				CopyProperty(_textTemplate, component, "raycastTarget", false);
			}
		}

		private static void CopyProperty(Component source, Component target, string propertyName, object fallback = null)
		{
			PropertyInfo property = ((object)target).GetType().GetProperty(propertyName);
			if (property == null || !property.CanWrite)
			{
				return;
			}
			try
			{
				PropertyInfo property2 = ((object)source).GetType().GetProperty(propertyName);
				object obj = ((property2 != null && property2.CanRead) ? property2.GetValue(source, null) : fallback);
				if (obj != null || fallback != null)
				{
					property.SetValue(target, obj, null);
				}
			}
			catch
			{
			}
		}

		private static void HandleSearchInput()
		{
			if (_listeningForBattleDashKey)
			{
				HandleBattleDashKeyCapture();
			}
			else if (_listeningForAutoShootKey)
			{
				HandleAutoShootKeyCapture();
			}
			else
			{
				if (!_searchFocused || (Object)(object)_panel == (Object)null || !_panel.activeSelf)
				{
					return;
				}
				if (Input.GetKeyDown((KeyCode)27))
				{
					_searchFocused = false;
					UpdateSearchLabel();
					return;
				}
				string inputString = Input.inputString;
				if (string.IsNullOrEmpty(inputString))
				{
					return;
				}
				bool flag = false;
				string text = inputString;
				for (int i = 0; i < text.Length; i++)
				{
					char c = text[i];
					switch (c)
					{
					case '\b':
						if (_search.Length > 0)
						{
							_search = _search.Substring(0, _search.Length - 1);
							flag = true;
						}
						break;
					case '\n':
					case '\r':
						_searchFocused = false;
						break;
					default:
						if (!char.IsControl(c))
						{
							_search += c;
							flag = true;
						}
						break;
					}
				}
				if (flag)
				{
					UpdateSearchLabel();
					Refresh(resetScroll: true);
				}
			}
		}

		private static void UpdateSearchLabel()
		{
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			string value = ((!string.IsNullOrEmpty(_search)) ? (_search + (_searchFocused ? "|" : "")) : (_searchFocused ? "|" : "Search..."));
			SetText(_searchText, value, (float?)17f, TextAlignment.Left, (Color?)new Color(0.86f, 0.88f, 0.9f, 1f), richText: false);
		}

		private static void HandleBattleDashKeyCapture()
		{
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Invalid comparison between Unknown and I4
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_panel == (Object)null || !_panel.activeSelf)
			{
				_listeningForBattleDashKey = false;
				return;
			}
			if (Input.GetKeyDown((KeyCode)27))
			{
				_listeningForBattleDashKey = false;
				UpdateBattleDashKeyButtonLabel();
				return;
			}
			foreach (KeyCode value in Enum.GetValues(typeof(KeyCode)))
			{
				if ((int)value != 0 && (int)value != 27 && Input.GetKeyDown(value))
				{
					AimExclusionStore.SetBattleDashToggleKey(value);
					_listeningForBattleDashKey = false;
					UpdateBattleDashKeyButtonLabel();
					break;
				}
			}
		}

		private static void HandleAutoShootKeyCapture()
		{
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Invalid comparison between Unknown and I4
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_panel == (Object)null || !_panel.activeSelf)
			{
				_listeningForAutoShootKey = false;
				return;
			}
			if (Input.GetKeyDown((KeyCode)27))
			{
				_listeningForAutoShootKey = false;
				UpdateAutoShootKeyButtonLabel();
				return;
			}
			foreach (KeyCode value in Enum.GetValues(typeof(KeyCode)))
			{
				if ((int)value != 0 && (int)value != 27 && Input.GetKeyDown(value))
				{
					AimExclusionStore.SetAutoShootToggleKey(value);
					_listeningForAutoShootKey = false;
					UpdateAutoShootKeyButtonLabel();
					break;
				}
			}
		}
	}
	internal static class AimExclusionStore
	{
		private class AimExclusionFile
		{
			public int version;

			public int battleDashToggleKey = 306;

			public int autoShootToggleKey = 118;

			public List<UnitEntry> units = new List<UnitEntry>();
		}

		internal class UnitEntry
		{
			public string guid;

			public string name;

			public string source;

			public int modId;

			public int workshopModId;

			public bool? isRanged;

			public bool excluded;

			public bool rangeGateEnabled = true;

			public bool volleySpreadEnabled;

			public bool meleeDashEnabled;

			public bool verticalAimEnabled = true;

			[JsonIgnore]
			public Sprite iconSprite;

			[JsonIgnore]
			public Texture iconTexture;

			[JsonIgnore]
			public object iconEntity;
		}

		internal const string FileName = "FreeAim.AimExclusions.json";

		private static readonly HashSet<string> ExcludedUnits = new HashSet<string>();

		private static readonly HashSet<string> RangeGateDisabled = new HashSet<string>();

		private const int SaveFormatVersion = 13;

		internal const KeyCode DefaultBattleDashToggleKey = 306;

		internal const KeyCode DefaultAutoShootToggleKey = 118;

		private static KeyCode _battleDashToggleKey = (KeyCode)306;

		private static KeyCode _autoShootToggleKey = (KeyCode)118;

		internal const string BuiltInSource = "Built-in";

		internal const string CustomSource = "Custom";

		private static readonly Dictionary<string, UnitEntry> UnitEntries = new Dictionary<string, UnitEntry>();

		private static int _lastUnitDiscoveryCount;

		private static int _builtInCount;

		private static int _customCount;

		private static bool _pendingDefaultSeed;

		private static bool _discoveryComplete;

		private static bool _pendingVolleySpreadSeed;

		private static bool _pendingMeleeDashSeed;

		private static bool _pendingVerticalAimSeed;

		private static readonly HashSet<string> DefaultExcludedUnitNames = new HashSet<string>
		{
			"UNIT_ASIA_HWACHA", "UNIT_FANTASYEVIL_MECHANIC", "UNIT_FANTASYEVIL_STORMPRIEST", "UNIT_FANTASYGOOD_ORBCASTER", "UNIT_FANTASYGOOD_TIMENINJA", "UNIT_FANTASYGOOD_TIMENINJATRANSFORMED", "UNIT_FARMER_SCARECROW", "UNIT_HALLOWEEN_SPOOKYCATAPULT", "UNIT_HALLOWEEN_SWORDCASTER", "UNIT_LEGACY_LEG_WIZARD",
			"UNIT_MEDIEVAL_CATAPULT", "UNIT_MEDIEVAL_PRIEST", "UNIT_PIRATE_CANNON", "UNIT_RENAISSANCE_DAVINCITANK", "UNIT_SECRET_BANSHEE", "UNIT_SECRET_BOMBCANNON", "UNIT_SECRET_INFERNAL_WHIP", "UNIT_SUBUNITS_DAVINCI", "UNIT_WESTERN_GUNSLINGER"
		};

		private static string FilePath => Path.Combine(Paths.ConfigPath, "FreeAim.AimExclusions.json");

		internal static IReadOnlyCollection<UnitEntry> Units => UnitEntries.Values;

		internal static string DiscoverySummary => $"{_lastUnitDiscoveryCount} units ({_builtInCount} built-in, {_customCount} custom)";

		internal static void Load()
		{
			//IL_00a1: 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)
			ExcludedUnits.Clear();
			RangeGateDisabled.Clear();
			UnitEntries.Clear();
			try
			{
				if (!File.Exists(FilePath))
				{
					_pendingDefaultSeed = true;
					return;
				}
				AimExclusionFile aimExclusionFile = JsonConvert.DeserializeObject<AimExclusionFile>(File.ReadAllText(FilePath)) ?? new AimExclusionFile();
				bool flag = aimExclusionFile.version < 13;
				if (aimExclusionFile.version < 9)
				{
					_pendingVolleySpreadSeed = true;
				}
				if (aimExclusionFile.version < 10)
				{
					_pendingMeleeDashSeed = true;
				}
				if (aimExclusionFile.version < 13)
				{
					_pendingVerticalAimSeed = true;
				}
				if (aimExclusionFile.version >= 11 && aimExclusionFile.battleDashToggleKey != 0)
				{
					_battleDashToggleKey = (KeyCode)aimExclusionFile.battleDashToggleKey;
				}
				if (aimExclusionFile.version >= 12 && aimExclusionFile.autoShootToggleKey != 0)
				{
					_autoShootToggleKey = (KeyCode)aimExclusionFile.autoShootToggleKey;
				}
				foreach (UnitEntry item in aimExclusionFile.units ?? new List<UnitEntry>())
				{
					if (!string.IsNullOrWhiteSpace(item.guid))
					{
						if (flag && aimExclusionFile.version < 8)
						{
							item.rangeGateEnabled = true;
							item.source = null;
						}
						UnitEntries[item.guid] = item;
						if (item.excluded)
						{
							ExcludedUnits.Add(item.guid);
						}
						if (!item.rangeGateEnabled)
						{
							RangeGateDisabled.Add(item.guid);
						}
					}
				}
				if (flag)
				{
					_discoveryComplete = false;
				}
			}
			catch (Exception ex)
			{
				Plugin.LogWarning("Aim exclusions: failed to load FreeAim.AimExclusions.json: " + ex.Message);
			}
		}

		internal static void Save()
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected I4, but got Unknown
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Expected I4, but got Unknown
			try
			{
				Directory.CreateDirectory(Paths.ConfigPath);
				AimExclusionFile aimExclusionFile = new AimExclusionFile
				{
					version = 13,
					battleDashToggleKey = (int)_battleDashToggleKey,
					autoShootToggleKey = (int)_autoShootToggleKey,
					units = UnitEntries.Values.OrderBy((UnitEntry u) => u.name).ToList()
				};
				File.WriteAllText(FilePath, JsonConvert.SerializeObject((object)aimExclusionFile, (Formatting)1));
			}
			catch (Exception ex)
			{
				Plugin.LogWarning("Aim exclusions: failed to save FreeAim.AimExclusions.json: " + ex.Message);
			}
		}

		internal static void EnsureDiscovered(bool force = false)
		{
			if (!File.Exists(FilePath))
			{
				_pendingDefaultSeed = true;
			}
			if (!force && _discoveryComplete)
			{
				ApplyDefaultSeedIfNeeded();
				return;
			}
			RefreshDiscoveredContent();
			_discoveryComplete = true;
			ApplyDefaultSeedIfNeeded();
		}

		private static void ApplyDefaultSeedIfNeeded()
		{
			if (_pendingDefaultSeed)
			{
				int num = 0;
				try
				{
					num = ApplyDefaultExclusions();
				}
				catch (Exception ex)
				{
					Plugin.LogWarning("Aim exclusions: failed to apply default exclusions: " + ex.Message);
				}
				_pendingDefaultSeed = false;
				Save();
				Plugin.LogInfo($"Aim exclusions: default exclusions seeded ({num} units)");
			}
		}

		internal static void HandleUnitRemoved(DatabaseID id)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			string text = Key(id);
			if (!string.IsNullOrEmpty(text) && UnitEntries.Remove(text))
			{
				ExcludedUnits.Remove(text);
				RangeGateDisabled.Remove(text);
				_lastUnitDiscoveryCount = UnitEntries.Count;
				_builtInCount = UnitEntries.Values.Count((UnitEntry u) => u.source != "Custom");
				_customCount = UnitEntries.Values.Count((UnitEntry u) => u.source == "Custom");
				Save();
				Plugin.LogInfo("Aim exclusions: removed deleted unit (" + text + ")");
				AimExclusionMenu.NotifyContentChanged();
			}
		}

		internal static void RemoveUserUnitBlueprint_Postfix(DatabaseID id)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			HandleUnitRemoved(id);
		}

		internal static void RefreshDiscoveredContent()
		{
			try
			{
				int count = UnitEntries.Count;
				ContentDatabase val = ContentDatabase.Instance();
				if (val == null)
				{
					return;
				}
				IEnumerable<UnitBlueprint> allUnitBlueprints = val.GetAllUnitBlueprints();
				if (allUnitBlueprints == null)
				{
					return;
				}
				HashSet<string> hashSet = new HashSet<string>();
				foreach (UnitBlueprint item in allUnitBlueprints)
				{
					TryRegisterUnit(item, hashSet);
				}
				if (hashSet.Count > 0)
				{
					int num = PruneStaleEntries(hashSet);
					if (num > 0)
					{
						Plugin.LogInfo($"Aim exclusions: pruned {num} removed unit(s)");
					}
				}
				_lastUnitDiscoveryCount = UnitEntries.Count;
				_builtInCount = UnitEntries.Values.Count((UnitEntry u) => u.source != "Custom");
				_customCount = UnitEntries.Values.Count((UnitEntry u) => u.source == "Custom");
				if (_lastUnitDiscoveryCount != count || !_discoveryComplete)
				{
					Plugin.LogInfo("Aim exclusions: discovered " + DiscoverySummary);
				}
				if (_pendingVolleySpreadSeed)
				{
					_pendingVolleySpreadSeed = false;
					Plugin.LogInfo("Aim exclusions: volley spread defaults seeded for all units");
				}
				if (_pendingMeleeDashSeed)
				{
					_pendingMeleeDashSeed = false;
					Plugin.LogInfo("Aim exclusions: melee dash defaults seeded for all units");
				}
				if (_pendingVerticalAimSeed)
				{
					_pendingVerticalAimSeed = false;
					Plugin.LogInfo("Aim exclusions: vertical aim defaults seeded for all units");
				}
				Save();
			}
			catch (Exception ex)
			{
				Plugin.LogWarning("Aim exclusions: failed to discover units: " + ex.Message);
			}
		}

		private static int ApplyDefaultExclusions()
		{
			int num = 0;
			foreach (UnitEntry item in UnitEntries.Values.ToList())
			{
				if (!string.IsNullOrWhiteSpace(item.name) && DefaultExcludedUnitNames.Contains(item.name))
				{
					if (ExcludedUnits.Add(item.guid))
					{
						num++;
					}
					item.excluded = true;
				}
			}
			return num;
		}

		internal static UnitEntry RegisterUnit(UnitBlueprint blueprint)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			if (((blueprint != null) ? blueprint.Entity : null) == null)
			{
				return null;
			}
			string text = Key(blueprint.Entity.GUID);
			UnitEntry value;
			bool num = !UnitEntries.TryGetValue(text, out value);
			if (num)
			{
				value = new UnitEntry
				{
					guid = text
				};
				UnitEntries[text] = value;
			}
			value.name = blueprint.Entity.Name ?? blueprint.Name ?? text;
			value.modId = blueprint.Entity.GUID.m_modID;
			value.workshopModId = blueprint.ModID;
			value.source = ClassifyUnitSource(blueprint);
			value.isRanged = ClassifyIsRanged(blueprint);
			value.excluded = ExcludedUnits.Contains(text);
			value.rangeGateEnabled = ShouldApplyRangeGate(text);
			if (num || _pendingVolleySpreadSeed)
			{
				value.volleySpreadEnabled = ClassifyDefaultVolleySpread(blueprint);
			}
			if (num || _pendingMeleeDashSeed)
			{
				value.meleeDashEnabled = ClassifyDefaultMeleeDash(blueprint);
			}
			if (num || _pendingVerticalAimSeed)
			{
				value.verticalAimEnabled = ClassifyDefaultVerticalAim(blueprint);
			}
			value.iconEntity = blueprint.Entity;
			return value;
		}

		internal static bool ClassifyDefaultVolleySpread(UnitBlueprint blueprint)
		{
			if ((Object)(object)blueprint == (Object)null)
			{
				return false;
			}
			if (GetRangeWeaponProjectileCount(blueprint.RightWeapon) <= 1)
			{
				return GetRangeWeaponProjectileCount(blueprint.LeftWeapon) > 1;
			}
			return true;
		}

		internal static bool ClassifyDefaultMeleeDash(UnitBlueprint blueprint)
		{
			if ((Object)(object)blueprint == (Object)null)
			{
				return false;
			}
			if (!HasWeaponComponent<WeaponForceAnimation>(blueprint.RightWeapon))
			{
				return HasWeaponComponent<WeaponForceAnimation>(blueprint.LeftWeapon);
			}
			return true;
		}

		internal static bool ClassifyDefaultVerticalAim(UnitBlueprint blueprint)
		{
			return true;
		}

		internal static bool IsMeleeDashCapable(Unit unit)
		{
			return ClassifyDefaultMeleeDash(unit?.unitBlueprint);
		}

		internal static bool IsMeleeDashCapable(DataHandler data)
		{
			return IsMeleeDashCapable(data?.unit);
		}

		internal static bool HasRuntimeMeleeWeapon(Unit unit)
		{
			if ((Object)(object)unit == (Object)null)
			{
				return false;
			}
			WeaponHandler componentInChildren = ((Component)unit).GetComponentInChildren<WeaponHandler>();
			if ((Object)(object)componentInChildren == (Object)null)
			{
				return false;
			}
			if (!(componentInChildren.leftWeapon is MeleeWeapon))
			{
				return componentInChildren.rightWeapon is MeleeWeapon;
			}
			return true;
		}

		internal static bool HasBlueprintMeleeWeapon(UnitBlueprint blueprint)
		{
			if ((Object)(object)blueprint == (Object)null)
			{
				return false;
			}
			if (ClassifyIsRanged(blueprint).GetValueOrDefault())
			{
				return false;
			}
			if (!HasWeaponComponent<MeleeWeapon>(blueprint.RightWeapon))
			{
				return HasWeaponComponent<MeleeWeapon>(blueprint.LeftWeapon);
			}
			return true;
		}

		internal static bool HasRuntimeRangeWeapon(Unit unit)
		{
			if ((Object)(object)unit == (Object)null)
			{
				return false;
			}
			WeaponHandler componentInChildren = ((Component)unit).GetComponen