Decompiled source of SwornProtectors v1.1.0

plugins\SwornProtectors.dll

Decompiled a month 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 float menuCloseCooldown;

		private bool placementMode;

		private int placementCount;

		private bool placementFemale;

		private bool enteringPlacement;

		private const float WIN_WIDTH = 340f;

		private const float WIN_HEIGHT_NORMAL = 920f;

		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; }

		public bool IsPlacementMode => placementMode;

		public bool MenuCloseCooldownActive => menuCloseCooldown > 0f;

		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 = 920f;
			windowRect = new Rect(((float)Screen.width - 340f) / 2f, ((float)Screen.height - currentWinHeight) / 2f, 340f, currentWinHeight);
		}

		private void Update()
		{
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			if (menuCloseCooldown > 0f)
			{
				menuCloseCooldown -= Time.deltaTime;
			}
			if (!defaultsApplied && EquipmentData.IsReady)
			{
				defaultsApplied = true;
				ApplyDefaultLoadout();
			}
			if (IsTyping())
			{
				return;
			}
			if (placementMode)
			{
				UpdatePlacementMode();
				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)
			{
				glowPulse = Mathf.PingPong(Time.time * 0.6f, 1f);
			}
		}

		private void LateUpdate()
		{
			if (IsMenuOpen || placementMode)
			{
				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)
			{
				return;
			}
			IsMenuOpen = open;
			if (open)
			{
				browsingSlot = -1;
				wasCursorVisible = Cursor.visible;
				wasCursorLock = Cursor.lockState;
				Cursor.visible = true;
				Cursor.lockState = (CursorLockMode)0;
				currentWinHeight = 920f;
				windowRect = new Rect(((float)Screen.width - 340f) / 2f, ((float)Screen.height - currentWinHeight) / 2f, 340f, currentWinHeight);
				return;
			}
			Cursor.visible = wasCursorVisible;
			Cursor.lockState = wasCursorLock;
			menuCloseCooldown = 0.3f;
			if (!enteringPlacement)
			{
				ProtectorManager instance = ProtectorManager.Instance;
				if ((Object)(object)instance != (Object)null)
				{
					instance.StopPreview();
				}
			}
			enteringPlacement = false;
		}

		private void OnGUI()
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Invalid comparison between Unknown and I4
			//IL_00a7: 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)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Expected O, but got Unknown
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			if (placementMode)
			{
				DrawPlacementHUD();
			}
			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 : 920f);
				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_09b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_09f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a38: 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("Custom Placement", buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(32f) }) && (Object)(object)instance != (Object)null)
			{
				placementCount = spawnCount;
				placementFemale = isFemale;
				placementMode = true;
				enteringPlacement = true;
				SetMenuOpen(open: false);
			}
			GUILayout.Space(4f);
			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.StopPreview();
				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>());
			bool flag2 = (Object)(object)instance != (Object)null && instance.ActiveProtectors.Exists((ProtectorAI p) => (Object)(object)p != (Object)null && p.CurrentState == ProtectorAI.AIState.Following);
			if (GUILayout.Button("Follow", flag2 ? activeButtonStyle : buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(32f) }))
			{
				SwornProtectorsPlugin.Log("GUI: Follow clicked");
				instance?.CommandFollow();
				ShowMsg("Following!");
				SetMenuOpen(open: false);
			}
			bool flag3 = (Object)(object)instance != (Object)null && instance.ActiveProtectors.Exists((ProtectorAI p) => (Object)(object)p != (Object)null && p.CurrentState == ProtectorAI.AIState.Holding);
			if (GUILayout.Button("Stay", flag3 ? activeButtonStyle : buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(32f) }))
			{
				SwornProtectorsPlugin.Log("GUI: Stay clicked");
				instance?.CommandHoldPosition();
				ShowMsg("Holding position!");
				SetMenuOpen(open: false);
			}
			GUILayout.EndHorizontal();
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			bool value2 = SwornProtectorsPlugin.AutoDefendEnabled.Value;
			bool value3 = SwornProtectorsPlugin.AggressiveEnabled.Value;
			if (GUILayout.Button(value2 ? "Defend: ON" : "Defend: OFF", value2 ? activeButtonStyle : buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(32f) }))
			{
				bool flag4 = !value2;
				SwornProtectorsPlugin.AutoDefendEnabled.Value = flag4;
				if (!flag4)
				{
					SwornProtectorsPlugin.AggressiveEnabled.Value = false;
				}
			}
			if (GUILayout.Button(value3 ? "SLAUGHTER: ON" : "Slaughter: OFF", value3 ? activeButtonStyle : buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(32f) }))
			{
				bool flag5 = !value3;
				SwornProtectorsPlugin.AggressiveEnabled.Value = flag5;
				if (flag5)
				{
					SwornProtectorsPlugin.AutoDefendEnabled.Value = true;
					instance?.CommandAggressive();
					ShowMsg("SLAUGHTER THEM ALL!");
				}
				else
				{
					instance?.CommandFollow();
					ShowMsg("Standing down.");
				}
			}
			GUILayout.EndHorizontal();
			GUILayout.Space(4f);
			bool value4 = SwornProtectorsPlugin.InvincibleEnabled.Value;
			if (GUILayout.Button(value4 ? "Invincible:  ON" : "Invincible:  OFF", value4 ? activeButtonStyle : buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(28f) }))
			{
				SwornProtectorsPlugin.InvincibleEnabled.Value = !value4;
			}
			GUILayout.Space(4f);
			if ((Object)(object)instance != (Object)null && instance.AnyBoarded)
			{
				if (GUILayout.Button("Disembark & Regroup", activeButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(28f) }))
				{
					instance.CommandDisembark();
					ShowMsg("Protectors regrouping in formation!");
				}
			}
			else if (GUILayout.Button("Board Ship", buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(28f) }))
			{
				Player localPlayer = Player.m_localPlayer;
				Ship val4 = ((localPlayer != null) ? ((Character)localPlayer).GetStandingOnShip() : null);
				if ((Object)(object)val4 != (Object)null)
				{
					instance?.CommandBoardShip(val4);
					ShowMsg("Protectors boarding ship!");
					SetMenuOpen(open: false);
				}
				else
				{
					ShowMsg("Stand on a ship first!");
				}
			}
			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 void UpdatePlacementMode()
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//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_006e: Unknown result type (might be due to invalid IL or missing references)
			ProtectorManager instance = ProtectorManager.Instance;
			if ((Object)(object)instance == (Object)null)
			{
				ExitPlacementMode();
				return;
			}
			Cursor.visible = true;
			Cursor.lockState = (CursorLockMode)0;
			Vector3 mouseWorldPoint = GetMouseWorldPoint();
			instance.UpdatePreviewAtPosition(mouseWorldPoint, placementCount);
			if (menuCloseCooldown > 0f)
			{
				return;
			}
			if (Input.GetMouseButtonDown(1) || Input.GetKeyDown((KeyCode)27))
			{
				ExitPlacementMode();
			}
			else
			{
				if (!Input.GetMouseButtonDown(0))
				{
					return;
				}
				if (placementCount == 1)
				{
					instance.SpawnProtectorAt(mouseWorldPoint, placementFemale);
					int value = SwornProtectorsPlugin.MaxProtectors.Value;
					if (instance.ActiveProtectors.Count >= value)
					{
						ExitPlacementMode();
					}
				}
				else
				{
					instance.SpawnFormationAt(mouseWorldPoint, placementCount, placementFemale);
					ExitPlacementMode();
				}
			}
		}

		private void ExitPlacementMode()
		{
			placementMode = false;
			ProtectorManager instance = ProtectorManager.Instance;
			if ((Object)(object)instance != (Object)null)
			{
				instance.StopPreview();
			}
			Cursor.visible = false;
			Cursor.lockState = (CursorLockMode)1;
		}

		private Vector3 GetMouseWorldPoint()
		{
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: 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_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: 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(Input.mousePosition);
			int num = LayerMask.GetMask(new string[6] { "Default", "Default_small", "static_solid", "piece", "piece_nonsolid", "terrain" });
			if (num == 0)
			{
				num = ~(1 << LayerMask.NameToLayer("character"));
			}
			RaycastHit val2 = default(RaycastHit);
			if (Physics.Raycast(val, ref val2, 200f, num))
			{
				return ((RaycastHit)(ref val2)).point;
			}
			return ((Ray)(ref val)).GetPoint(30f);
		}

		private void DrawPlacementHUD()
		{
			//IL_00a1: 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_00ab: 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_00cb: 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_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Expected O, but got Unknown
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			if (placementMode)
			{
				int num = ProtectorManager.Instance?.ActiveProtectors.Count ?? 0;
				int value = SwornProtectorsPlugin.MaxProtectors.Value;
				string text = ((placementCount != 1) ? $"Left-click to place {placementCount}  ({num}/{value})   |   Right-click to cancel" : $"Left-click to place  ({num}/{value})   |   Right-click to cancel");
				float num2 = 500f;
				float num3 = 36f;
				float num4 = ((float)Screen.width - num2) / 2f;
				float num5 = (float)Screen.height - 80f;
				Rect val = new Rect(num4, num5, num2, num3);
				Color color = GUI.color;
				GUI.color = new Color(0f, 0f, 0f, 0.65f);
				GUI.DrawTexture(val, (Texture)(object)Texture2D.whiteTexture);
				GUI.color = color;
				GUIStyle val2 = new GUIStyle(GUI.skin.label);
				val2.alignment = (TextAnchor)4;
				val2.fontSize = 16;
				val2.fontStyle = (FontStyle)1;
				val2.normal.textColor = new Color(1f, 0.85f, 0.3f, 1f);
				GUI.Label(val, text, val2);
			}
		}

		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)
				{
					return true;
				}
				if (CommandMenu.Instance.IsMenuOpen || CommandMenu.Instance.MenuCloseCooldownActive || CommandMenu.Instance.IsPlacementMode)
				{
					__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)
				{
					if (CommandMenu.Instance.IsMenuOpen)
					{
						return false;
					}
					if (CommandMenu.Instance.MenuCloseCooldownActive)
					{
						return false;
					}
					if (CommandMenu.Instance.IsPlacementMode)
					{
						return false;
					}
				}
				return true;
			}
		}

		[HarmonyPatch(typeof(GameCamera), "UpdateCamera")]
		public static class GameCameraUpdate_Patch
		{
			private static bool Prefix()
			{
				if ((Object)(object)CommandMenu.Instance == (Object)null)
				{
					return true;
				}
				if (CommandMenu.Instance.IsMenuOpen || CommandMenu.Instance.IsPlacementMode)
				{
					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)
				{
					if (SwornProtectorsPlugin.InvincibleEnabled.Value)
					{
						return false;
					}
					if (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", "1.1.0")]
	public class SwornProtectorsPlugin : BaseUnityPlugin
	{
		public const string PluginGUID = "com.mitch.swornprotectors";

		public const string PluginName = "Sworn Protectors";

		public const string PluginVersion = "1.1.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<bool> InvincibleEnabled;

		public static ConfigEntry<bool> AggressiveEnabled;

		public static ConfigEntry<float> ProtectorScale;

		public static ConfigEntry<float> ProtectorHealth;

		private Harmony harmony;

		public static SwornProtectorsPlugin Instance { get; private set; }

		private void Awake()
		{
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Expected O, but got Unknown
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Expected O, but got Unknown
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01df: 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.");
			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.");
			InvincibleEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Combat", "InvincibleEnabled", false, "If enabled, protectors cannot take damage. Toggle via the command panel.");
			AggressiveEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Combat", "AggressiveEnabled", false, "If enabled, protectors actively hunt and kill all nearby enemies in a wide radius.");
			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 v1.1.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,
			Boarded
		}

		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 Ship boardedShip;

		private Vector3 boardedLocalPos;

		private Transform originalParent;

		private bool wasKinematic;

		private List<Collider> disabledColliders = new List<Collider>();

		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 const float AGGRESSIVE_RANGE = 60f;

		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 bool HoldOnActivate { get; set; }

		public bool IsBoarded => CurrentState == AIState.Boarded;

		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) || activeProtector.CurrentState == AIState.Boarded)
				{
					continue;
				}
				activeProtector.settledAtFormation = false;
				if (formation == FormationType.Parade)
				{
					if (activeProtector.CurrentState != 0)
					{
						activeProtector.CurrentState = AIState.Following;
						activeProtector.attackTarget = null;
						activeProtector.isRunning = true;
					}
					activeProtector.paradeHolding = false;
				}
				else if (activeProtector.CurrentState != 0)
				{
					activeProtector.CurrentState = AIState.Following;
					activeProtector.attackTarget = null;
					activeProtector.isRunning = true;
					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)
		{
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: 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_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (CurrentState == AIState.Boarded)
				{
					UpdateMinimapPin();
					if ((Object)(object)boardedShip == (Object)null)
					{
						Vector3 position = ((Component)this).transform.position;
						((Component)this).transform.SetParent(originalParent);
						((Component)this).transform.position = position;
						ZSyncTransform component = ((Component)this).GetComponent<ZSyncTransform>();
						if ((Object)(object)component != (Object)null)
						{
							((Behaviour)component).enabled = true;
						}
						FootStep component2 = ((Component)this).GetComponent<FootStep>();
						if ((Object)(object)component2 != (Object)null)
						{
							((Behaviour)component2).enabled = true;
						}
						if ((Object)(object)body != (Object)null)
						{
							body.isKinematic = wasKinematic;
							body.constraints = (RigidbodyConstraints)112;
						}
						foreach (Collider disabledCollider in disabledColliders)
						{
							if ((Object)(object)disabledCollider != (Object)null)
							{
								disabledCollider.enabled = true;
							}
						}
						disabledColliders.Clear();
						originalParent = null;
						CurrentState = AIState.Following;
						isRunning = true;
						settledAtFormation = false;
						SwornProtectorsPlugin.LogWarn($"Protector #{FormationIndex}: Ship destroyed, auto-disembarked!");
					}
					else
					{
						((Component)this).transform.localPosition = boardedLocalPos;
						if ((Object)(object)body != (Object)null)
						{
							body.velocity = Vector3.zero;
							body.angularVelocity = Vector3.zero;
						}
						if ((Object)(object)humanoid != (Object)null)
						{
							humanoid.HideHandItems(false, true);
						}
					}
					return true;
				}
				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 || SwornProtectorsPlugin.AggressiveEnabled.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_025c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0284: Unknown result type (might be due to invalid IL or missing references)
			//IL_0289: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_034f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0356: 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_0370: Unknown result type (might be due to invalid IL or missing references)
			//IL_0375: Unknown result type (might be due to invalid IL or missing references)
			//IL_0378: Unknown result type (might be due to invalid IL or missing references)
			//IL_037a: Unknown result type (might be due to invalid IL or missing references)
			//IL_037f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0387: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03be: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d3: 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_0473: Unknown result type (might be due to invalid IL or missing references)
			//IL_048f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0494: Unknown result type (might be due to invalid IL or missing references)
			//IL_049b: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_043c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0441: Unknown result type (might be due to invalid IL or missing references)
			//IL_044b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0450: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0301: Unknown result type (might be due to invalid IL or missing references)
			//IL_0304: 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;
			bool flag = ((Character)ownerPlayer).IsRunning();
			if (flag || num3 > value)
			{
				isRunning = true;
			}
			else if (num3 < num4 && !flag)
			{
				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 if (CurrentFormation == FormationType.ShieldWall)
				{
					Vector3 forward = ((Component)ownerPlayer).transform.forward;
					forward.y = 0f;
					((Vector3)(ref forward)).Normalize();
					((BaseAI)this).LookAt(((Component)this).transform.position + forward * 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_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: 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_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)attackTarget == (Object)null || attackTarget.IsDead())
			{
				attackTarget = null;
				if (SwornProtectorsPlugin.AggressiveEnabled.Value)
				{
					Character val = FindNearestEnemy(((Component)this).transform.position, 60f);
					if ((Object)(object)val != (Object)null)
					{
						attackTarget = val;
						return;
					}
				}
				SetStateFollow();
			}
			else if (Vector3.Distance(((Component)this).transform.position, ((Component)attackTarget).transform.position) > 2.5f)
			{
				if ((Object)(object)base.m_character != (Object)null)
				{
					base.m_character.SetWalk(false);
					base.m_character.SetRun(true);
				}
				((BaseAI)this).MoveTo(dt, ((Component)attackTarget).transform.position, 2f, true);
				if (!((BaseAI)this).FoundPath())
				{
					Vector3 val2 = ((Component)attackTarget).transform.position - ((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();
				((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");
				}
				if (HoldOnActivate)
				{
					CurrentState = AIState.Holding;
					isRunning = false;
					settledAtFormation = true;
					HoldOnActivate = false;
				}
				else
				{
					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! State={CurrentState}.");
			}
		}

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

		private void CheckAutoDefend()
		{
			//IL_006f: 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))
			{
				bool value = SwornProtectorsPlugin.AggressiveEnabled.Value;
				attackScanTimer = (value ? 0.5f : 1f);
				float range = (value ? 60f : 12f);
				Character val = FindNearestEnemy(((Component)this).transform.position, range);
				if ((Object)(object)val != (Object)null)
				{
					attackTarget = val;
					DrawWeap