Decompiled source of SwornProtectors v0.5.0

plugins/SwornProtectors.dll

Decompiled 5 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Splatform;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")]
[assembly: AssemblyCompany("SwornProtectors")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("SwornProtectors")]
[assembly: AssemblyTitle("SwornProtectors")]
[assembly: AssemblyVersion("1.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 SwornProtectors
{
	public class CommandMenu : MonoBehaviour
	{
		private bool isFemale;

		private int spawnCount = 3;

		private int[] selectedEquip = new int[6];

		private int browsingSlot = -1;

		private Vector2 browseScroll;

		private const int MAX_SAVED_OUTFITS = 3;

		private int[][] savedOutfits = new int[3][];

		private bool[] outfitSaved = new bool[3];

		private bool defaultsApplied;

		private Rect windowRect;

		private bool stylesReady;

		private GUIStyle headerStyle;

		private GUIStyle titleStyle;

		private GUIStyle sectionStyle;

		private GUIStyle labelStyle;

		private GUIStyle buttonStyle;

		private GUIStyle activeButtonStyle;

		private GUIStyle closeHintStyle;

		private GUIStyle slotButtonStyle;

		private GUIStyle browseItemStyle;

		private GUIStyle browseItemActiveStyle;

		private Texture2D bgTex;

		private Texture2D btnTex;

		private Texture2D btnActiveTex;

		private Texture2D btnHoverTex;

		private Texture2D glowTex;

		private Texture2D ropeBorderH;

		private Texture2D ropeBorderV;

		private Texture2D cornerTex;

		private Texture2D slotBtnTex;

		private Texture2D slotBtnHoverTex;

		private bool wasCursorVisible;

		private CursorLockMode wasCursorLock;

		private float glowPulse;

		private const float WIN_WIDTH = 340f;

		private const float WIN_HEIGHT_NORMAL = 800f;

		private const float WIN_HEIGHT_BROWSE = 520f;

		private const float GLOW_SIZE = 18f;

		private const float ROPE_WIDTH = 6f;

		private const float CORNER_SIZE = 16f;

		private const int SLOT_COUNT = 6;

		private float currentWinHeight;

		public static CommandMenu Instance { get; private set; }

		public bool IsMenuOpen { get; private set; }

		private void Awake()
		{
			//IL_0042: 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)
			Instance = this;
			currentWinHeight = 800f;
			windowRect = new Rect(((float)Screen.width - 340f) / 2f, ((float)Screen.height - currentWinHeight) / 2f, 340f, currentWinHeight);
		}

		private void Update()
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			if (!defaultsApplied && EquipmentData.IsReady)
			{
				defaultsApplied = true;
				ApplyDefaultLoadout();
			}
			if (IsTyping())
			{
				return;
			}
			if (Input.GetKeyDown(SwornProtectorsPlugin.CommandMenuKey.Value))
			{
				SetMenuOpen(!IsMenuOpen);
			}
			if (IsMenuOpen && Input.GetKeyDown((KeyCode)27))
			{
				if (browsingSlot >= 0)
				{
					browsingSlot = -1;
				}
				else
				{
					SetMenuOpen(open: false);
				}
			}
			if (!IsMenuOpen)
			{
				ProtectorManager instance = ProtectorManager.Instance;
				if ((Object)(object)instance != (Object)null && instance.ActiveProtectors.Count > 0)
				{
					if (Input.GetKeyDown(SwornProtectorsPlugin.FollowKey.Value))
					{
						instance.CommandFollow();
						ShowMsg("Follow");
					}
					if (Input.GetKeyDown(SwornProtectorsPlugin.AttackMoveKey.Value))
					{
						Vector3 crosshairWorldPoint = GetCrosshairWorldPoint();
						instance.CommandAttackOrMoveTo(crosshairWorldPoint);
						ShowMsg("Attack / Move");
					}
					if (Input.GetKeyDown(SwornProtectorsPlugin.HoldKey.Value))
					{
						instance.CommandHoldPosition();
						ShowMsg("Hold Position");
					}
				}
			}
			if (IsMenuOpen)
			{
				glowPulse = Mathf.PingPong(Time.time * 0.6f, 1f);
			}
		}

		private void LateUpdate()
		{
			if (IsMenuOpen)
			{
				Cursor.visible = true;
				Cursor.lockState = (CursorLockMode)0;
			}
		}

		private void SetMenuOpen(bool open)
		{
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			if (open != IsMenuOpen)
			{
				IsMenuOpen = open;
				if (open)
				{
					browsingSlot = -1;
					wasCursorVisible = Cursor.visible;
					wasCursorLock = Cursor.lockState;
					Cursor.visible = true;
					Cursor.lockState = (CursorLockMode)0;
					currentWinHeight = 800f;
					windowRect = new Rect(((float)Screen.width - 340f) / 2f, ((float)Screen.height - currentWinHeight) / 2f, 340f, currentWinHeight);
				}
				else
				{
					Cursor.visible = wasCursorVisible;
					Cursor.lockState = wasCursorLock;
				}
			}
		}

		private void OnGUI()
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Invalid comparison between Unknown and I4
			//IL_0099: 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_00b1: 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_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Expected O, but got Unknown
			//IL_00de: 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)
			if (IsMenuOpen)
			{
				InitStyles();
				Cursor.visible = true;
				Cursor.lockState = (CursorLockMode)0;
				if (((int)Event.current.type == 0 || (int)Event.current.type == 1) && !((Rect)(ref windowRect)).Contains(Event.current.mousePosition))
				{
					Event.current.Use();
				}
				float num = ((browsingSlot >= 0) ? 520f : 800f);
				if (Mathf.Abs(currentWinHeight - num) > 1f)
				{
					currentWinHeight = num;
					((Rect)(ref windowRect)).height = currentWinHeight;
				}
				DrawGoldenGlow(windowRect);
				DrawRopeBorder(windowRect);
				DrawCornerKnots(windowRect);
				windowRect = GUI.Window(98234, windowRect, new WindowFunction(DrawPanel), "", headerStyle);
			}
		}

		private void DrawGoldenGlow(Rect rect)
		{
			//IL_0026: 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_0076: Unknown result type (might be due to invalid IL or missing references)
			float num = Mathf.Lerp(0.25f, 0.45f, glowPulse);
			GUI.color = new Color(1f, 1f, 1f, num);
			float num2 = 18f;
			GUI.DrawTexture(new Rect(((Rect)(ref rect)).x - num2, ((Rect)(ref rect)).y - num2, ((Rect)(ref rect)).width + num2 * 2f, ((Rect)(ref rect)).height + num2 * 2f), (Texture)(object)glowTex);
			GUI.color = Color.white;
		}

		private void DrawRopeBorder(Rect rect)
		{
			//IL_0031: 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_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			float num = 6f;
			float x = ((Rect)(ref rect)).x;
			float y = ((Rect)(ref rect)).y;
			float width = ((Rect)(ref rect)).width;
			float height = ((Rect)(ref rect)).height;
			GUI.DrawTexture(new Rect(x, y - num * 0.5f, width, num), (Texture)(object)ropeBorderH);
			GUI.DrawTexture(new Rect(x, y + height - num * 0.5f, width, num), (Texture)(object)ropeBorderH);
			GUI.DrawTexture(new Rect(x - num * 0.5f, y, num, height), (Texture)(object)ropeBorderV);
			GUI.DrawTexture(new Rect(x + width - num * 0.5f, y, num, height), (Texture)(object)ropeBorderV);
		}

		private void DrawCornerKnots(Rect rect)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			float num = 16f;
			float num2 = num * 0.5f;
			float x = ((Rect)(ref rect)).x;
			float y = ((Rect)(ref rect)).y;
			float width = ((Rect)(ref rect)).width;
			float height = ((Rect)(ref rect)).height;
			GUI.DrawTexture(new Rect(x - num2, y - num2, num, num), (Texture)(object)cornerTex);
			GUI.DrawTexture(new Rect(x + width - num2, y - num2, num, num), (Texture)(object)cornerTex);
			GUI.DrawTexture(new Rect(x - num2, y + height - num2, num, num), (Texture)(object)cornerTex);
			GUI.DrawTexture(new Rect(x + width - num2, y + height - num2, num, num), (Texture)(object)cornerTex);
		}

		private void DrawPanel(int windowID)
		{
			if (browsingSlot >= 0)
			{
				DrawBrowseMode(windowID);
			}
			else
			{
				DrawNormalMode(windowID);
			}
		}

		private void DrawNormalMode(int windowID)
		{
			//IL_0597: Unknown result type (might be due to invalid IL or missing references)
			//IL_0605: Unknown result type (might be due to invalid IL or missing references)
			//IL_0663: Unknown result type (might be due to invalid IL or missing references)
			//IL_05da: Unknown result type (might be due to invalid IL or missing references)
			//IL_05df: Unknown result type (might be due to invalid IL or missing references)
			//IL_05e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_078d: Unknown result type (might be due to invalid IL or missing references)
			//IL_07c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_080c: Unknown result type (might be due to invalid IL or missing references)
			ProtectorManager instance = ProtectorManager.Instance;
			int num = instance?.ActiveProtectors.Count ?? 0;
			int value = SwornProtectorsPlugin.MaxProtectors.Value;
			GUILayout.Space(8f);
			GUILayout.Label($"SWORN PROTECTORS  ({num}/{value})", titleStyle, Array.Empty<GUILayoutOption>());
			GUILayout.Space(6f);
			GUILayout.Label("— SUMMON —", sectionStyle, Array.Empty<GUILayoutOption>());
			GUILayout.Space(4f);
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Label("Gender:", labelStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(60f) });
			if (GUILayout.Button("Male", isFemale ? buttonStyle : activeButtonStyle, Array.Empty<GUILayoutOption>()))
			{
				isFemale = false;
			}
			if (GUILayout.Button("Female", isFemale ? activeButtonStyle : buttonStyle, Array.Empty<GUILayoutOption>()))
			{
				isFemale = true;
			}
			GUILayout.EndHorizontal();
			GUILayout.Space(4f);
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Label($"Count: {spawnCount}", labelStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(80f) });
			spawnCount = Mathf.RoundToInt(GUILayout.HorizontalSlider((float)spawnCount, 1f, (float)value, Array.Empty<GUILayoutOption>()));
			GUILayout.EndHorizontal();
			GUILayout.Space(6f);
			if (GUILayout.Button(string.Format("Summon {0} Protector{1}", spawnCount, (spawnCount > 1) ? "s" : ""), buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(32f) }) && (Object)(object)instance != (Object)null)
			{
				instance.SpawnMultiple(spawnCount, isFemale);
			}
			GUILayout.Space(8f);
			GUILayout.Label("— FORMATION —", sectionStyle, Array.Empty<GUILayoutOption>());
			GUILayout.Space(4f);
			string[] formationNames = ProtectorAI.FormationNames;
			int currentFormation = (int)ProtectorAI.CurrentFormation;
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			for (int i = 0; i < 3 && i < formationNames.Length; i++)
			{
				GUIStyle val = ((i == currentFormation) ? activeButtonStyle : buttonStyle);
				if (GUILayout.Button(formationNames[i], val, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(24f) }))
				{
					ProtectorAI.SetFormation((ProtectorAI.FormationType)i);
				}
			}
			GUILayout.EndHorizontal();
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			for (int j = 3; j < formationNames.Length; j++)
			{
				GUIStyle val2 = ((j == currentFormation) ? activeButtonStyle : buttonStyle);
				if (GUILayout.Button(formationNames[j], val2, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(24f) }))
				{
					ProtectorAI.SetFormation((ProtectorAI.FormationType)j);
				}
			}
			GUILayout.EndHorizontal();
			GUILayout.Space(8f);
			GUILayout.Label("— EQUIPMENT —", sectionStyle, Array.Empty<GUILayoutOption>());
			GUILayout.Space(4f);
			if (!EquipmentData.IsReady)
			{
				GUILayout.Label("Loading items...", closeHintStyle, Array.Empty<GUILayoutOption>());
			}
			else
			{
				for (int k = 0; k < 6; k++)
				{
					DrawSlotRow(k);
				}
				GUILayout.Space(4f);
				GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				if (GUILayout.Button("Apply to All", buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(26f) }))
				{
					ApplyEquipmentToAll();
				}
				if (GUILayout.Button("Clear All", buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(26f) }))
				{
					ClearEquipmentFromAll();
				}
				GUILayout.EndHorizontal();
				GUILayout.Space(4f);
				GUILayout.Label("— OUTFITS —", sectionStyle, Array.Empty<GUILayoutOption>());
				GUILayout.Space(2f);
				for (int l = 0; l < 3; l++)
				{
					int num2 = l;
					bool flag = outfitSaved[num2];
					GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
					GUIStyle val3 = (flag ? activeButtonStyle : labelStyle);
					GUILayout.Label($"Outfit {num2 + 1}", val3, (GUILayoutOption[])(object)new GUILayoutOption[2]
					{
						GUILayout.Width(68f),
						GUILayout.Height(22f)
					});
					GUI.enabled = flag;
					if (GUILayout.Button("Load", buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(22f) }))
					{
						LoadOutfit(num2);
						ApplyEquipmentToAll();
						ShowMsg($"Outfit {num2 + 1} loaded!");
					}
					GUI.enabled = true;
					if (GUILayout.Button("Save", buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(22f) }))
					{
						SaveOutfit(num2);
						ShowMsg($"Outfit {num2 + 1} saved!");
					}
					GUI.enabled = flag;
					if (GUILayout.Button("Del", buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[2]
					{
						GUILayout.Height(22f),
						GUILayout.Width(38f)
					}))
					{
						DeleteOutfit(num2);
						ShowMsg($"Outfit {num2 + 1} deleted.");
					}
					GUI.enabled = true;
					GUILayout.EndHorizontal();
				}
			}
			GUILayout.Space(8f);
			GUILayout.Label("— COMMANDS —", sectionStyle, Array.Empty<GUILayoutOption>());
			GUILayout.Space(4f);
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			if (GUILayout.Button($"Attack\n/ Move To\n[{SwornProtectorsPlugin.AttackMoveKey.Value}]", buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(52f) }))
			{
				SwornProtectorsPlugin.Log("GUI: Attack/MoveTo clicked");
				if ((Object)(object)instance != (Object)null)
				{
					Vector3 crosshairWorldPoint = GetCrosshairWorldPoint();
					instance.CommandAttackOrMoveTo(crosshairWorldPoint);
					ShowMsg("Attack / Move to target!");
					SetMenuOpen(open: false);
				}
			}
			if (GUILayout.Button($"Follow\n& Sheathe\n[{SwornProtectorsPlugin.FollowKey.Value}]", buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(52f) }))
			{
				SwornProtectorsPlugin.Log("GUI: Follow clicked");
				instance?.CommandFollow();
				ShowMsg("Returning to formation.");
				SetMenuOpen(open: false);
			}
			if (GUILayout.Button($"Hold\nPosition\n[{SwornProtectorsPlugin.HoldKey.Value}]", buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(52f) }))
			{
				SwornProtectorsPlugin.Log("GUI: Hold clicked");
				instance?.CommandHoldPosition();
				ShowMsg("Holding position.");
				SetMenuOpen(open: false);
			}
			GUILayout.EndHorizontal();
			GUILayout.Space(4f);
			bool value2 = SwornProtectorsPlugin.AutoDefendEnabled.Value;
			if (GUILayout.Button(value2 ? "Auto-Defend:  ON" : "Auto-Defend:  OFF", value2 ? activeButtonStyle : buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(28f) }))
			{
				SwornProtectorsPlugin.AutoDefendEnabled.Value = !value2;
			}
			GUILayout.Space(8f);
			GUILayout.Label("— MANAGE —", sectionStyle, Array.Empty<GUILayoutOption>());
			GUILayout.Space(4f);
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			if (GUILayout.Button("Dismiss Last", buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(28f) }))
			{
				instance?.DespawnLast();
			}
			GUI.color = new Color(1f, 0.5f, 0.5f);
			if (GUILayout.Button("Dismiss All", buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(28f) }))
			{
				instance?.DespawnAll();
			}
			GUI.color = Color.white;
			GUILayout.EndHorizontal();
			GUILayout.Space(8f);
			GUILayout.FlexibleSpace();
			GUILayout.Label("[H] or [Esc] to close", closeHintStyle, Array.Empty<GUILayoutOption>());
			GUI.DragWindow(new Rect(0f, 0f, 340f, 30f));
		}

		private void DrawSlotRow(int slotIndex)
		{
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			List<EquipmentData.ItemEntry> listForSlot = EquipmentData.GetListForSlot(slotIndex);
			int num = selectedEquip[slotIndex];
			string text = ((num >= 0 && num < listForSlot.Count) ? listForSlot[num].DisplayName : "— None —");
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Label(EquipmentData.GetSlotName(slotIndex) + ":", labelStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(58f) });
			if (GUILayout.Button(text + "  ▼", slotButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(22f) }))
			{
				browsingSlot = slotIndex;
				browseScroll = Vector2.zero;
			}
			GUILayout.EndHorizontal();
		}

		private void DrawBrowseMode(int windowID)
		{
			//IL_006d: 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_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			GUILayout.Space(8f);
			GUILayout.Label("SELECT " + EquipmentData.GetSlotName(browsingSlot).ToUpper(), titleStyle, Array.Empty<GUILayoutOption>());
			GUILayout.Space(6f);
			List<EquipmentData.ItemEntry> listForSlot = EquipmentData.GetListForSlot(browsingSlot);
			int num = selectedEquip[browsingSlot];
			float num2 = 24f;
			float num3 = currentWinHeight - 100f;
			browseScroll = GUILayout.BeginScrollView(browseScroll, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(num3) });
			for (int i = 0; i < listForSlot.Count; i++)
			{
				GUIStyle val = ((i == num) ? browseItemActiveStyle : browseItemStyle);
				if (GUILayout.Button(listForSlot[i].DisplayName, val, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(num2) }))
				{
					selectedEquip[browsingSlot] = i;
					browsingSlot = -1;
				}
			}
			GUILayout.EndScrollView();
			GUILayout.Space(4f);
			if (GUILayout.Button("Back", buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(28f) }))
			{
				browsingSlot = -1;
			}
			GUI.DragWindow(new Rect(0f, 0f, 340f, 30f));
		}

		private void ApplyEquipmentToAll()
		{
			ProtectorManager instance = ProtectorManager.Instance;
			if ((Object)(object)instance == (Object)null || instance.ActiveProtectors.Count == 0)
			{
				ShowMsg("No protectors to equip! Summon them first.");
				return;
			}
			EquipmentData.ItemEntry[] array = new EquipmentData.ItemEntry[6];
			for (int i = 0; i < 6; i++)
			{
				List<EquipmentData.ItemEntry> listForSlot = EquipmentData.GetListForSlot(i);
				int num = selectedEquip[i];
				if (num >= 0 && num < listForSlot.Count)
				{
					array[i] = listForSlot[num];
					continue;
				}
				array[i] = new EquipmentData.ItemEntry
				{
					PrefabName = "",
					DisplayName = "",
					Variant = 0
				};
			}
			instance.ApplyEquipment(array);
			ShowMsg($"Equipment applied to {instance.ActiveProtectors.Count} protector(s)!");
		}

		private void ClearEquipmentFromAll()
		{
			ProtectorManager instance = ProtectorManager.Instance;
			if ((Object)(object)instance == (Object)null || instance.ActiveProtectors.Count == 0)
			{
				ShowMsg("No protectors to clear.");
				return;
			}
			for (int i = 0; i < 6; i++)
			{
				selectedEquip[i] = 0;
			}
			instance.ClearEquipment();
			ShowMsg("Equipment cleared from all protectors.");
		}

		private void SaveOutfit(int slot)
		{
			savedOutfits[slot] = new int[6];
			for (int i = 0; i < 6; i++)
			{
				savedOutfits[slot][i] = selectedEquip[i];
			}
			outfitSaved[slot] = true;
		}

		private void LoadOutfit(int slot)
		{
			if (outfitSaved[slot] && savedOutfits[slot] != null)
			{
				for (int i = 0; i < 6; i++)
				{
					selectedEquip[i] = savedOutfits[slot][i];
				}
			}
		}

		private void DeleteOutfit(int slot)
		{
			savedOutfits[slot] = null;
			outfitSaved[slot] = false;
		}

		private void ApplyDefaultLoadout()
		{
			selectedEquip[0] = EquipmentData.FindIndexByName(0, "Flametal Helmet");
			selectedEquip[1] = EquipmentData.FindIndexByName(1, "Flametal Breastplate");
			selectedEquip[2] = EquipmentData.FindIndexByName(2, "Flametal Greaves");
			selectedEquip[3] = EquipmentData.FindIndexByName(3, "Linen Cape (#0 Red");
			selectedEquip[4] = EquipmentData.FindIndexByName(4, "Splitnir");
			selectedEquip[5] = EquipmentData.FindIndexByName(5, "Flametal Shield");
			SwornProtectorsPlugin.Log($"Default loadout applied: Head={selectedEquip[0]}, Chest={selectedEquip[1]}, " + $"Legs={selectedEquip[2]}, Cape={selectedEquip[3]}, Weapon={selectedEquip[4]}, " + $"Offhand={selectedEquip[5]}");
		}

		private Vector3 GetCrosshairWorldPoint()
		{
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: 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_002a: 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_003f: 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_001e: Unknown result type (might be due to invalid IL or missing references)
			Camera main = Camera.main;
			if ((Object)(object)main == (Object)null)
			{
				Player localPlayer = Player.m_localPlayer;
				if (!((Object)(object)localPlayer != (Object)null))
				{
					return Vector3.zero;
				}
				return ((Component)localPlayer).transform.position + ((Component)localPlayer).transform.forward * 15f;
			}
			Ray val = main.ScreenPointToRay(new Vector3((float)Screen.width / 2f, (float)Screen.height / 2f, 0f));
			RaycastHit val2 = default(RaycastHit);
			if (Physics.Raycast(val, ref val2, 200f))
			{
				return ((RaycastHit)(ref val2)).point;
			}
			return ((Ray)(ref val)).GetPoint(30f);
		}

		private void ShowMsg(string text)
		{
			Player localPlayer = Player.m_localPlayer;
			if (localPlayer != null)
			{
				((Character)localPlayer).Message((MessageType)2, text, 0, (Sprite)null);
			}
		}

		private bool IsTyping()
		{
			try
			{
				if (Console.IsVisible())
				{
					return true;
				}
				if ((Object)(object)Chat.instance != (Object)null && Chat.instance.HasFocus())
				{
					return true;
				}
			}
			catch
			{
			}
			return false;
		}

		private void InitStyles()
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Expected O, but got Unknown
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Expected O, but got Unknown
			//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c8: Expected O, but got Unknown
			//IL_01e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0204: Unknown result type (might be due to invalid IL or missing references)
			//IL_020b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0217: Expected O, but got Unknown
			//IL_0231: Unknown result type (might be due to invalid IL or missing references)
			//IL_0246: Unknown result type (might be due to invalid IL or missing references)
			//IL_024b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0253: Unknown result type (might be due to invalid IL or missing references)
			//IL_025f: Expected O, but got Unknown
			//IL_0279: Unknown result type (might be due to invalid IL or missing references)
			//IL_028e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0293: Unknown result type (might be due to invalid IL or missing references)
			//IL_029b: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a7: Expected O, but got Unknown
			//IL_02c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02db: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f6: Expected O, but got Unknown
			//IL_0326: Unknown result type (might be due to invalid IL or missing references)
			//IL_0360: Unknown result type (might be due to invalid IL or missing references)
			//IL_038b: Unknown result type (might be due to invalid IL or missing references)
			//IL_039c: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a6: Expected O, but got Unknown
			//IL_03d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0404: Expected O, but got Unknown
			//IL_0434: Unknown result type (might be due to invalid IL or missing references)
			//IL_046e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0499: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b7: Expected O, but got Unknown
			//IL_04c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_04cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_04db: Expected O, but got Unknown
			//IL_050b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0545: Unknown result type (might be due to invalid IL or missing references)
			//IL_0570: Unknown result type (might be due to invalid IL or missing references)
			//IL_0585: Unknown result type (might be due to invalid IL or missing references)
			//IL_058f: Expected O, but got Unknown
			//IL_0596: Unknown result type (might be due to invalid IL or missing references)
			//IL_05a0: Expected O, but got Unknown
			//IL_05d0: Unknown result type (might be due to invalid IL or missing references)
			if (!stylesReady)
			{
				stylesReady = true;
				bgTex = MakeTex(2, 2, new Color(0.06f, 0.05f, 0.08f, 0.95f));
				btnTex = MakeButtonTex(64, 24, active: false);
				btnActiveTex = MakeButtonTex(64, 24, active: true);
				btnHoverTex = MakeButtonHoverTex(64, 24);
				glowTex = MakeGoldenGlowTex(64, 64);
				ropeBorderH = MakeRopeTexH(128, 8);
				ropeBorderV = MakeRopeTexV(8, 128);
				cornerTex = MakeCornerKnotTex(24, 24);
				slotBtnTex = MakeTex(2, 2, new Color(0.1f, 0.09f, 0.13f, 1f));
				slotBtnHoverTex = MakeTex(2, 2, new Color(0.16f, 0.14f, 0.2f, 1f));
				headerStyle = new GUIStyle(GUI.skin.window);
				headerStyle.normal.background = bgTex;
				headerStyle.onNormal.background = bgTex;
				headerStyle.normal.textColor = new Color(0.9f, 0.75f, 0.3f);
				headerStyle.fontSize = 14;
				headerStyle.fontStyle = (FontStyle)1;
				headerStyle.alignment = (TextAnchor)1;
				headerStyle.padding = new RectOffset(12, 12, 10, 10);
				titleStyle = new GUIStyle(GUI.skin.label)
				{
					fontSize = 17,
					fontStyle = (FontStyle)1,
					alignment = (TextAnchor)4
				};
				titleStyle.normal.textColor = new Color(0.95f, 0.78f, 0.25f);
				sectionStyle = new GUIStyle(GUI.skin.label)
				{
					fontSize = 12,
					fontStyle = (FontStyle)1,
					alignment = (TextAnchor)4
				};
				sectionStyle.normal.textColor = new Color(0.7f, 0.3f, 0.25f);
				labelStyle = new GUIStyle(GUI.skin.label)
				{
					fontSize = 13,
					alignment = (TextAnchor)3
				};
				labelStyle.normal.textColor = new Color(0.8f, 0.78f, 0.72f);
				closeHintStyle = new GUIStyle(GUI.skin.label)
				{
					fontSize = 11,
					alignment = (TextAnchor)4
				};
				closeHintStyle.normal.textColor = new Color(0.5f, 0.48f, 0.42f);
				buttonStyle = new GUIStyle(GUI.skin.button)
				{
					fontSize = 13,
					fontStyle = (FontStyle)1,
					alignment = (TextAnchor)4
				};
				buttonStyle.normal.background = btnTex;
				buttonStyle.normal.textColor = new Color(0.9f, 0.85f, 0.7f);
				buttonStyle.hover.background = btnHoverTex;
				buttonStyle.hover.textColor = new Color(1f, 0.92f, 0.6f);
				buttonStyle.active.background = btnActiveTex;
				buttonStyle.active.textColor = Color.white;
				activeButtonStyle = new GUIStyle(buttonStyle);
				activeButtonStyle.normal.background = btnActiveTex;
				activeButtonStyle.normal.textColor = new Color(0.85f, 1f, 0.75f);
				slotButtonStyle = new GUIStyle(GUI.skin.button)
				{
					fontSize = 12,
					alignment = (TextAnchor)3
				};
				slotButtonStyle.normal.background = slotBtnTex;
				slotButtonStyle.normal.textColor = new Color(0.85f, 0.82f, 0.72f);
				slotButtonStyle.hover.background = slotBtnHoverTex;
				slotButtonStyle.hover.textColor = new Color(1f, 0.92f, 0.6f);
				slotButtonStyle.active.background = btnActiveTex;
				slotButtonStyle.active.textColor = Color.white;
				slotButtonStyle.padding = new RectOffset(8, 8, 2, 2);
				browseItemStyle = new GUIStyle(GUI.skin.button)
				{
					fontSize = 12,
					alignment = (TextAnchor)3
				};
				browseItemStyle.normal.background = slotBtnTex;
				browseItemStyle.normal.textColor = new Color(0.82f, 0.8f, 0.72f);
				browseItemStyle.hover.background = slotBtnHoverTex;
				browseItemStyle.hover.textColor = new Color(1f, 0.92f, 0.6f);
				browseItemStyle.active.background = btnActiveTex;
				browseItemStyle.active.textColor = Color.white;
				browseItemStyle.padding = new RectOffset(10, 6, 2, 2);
				browseItemActiveStyle = new GUIStyle(browseItemStyle);
				browseItemActiveStyle.normal.background = btnActiveTex;
				browseItemActiveStyle.normal.textColor = new Color(0.85f, 1f, 0.75f);
			}
		}

		private Texture2D MakeGoldenGlowTex(int w, int h)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(w, h);
			Color[] array = (Color[])(object)new Color[w * h];
			float num = (float)w * 0.5f;
			float num2 = (float)h * 0.5f;
			for (int i = 0; i < h; i++)
			{
				for (int j = 0; j < w; j++)
				{
					float num3 = ((float)j - num) / num;
					float num4 = ((float)i - num2) / num2;
					float num5 = Mathf.Sqrt(num3 * num3 + num4 * num4);
					float num6 = 0.55f;
					float num7 = ((!(num5 < num6)) ? Mathf.Clamp01((num5 - num6) / (1f - num6)) : 0f);
					num7 = Mathf.Sin(num7 * (float)Math.PI) * 0.8f;
					float num8 = Mathf.Lerp(0.85f, 0.95f, num5);
					float num9 = Mathf.Lerp(0.65f, 0.55f, num5);
					float num10 = Mathf.Lerp(0.15f, 0.08f, num5);
					array[i * w + j] = new Color(num8, num9, num10, num7);
				}
			}
			val.SetPixels(array);
			val.Apply();
			((Texture)val).wrapMode = (TextureWrapMode)1;
			return val;
		}

		private Texture2D MakeRopeTexH(int w, int h)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: 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_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: 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_0186: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(w, h);
			Color[] array = (Color[])(object)new Color[w * h];
			Color val2 = default(Color);
			((Color)(ref val2))..ctor(0.45f, 0.12f, 0.08f, 1f);
			Color val3 = default(Color);
			((Color)(ref val3))..ctor(0.22f, 0.06f, 0.04f, 1f);
			Color val4 = default(Color);
			((Color)(ref val4))..ctor(0.6f, 0.25f, 0.12f, 1f);
			Color val5 = default(Color);
			((Color)(ref val5))..ctor(0.7f, 0.55f, 0.15f, 0.6f);
			for (int i = 0; i < h; i++)
			{
				for (int j = 0; j < w; j++)
				{
					float num = Mathf.Sin((float)j * 0.35f + (float)i * 1.2f) * 0.5f + 0.5f;
					float num2 = Mathf.Sin((float)j * 0.35f - (float)i * 0.8f + 2f) * 0.5f + 0.5f;
					Color val6 = Color.Lerp(val3, val2, num * 0.7f + num2 * 0.3f);
					float num3 = Mathf.Abs((float)i / (float)h - 0.5f) * 2f;
					if (num3 < 0.4f)
					{
						val6 = Color.Lerp(val6, val4, (1f - num3 / 0.4f) * num * 0.5f);
					}
					if (i == 0 || i == h - 1)
					{
						val6 = Color.Lerp(val6, val5, 0.7f);
					}
					float a = Mathf.Clamp01((float)Mathf.Min(i, h - 1 - i) / 2f);
					val6.a = a;
					array[i * w + j] = val6;
				}
			}
			val.SetPixels(array);
			val.Apply();
			((Texture)val).wrapMode = (TextureWrapMode)0;
			return val;
		}

		private Texture2D MakeRopeTexV(int w, int h)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: 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_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: 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_0186: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(w, h);
			Color[] array = (Color[])(object)new Color[w * h];
			Color val2 = default(Color);
			((Color)(ref val2))..ctor(0.45f, 0.12f, 0.08f, 1f);
			Color val3 = default(Color);
			((Color)(ref val3))..ctor(0.22f, 0.06f, 0.04f, 1f);
			Color val4 = default(Color);
			((Color)(ref val4))..ctor(0.6f, 0.25f, 0.12f, 1f);
			Color val5 = default(Color);
			((Color)(ref val5))..ctor(0.7f, 0.55f, 0.15f, 0.6f);
			for (int i = 0; i < h; i++)
			{
				for (int j = 0; j < w; j++)
				{
					float num = Mathf.Sin((float)i * 0.35f + (float)j * 1.2f) * 0.5f + 0.5f;
					float num2 = Mathf.Sin((float)i * 0.35f - (float)j * 0.8f + 2f) * 0.5f + 0.5f;
					Color val6 = Color.Lerp(val3, val2, num * 0.7f + num2 * 0.3f);
					float num3 = Mathf.Abs((float)j / (float)w - 0.5f) * 2f;
					if (num3 < 0.4f)
					{
						val6 = Color.Lerp(val6, val4, (1f - num3 / 0.4f) * num * 0.5f);
					}
					if (j == 0 || j == w - 1)
					{
						val6 = Color.Lerp(val6, val5, 0.7f);
					}
					float a = Mathf.Clamp01((float)Mathf.Min(j, w - 1 - j) / 2f);
					val6.a = a;
					array[i * w + j] = val6;
				}
			}
			val.SetPixels(array);
			val.Apply();
			((Texture)val).wrapMode = (TextureWrapMode)0;
			return val;
		}

		private Texture2D MakeCornerKnotTex(int w, int h)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: 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_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(w, h);
			Color[] array = (Color[])(object)new Color[w * h];
			float num = (float)w * 0.5f;
			float num2 = (float)h * 0.5f;
			float num3 = Mathf.Min(num, num2);
			Color val2 = default(Color);
			((Color)(ref val2))..ctor(0.9f, 0.72f, 0.2f, 1f);
			Color val3 = default(Color);
			((Color)(ref val3))..ctor(0.6f, 0.4f, 0.1f, 1f);
			Color val4 = default(Color);
			((Color)(ref val4))..ctor(0.25f, 0.1f, 0.05f, 1f);
			for (int i = 0; i < h; i++)
			{
				for (int j = 0; j < w; j++)
				{
					float num4 = (float)j - num;
					float num5 = (float)i - num2;
					float num6 = Mathf.Sqrt(num4 * num4 + num5 * num5) / num3;
					if (num6 > 1f)
					{
						array[i * w + j] = Color.clear;
						continue;
					}
					Color val5;
					if (num6 < 0.35f)
					{
						val5 = Color.Lerp(val4, val3, num6 / 0.35f);
					}
					else if (num6 < 0.7f)
					{
						float num7 = (num6 - 0.35f) / 0.35f;
						val5 = Color.Lerp(val3, val2, Mathf.Sin(num7 * (float)Math.PI));
					}
					else
					{
						float num8 = (num6 - 0.7f) / 0.3f;
						val5 = Color.Lerp(val3, Color.clear, num8);
					}
					if (num6 > 0.85f)
					{
						val5.a *= 1f - (num6 - 0.85f) / 0.15f;
					}
					array[i * w + j] = val5;
				}
			}
			val.SetPixels(array);
			val.Apply();
			((Texture)val).wrapMode = (TextureWrapMode)1;
			return val;
		}

		private Texture2D MakeButtonTex(int w, int h, bool active)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: 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_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(w, h);
			Color[] array = (Color[])(object)new Color[w * h];
			Color val2 = (active ? new Color(0.2f, 0.35f, 0.18f, 1f) : new Color(0.12f, 0.1f, 0.15f, 1f));
			Color val3 = default(Color);
			((Color)(ref val3))..ctor(0.5f, 0.38f, 0.12f, 0.5f);
			for (int i = 0; i < h; i++)
			{
				for (int j = 0; j < w; j++)
				{
					bool flag = j == 0 || j == w - 1 || i == 0 || i == h - 1;
					array[i * w + j] = (flag ? val3 : val2);
				}
			}
			val.SetPixels(array);
			val.Apply();
			return val;
		}

		private Texture2D MakeButtonHoverTex(int w, int h)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_007b: 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_007c: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(w, h);
			Color[] array = (Color[])(object)new Color[w * h];
			Color val2 = default(Color);
			((Color)(ref val2))..ctor(0.18f, 0.16f, 0.22f, 1f);
			Color val3 = default(Color);
			((Color)(ref val3))..ctor(0.75f, 0.58f, 0.18f, 0.7f);
			for (int i = 0; i < h; i++)
			{
				for (int j = 0; j < w; j++)
				{
					bool flag = j == 0 || j == w - 1 || i == 0 || i == h - 1;
					array[i * w + j] = (flag ? val3 : val2);
				}
			}
			val.SetPixels(array);
			val.Apply();
			return val;
		}

		private Texture2D MakeTex(int w, int h, Color col)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: 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_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Expected O, but got Unknown
			Color[] array = (Color[])(object)new Color[w * h];
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = col;
			}
			Texture2D val = new Texture2D(w, h);
			val.SetPixels(array);
			val.Apply();
			return val;
		}
	}
	public static class EquipmentData
	{
		public struct ItemEntry
		{
			public string PrefabName;

			public string DisplayName;

			public int Variant;
		}

		private static List<ItemEntry> helmets;

		private static List<ItemEntry> chests;

		private static List<ItemEntry> legs;

		private static List<ItemEntry> capes;

		private static List<ItemEntry> weapons;

		private static List<ItemEntry> shields;

		private static bool initialized;

		private static readonly List<ItemEntry> Empty = new List<ItemEntry>
		{
			new ItemEntry
			{
				PrefabName = "",
				DisplayName = "— None —",
				Variant = 0
			}
		};

		private static readonly Dictionary<string, string[]> CapeVariants = new Dictionary<string, string[]>
		{
			{
				"CapeLinen",
				new string[10] { "#0 Red", "#1 White", "#2 Blue", "#3 Yellow", "#4 Green", "#5 Black", "#6 Purple", "#7 White Alt", "#8 Teal", "#9 Brown" }
			},
			{
				"CapeLox",
				new string[3] { "#0 Default", "#1 Dark", "#2 White" }
			}
		};

		public static List<ItemEntry> Helmets
		{
			get
			{
				EnsureInit();
				return helmets ?? Empty;
			}
		}

		public static List<ItemEntry> Chests
		{
			get
			{
				EnsureInit();
				return chests ?? Empty;
			}
		}

		public static List<ItemEntry> Legs
		{
			get
			{
				EnsureInit();
				return legs ?? Empty;
			}
		}

		public static List<ItemEntry> Capes
		{
			get
			{
				EnsureInit();
				return capes ?? Empty;
			}
		}

		public static List<ItemEntry> Weapons
		{
			get
			{
				EnsureInit();
				return weapons ?? Empty;
			}
		}

		public static List<ItemEntry> Shields
		{
			get
			{
				EnsureInit();
				return shields ?? Empty;
			}
		}

		public static bool IsReady
		{
			get
			{
				if (!initialized)
				{
					EnsureInit();
				}
				return initialized;
			}
		}

		public static List<ItemEntry> GetListForSlot(int slot)
		{
			return slot switch
			{
				0 => Helmets, 
				1 => Chests, 
				2 => Legs, 
				3 => Capes, 
				4 => Weapons, 
				5 => Shields, 
				_ => Empty, 
			};
		}

		public static string GetSlotName(int slot)
		{
			return slot switch
			{
				0 => "Head", 
				1 => "Chest", 
				2 => "Legs", 
				3 => "Cape", 
				4 => "Weapon", 
				5 => "Offhand", 
				_ => "???", 
			};
		}

		private static void EnsureInit()
		{
			if (!initialized && !((Object)(object)ObjectDB.instance == (Object)null) && ObjectDB.instance.m_items != null && ObjectDB.instance.m_items.Count != 0)
			{
				SwornProtectorsPlugin.Log("EquipmentData: Scanning ObjectDB for equipment items...");
				helmets = ScanItems((ItemType)6);
				chests = ScanItems((ItemType)7);
				legs = ScanItems((ItemType)11);
				capes = ScanCapes();
				ItemType[] array = new ItemType[4];
				RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/);
				weapons = ScanItems((ItemType[])(object)array);
				shields = ScanItems((ItemType)5);
				ItemEntry itemEntry = default(ItemEntry);
				itemEntry.PrefabName = "";
				itemEntry.DisplayName = "— None —";
				itemEntry.Variant = 0;
				ItemEntry item = itemEntry;
				helmets.Insert(0, item);
				chests.Insert(0, item);
				legs.Insert(0, item);
				capes.Insert(0, item);
				weapons.Insert(0, item);
				shields.Insert(0, item);
				initialized = true;
				SwornProtectorsPlugin.Log($"EquipmentData ready: {helmets.Count} helmets, {chests.Count} chests, " + $"{legs.Count} legs, {capes.Count} capes, {weapons.Count} weapons, " + $"{shields.Count} shields");
			}
		}

		private static List<ItemEntry> ScanItems(params ItemType[] types)
		{
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			HashSet<ItemType> hashSet = new HashSet<ItemType>(types);
			HashSet<string> hashSet2 = new HashSet<string>();
			List<ItemEntry> list = new List<ItemEntry>();
			foreach (GameObject item in ObjectDB.instance.m_items)
			{
				if (!((Object)(object)item == (Object)null))
				{
					ItemDrop component = item.GetComponent<ItemDrop>();
					if (!((Object)(object)component == (Object)null) && component.m_itemData != null && component.m_itemData.m_shared != null && hashSet.Contains(component.m_itemData.m_shared.m_itemType) && hashSet2.Add(((Object)item).name))
					{
						string localizedName = GetLocalizedName(item, component);
						list.Add(new ItemEntry
						{
							PrefabName = ((Object)item).name,
							DisplayName = localizedName,
							Variant = 0
						});
					}
				}
			}
			list.Sort((ItemEntry a, ItemEntry b) => string.Compare(a.DisplayName, b.DisplayName, StringComparison.OrdinalIgnoreCase));
			return list;
		}

		private static List<ItemEntry> ScanCapes()
		{
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Invalid comparison between Unknown and I4
			HashSet<string> hashSet = new HashSet<string>();
			List<ItemEntry> list = new List<ItemEntry>();
			foreach (GameObject item in ObjectDB.instance.m_items)
			{
				if ((Object)(object)item == (Object)null)
				{
					continue;
				}
				ItemDrop component = item.GetComponent<ItemDrop>();
				if ((Object)(object)component == (Object)null || component.m_itemData == null || component.m_itemData.m_shared == null || (int)component.m_itemData.m_shared.m_itemType != 17 || !hashSet.Add(((Object)item).name))
				{
					continue;
				}
				string localizedName = GetLocalizedName(item, component);
				if (CapeVariants.TryGetValue(((Object)item).name, out var value))
				{
					for (int i = 0; i < value.Length; i++)
					{
						list.Add(new ItemEntry
						{
							PrefabName = ((Object)item).name,
							DisplayName = localizedName + " (" + value[i] + ")",
							Variant = i
						});
					}
				}
				else
				{
					list.Add(new ItemEntry
					{
						PrefabName = ((Object)item).name,
						DisplayName = localizedName,
						Variant = 0
					});
				}
			}
			list.Sort((ItemEntry a, ItemEntry b) => string.Compare(a.DisplayName, b.DisplayName, StringComparison.OrdinalIgnoreCase));
			return list;
		}

		private static string GetLocalizedName(GameObject go, ItemDrop itemDrop)
		{
			string name = itemDrop.m_itemData.m_shared.m_name;
			string text = name;
			try
			{
				if (Localization.instance != null)
				{
					text = Localization.instance.Localize(name);
				}
			}
			catch
			{
			}
			if (string.IsNullOrEmpty(text))
			{
				text = ((Object)go).name;
			}
			if (text.StartsWith("$"))
			{
				text = ((Object)go).name;
			}
			return text;
		}

		public static int FindIndexByName(int slot, string nameContains)
		{
			List<ItemEntry> listForSlot = GetListForSlot(slot);
			for (int i = 0; i < listForSlot.Count; i++)
			{
				if (listForSlot[i].DisplayName.IndexOf(nameContains, StringComparison.OrdinalIgnoreCase) >= 0)
				{
					return i;
				}
			}
			return 0;
		}

		public static void Reset()
		{
			initialized = false;
			helmets = null;
			chests = null;
			legs = null;
			capes = null;
			weapons = null;
			shields = null;
		}
	}
	public static class Patches
	{
		[HarmonyPatch(typeof(BaseAI), "IsEnemy", new Type[]
		{
			typeof(Character),
			typeof(Character)
		})]
		public static class IsEnemy_Patch
		{
			private static void Postfix(Character a, Character b, ref bool __result)
			{
				if (__result)
				{
					bool flag = (Object)(object)a != (Object)null && (Object)(object)((Component)a).GetComponent<ProtectorAI>() != (Object)null;
					bool flag2 = (Object)(object)b != (Object)null && (Object)(object)((Component)b).GetComponent<ProtectorAI>() != (Object)null;
					if (flag && flag2)
					{
						__result = false;
					}
					else if (flag && b is Player)
					{
						__result = false;
					}
					else if (a is Player && flag2)
					{
						__result = false;
					}
				}
			}
		}

		[HarmonyPatch(typeof(Player), "TakeInput")]
		public static class PlayerTakeInput_Patch
		{
			private static bool Prefix(ref bool __result)
			{
				if ((Object)(object)CommandMenu.Instance != (Object)null && CommandMenu.Instance.IsMenuOpen)
				{
					__result = false;
					return false;
				}
				return true;
			}
		}

		[HarmonyPatch(typeof(Humanoid), "StartAttack")]
		public static class BlockAttackWhenMenuOpen_Patch
		{
			private static bool Prefix(Humanoid __instance)
			{
				if (__instance is Player && (Object)(object)CommandMenu.Instance != (Object)null && CommandMenu.Instance.IsMenuOpen)
				{
					return false;
				}
				return true;
			}
		}

		[HarmonyPatch(typeof(GameCamera), "UpdateCamera")]
		public static class GameCameraUpdate_Patch
		{
			private static bool Prefix()
			{
				if ((Object)(object)CommandMenu.Instance != (Object)null && CommandMenu.Instance.IsMenuOpen)
				{
					return false;
				}
				return true;
			}
		}

		[HarmonyPatch(typeof(Character), "Damage")]
		public static class Damage_Patch
		{
			private static bool Prefix(Character __instance, HitData hit)
			{
				if ((Object)(object)((Component)__instance).GetComponent<ProtectorAI>() != (Object)null && hit.GetAttacker() is Player)
				{
					return false;
				}
				return true;
			}
		}

		[HarmonyPatch(typeof(Character), "GetSkillFactor")]
		public static class ProtectorSkillProficiency_Patch
		{
			private static bool Prefix(Character __instance, ref float __result)
			{
				if ((Object)(object)((Component)__instance).GetComponent<ProtectorAI>() != (Object)null)
				{
					__result = 1f;
					return false;
				}
				return true;
			}
		}

		[HarmonyPatch(typeof(Character), "RaiseSkill")]
		public static class ProtectorNoSkillRaise_Patch
		{
			private static bool Prefix(Character __instance)
			{
				if ((Object)(object)((Component)__instance).GetComponent<ProtectorAI>() != (Object)null)
				{
					return false;
				}
				return true;
			}
		}

		[HarmonyPatch(typeof(Game), "OnDestroy")]
		public static class GameCleanup_Patch
		{
			private static void Prefix()
			{
				ProtectorManager.Instance?.DespawnAll();
				SwornProtectorsPlugin.Log("World unloading — all protectors despawned.");
			}
		}

		[HarmonyPatch(typeof(ZNetScene), "Awake")]
		public static class ZNetScene_Awake_Patch
		{
			private static void Postfix()
			{
				SwornProtectorsPlugin.Log("ZNetScene loaded — protector prefab will be built on first spawn.");
			}
		}
	}
	[BepInPlugin("com.mitch.swornprotectors", "Sworn Protectors", "0.5.0")]
	public class SwornProtectorsPlugin : BaseUnityPlugin
	{
		public const string PluginGUID = "com.mitch.swornprotectors";

		public const string PluginName = "Sworn Protectors";

		public const string PluginVersion = "0.5.0";

		public static ConfigEntry<KeyCode> CommandMenuKey;

		public static ConfigEntry<int> MaxProtectors;

		public static ConfigEntry<float> FollowDistance;

		public static ConfigEntry<float> FormationSpacing;

		public static ConfigEntry<float> MoveSpeedWalk;

		public static ConfigEntry<float> MoveSpeedRun;

		public static ConfigEntry<float> RunCatchUpDistance;

		public static ConfigEntry<bool> AutoDefendEnabled;

		public static ConfigEntry<KeyCode> FollowKey;

		public static ConfigEntry<KeyCode> AttackMoveKey;

		public static ConfigEntry<KeyCode> HoldKey;

		public static ConfigEntry<float> ProtectorScale;

		public static ConfigEntry<float> ProtectorHealth;

		private Harmony harmony;

		public static SwornProtectorsPlugin Instance { get; private set; }

		private void Awake()
		{
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Expected O, but got Unknown
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d2: Expected O, but got Unknown
			//IL_0201: Unknown result type (might be due to invalid IL or missing references)
			//IL_020b: Expected O, but got Unknown
			Instance = this;
			CommandMenuKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Controls", "CommandMenuKey", (KeyCode)104, "Key to open/close the Sworn Protectors panel.");
			FollowKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Controls", "FollowKey", (KeyCode)291, "Silent keybind: Follow & Sheathe (no on-screen text — cinematic safe).");
			AttackMoveKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Controls", "AttackMoveKey", (KeyCode)290, "Silent keybind: Attack / Move to crosshair target (no on-screen text — cinematic safe).");
			HoldKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Controls", "HoldKey", (KeyCode)292, "Silent keybind: Hold position (no on-screen text — cinematic safe).");
			MaxProtectors = ((BaseUnityPlugin)this).Config.Bind<int>("General", "MaxProtectors", 15, new ConfigDescription("Maximum Sworn Protectors allowed at once.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 15), Array.Empty<object>()));
			FollowDistance = ((BaseUnityPlugin)this).Config.Bind<float>("Formation", "FollowDistance", 6f, "How far behind you (meters) the front row walks.");
			FormationSpacing = ((BaseUnityPlugin)this).Config.Bind<float>("Formation", "FormationSpacing", 2f, "Lateral spacing (meters) between protectors in a row.");
			MoveSpeedWalk = ((BaseUnityPlugin)this).Config.Bind<float>("Movement", "WalkSpeed", 2.5f, "Normal walking speed when following in formation.");
			MoveSpeedRun = ((BaseUnityPlugin)this).Config.Bind<float>("Movement", "RunSpeed", 7f, "Sprint speed when catching up to the player. Vanilla player run is ~7 m/s.");
			RunCatchUpDistance = ((BaseUnityPlugin)this).Config.Bind<float>("Movement", "RunCatchUpDistance", 8f, "Distance (meters) at which protectors start running to catch up.");
			AutoDefendEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Combat", "AutoDefendEnabled", false, "If enabled, protectors auto-engage enemies within range.");
			ProtectorScale = ((BaseUnityPlugin)this).Config.Bind<float>("Appearance", "ProtectorScale", 0.95f, new ConfigDescription("Scale of protectors (1.0 = same skeleton size, 0.95 = compensates for armor bulk).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.7f, 1.2f), Array.Empty<object>()));
			ProtectorHealth = ((BaseUnityPlugin)this).Config.Bind<float>("General", "ProtectorHealth", 500f, "Health of each protector. Default 500 (tanky bodyguards).");
			harmony = new Harmony("com.mitch.swornprotectors");
			harmony.PatchAll();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Sworn Protectors v0.5.0 loaded!");
		}

		private void Start()
		{
			((Component)this).gameObject.AddComponent<ProtectorManager>();
			((Component)this).gameObject.AddComponent<CommandMenu>();
		}

		private void OnDestroy()
		{
			Harmony obj = harmony;
			if (obj != null)
			{
				obj.UnpatchSelf();
			}
		}

		public static void Log(string msg)
		{
			SwornProtectorsPlugin instance = Instance;
			if (instance != null)
			{
				((BaseUnityPlugin)instance).Logger.LogInfo((object)msg);
			}
		}

		public static void LogWarn(string msg)
		{
			SwornProtectorsPlugin instance = Instance;
			if (instance != null)
			{
				((BaseUnityPlugin)instance).Logger.LogWarning((object)msg);
			}
		}

		public static void LogErr(string msg)
		{
			SwornProtectorsPlugin instance = Instance;
			if (instance != null)
			{
				((BaseUnityPlugin)instance).Logger.LogError((object)msg);
			}
		}
	}
	public class ProtectorAI : BaseAI
	{
		public enum AIState
		{
			Awaiting,
			Following,
			MovingTo,
			Attacking,
			Holding
		}

		public enum FormationType
		{
			Diamond,
			Line,
			Wedge,
			ShieldWall,
			Circle,
			Parade
		}

		public static readonly string[] FormationNames = new string[6] { "Diamond", "Line", "Wedge", "Shield Wall", "Circle", "Parade" };

		private Player ownerPlayer;

		private Humanoid humanoid;

		private Rigidbody body;

		private PinData minimapPin;

		private Vector3 commandTarget;

		private bool isRunning;

		private bool paradeHolding;

		private static Vector3 paradeSnapshotForward;

		private static Vector3 paradeSnapshotRight;

		private static Vector3 paradeSnapshotPosition;

		private bool settledAtFormation;

		private const float SETTLE_ARRIVE_DIST = 1f;

		private const float SETTLE_DEPART_DIST = 2f;

		private const float WALK_RESUME_RATIO = 0.6f;

		private const float PLAYER_AVOID_RADIUS = 2f;

		private const float PLAYER_AVOID_STRENGTH = 2.5f;

		private const float PLAYER_REPULSE_RADIUS = 1.8f;

		private const float PLAYER_REPULSE_FORCE = 4f;

		private float pathStuckTimer;

		private const float PATH_STUCK_THRESHOLD = 2f;

		private Character attackTarget;

		private float attackScanTimer;

		private const float ATTACK_SCAN_INTERVAL = 1f;

		private const float ATTACK_RANGE = 2.5f;

		private const float AUTO_DEFEND_RANGE = 12f;

		private bool healthInitialized;

		private float perlinSeedX;

		private float perlinSeedZ;

		private float reactionDelay;

		private float reactionTimer;

		private Vector3 lastKnownPlayerForward;

		private static MethodInfo s_showHandItemsMethod;

		private static FieldInfo s_hiddenRightItemField;

		private static FieldInfo s_hiddenLeftItemField;

		private static FieldInfo s_rightItemField;

		private static FieldInfo s_leftItemField;

		private static MethodInfo s_getRightItemMethod;

		private static MethodInfo s_getLeftItemMethod;

		private static bool s_reflectionCached;

		private static MethodInfo s_setupVisEquipMethod;

		private bool lastPlayerSheathed;

		private float visEquipSyncTimer;

		private bool visEquipSetupFailed;

		public static FormationType CurrentFormation { get; private set; } = FormationType.Diamond;


		public AIState CurrentState { get; private set; } = AIState.Following;


		public int FormationIndex { get; set; }

		public static void SetFormation(FormationType formation)
		{
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: 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_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			CurrentFormation = formation;
			ProtectorManager instance = ProtectorManager.Instance;
			if ((Object)(object)instance == (Object)null)
			{
				return;
			}
			if (formation == FormationType.Parade && instance.ActiveProtectors.Count > 0)
			{
				ProtectorAI protectorAI = instance.ActiveProtectors[0];
				if ((Object)(object)protectorAI != (Object)null && (Object)(object)protectorAI.ownerPlayer != (Object)null)
				{
					paradeSnapshotForward = ((Component)protectorAI.ownerPlayer).transform.forward;
					paradeSnapshotForward.y = 0f;
					((Vector3)(ref paradeSnapshotForward)).Normalize();
					Vector3 val = Vector3.Cross(Vector3.up, paradeSnapshotForward);
					paradeSnapshotRight = ((Vector3)(ref val)).normalized;
					paradeSnapshotPosition = ((Component)protectorAI.ownerPlayer).transform.position;
				}
			}
			foreach (ProtectorAI activeProtector in instance.ActiveProtectors)
			{
				if (!((Object)(object)activeProtector != (Object)null))
				{
					continue;
				}
				activeProtector.settledAtFormation = false;
				if (formation == FormationType.Parade)
				{
					if (activeProtector.CurrentState == AIState.Following || activeProtector.CurrentState == AIState.Holding)
					{
						activeProtector.CurrentState = AIState.Following;
					}
					activeProtector.paradeHolding = false;
				}
				else if (activeProtector.paradeHolding)
				{
					activeProtector.CurrentState = AIState.Following;
					activeProtector.paradeHolding = false;
				}
			}
		}

		private static void CacheReflection()
		{
			if (!s_reflectionCached)
			{
				s_reflectionCached = true;
				s_showHandItemsMethod = typeof(Humanoid).GetMethod("ShowHandItems", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				s_hiddenRightItemField = AccessTools.Field(typeof(Humanoid), "m_hiddenRightItem");
				s_hiddenLeftItemField = AccessTools.Field(typeof(Humanoid), "m_hiddenLeftItem");
				s_rightItemField = AccessTools.Field(typeof(Humanoid), "m_rightItem");
				s_leftItemField = AccessTools.Field(typeof(Humanoid), "m_leftItem");
				s_getRightItemMethod = AccessTools.Method(typeof(Humanoid), "GetRightItem", (Type[])null, (Type[])null);
				s_getLeftItemMethod = AccessTools.Method(typeof(Humanoid), "GetLeftItem", (Type[])null, (Type[])null);
				s_setupVisEquipMethod = AccessTools.Method(typeof(Humanoid), "SetupVisEquipment", new Type[2]
				{
					typeof(VisEquipment),
					typeof(bool)
				}, (Type[])null);
				SwornProtectorsPlugin.Log($"Reflection cache: showHand={s_showHandItemsMethod != null}, " + $"hiddenRight={s_hiddenRightItemField != null}, " + $"hiddenLeft={s_hiddenLeftItemField != null}, " + $"rightItem={s_rightItemField != null}, leftItem={s_leftItemField != null}");
			}
		}

		protected override void Awake()
		{
			((BaseAI)this).Awake();
			humanoid = ((Component)this).GetComponent<Humanoid>();
			body = ((Component)this).GetComponent<Rigidbody>();
			CacheReflection();
			SwornProtectorsPlugin.Log("ProtectorAI.Awake() — BaseAI initialized.");
		}

		public void Initialize(Player owner)
		{
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			ownerPlayer = owner;
			if ((Object)(object)humanoid == (Object)null)
			{
				humanoid = ((Component)this).GetComponent<Humanoid>();
			}
			if ((Object)(object)body == (Object)null)
			{
				body = ((Component)this).GetComponent<Rigidbody>();
			}
			if ((Object)(object)body != (Object)null)
			{
				body.constraints = (RigidbodyConstraints)112;
			}
			EnsureHealth();
			SheatheWeapons();
			perlinSeedX = Random.Range(0f, 1000f);
			perlinSeedZ = Random.Range(0f, 1000f);
			reactionDelay = ((FormationIndex == 0) ? Random.Range(0.05f, 0.15f) : Random.Range(0.3f, 1f));
			reactionTimer = 0f;
			lastKnownPlayerForward = ((Component)owner).transform.forward;
			CurrentState = AIState.Awaiting;
			StartKneeling();
			AddMinimapPin();
			string[] obj = new string[5]
			{
				$"Protector #{FormationIndex} initialized (Awaiting). ",
				$"m_character={(Object)(object)base.m_character != (Object)null}, ",
				$"humanoid={(Object)(object)humanoid != (Object)null}, ",
				null,
				null
			};
			Humanoid obj2 = humanoid;
			object arg = ((obj2 != null) ? ((Character)obj2).GetHealth() : (-1f));
			Humanoid obj3 = humanoid;
			obj[3] = $"health={arg}/{((obj3 != null) ? ((Character)obj3).GetMaxHealth() : (-1f))}, ";
			obj[4] = $"reactionDelay={reactionDelay:F2}s";
			SwornProtectorsPlugin.Log(string.Concat(obj));
		}

		private void EnsureHealth()
		{
			if (!((Object)(object)humanoid == (Object)null))
			{
				((Character)humanoid).SetMaxHealth(SwornProtectorsPlugin.ProtectorHealth.Value);
				if (((Character)humanoid).GetHealth() <= 0f)
				{
					((Character)humanoid).SetHealth(((Character)humanoid).GetMaxHealth());
					SwornProtectorsPlugin.Log($"Protector #{FormationIndex} health forced to {((Character)humanoid).GetHealth()}");
				}
				healthInitialized = true;
			}
		}

		public override bool UpdateAI(float dt)
		{
			try
			{
				if (!((BaseAI)this).UpdateAI(dt))
				{
					return false;
				}
				UpdateMinimapPin();
				if ((Object)(object)ownerPlayer == (Object)null)
				{
					return true;
				}
				if (!healthInitialized || ((Object)(object)humanoid != (Object)null && ((Character)humanoid).GetHealth() <= 0f))
				{
					EnsureHealth();
				}
				if ((Object)(object)base.m_character == (Object)null)
				{
					return true;
				}
				if (base.m_character.IsDead())
				{
					return true;
				}
				switch (CurrentState)
				{
				case AIState.Awaiting:
					UpdateAwaiting(dt);
					return true;
				case AIState.Following:
					UpdateFollowing(dt);
					break;
				case AIState.MovingTo:
					UpdateMovingTo(dt);
					break;
				case AIState.Attacking:
					UpdateAttacking(dt);
					break;
				case AIState.Holding:
					UpdateHolding(dt);
					break;
				}
				if (SwornProtectorsPlugin.AutoDefendEnabled.Value && !paradeHolding)
				{
					CheckAutoDefend();
				}
				TickVisEquipmentSync();
				return true;
			}
			catch (Exception ex)
			{
				SwornProtectorsPlugin.LogErr($"ProtectorAI.UpdateAI exception on #{FormationIndex}: {ex.Message}\n{ex.StackTrace}");
				return true;
			}
		}

		private void UpdateFollowing(float dt)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//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_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0247: Unknown result type (might be due to invalid IL or missing references)
			//IL_026f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0274: Unknown result type (might be due to invalid IL or missing references)
			//IL_03da: Unknown result type (might be due to invalid IL or missing references)
			//IL_033a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0341: Unknown result type (might be due to invalid IL or missing references)
			//IL_0346: Unknown result type (might be due to invalid IL or missing references)
			//IL_034b: Unknown result type (might be due to invalid IL or missing references)
			//IL_035b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0360: Unknown result type (might be due to invalid IL or missing references)
			//IL_0363: Unknown result type (might be due to invalid IL or missing references)
			//IL_0365: Unknown result type (might be due to invalid IL or missing references)
			//IL_036a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0372: Unknown result type (might be due to invalid IL or missing references)
			//IL_0398: Unknown result type (might be due to invalid IL or missing references)
			//IL_039d: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b9: 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_0427: Unknown result type (might be due to invalid IL or missing references)
			//IL_042c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0436: Unknown result type (might be due to invalid IL or missing references)
			//IL_043b: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ef: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)ownerPlayer == (Object)null)
			{
				return;
			}
			float num = Vector3.Distance(((Component)this).transform.position, ((Component)ownerPlayer).transform.position);
			if (num < 1.8f && num > 0.05f)
			{
				Vector3 val = ((Component)this).transform.position - ((Component)ownerPlayer).transform.position;
				val.y = 0f;
				((Vector3)(ref val)).Normalize();
				float num2 = (1f - num / 1.8f) * 4f * dt;
				Transform transform = ((Component)this).transform;
				transform.position += val * num2;
			}
			if (num > 40f)
			{
				TeleportToOwner();
				return;
			}
			SyncWeaponsWithPlayer();
			if ((Object)(object)base.m_character != (Object)null && (base.m_character.IsSwimming() || base.m_character.InWater()))
			{
				if (num > 3f)
				{
					Vector3 val2 = ((Component)ownerPlayer).transform.position - ((Component)this).transform.position;
					val2.y = 0f;
					((Vector3)(ref val2)).Normalize();
					((BaseAI)this).MoveTowards(val2, false);
				}
				else
				{
					((BaseAI)this).StopMoving();
				}
				return;
			}
			if ((Object)(object)humanoid != (Object)null)
			{
				((Character)humanoid).m_walkSpeed = ((Character)ownerPlayer).m_walkSpeed;
			}
			Vector3 val3 = ((CurrentFormation != FormationType.Parade) ? GetNaturalFormationTarget(dt) : GetStableFormationTarget());
			float num3 = Vector3.Distance(((Component)this).transform.position, val3);
			if (settledAtFormation)
			{
				if (!(num3 > 2f))
				{
					((BaseAI)this).StopMoving();
					if ((Object)(object)base.m_character != (Object)null)
					{
						base.m_character.SetMoveDir(Vector3.zero);
						base.m_character.SetRun(false);
					}
					FaceOutwardFromPlayer();
					pathStuckTimer = 0f;
					return;
				}
				settledAtFormation = false;
			}
			float value = SwornProtectorsPlugin.RunCatchUpDistance.Value;
			float num4 = value * 0.6f;
			if (num3 > value)
			{
				isRunning = true;
			}
			else if (num3 < num4)
			{
				isRunning = false;
			}
			if (isRunning)
			{
				settledAtFormation = false;
				if ((Object)(object)base.m_character != (Object)null)
				{
					base.m_character.SetWalk(false);
					base.m_character.SetRun(true);
				}
				if (!((BaseAI)this).MoveTo(dt, val3, 1.5f, true) && (Object)(object)base.m_character != (Object)null)
				{
					Vector3 velocity = base.m_character.GetVelocity();
					if (((Vector3)(ref velocity)).magnitude < 0.3f)
					{
						pathStuckTimer += dt;
						if (pathStuckTimer >= 2f)
						{
							pathStuckTimer = 0f;
							Vector3 val4 = val3 - ((Component)this).transform.position;
							val4.y = 0f;
							if (((Vector3)(ref val4)).sqrMagnitude > 0.01f)
							{
								((Vector3)(ref val4)).Normalize();
								val4 = ApplyPlayerAvoidance(val4);
								((BaseAI)this).MoveTowards(val4, true);
							}
						}
						return;
					}
				}
				pathStuckTimer = 0f;
			}
			else if (num3 > ((CurrentFormation == FormationType.Parade) ? 1.5f : 1f))
			{
				pathStuckTimer = 0f;
				if ((Object)(object)base.m_character != (Object)null)
				{
					Vector3 val5 = val3 - ((Component)this).transform.position;
					val5.y = 0f;
					Vector3 normalized = ((Vector3)(ref val5)).normalized;
					normalized = ApplyPlayerAvoidance(normalized);
					base.m_character.SetMoveDir(normalized);
					base.m_character.SetRun(false);
					base.m_character.SetWalk(true);
					((BaseAI)this).LookAt(((Component)this).transform.position + normalized * 10f);
				}
			}
			else
			{
				settledAtFormation = true;
				pathStuckTimer = 0f;
				if ((Object)(object)base.m_character != (Object)null)
				{
					base.m_character.SetMoveDir(Vector3.zero);
					base.m_character.SetRun(false);
					base.m_character.SetWalk(false);
				}
				((BaseAI)this).StopMoving();
				if (CurrentFormation == FormationType.Parade && !paradeHolding)
				{
					paradeHolding = true;
					CurrentState = AIState.Holding;
					((BaseAI)this).LookAt(((Component)this).transform.position + paradeSnapshotForward * 10f);
				}
				else
				{
					FaceOutwardFromPlayer();
				}
			}
		}

		private void FaceOutwardFromPlayer()
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: 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_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)ownerPlayer == (Object)null))
			{
				Vector3 val = ((Component)this).transform.position - ((Component)ownerPlayer).transform.position;
				val.y = 0f;
				if (((Vector3)(ref val)).sqrMagnitude < 0.5f)
				{
					val = lastKnownPlayerForward;
				}
				else
				{
					((Vector3)(ref val)).Normalize();
				}
				((BaseAI)this).LookAt(((Component)this).transform.position + val * 10f);
			}
		}

		private void FaceTowardPlayer()
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: 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)
			if (!((Object)(object)ownerPlayer == (Object)null))
			{
				Vector3 val = ((Component)ownerPlayer).transform.position - ((Component)this).transform.position;
				val.y = 0f;
				if (!(((Vector3)(ref val)).sqrMagnitude < 0.1f))
				{
					((Vector3)(ref val)).Normalize();
					((BaseAI)this).LookAt(((Component)this).transform.position + val * 10f);
				}
			}
		}

		private Vector3 ApplyPlayerAvoidance(Vector3 desiredDir)
		{
			//IL_001b: 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_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: 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_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: 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_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)ownerPlayer == (Object)null)
			{
				return desiredDir;
			}
			Vector3 val = ((Component)ownerPlayer).transform.position - ((Component)this).transform.position;
			val.y = 0f;
			float magnitude = ((Vector3)(ref val)).magnitude;
			if (magnitude > 5f || magnitude < 0.1f)
			{
				return desiredDir;
			}
			Vector3 val2 = val / magnitude;
			float num = Vector3.Dot(desiredDir, val2);
			if (num <= 0.1f)
			{
				return desiredDir;
			}
			Vector3 val3 = default(Vector3);
			((Vector3)(ref val3))..ctor(val2.z, 0f, 0f - val2.x);
			Vector3 val4 = -val3;
			Vector3 val5 = ((Vector3.Dot(desiredDir, val3) >= 0f) ? val3 : val4);
			float num2 = (1f - Mathf.Clamp01(magnitude / 5f)) * 2.5f * num;
			Vector3 val6 = desiredDir + val5 * num2;
			return ((Vector3)(ref val6)).normalized;
		}

		private void UpdateMovingTo(float dt)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: 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)
			if (Vector3.Distance(((Component)this).transform.position, commandTarget) > 1.5f)
			{
				Character val = FindNearestEnemy(commandTarget, 7.5f);
				if ((Object)(object)val != (Object)null)
				{
					attackTarget = val;
					DrawWeapons();
					CurrentState = AIState.Attacking;
				}
				else
				{
					if (((BaseAI)this).MoveTo(dt, commandTarget, 1f, true) || !((Object)(object)base.m_character != (Object)null))
					{
						return;
					}
					Vector3 velocity = base.m_character.GetVelocity();
					if (((Vector3)(ref velocity)).magnitude < 0.3f)
					{
						Vector3 val2 = commandTarget - ((Component)this).transform.position;
						val2.y = 0f;
						if (((Vector3)(ref val2)).sqrMagnitude > 0.01f)
						{
							((Vector3)(ref val2)).Normalize();
							((BaseAI)this).MoveTowards(val2, true);
						}
					}
				}
			}
			else
			{
				((BaseAI)this).StopMoving();
				CurrentState = AIState.Holding;
			}
		}

		private void UpdateAttacking(float dt)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: 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_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)attackTarget == (Object)null || attackTarget.IsDead())
			{
				attackTarget = null;
				SetStateFollow();
			}
			else if (Vector3.Distance(((Component)this).transform.position, ((Component)attackTarget).transform.position) > 2.5f)
			{
				((BaseAI)this).MoveTo(dt, ((Component)attackTarget).transform.position, 2f, true);
				if (!((BaseAI)this).FoundPath())
				{
					Vector3 val = ((Component)attackTarget).transform.position - ((Component)this).transform.position;
					val.y = 0f;
					if (((Vector3)(ref val)).sqrMagnitude > 0.01f)
					{
						((Vector3)(ref val)).Normalize();
						((BaseAI)this).MoveTowards(val, true);
					}
				}
			}
			else
			{
				((BaseAI)this).StopMoving();
				((BaseAI)this).LookAt(((Component)attackTarget).transform.position);
				if ((Object)(object)humanoid != (Object)null)
				{
					((Character)humanoid).StartAttack(attackTarget, false);
				}
			}
		}

		private void UpdateHolding(float dt)
		{
			((BaseAI)this).StopMoving();
		}

		private void UpdateAwaiting(float dt)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			((BaseAI)this).StopMoving();
			if ((Object)(object)base.m_character != (Object)null)
			{
				base.m_character.SetMoveDir(Vector3.zero);
				base.m_character.SetRun(false);
				base.m_character.SetWalk(false);
			}
		}

		private void StartKneeling()
		{
			if ((Object)(object)base.m_animator != (Object)null)
			{
				base.m_animator.SetTrigger("emote_kneel");
				SwornProtectorsPlugin.Log($"Protector #{FormationIndex}: Kneel triggered.");
			}
			float num = Random.Range(0.5f, 3f);
			((MonoBehaviour)this).Invoke("DoSpawnBark", num);
		}

		private void DoSpawnBark()
		{
			ProtectorBarks.SaySpawnBark(((Component)this).gameObject);
		}

		public void Activate()
		{
			if (CurrentState == AIState.Awaiting)
			{
				if ((Object)(object)base.m_animator != (Object)null)
				{
					base.m_animator.SetTrigger("emote_stop");
				}
				CurrentState = AIState.Following;
				isRunning = true;
				settledAtFormation = false;
				float num = Random.Range(0.3f, 2.5f);
				((MonoBehaviour)this).Invoke("DoEquipBark", num);
				SwornProtectorsPlugin.Log($"Protector #{FormationIndex}: Activated! Now following.");
			}
		}

		private void DoEquipBark()
		{
			ProtectorBarks.SayEquipBark(((Component)this).gameObject);
		}

		private void CheckAutoDefend()
		{
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			if (CurrentState == AIState.Attacking && (Object)(object)attackTarget != (Object)null)
			{
				return;
			}
			attackScanTimer -= Time.deltaTime;
			if (!(attackScanTimer > 0f))
			{
				attackScanTimer = 1f;
				Character val = FindNearestEnemy(((Component)this).transform.position, 12f);
				if ((Object)(object)val != (Object)null)
				{
					attackTarget = val;
					DrawWeapons();
					CurrentState = AIState.Attacking;
				}
			}
		}

		public void SetCommandTarget(Vector3 worldPoint)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			paradeHolding = false;
			commandTarget = worldPoint;
			DrawWeapons();
			CurrentState = AIState.MovingTo;
			SwornProtectorsPlugin.Log($"Protector #{FormationIndex} -> MoveTo {worldPoint}");
		}

		public void SetStateFollow()
		{
			paradeHolding = false;
			attackTarget = null;
			SheatheWeapons();
			CurrentState = AIState.Following;
			isRunning = true;
			pathStuckTimer = 0f;
			settledAtFormation = false;
			SwornProtectorsPlugin.Log($"Protector #{FormationIndex} -> Following");
		}

		public void SetStateHold()
		{
			((BaseAI)this).StopMoving();
			CurrentState = AIState.Holding;
			SwornProtectorsPlugin.Log($"Protector #{FormationIndex} -> Holding");
		}

		private void TeleportToOwner()
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_005e: 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_0069: 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_0099: 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_00b3: 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)
			if (!((Object)(object)ownerPlayer == (Object)null))
			{
				Vector3 val = -((Component)ownerPlayer).transform.forward;
				val.y = 0f;
				if (((Vector3)(ref val)).sqrMagnitude < 0.01f)
				{
					val = Vector3.back;
				}
				else
				{
					((Vector3)(ref val)).Normalize();
				}
				Vector3 val2 = ((Component)ownerPlayer).transform.position + val * 2.5f;
				float y = default(float);
				if ((Object)(object)ZoneSystem.instance != (Object)null && ZoneSystem.instance.GetGroundHeight(val2, ref y))
				{
					val2.y = y;
				}
				((Component)this).transform.position = val2;
				if ((Object)(object)body != (Object)null)
				{
					body.position = val2;
					body.velocity = Vector3.zero;
				}
				pathStuckTimer = 0f;
				ResetClothSimulation();
			}
		}

		private void ResetClothSimulation()
		{
			try
			{
				Behaviour[] componentsInChildren = ((Component)this).GetComponentsInChildren<Behaviour>(true);
				foreach (Behaviour val in componentsInChildren)
				{
					if ((Object)(object)val != (Object)null && ((object)val).GetType().Name == "Cloth")
					{
						val.enabled = false;
						val.enabled = true;
					}
				}
			}
			catch
			{
			}
		}

		public void SetGender(bool female)
		{
			VisEquipment component = ((Component)this).GetComponent<VisEquipment>();
			if ((Object)(object)component != (Object)null)
			{
				int model = (female ? 1 : 0);
				component.SetModel(model);
				SwornProtectorsPlugin.Log(string.Format("Protector #{0} gender -> {1}", FormationIndex, female ? "Female" : "Male"));
			}
		}

		private void SyncWeaponsWithPlayer()
		{
			if ((Object)(object)ownerPlayer == (Object)null || (Object)(object)humanoid == (Object)null || CurrentState == AIState.Attacking || CurrentState == AIState.MovingTo)
			{
				return;
			}
			try
			{
				bool flag = IsPlayerWeaponsSheathed();
				if (flag != lastPlayerSheathed)
				{
					lastPlayerSheathed = flag;
					if (flag)
					{
						SheatheWeapons();
					}
					else
					{
						DrawWeapons();
					}
				}
			}
			catch
			{
			}
		}

		private bool IsPlayerWeaponsSheathed()
		{
			try
			{
				if (s_hiddenRightItemField?.GetValue(ownerPlayer) != null || s_hiddenLeftItemField?.GetValue(ownerPlayer) != null)
				{
					return true;
				}
				bool flag = s_getRightItemMethod?.Invoke(ownerPlayer, null) != null || s_getLeftItemMethod?.Invoke(ownerPlayer, null) != null;
				return (s_rightItemField?.GetValue(ownerPlayer) != null || s_leftItemField?.GetValue(ownerPlayer) != null) && !flag;
			}
			catch
			{
				return false;
			}
		}

		public void SheatheWeapons()
		{
			if ((Object)(object)humanoid == (Object)null)
			{
				return;
			}
			try
			{
				humanoid.HideHandItems(false, true);
				ForceVisEquipmentUpdate();
				SwornProtectorsPlugin.Log($"Protector #{FormationIndex}: Sheathed weapons.");
			}
			catch (Exception ex)
			{
				SwornProtectorsPlugin.LogWarn("SheatheWeapons failed: " + ex.Message);
			}
		}

		public void DrawWeapons()
		{
			if ((Object)(object)humanoid == (Object)null)
			{
				return;
			}
			try
			{
				bool flag = false;
				if (s_showHandItemsMethod != null)
				{
					if (s_showHandItemsMethod.GetParameters().Length == 0)
					{
						s_showHandItemsMethod.Invoke(humanoid, null);
					}
					else
					{
						s_showHandItemsMethod.Invoke(humanoid, new object[2] { false, false });
					}
					flag = true;
				}
				if (!flag)
				{
					if (s_hiddenRightItemField != null && s_rightItemField != null)
					{
						object value = s_hiddenRightItemField.GetValue(humanoid);
						if (value != null)
						{
							s_rightItemField.SetValue(humanoid, value);
							s_hiddenRightItemField.SetValue(humanoid, null);
						}
					}
					if (s_hiddenLeftItemField != null && s_leftItemField != null)
					{
						object value2 = s_hiddenLeftItemField.GetValue(humanoid);
						if (value2 != null)
						{
							s_leftItemField.SetValue(humanoid, value2);
							s_hiddenLeftItemField.SetValue(humanoid, null);
						}
					}
				}
				ForceVisEquipmentUpdate();
				try
				{
					VisEquipment component = ((Component)this).GetComponent<VisEquipment>();
					if ((Object)(object)component != (Object)null)
					{
						MethodInfo methodInfo = AccessTools.Method(typeof(VisEquipment), "SetRightBackItem", (Type[])null, (Type[])null);
						MethodInfo methodInfo2 = AccessTools.Method(typeof(VisEquipment), "SetLeftBackItem", (Type[])null, (Type[])null);
						if (methodInfo != null)
						{
							methodInfo.Invoke(component, new object[1] { "" });
						}
						if (methodInfo2 != null)
						{
							methodInfo2.Invoke(component, new object[1] { "" });
						}
						object? obj = s_rightItemField?.GetValue(humanoid);
						ItemData val = (ItemData)((obj is ItemData) ? obj : null);
						object? obj2 = s_leftItemField?.GetValue(humanoid);
						ItemData val2 = (ItemData)((obj2 is ItemData) ? obj2 : null);
						string text = (((Object)(object)val?.m_dropPrefab != (Object)null) ? ((Object)val.m_dropPrefab).name : "");
						string text2 = (((Object)(object)val2?.m_dropPrefab != (Object)null) ? ((Object)val2.m_dropPrefab).name : "");
						MethodInfo methodInfo3 = AccessTools.Method(typeof(VisEquipment), "SetRightItem", (Type[])null, (Type[])null);
						MethodInfo methodInfo4 = AccessTools.Method(typeof(VisEquipment), "SetLeftItem", (Type[])null, (Type[])null);
						if (methodInfo3 != null && !string.IsNullOrEmpty(text))
						{
							methodInfo3.Invoke(component, new object[1] { text });
						}
						if (methodInfo4 != null && !string.IsNullOrEmpty(text2))
						{
							methodInfo4.Invoke(component, new object[1] { text2 });
						}
					}
				}
				catch
				{
				}
				SwornProtectorsPlugin.Log($"Protector #{FormationIndex}: Drew weapons.");
			}
			catch (Exception ex)
			{
				SwornProtectorsPlugin.LogWarn("DrawWeapons failed: " + ex.Message);
			}
		}

		private void TickVisEquipmentSync()
		{
			if ((Object)(object)humanoid == (Object)null)
			{
				return;
			}
			VisEquipment component = ((Component)this).GetComponent<VisEquipment>();
			if ((Object)(object)component == (Object)null)
			{
				return;
			}
			try
			{
				if (!visEquipSetupFailed && s_setupVisEquipMethod != null)
				{
					s_setupVisEquipMethod.Invoke(humanoid, new object[2] { component, false });
				}
				visEquipSyncTimer -= Time.deltaTime;
				if (visEquipSyncTimer <= 0f)
				{
					visEquipSyncTimer = 0.5f;
					PushEquipmentToZDO(component);
				}
			}
			catch
			{
				visEquipSetupFailed = true;
			}
		}

		private void PushEquipmentToZDO(VisEquipment visEquip)
		{
			try
			{
				ZNetView component = ((Component)this).GetComponent<ZNetView>();
				if (!((Object)(object)component == (Object)null) && component.IsValid())
				{
					ZDO zDO = component.GetZDO();
					if (zDO != null)
					{
						object? obj = s_rightItemField?.GetValue(humanoid);
						ItemData item = (ItemData)((obj is ItemData) ? obj : null);
						object? obj2 = s_leftItemField?.GetValue(humanoid);
						ItemData item2 = (ItemData)((obj2 is ItemData) ? obj2 : null);
						object? obj3 = s_hiddenRightItemField?.GetValue(humanoid);
						ItemData item3 = (ItemData)((obj3 is ItemData) ? obj3 : null);
						object? obj4 = s_hiddenLeftItemField?.GetValue(humanoid);
						ItemData item4 = (ItemData)((obj4 is ItemData) ? obj4 : null);
						object? obj5 = AccessTools.Field(typeof(Humanoid), "m_chestItem")?.GetValue(humanoid);
						ItemData item5 = (ItemData)((obj5 is ItemData) ? obj5 : null);
						object? obj6 = AccessTools.Field(typeof(Humanoid), "m_legItem")?.GetValue(humanoid);
						ItemData item6 = (ItemData)((obj6 is ItemData) ? obj6 : null);
						object? obj7 = AccessTools.Field(typeof(Humanoid), "m_helmetItem")?.GetValue(humanoid);
						ItemData item7 = (ItemData)((obj7 is ItemData) ? obj7 : null);
						object? obj8 = AccessTools.Field(typeof(Humanoid), "m_shoulderItem")?.GetValue(humanoid);
						ItemData item8 = (ItemData)((obj8 is ItemData) ? obj8 : null);
						object? obj9 = AccessTools.Field(typeof(Humanoid), "m_utilityItem")?.GetValue(humanoid);
						ItemData item9 = (ItemData)((obj9 is ItemData) ? obj9 : null);
						SetZDOItemHash(zDO, "RightItem", item);
						SetZDOItemHash(zDO, "LeftItem", item2);
						SetZDOItemHash(zDO, "RightBackItem", item3);
						SetZDOItemHash(zDO, "LeftBackItem", item4);
						SetZDOItemHash(zDO, "ChestItem", item5);
						SetZDOItemHash(zDO, "LegItem", item6);
						SetZDOItemHash(zDO, "HelmetItem", item7);
						SetZDOItemHash(zDO, "ShoulderItem", item8);
						SetZDOItemHash(zDO, "UtilityItem", item9);
					}
				}
			}
			catch
			{
			}
		}

		private void SetZDOItemHash(ZDO zdo, string key, ItemData item)
		{
			string text = "";
			if ((Object)(object)item?.m_dropPrefab != (Object)null)
			{
				text = ((Object)item.m_dropPrefab).name;
			}
			int num = ((!string.IsNullOrEmpty(text)) ? StringExtensionMethods.GetStableH