Decompiled source of Huskarl v1.11.1

plugins/Huskarl/Huskarl.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using ModCommon;
using Splatform;
using TMPro;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.UI;
using Valheim.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: InternalsVisibleTo("HuskarlDev")]
[assembly: InternalsVisibleTo("HuskarlDev.Scripts")]
[assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")]
[assembly: AssemblyCompany("Huskarl")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.11.1.0")]
[assembly: AssemblyInformationalVersion("1.11.1")]
[assembly: AssemblyProduct("Huskarl")]
[assembly: AssemblyTitle("Huskarl")]
[assembly: AssemblyMetadata("AI_Assisted_Creation", "Code, documentation and translations written with generative AI assistance")]
[assembly: AssemblyMetadata("AI_Model_Vendor", "Anthropic (Claude, via Claude Code)")]
[assembly: AssemblyVersion("1.11.1.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace ModCommon
{
	internal static class Lang
	{
		private const string Fallback = "English";

		private const string SettingsSource = "Russian";

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

		private static readonly MethodInfo s_addWord = AccessTools.Method(typeof(Localization), "AddWord", (Type[])null, (Type[])null);

		private static string s_current;

		public static string Current => s_current ?? Saved();

		private static string Saved()
		{
			try
			{
				string text = PlatformPrefs.GetString("language", "");
				return string.IsNullOrEmpty(text) ? "English" : text;
			}
			catch
			{
				return "English";
			}
		}

		private static Dictionary<string, string> Table(string language)
		{
			if (s_tables.TryGetValue(language, out var value))
			{
				return value;
			}
			value = new Dictionary<string, string>();
			Read(value, "common." + language + ".txt");
			Read(value, "lang." + language + ".txt");
			return s_tables[language] = value;
		}

		private static void Read(Dictionary<string, string> table, string resource)
		{
			using Stream stream = typeof(Lang).Assembly.GetManifestResourceStream(resource);
			if (stream == null)
			{
				return;
			}
			using StreamReader streamReader = new StreamReader(stream, Encoding.UTF8);
			string text;
			while ((text = streamReader.ReadLine()) != null)
			{
				text = text.Trim();
				if (text.Length != 0 && text[0] != '#')
				{
					int num = text.IndexOf('=');
					if (num > 0)
					{
						table[text.Substring(0, num).Trim()] = text.Substring(num + 1).Trim().Replace("\\n", "\n");
					}
				}
			}
		}

		private static string Find(string language, string key)
		{
			if (!Table(language).TryGetValue(key, out var value))
			{
				return null;
			}
			return value;
		}

		public static string Text(string key)
		{
			return Find(Current, key) ?? Find("English", key) ?? key;
		}

		public static string Setting(string key, string russian)
		{
			string current = Current;
			if (current == "Russian")
			{
				return russian;
			}
			return Find(current, key) ?? Find("English", key) ?? russian;
		}

		internal static void AddTokens(Localization loc, string language)
		{
			s_current = language;
			Dictionary<string, string> dictionary = Table(language);
			foreach (KeyValuePair<string, string> item in Table("English"))
			{
				if (item.Key[0] == '$')
				{
					string value;
					string text = (dictionary.TryGetValue(item.Key, out value) ? value : item.Value);
					s_addWord.Invoke(loc, new object[2]
					{
						item.Key.Substring(1),
						text
					});
				}
			}
		}

		public static void AddTokens()
		{
			Localization instance = Localization.instance;
			if (instance != null)
			{
				AddTokens(instance, instance.GetSelectedLanguage());
			}
		}
	}
	[HarmonyPatch(typeof(Localization), "SetupLanguage")]
	internal static class Lang_SetupLanguage
	{
		private static void Postfix(Localization __instance, string language)
		{
			Lang.AddTokens(__instance, language);
		}
	}
	internal sealed class MenuInfo
	{
		internal string SectionKey;

		internal string KeyPrefix;

		internal string RussianName;

		internal string RussianSection;

		internal string RussianDescription;

		public string Name => Lang.Setting(KeyPrefix + ".name", RussianName);

		public string Section => Lang.Setting("cfg.section." + SectionKey, RussianSection);

		public string Description => ConfigSync.Describe(KeyPrefix, RussianDescription, HostControlled, NeedsRelog, NeedsRestart);

		public string ModName => ConfigSync.ModText("name", "MenuName");

		public string ModDescription => ConfigSync.ModText("description", "MenuDescription");

		public int Order { get; set; }

		public bool HostControlled { get; set; }

		public bool NeedsRelog { get; set; }

		public bool NeedsRestart { get; set; }

		public Func<bool> LockedByHost { get; set; }
	}
	internal static class ConfigSync
	{
		private static BaseUnityPlugin s_plugin;

		private static ManualLogSource s_log;

		private static ConfigFile s_cfg;

		private static string s_version;

		private static string s_rpcRequest;

		private static string s_rpcData;

		private static int s_order;

		private static bool s_sendQueued;

		private static readonly List<ConfigEntryBase> s_hostEntries = new List<ConfigEntryBase>();

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

		private static readonly Dictionary<ConfigEntryBase, string> s_local = new Dictionary<ConfigEntryBase, string>();

		private static readonly HashSet<long> s_peers = new HashSet<long>();

		private static readonly Dictionary<Type, FieldInfo> s_valueFields = new Dictionary<Type, FieldInfo>();

		private static List<KeyValuePair<ConfigEntryBase, object>> s_setAside;

		public static bool HostValuesActive { get; private set; }

		public static event Action<string> Received;

		public static void Init(BaseUnityPlugin plugin, string version)
		{
			s_plugin = plugin;
			s_log = Logger.CreateLogSource(plugin.Info.Metadata.Name + " sync");
			s_cfg = plugin.Config;
			s_version = version;
			string gUID = plugin.Info.Metadata.GUID;
			s_rpcRequest = gUID + ".ConfigRequest";
			s_rpcData = gUID + ".ConfigData";
			s_cfg.SettingChanged += OnSettingChanged;
		}

		public static void Section(string key, string name)
		{
			s_sectionNames[key] = name;
		}

		public static ConfigEntry<T> Bind<T>(string section, string key, T defaultValue, string name, string description, bool host, AcceptableValueBase acceptable = null, bool relog = false, bool restart = false)
		{
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Expected O, but got Unknown
			string value;
			MenuInfo menuInfo = new MenuInfo
			{
				SectionKey = section,
				KeyPrefix = "cfg." + section + "." + key,
				RussianName = name,
				RussianSection = (s_sectionNames.TryGetValue(section, out value) ? value : section),
				RussianDescription = description,
				Order = s_order++,
				HostControlled = host,
				NeedsRelog = relog,
				NeedsRestart = restart,
				LockedByHost = (host ? ((Func<bool>)(() => HostValuesActive)) : ((Func<bool>)(() => false)))
			};
			ConfigEntry<T> val = s_cfg.Bind<T>(section, key, defaultValue, new ConfigDescription(menuInfo.Description, acceptable, new object[1] { menuInfo }));
			if (host)
			{
				s_hostEntries.Add((ConfigEntryBase)(object)val);
			}
			return val;
		}

		internal static string Describe(string keyPrefix, string russian, bool host, bool relog, bool restart)
		{
			string text = Lang.Setting(keyPrefix + ".desc", russian);
			if (host)
			{
				text = text + "\n" + Lang.Text("common.host");
			}
			if (restart)
			{
				text = text + "\n" + Lang.Text("common.restart");
			}
			else if (relog)
			{
				text = text + "\n" + Lang.Text("common.relog");
			}
			return text;
		}

		internal static string ModText(string key, string constant)
		{
			FieldInfo field = ((object)s_plugin).GetType().GetField(constant, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			return Lang.Setting("menu." + key, (field?.GetValue(null) as string) ?? s_plugin.Info.Metadata.Name);
		}

		internal static void RegisterRpcs()
		{
			if (s_cfg != null && ZRoutedRpc.instance != null)
			{
				ZRoutedRpc.instance.Register<string>(s_rpcRequest, (Action<long, string>)RPC_Request);
				ZRoutedRpc.instance.Register<ZPackage>(s_rpcData, (Action<long, ZPackage>)RPC_Data);
			}
		}

		internal static void RequestFromHost()
		{
			if (s_cfg != null && s_hostEntries.Count != 0 && Object.op_Implicit((Object)(object)ZNet.instance) && !ZNet.instance.IsServer())
			{
				ZRoutedRpc.instance.InvokeRoutedRPC(s_rpcRequest, new object[1] { s_version });
			}
		}

		private static void RPC_Request(long sender, string clientVersion)
		{
			if (Object.op_Implicit((Object)(object)ZNet.instance) && ZNet.instance.IsServer())
			{
				if (clientVersion != s_version)
				{
					s_log.LogWarning((object)$"Client {sender} runs version {clientVersion}, this host runs {s_version}");
				}
				s_peers.Add(sender);
				ZRoutedRpc.instance.InvokeRoutedRPC(sender, s_rpcData, new object[1] { Pack() });
			}
		}

		private static ZPackage Pack()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Expected O, but got Unknown
			ZPackage val = new ZPackage();
			val.Write(s_version);
			val.Write(s_hostEntries.Count);
			foreach (ConfigEntryBase s_hostEntry in s_hostEntries)
			{
				val.Write(s_hostEntry.Definition.Section + "/" + s_hostEntry.Definition.Key);
				val.Write(s_hostEntry.GetSerializedValue());
			}
			return val;
		}

		private static void RPC_Data(long sender, ZPackage p)
		{
			if (!Object.op_Implicit((Object)(object)ZNet.instance) || ZNet.instance.IsServer())
			{
				return;
			}
			string text = p.ReadString();
			Dictionary<string, ConfigEntryBase> dictionary = new Dictionary<string, ConfigEntryBase>();
			foreach (ConfigEntryBase s_hostEntry in s_hostEntries)
			{
				dictionary[s_hostEntry.Definition.Section + "/" + s_hostEntry.Definition.Key] = s_hostEntry;
			}
			bool saveOnConfigSet = s_cfg.SaveOnConfigSet;
			s_cfg.SaveOnConfigSet = false;
			HostValuesActive = true;
			try
			{
				int num = p.ReadInt();
				for (int i = 0; i < num; i++)
				{
					string text2 = p.ReadString();
					string text3 = p.ReadString();
					if (!dictionary.TryGetValue(text2, out var value))
					{
						continue;
					}
					if (!s_local.ContainsKey(value))
					{
						s_local[value] = value.GetSerializedValue();
					}
					if (!(value.GetSerializedValue() == text3))
					{
						try
						{
							value.SetSerializedValue(text3);
						}
						catch (Exception ex)
						{
							s_log.LogWarning((object)("Host value '" + text3 + "' for " + text2 + " rejected: " + ex.Message));
						}
					}
				}
			}
			finally
			{
				s_cfg.SaveOnConfigSet = saveOnConfigSet;
			}
			s_log.LogInfo((object)("Using the host's settings (host runs version " + text + ")"));
			try
			{
				ConfigSync.Received?.Invoke(text);
			}
			catch (Exception ex2)
			{
				s_log.LogError((object)ex2);
			}
		}

		internal static void RestoreLocal()
		{
			s_peers.Clear();
			if (!HostValuesActive)
			{
				return;
			}
			HostValuesActive = false;
			bool saveOnConfigSet = s_cfg.SaveOnConfigSet;
			s_cfg.SaveOnConfigSet = false;
			try
			{
				foreach (KeyValuePair<ConfigEntryBase, string> item in s_local)
				{
					if (item.Key.GetSerializedValue() != item.Value)
					{
						item.Key.SetSerializedValue(item.Value);
					}
				}
			}
			finally
			{
				s_cfg.SaveOnConfigSet = saveOnConfigSet;
			}
			s_local.Clear();
		}

		private static void OnSettingChanged(object sender, SettingChangedEventArgs e)
		{
			if (!s_sendQueued && s_peers.Count != 0 && Object.op_Implicit((Object)(object)ZNet.instance) && ZNet.instance.IsServer() && s_hostEntries.Contains(e.ChangedSetting))
			{
				s_sendQueued = true;
				((MonoBehaviour)s_plugin).StartCoroutine(SendSoon());
			}
		}

		private static IEnumerator SendSoon()
		{
			yield return (object)new WaitForSecondsRealtime(0.3f);
			s_sendQueued = false;
			if (!Object.op_Implicit((Object)(object)ZNet.instance) || !ZNet.instance.IsServer() || ZRoutedRpc.instance == null)
			{
				yield break;
			}
			s_peers.RemoveWhere((long uid) => ZNet.instance.GetPeer(uid) == null);
			foreach (long s_peer in s_peers)
			{
				ZRoutedRpc.instance.InvokeRoutedRPC(s_peer, s_rpcData, new object[1] { Pack() });
			}
		}

		private static void SetRaw(ConfigEntryBase e, object value)
		{
			Type type = ((object)e).GetType();
			if (!s_valueFields.TryGetValue(type, out var value2))
			{
				value2 = (s_valueFields[type] = type.GetField("_typedValue", BindingFlags.Instance | BindingFlags.NonPublic));
			}
			value2.SetValue(e, value);
		}

		internal static void SwapToLocal(ConfigFile file)
		{
			if (file != s_cfg || s_local.Count == 0 || s_setAside != null)
			{
				return;
			}
			s_setAside = new List<KeyValuePair<ConfigEntryBase, object>>();
			foreach (KeyValuePair<ConfigEntryBase, string> item in s_local)
			{
				s_setAside.Add(new KeyValuePair<ConfigEntryBase, object>(item.Key, item.Key.BoxedValue));
				SetRaw(item.Key, TomlTypeConverter.ConvertToValue(item.Value, item.Key.SettingType));
			}
		}

		internal static void SwapBack(ConfigFile file)
		{
			if (file != s_cfg || s_setAside == null)
			{
				return;
			}
			foreach (KeyValuePair<ConfigEntryBase, object> item in s_setAside)
			{
				SetRaw(item.Key, item.Value);
			}
			s_setAside = null;
		}
	}
	[HarmonyPatch(typeof(Game), "Start")]
	internal static class ConfigSync_GameStart
	{
		private static void Postfix()
		{
			ConfigSync.RegisterRpcs();
		}
	}
	[HarmonyPatch(typeof(Game), "Shutdown")]
	internal static class ConfigSync_GameShutdown
	{
		private static void Postfix()
		{
			ConfigSync.RestoreLocal();
		}
	}
	[HarmonyPatch(typeof(Player), "OnSpawned")]
	internal static class ConfigSync_PlayerSpawned
	{
		private static void Postfix(Player __instance)
		{
			if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer)
			{
				ConfigSync.RequestFromHost();
			}
		}
	}
	[HarmonyPatch(typeof(ConfigFile), "Save")]
	internal static class ConfigSync_Save
	{
		private static void Prefix(ConfigFile __instance)
		{
			ConfigSync.SwapToLocal(__instance);
		}

		private static Exception Finalizer(ConfigFile __instance, Exception __exception)
		{
			ConfigSync.SwapBack(__instance);
			return __exception;
		}
	}
}
namespace Huskarl
{
	internal static class Ballistics
	{
		public static Vector3 Aim(Vector3 from, Character target, float speed, float gravity)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//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_0053: 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_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			Vector3 velocity = target.GetVelocity();
			velocity.y = 0f;
			Vector3 val = target.GetCenterPoint();
			for (int i = 0; i < 2; i++)
			{
				float num = Vector3.Distance(from, val) / speed;
				val = target.GetCenterPoint() + velocity * num;
			}
			Vector3 val2 = val - from;
			Vector3 val3 = default(Vector3);
			((Vector3)(ref val3))..ctor(val2.x, 0f, val2.z);
			float magnitude = ((Vector3)(ref val3)).magnitude;
			if (gravity <= 0.01f || magnitude < 0.5f)
			{
				return ((Vector3)(ref val2)).normalized;
			}
			float y = val2.y;
			float num2 = speed * speed;
			float num3 = num2 * num2 - gravity * (gravity * magnitude * magnitude + 2f * y * num2);
			float num4 = ((num3 < 0f) ? ((float)Math.PI / 4f) : Mathf.Atan((num2 - Mathf.Sqrt(num3)) / (gravity * magnitude)));
			return val3 / magnitude * Mathf.Cos(num4) + Vector3.up * Mathf.Sin(num4);
		}
	}
	internal static class Cannons
	{
		internal class Gun
		{
			public Ship Ship;

			public Component Interact;

			public Component Root;

			public string Name;

			public Transform Tr;

			public Transform Muzzle;

			public Ships.Seat Post;

			public float NextShot;

			public bool Active
			{
				get
				{
					if (Object.op_Implicit((Object)(object)Tr) && Object.op_Implicit((Object)(object)Muzzle) && Object.op_Implicit((Object)(object)Root))
					{
						return ((Component)Tr).gameObject.activeInHierarchy;
					}
					return false;
				}
			}
		}

		internal struct Load
		{
			public ItemData Item;

			public int Profile;

			public float Speed;

			public float Pitch;

			public float Gravity;
		}

		private static bool s_init;

		private static Type s_interactType;

		private static FieldInfo s_interactRoot;

		private static FieldInfo s_interactName;

		private static MethodInfo s_findMuzzle;

		private static MethodInfo s_direction;

		private static MethodInfo s_limits;

		private static MethodInfo s_requestFire;

		private static MethodInfo s_ensureAmmo;

		private static FieldInfo s_profiles;

		private static FieldInfo s_cooldown;

		private static FieldInfo s_profAmmo;

		private static FieldInfo s_profProjectile;

		private static FieldInfo s_profSpeed;

		private static FieldInfo s_profPitch;

		private static PropertyInfo s_aimActive;

		private static readonly Dictionary<Ship, List<Gun>> s_guns = new Dictionary<Ship, List<Gun>>();

		private static readonly Dictionary<string, float> s_gravity = new Dictionary<string, float>();

		private static readonly string[] AmmoOrder = new string[5] { "CannonballBlackmetal_DO", "CannonballIron_DO", "CannonballGrausten_DO", "CannonballStone_DO", "CannonballBomb_DO" };

		private static readonly List<Gun> Empty = new List<Gun>();

		private static int s_deckMask;

		internal static bool Available
		{
			get
			{
				if (!s_init)
				{
					Init();
				}
				return s_interactType != null;
			}
		}

		private static void Init()
		{
			s_init = true;
			try
			{
				Type type = AccessTools.TypeByName("Artisan_Mastery.CannonFireInteract");
				Type type2 = AccessTools.TypeByName("Artisan_Mastery.CannonFireRoot");
				Type type3 = AccessTools.TypeByName("Artisan_Mastery.AmmoProfile");
				Type type4 = AccessTools.TypeByName("Artisan_Mastery.CannonAimController");
				if (!(type == null) && !(type2 == null) && !(type3 == null))
				{
					s_interactRoot = AccessTools.Field(type, "Root");
					s_interactName = AccessTools.Field(type, "CannonName");
					s_findMuzzle = AccessTools.Method(type2, "FindMuzzle", new Type[1] { typeof(Transform) }, (Type[])null);
					s_direction = AccessTools.Method(type2, "ComputeWorldDirection", new Type[4]
					{
						typeof(Transform),
						typeof(string),
						typeof(float),
						typeof(float)
					}, (Type[])null);
					s_limits = AccessTools.Method(type2, "GetAimLimits", (Type[])null, (Type[])null);
					s_requestFire = AccessTools.Method(type2, "RequestFire", new Type[5]
					{
						typeof(string),
						typeof(int),
						typeof(long),
						typeof(float),
						typeof(float)
					}, (Type[])null);
					s_ensureAmmo = AccessTools.Method(type2, "EnsureDefaultAmmoProfiles", (Type[])null, (Type[])null);
					s_profiles = AccessTools.Field(type2, "AmmoProfiles");
					s_cooldown = AccessTools.Field(type2, "CooldownSeconds");
					s_profAmmo = AccessTools.Field(type3, "AmmoItemPrefabName");
					s_profProjectile = AccessTools.Field(type3, "ProjectilePrefabName");
					s_profSpeed = AccessTools.Field(type3, "Speed");
					s_profPitch = AccessTools.Field(type3, "PitchDegrees");
					s_aimActive = ((type4 != null) ? AccessTools.Property(type4, "ActiveInteract") : null);
					if (s_interactRoot == null || s_interactName == null || s_findMuzzle == null || s_direction == null || s_limits == null || s_requestFire == null || s_profiles == null || s_profAmmo == null || s_profProjectile == null || s_profSpeed == null || s_profPitch == null)
					{
						Plugin.Log.LogWarning((object)"Artisan Mastery cannons found, but not the way Huskarl knows them: huskarls will not man them");
						return;
					}
					s_interactType = type;
					Plugin.Log.LogInfo((object)"Artisan Mastery found: huskarls man ship cannons");
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("Artisan Mastery cannons: " + ex.Message));
				s_interactType = null;
			}
		}

		internal static List<Gun> Of(Ship ship)
		{
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			if (!Available || !Object.op_Implicit((Object)(object)ship))
			{
				return Empty;
			}
			if (s_guns.TryGetValue(ship, out var value))
			{
				return value;
			}
			if (s_guns.Count > 16)
			{
				Prune();
			}
			value = new List<Gun>();
			Rigidbody component = ((Component)ship).GetComponent<Rigidbody>();
			Component[] componentsInChildren = ((Component)ship).GetComponentsInChildren(s_interactType, true);
			foreach (Component val in componentsInChildren)
			{
				try
				{
					Gun gun = new Gun
					{
						Ship = ship,
						Interact = val,
						Root = (Component)/*isinst with value type is only supported in some contexts*/,
						Name = (s_interactName.GetValue(val) as string),
						Tr = val.transform
					};
					if (Object.op_Implicit((Object)(object)gun.Root) && !string.IsNullOrEmpty(gun.Name))
					{
						ref Transform muzzle = ref gun.Muzzle;
						object? obj = s_findMuzzle.Invoke(gun.Root, new object[1] { gun.Tr });
						muzzle = (Transform)((obj is Transform) ? obj : null);
						if (Object.op_Implicit((Object)(object)gun.Muzzle))
						{
							Vector3 val2 = PostFor(gun);
							gun.Post = new Ships.Seat
							{
								Ship = ship,
								Point = Ships.LocalPoint(ship, ((Component)ship).transform.InverseTransformPoint(val2), "huskarl_gunpost"),
								Body = component,
								Stand = true,
								Gun = gun
							};
							value.Add(gun);
						}
					}
				}
				catch (Exception ex)
				{
					Plugin.Log.LogWarning((object)("Cannon skipped: " + ex.Message));
				}
			}
			s_guns[ship] = value;
			if (value.Count > 0)
			{
				Plugin.Log.LogInfo((object)$"{Utils.GetPrefabName(((Component)ship).gameObject)}: {value.Count} cannons for huskarl gunners");
			}
			return value;
		}

		private static void Prune()
		{
			List<Ship> list = new List<Ship>();
			foreach (Ship key in s_guns.Keys)
			{
				if (!Object.op_Implicit((Object)(object)key))
				{
					list.Add(key);
				}
			}
			foreach (Ship item in list)
			{
				s_guns.Remove(item);
			}
		}

		private static Vector3 PostFor(Gun g)
		{
			//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)
			//IL_0076: 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_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: 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_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			if (s_deckMask == 0)
			{
				s_deckMask = LayerMask.GetMask(new string[4] { "Default", "static_solid", "piece", "vehicle" });
			}
			Vector3 val = Direction(g, 0f, 0f);
			val.y = 0f;
			val = ((((Vector3)(ref val)).sqrMagnitude > 0.01f) ? ((Vector3)(ref val)).normalized : ((Component)g.Ship).transform.right);
			float y = g.Tr.position.y;
			float[] array = new float[3] { 1.3f, 1f, 1.6f };
			foreach (float num in array)
			{
				RaycastHit[] array2 = Physics.RaycastAll(g.Tr.position - val * num + Vector3.up * 1.2f, Vector3.down, 3f, s_deckMask, (QueryTriggerInteraction)1);
				for (int j = 0; j < array2.Length; j++)
				{
					RaycastHit val2 = array2[j];
					if (!((Object)(object)((Component)((RaycastHit)(ref val2)).collider).GetComponentInParent<Ship>() != (Object)(object)g.Ship) && !(((RaycastHit)(ref val2)).normal.y < 0.8f) && !(((RaycastHit)(ref val2)).point.y > g.Tr.position.y + 0.6f))
					{
						return ((RaycastHit)(ref val2)).point + Vector3.up * 0.05f;
					}
				}
			}
			Vector3 result = g.Tr.position - val * 1.3f;
			result.y = y;
			return result;
		}

		private static Vector3 Direction(Gun g, float pitch, float yaw)
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			return (Vector3)s_direction.Invoke(g.Root, new object[4] { g.Tr, g.Name, pitch, yaw });
		}

		internal static bool FindLoad(Gun g, Inventory bag, out Load load)
		{
			load = default(Load);
			if (bag == null || !Object.op_Implicit((Object)(object)g.Root))
			{
				return false;
			}
			s_ensureAmmo?.Invoke(g.Root, null);
			if (!(s_profiles.GetValue(g.Root) is IList list))
			{
				return false;
			}
			string[] ammoOrder = AmmoOrder;
			foreach (string text in ammoOrder)
			{
				for (int j = 0; j < list.Count; j++)
				{
					object obj = list[j];
					if (obj != null && !((string)s_profAmmo.GetValue(obj) != text))
					{
						ItemData val = ItemByPrefab(bag, text);
						if (val == null)
						{
							break;
						}
						load = new Load
						{
							Item = val,
							Profile = j,
							Speed = Mathf.Max(0.1f, (float)s_profSpeed.GetValue(obj)),
							Pitch = (float)s_profPitch.GetValue(obj),
							Gravity = GravityOf((string)s_profProjectile.GetValue(obj))
						};
						return true;
					}
				}
			}
			return false;
		}

		internal static bool HasAmmo(Inventory bag)
		{
			if (bag == null)
			{
				return false;
			}
			string[] ammoOrder = AmmoOrder;
			foreach (string prefab in ammoOrder)
			{
				if (ItemByPrefab(bag, prefab) != null)
				{
					return true;
				}
			}
			return false;
		}

		private static ItemData ItemByPrefab(Inventory bag, string prefab)
		{
			foreach (ItemData allItem in bag.GetAllItems())
			{
				if (Object.op_Implicit((Object)(object)allItem.m_dropPrefab) && ((Object)allItem.m_dropPrefab).name == prefab)
				{
					return allItem;
				}
			}
			return null;
		}

		private static float GravityOf(string projectile)
		{
			if (string.IsNullOrEmpty(projectile))
			{
				return 0f;
			}
			if (s_gravity.TryGetValue(projectile, out var value))
			{
				return value;
			}
			GameObject val = (Object.op_Implicit((Object)(object)ZNetScene.instance) ? ZNetScene.instance.GetPrefab(projectile) : null);
			Projectile val2 = (Object.op_Implicit((Object)(object)val) ? val.GetComponentInChildren<Projectile>(true) : null);
			value = (Object.op_Implicit((Object)(object)val2) ? val2.m_gravity : 0f);
			s_gravity[projectile] = value;
			return value;
		}

		internal static bool Aim(Gun g, Character target, Load load, out float yaw, out float pitch)
		{
			//IL_0027: 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_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: 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_00ae: 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)
			yaw = (pitch = 0f);
			if (!g.Active || !Object.op_Implicit((Object)(object)target))
			{
				return false;
			}
			Vector3 val = Ballistics.Aim(g.Muzzle.position, target, load.Speed, load.Gravity);
			Vector3 val2 = Direction(g, 0f, 0f);
			Vector3 val3 = default(Vector3);
			((Vector3)(ref val3))..ctor(val.x, 0f, val.z);
			Vector3 val4 = default(Vector3);
			((Vector3)(ref val4))..ctor(val2.x, 0f, val2.z);
			if (((Vector3)(ref val3)).sqrMagnitude < 0.0001f || ((Vector3)(ref val4)).sqrMagnitude < 0.0001f)
			{
				return false;
			}
			yaw = Vector3.SignedAngle(val4, val3, Vector3.up);
			float num = Mathf.Asin(Mathf.Clamp(((Vector3)(ref val)).normalized.y, -1f, 1f)) * 57.29578f;
			float num2 = Mathf.Asin(Mathf.Clamp(((Vector3)(ref val2)).normalized.y, -1f, 1f)) * 57.29578f;
			pitch = num - num2 - load.Pitch;
			object[] array = new object[5] { g.Name, 0f, 0f, 0f, 0f };
			s_limits.Invoke(g.Root, array);
			float num3 = (float)array[1];
			float num4 = (float)array[2];
			float num5 = (float)array[3];
			float num6 = (float)array[4];
			if (yaw >= num3 && yaw <= num4 && pitch >= num5)
			{
				return pitch <= num6;
			}
			return false;
		}

		internal static bool Fire(Gun g, Load load, float yaw, float pitch)
		{
			if (!g.Active || Time.time < g.NextShot)
			{
				return false;
			}
			float num = ((s_cooldown != null) ? ((float)s_cooldown.GetValue(g.Root)) : 3f);
			g.NextShot = Time.time + Mathf.Max(0.5f, num) + 0.1f;
			s_requestFire.Invoke(g.Root, new object[5] { g.Name, load.Profile, 0L, yaw, pitch });
			return true;
		}

		internal static float Cooldown(Gun g)
		{
			if (!(s_cooldown != null) || !Object.op_Implicit((Object)(object)g.Root))
			{
				return 3f;
			}
			return (float)s_cooldown.GetValue(g.Root);
		}

		internal static bool PlayerAt(Gun g)
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			//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)
			if (s_aimActive != null && (Object)s_aimActive.GetValue(null) == (Object)(object)g.Interact)
			{
				return true;
			}
			Vector3 position = g.Tr.position;
			foreach (Player allPlayer in Player.GetAllPlayers())
			{
				if (Object.op_Implicit((Object)(object)allPlayer) && Vector3.Distance(((Component)allPlayer).transform.position, position) < 1.5f)
				{
					return true;
				}
			}
			return false;
		}
	}
	internal static class Cfg
	{
		private static ConfigEntry<int> s_maxHelpers;

		private static ConfigEntry<bool> s_allowImmortality;

		private static ConfigEntry<bool> s_ownerOnly;

		private static ConfigEntry<string> s_reviveCost;

		private static ConfigEntry<string> s_hornRecipe;

		private static ConfigEntry<string> s_hornStation;

		private static ConfigEntry<float> s_maxHealth;

		private static ConfigEntry<float> s_regenSeconds;

		private static ConfigEntry<float> s_damageMultiplier;

		private static ConfigEntry<float> s_armorMultiplier;

		private static ConfigEntry<int> s_bagWidth;

		private static ConfigEntry<int> s_bagHeight;

		private static ConfigEntry<float> s_workRadius;

		private static ConfigEntry<float> s_teleportDistance;

		private static ConfigEntry<KeyCode> s_wheelModifier;

		private static ConfigEntry<KeyCode> s_wheelKey;

		private static ConfigEntry<bool> s_gameStyleWheel;

		private static ConfigEntry<float> s_squadRadius;

		private static ConfigEntry<string> s_gatherPrefabs;

		private static ConfigEntry<string> s_huntPrefabs;

		private static ConfigEntry<string> s_oreKeywords;

		private static ConfigEntry<bool> s_useRanged;

		private static ConfigEntry<float> s_rangedSkill;

		private static ConfigEntry<float> s_meleeDistance;

		private static ConfigEntry<bool> s_mapHelpers;

		private static ConfigEntry<bool> s_mapGraves;

		private static ConfigEntry<bool> s_mapOthers;

		private static ConfigEntry<float> s_clearRadius;

		private static ConfigEntry<float> s_lootRadius;

		private static ConfigEntry<string> s_lootIgnore;

		private static ConfigEntry<bool> s_lootContainers;

		private static ConfigEntry<bool> s_openDoors;

		private static ConfigEntry<bool> s_chatter;

		private static ConfigEntry<bool> s_lively;

		private static ConfigEntry<bool> s_passThrough;

		private static ConfigEntry<bool> s_boardShips;

		private static ConfigEntry<float> s_boardDistance;

		private static ConfigEntry<float> s_shipCatchUp;

		private static ConfigEntry<bool> s_useCannons;

		private static ConfigEntry<float> s_cannonRange;

		private static ConfigEntry<FormationShape> s_formationShape;

		private static ConfigEntry<float> s_formationSpacing;

		public static int MaxHelpers => s_maxHelpers.Value;

		public static bool AllowImmortality => s_allowImmortality.Value;

		public static bool OwnerOnly => s_ownerOnly.Value;

		public static string ReviveCost => s_reviveCost.Value;

		public static string HornRecipe => s_hornRecipe.Value;

		public static string HornStation => s_hornStation.Value;

		public static float MaxHealth => s_maxHealth.Value;

		public static float RegenSeconds => Math.Max(10f, s_regenSeconds.Value);

		public static float DamageMultiplier => s_damageMultiplier.Value;

		public static float ArmorMultiplier => s_armorMultiplier.Value;

		public static int BagWidth => Math.Max(1, Math.Min(8, s_bagWidth.Value));

		public static int BagHeight => Math.Max(1, Math.Min(16, s_bagHeight.Value));

		public static float WorkRadius => s_workRadius.Value;

		public static float TeleportDistance => s_teleportDistance.Value;

		public static KeyCode WheelModifier => s_wheelModifier.Value;

		public static KeyCode WheelKey => s_wheelKey.Value;

		public static bool GameStyleWheel => s_gameStyleWheel.Value;

		public static float SquadRadius => s_squadRadius.Value;

		public static string GatherPrefabs => s_gatherPrefabs.Value;

		public static string HuntPrefabs => s_huntPrefabs.Value;

		public static string OreKeywords => s_oreKeywords.Value;

		public static bool UseRanged => s_useRanged.Value;

		public static float RangedSkill => s_rangedSkill.Value;

		public static float MeleeDistance => s_meleeDistance.Value;

		public static bool MapShowHelpers => s_mapHelpers.Value;

		public static bool MapShowGraves => s_mapGraves.Value;

		public static bool MapShowOthers => s_mapOthers.Value;

		public static float ClearRadius => s_clearRadius.Value;

		public static float LootRadius => s_lootRadius.Value;

		public static string LootIgnore => s_lootIgnore.Value;

		public static bool LootContainers => s_lootContainers.Value;

		public static bool OpenDoors => s_openDoors.Value;

		public static bool Lively => s_lively.Value;

		public static bool Chatter => s_chatter.Value;

		public static bool PassThrough => s_passThrough.Value;

		public static bool BoardShips => s_boardShips.Value;

		public static float BoardDistance => s_boardDistance.Value;

		public static float ShipCatchUp => s_shipCatchUp.Value;

		public static bool UseCannons => s_useCannons.Value;

		public static float CannonRange => s_cannonRange.Value;

		public static FormationShape FormationShape => s_formationShape.Value;

		public static float FormationSpacing => Math.Max(1.5f, Math.Min(8f, s_formationSpacing.Value));

		public static event Action Changed;

		private static AcceptableValueRange<float> Range(float min, float max)
		{
			return new AcceptableValueRange<float>(min, max);
		}

		private static AcceptableValueRange<int> Range(int min, int max)
		{
			return new AcceptableValueRange<int>(min, max);
		}

		public static void Bind(ConfigFile f)
		{
			ConfigSync.Section("Helpers", "Помощники");
			ConfigSync.Section("Combat", "Бой");
			ConfigSync.Section("Work", "Работа");
			ConfigSync.Section("Death", "Смерть");
			ConfigSync.Section("Horn", "Рог");
			ConfigSync.Section("Controls", "Управление");
			ConfigSync.Section("Map", "Карта");
			ConfigSync.Section("Dungeon", "Подземелья");
			ConfigSync.Section("Life", "Живость");
			ConfigSync.Section("Ships", "Корабли");
			ConfigSync.Section("Formation", "Строй");
			s_maxHelpers = ConfigSync.Bind("Helpers", "MaxHelpersPerPlayer", 5, "Помощников на игрока", "Сколько помощников (живых или в могиле) может быть у одного игрока. Рог на пределе не призывает нового, а зовёт ваших помощников к вам.", host: true, (AcceptableValueBase)(object)Range(0, 20));
			s_ownerOnly = ConfigSync.Bind("Helpers", "OwnerOnlyCommands", defaultValue: false, "Приказы только от хозяина", "Если включено, отдавать приказы и открывать рюкзак помощника может только тот, кто его призвал. Иначе — любой игрок.", host: true);
			s_maxHealth = ConfigSync.Bind("Helpers", "MaxHealth", 300f, "Здоровье", "Здоровье помощника.", host: true, (AcceptableValueBase)(object)Range(50f, 3000f));
			s_regenSeconds = ConfigSync.Bind("Helpers", "RegenSeconds", 300f, "Восстановление здоровья, с", "За сколько секунд здоровье восстанавливается с нуля до полного.", host: true, (AcceptableValueBase)(object)Range(10f, 3600f));
			s_damageMultiplier = ConfigSync.Bind("Helpers", "DamageMultiplier", 1f, "Множитель урона", "Множитель урона, который помощник наносит оружием и инструментами.", host: true, (AcceptableValueBase)(object)Range(0.1f, 5f));
			s_armorMultiplier = ConfigSync.Bind("Helpers", "ArmorMultiplier", 1f, "Множитель брони", "Множитель брони, которую помощник получает от надетой экипировки.", host: true, (AcceptableValueBase)(object)Range(0.1f, 5f));
			s_bagWidth = ConfigSync.Bind("Helpers", "BagWidth", 8, "Ширина рюкзака", "Столбцов в рюкзаке помощника. У всех игроков и на сервере должно быть одинаковое значение.", host: false, (AcceptableValueBase)(object)Range(1, 8), relog: false, restart: true);
			s_bagHeight = ConfigSync.Bind("Helpers", "BagHeight", 6, "Высота рюкзака", "Рядов в рюкзаке помощника. У всех игроков и на сервере должно быть одинаковое значение.", host: false, (AcceptableValueBase)(object)Range(1, 16), relog: false, restart: true);
			s_useRanged = ConfigSync.Bind("Combat", "UseRanged", defaultValue: true, "Стрелять из лука и ружья", "Помощники стреляют из луков, арбалетов и ружей из рюкзака, если у них есть боеприпасы.", host: true);
			s_rangedSkill = ConfigSync.Bind("Combat", "RangedSkill", 50f, "Навык стрельбы", "Навык луков и арбалетов у помощника, 0–100: точность, скорость натяжения и перезарядки.", host: true, (AcceptableValueBase)(object)Range(0f, 100f));
			s_meleeDistance = ConfigSync.Bind("Combat", "MeleeDistance", 4f, "Ближний бой с, м", "Стрелок, у которого есть и оружие ближнего боя, переключается на него, когда враг подходит ближе этого расстояния. Ружья с дробью вблизи используются всё равно.", host: true, (AcceptableValueBase)(object)Range(0f, 15f));
			s_workRadius = ConfigSync.Bind("Work", "WorkRadius", 30f, "Радиус работы, м", "Как далеко от места приказа помощник ищет деревья, руду, ягоды и дичь.", host: true, (AcceptableValueBase)(object)Range(5f, 100f));
			s_teleportDistance = ConfigSync.Bind("Work", "FollowTeleportDistance", 50f, "Подтягивать отставших с, м", "Помощник, который отстал от ведущего на это расстояние, переносится к нему.", host: true, (AcceptableValueBase)(object)Range(10f, 200f));
			s_gatherPrefabs = ConfigSync.Bind("Work", "GatherPrefabs", "RaspberryBush,BlueberryBush,CloudberryBush,LingonberryBush,VineAsh,Pickable_Mushroom,Pickable_Mushroom_yellow,Pickable_Mushroom_blue,Pickable_Mushroom_JotunPuffs,Pickable_Mushroom_Magecap,Pickable_SmokePuff,Pickable_Fiddlehead", "Что собирать", "Префабы, которые помощники собирают по приказу «Собирать», через запятую.", host: true);
			s_huntPrefabs = ConfigSync.Bind("Work", "HuntPrefabs", "Deer,Hare,Boar,Neck,Lox,Moose,Seal", "На кого охотиться", "Существа, на которых помощники охотятся по приказу «Охота». В других режимах их не трогают, если те не нападают.", host: true);
			s_oreKeywords = ConfigSync.Bind("Work", "OreKeywords", "Ore,Scrap", "Что считать рудой", "Камень считается рудой, если в названии его добычи есть одно из этих слов.", host: true);
			s_allowImmortality = ConfigSync.Bind("Death", "AllowImmortality", defaultValue: true, "Разрешить бессмертие", "Игроки могут сделать помощника бессмертным в меню приказов.", host: true);
			s_reviveCost = ConfigSync.Bind("Death", "ReviveCost", "SurtlingCore:3", "Цена воскрешения", "Предметы для воскрешения помощника у могилы, например «SurtlingCore:3,Coins:50». Пусто — бесплатно.", host: true);
			s_hornRecipe = ConfigSync.Bind("Horn", "Recipe", "TrophyDeer:1,LeatherScraps:6,Wood:10", "Рецепт рога", "Предметы для крафта рога помощника.", host: true);
			s_hornStation = ConfigSync.Bind("Horn", "CraftingStation", "piece_workbench", "Станция для рога", "Префаб станции, на которой крафтится рог. Пусто — крафт с рук.", host: true);
			s_wheelModifier = ConfigSync.Bind<KeyCode>("Controls", "WheelModifier", (KeyCode)304, "Клавиша колеса приказов", "Удерживайте эту клавишу и крутите колесо мыши, чтобы открыть колесо приказов отряду. Пока она зажата, колесо мыши не меняет приближение камеры. None — выключено.", host: false);
			s_wheelKey = ConfigSync.Bind<KeyCode>("Controls", "WheelKey", (KeyCode)0, "Отдельная клавиша колеса", "Необязательная клавиша, которая открывает колесо приказов сама по себе.", host: false);
			s_gameStyleWheel = ConfigSync.Bind("Controls", "GameStyleWheel", defaultValue: true, "Колесо в стиле игры", "Колесо приказов рисуется радиальным меню самой игры, как эмоции: иконки, анимация, выбор мышью или стиком, ПКМ — назад. Выключите, чтобы вернуть простое колесо мода (например, если другой мод меняет радиальное меню игры).", host: false);
			s_squadRadius = ConfigSync.Bind("Controls", "SquadRadius", 40f, "Радиус отряда, м", "Приказы с колеса получают ваши помощники в этом радиусе.", host: false, (AcceptableValueBase)(object)Range(5f, 150f));
			s_mapHelpers = ConfigSync.Bind("Map", "ShowHelpers", defaultValue: true, "Хускарлы на карте", "Ваши хускарлы отмечены на миникарте и большой карте значком рога с именем, метка движется вместе с ними — даже если хускарл остался далеко.", host: false);
			s_mapGraves = ConfigSync.Bind("Map", "ShowGraves", defaultValue: true, "Могилы на карте", "Могила погибшего хускарла отмечена на карте черепом с его именем, пока его не воскресят. Если выключить, при гибели ставится обычная метка смерти.", host: false);
			s_mapOthers = ConfigSync.Bind("Map", "ShowOthers", defaultValue: false, "Чужие хускарлы на карте", "Показывать на карте и хускарлов (и их могилы) других игроков, с именем хозяина в скобках.", host: false);
			s_clearRadius = ConfigSync.Bind("Dungeon", "ClearRadius", 25f, "Радиус зачистки, м", "По приказу «Зачистка» хускарлы убивают врагов (и разбивают кучи костей, из которых лезут скелеты) в этом радиусе от места приказа, потом возвращаются к вам. Враг за стеной, до которого идти дальше полутора радиусов, не считается.", host: true, (AcceptableValueBase)(object)Range(5f, 80f));
			s_lootRadius = ConfigSync.Bind("Dungeon", "LootRadius", 25f, "Радиус разграбления, м", "По приказу «Разграбление» хускарлы обыскивают сундуки, подбирают ценности и предметы с пола в этом радиусе от места приказа, потом возвращаются к вам.", host: true, (AcceptableValueBase)(object)Range(5f, 80f));
			s_lootIgnore = ConfigSync.Bind("Dungeon", "LootIgnore", "Stone,Wood,Flint,Resin,Grausten", "Что не брать", "Предметы, которые хускарлы не берут при разграблении, через запятую (имена префабов).", host: true);
			s_lootContainers = ConfigSync.Bind("Dungeon", "LootContainers", defaultValue: true, "Обыскивать сундуки", "При разграблении хускарлы забирают вещи из сундуков подземелий и других ничейных сундуков. Сундуки, построенные игроками, они не трогают никогда.", host: true);
			s_openDoors = ConfigSync.Bind("Dungeon", "OpenDoors", defaultValue: true, "Открывать двери", "Хускарлы сами открывают двери на пути и закрывают за собой, если за ними никто не идёт. Запертые двери (нужен ключ) не открывают.", host: true);
			s_lively = ConfigSync.Bind("Life", "Lively", defaultValue: true, "Живое поведение", "Хускарлы смотрят на вас, когда вы рядом, иногда разминаются и машут рукой, ночью садятся греться у костра, садятся рядом, когда вы сидите. Действует на хускарлов, которыми управляет ваша игра.", host: false);
			s_chatter = ConfigSync.Bind("Life", "Chatter", defaultValue: true, "Реплики", "Хускарлы иногда говорят что-нибудь к месту: ранен, дождь, ночь, вы вернулись, повержен сильный враг. Выключите, чтобы видеть только ответы на приказы.", host: false);
			s_passThrough = ConfigSync.Bind("Life", "PassThrough", defaultValue: true, "Проходить сквозь хускарлов", "Если вы упёрлись в хускарла (например, в узком проходе пещеры) и он не успел уступить, через полсекунды вы проходите сквозь него.", host: false);
			s_boardShips = ConfigSync.Bind("Ships", "BoardShips", defaultValue: true, "Садиться на корабль", "Хускарлы в режиме «За мной» запрыгивают к вам на корабль: на скамьи, а где их нет — на палубу, сидя или стоя. Плывут на своих местах, стреляют с места по серпентам и сходят на берег вслед за вами. Место, где сидит хускарл, можно занять: E по хускарлу — он встанет и уступит.", host: true);
			s_boardDistance = ConfigSync.Bind("Ships", "BoardDistance", 8f, "Запрыгивают на борт с, м", "С какого расстояния до борта хускарл запрыгивает на корабль. Дальше он бежит или плывёт к кораблю.", host: true, (AcceptableValueBase)(object)Range(2f, 12f));
			s_shipCatchUp = ConfigSync.Bind("Ships", "ShipCatchUpSeconds", 8f, "Подтягивать на борт через, с", "Хускарл, не успевший на корабль (вы отплыли без него), через столько секунд оказывается на свободном месте на борту. 0 — не подтягивать: он поплывёт следом, а если отстанет, будет ждать.", host: true, (AcceptableValueBase)(object)Range(0f, 60f));
			s_useCannons = ConfigSync.Bind("Ships", "UseCannons", defaultValue: true, "Стрелять из пушек", "На корабле с пушками (галеон из мода Artisan Mastery) хускарлы с ядрами в мешке встают к свободной пушке, которая достаёт до врага, наводят её и стреляют. Ядра берут из своего мешка. Без мода Artisan Mastery ничего не делает.", host: true);
			s_cannonRange = ConfigSync.Bind("Ships", "CannonRange", 70f, "Дальность стрельбы из пушек, м", "Враги дальше этого от корабля пушкари не обстреливают.", host: true, (AcceptableValueBase)(object)Range(20f, 150f));
			s_formationShape = ConfigSync.Bind("Formation", "Shape", FormationShape.Free, "Строй", "Как ваши хускарлы идут за вами в режиме «За мной»: дугой позади, клином, колонной по вашим следам, кольцом вокруг вас или свободно (без строя, просто рядом, как раньше, но не ближе заданного расстояния). Строй поворачивается по направлению вашего движения, а не камеры. Где место в строю занято деревом, стеной или водой, хускарл идёт по вашим следам. Меняется и на колесе приказов: «Строй». Действует на хускарлов, которые идут за вами, и по приказу «Идите туда».", host: false);
			s_formationSpacing = ConfigSync.Bind("Formation", "Spacing", 3f, "Расстояние в строю, м", "Сколько метров между соседями в строю и от вас до ближайших хускарлов. В свободном строю — как близко они подходят к вам и друг к другу. Меняется и на колесе приказов: «Строй» → «Расстояние».", host: false, (AcceptableValueBase)(object)Range(1.5f, 8f));
			f.SettingChanged += delegate
			{
				RaiseChanged();
			};
		}

		public static void SetFormationShape(FormationShape shape)
		{
			s_formationShape.Value = shape;
		}

		public static void SetFormationSpacing(float spacing)
		{
			s_formationSpacing.Value = spacing;
		}

		private static void RaiseChanged()
		{
			try
			{
				Cfg.Changed?.Invoke();
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)ex);
			}
		}

		public static List<KeyValuePair<string, int>> ParseItems(string s)
		{
			List<KeyValuePair<string, int>> list = new List<KeyValuePair<string, int>>();
			if (string.IsNullOrWhiteSpace(s))
			{
				return list;
			}
			string[] array = s.Split(new char[1] { ',' });
			for (int i = 0; i < array.Length; i++)
			{
				string[] array2 = array[i].Trim().Split(new char[1] { ':' });
				if (array2[0].Length != 0)
				{
					int result = 1;
					if (array2.Length > 1)
					{
						int.TryParse(array2[1].Trim(), out result);
					}
					list.Add(new KeyValuePair<string, int>(array2[0].Trim(), Math.Max(1, result)));
				}
			}
			return list;
		}

		public static HashSet<string> ParseSet(string s)
		{
			HashSet<string> hashSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
			if (string.IsNullOrWhiteSpace(s))
			{
				return hashSet;
			}
			string[] array = s.Split(new char[1] { ',' });
			foreach (string text in array)
			{
				if (text.Trim().Length > 0)
				{
					hashSet.Add(text.Trim());
				}
			}
			return hashSet;
		}
	}
	internal static class CommandMenu
	{
		private static float s_openedAt;

		private static int s_openFrame;

		private static readonly Stack<string> s_path = new Stack<string>();

		private static List<OrderNode> s_nodes = new List<OrderNode>();

		private static string s_title = "";

		private static string s_subtitle = "";

		private static int s_hover = -2;

		private static readonly List<Rect> s_rows = new List<Rect>();

		private static bool s_rowsSub;

		private const int BackRow = -1;

		public static HuskarlNpc Target { get; private set; }

		public static bool IsOpen => Object.op_Implicit((Object)(object)Target);

		public static void Open(HuskarlNpc npc)
		{
			CommandWheel.Close();
			Target = npc;
			s_openedAt = Time.time;
			s_openFrame = Time.frameCount;
			s_path.Clear();
			s_rows.Clear();
			s_hover = -2;
			Rebuild();
		}

		public static void Close()
		{
			if (Object.op_Implicit((Object)(object)Target))
			{
				InputGuard.Arm();
			}
			Target = null;
			s_path.Clear();
			s_rows.Clear();
		}

		private static void Back()
		{
			if (s_path.Count > 0)
			{
				s_path.Pop();
			}
			else
			{
				Close();
			}
		}

		private static void Rebuild()
		{
			HuskarlNpc target = Target;
			List<OrderNode> list = Orders.Build(new List<HuskarlNpc> { target }, null, "", null, single: true);
			string text = target.GetHelperName();
			List<string> list2 = new List<string>(s_path);
			list2.Reverse();
			int num = 0;
			foreach (string step in list2)
			{
				OrderNode orderNode = list.Find((OrderNode n) => n.Label == step && n.Children != null);
				if (orderNode == null)
				{
					break;
				}
				list = orderNode.Children;
				text = orderNode.Label;
				num++;
			}
			while (s_path.Count > num)
			{
				s_path.Pop();
			}
			s_nodes = list;
			s_title = text;
			s_subtitle = ((s_path.Count > 0) ? target.GetHelperName() : $"{Mathf.CeilToInt(((Character)target).GetHealth())} / {Mathf.CeilToInt(((Character)target).GetMaxHealth())}");
		}

		public static void Update()
		{
			//IL_003c: 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_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			if (!IsOpen)
			{
				return;
			}
			Player localPlayer = Player.m_localPlayer;
			if (!Object.op_Implicit((Object)(object)Target) || ((Character)Target).IsDead() || !Object.op_Implicit((Object)(object)localPlayer) || ((Character)localPlayer).IsDead() || Vector3.Distance(((Component)localPlayer).transform.position, ((Component)Target).transform.position) > 8f || InventoryGui.IsVisible() || Menu.IsVisible() || TextInput.IsVisible() || Minimap.IsOpen())
			{
				Close();
				return;
			}
			Rebuild();
			bool flag = s_path.Count > 0;
			s_hover = -2;
			if (s_rowsSub == flag)
			{
				Vector2 val = InputGuard.Pointer();
				for (int i = 0; i < s_rows.Count; i++)
				{
					Rect val2 = s_rows[i];
					if (((Rect)(ref val2)).Contains(val))
					{
						s_hover = (flag ? (i - 1) : i);
					}
				}
			}
			if (Time.frameCount == s_openFrame || Time.time - s_openedAt < 0.15f)
			{
				return;
			}
			if (InputGuard.KeyDown((KeyCode)27) || ZInput.GetButtonDown("Use") || ZInput.GetButtonDown("JoyButtonB"))
			{
				Close();
				return;
			}
			if (InputGuard.KeyDown((KeyCode)8) || ZInput.GetMouseButtonDown(1))
			{
				Back();
				return;
			}
			OrderNode orderNode = null;
			int num = InputGuard.DigitDown();
			if (num >= 0 && num < s_nodes.Count)
			{
				orderNode = s_nodes[num];
			}
			if (ZInput.GetMouseButtonDown(0))
			{
				if (s_hover == -1 && flag)
				{
					Back();
					return;
				}
				if (s_hover >= 0 && s_hover < s_nodes.Count)
				{
					orderNode = s_nodes[s_hover];
				}
			}
			if (orderNode == null || !orderNode.Enabled)
			{
				return;
			}
			if (orderNode.Children != null)
			{
				s_path.Push(orderNode.Label);
				return;
			}
			orderNode.Run?.Invoke();
			if (IsOpen && !IsToggle(orderNode))
			{
				Close();
			}
		}

		public static void OnGUI()
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: 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)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0330: Unknown result type (might be due to invalid IL or missing references)
			//IL_034e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0222: Unknown result type (might be due to invalid IL or missing references)
			//IL_0225: 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_02e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e6: Unknown result type (might be due to invalid IL or missing references)
			if (IsOpen && s_nodes != null)
			{
				UiStyle.Init();
				List<OrderNode> list = s_nodes;
				bool flag = s_path.Count > 0;
				float scale = UiStyle.Scale;
				Matrix4x4 matrix = GUI.matrix;
				GUI.matrix = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, new Vector3(scale, scale, 1f));
				float num = (float)Screen.width / scale;
				float num2 = (float)Screen.height / scale;
				int num3 = list.Count + (flag ? 1 : 0);
				float num4 = 70f + (float)num3 * 43f + 4f + 40f + 12f;
				Rect val = default(Rect);
				((Rect)(ref val))..ctor(num * 0.5f + 140f, (num2 - num4) * 0.5f, 420f, num4);
				if (((Rect)(ref val)).xMax > num - 10f)
				{
					((Rect)(ref val)).x = num - 420f - 10f;
				}
				GUI.DrawTexture(new Rect(((Rect)(ref val)).x - 2f, ((Rect)(ref val)).y - 2f, ((Rect)(ref val)).width + 4f, ((Rect)(ref val)).height + 4f), (Texture)(object)UiStyle.Border);
				GUI.Box(val, GUIContent.none, UiStyle.Window);
				float num5 = ((Rect)(ref val)).y + 14f;
				GUI.Label(new Rect(((Rect)(ref val)).x + 18f, num5, 384f, 30f), s_title, UiStyle.Title);
				num5 += 30f;
				GUI.Label(new Rect(((Rect)(ref val)).x + 18f, num5, 384f, 18f), s_subtitle, UiStyle.Hint);
				num5 += 26f;
				s_rows.Clear();
				s_rowsSub = flag;
				if (flag)
				{
					Rect val2 = default(Rect);
					((Rect)(ref val2))..ctor(((Rect)(ref val)).x + 18f, num5, 384f, 38f);
					GUI.Label(val2, "←  " + Localization.instance.Localize("$huskarl_back"), (s_hover == -1) ? UiStyle.Hover : UiStyle.Button);
					s_rows.Add(Unscale(val2, scale));
					num5 += 43f;
				}
				Rect val3 = default(Rect);
				for (int i = 0; i < list.Count; i++)
				{
					OrderNode orderNode = list[i];
					((Rect)(ref val3))..ctor(((Rect)(ref val)).x + 18f, num5, 384f, 38f);
					string text = string.Format("{0}.  {1}{2}", i + 1, orderNode.Label, (orderNode.Children != null) ? "  ›" : "");
					GUIStyle val4 = ((!orderNode.Enabled) ? UiStyle.Disabled : (orderNode.Active ? UiStyle.Active : ((s_hover == i) ? UiStyle.Hover : UiStyle.Button)));
					GUI.Label(val3, text, val4);
					s_rows.Add(Unscale(val3, scale));
					num5 += 43f;
				}
				num5 += 4f;
				GUI.Label(new Rect(((Rect)(ref val)).x + 18f, num5, 384f, 40f), Localization.instance.Localize("$huskarl_menu_hint"), UiStyle.Hint);
				GUI.matrix = matrix;
			}
		}

		private static Rect Unscale(Rect r, float scale)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			return new Rect(((Rect)(ref r)).x * scale, ((Rect)(ref r)).y * scale, ((Rect)(ref r)).width * scale, ((Rect)(ref r)).height * scale);
		}

		private static bool IsToggle(OrderNode n)
		{
			string text = Localization.instance.Localize("$huskarl_cmd_passive_on");
			string text2 = Localization.instance.Localize("$huskarl_cmd_passive_off");
			string text3 = Localization.instance.Localize("$huskarl_cmd_immortal_on");
			string text4 = Localization.instance.Localize("$huskarl_cmd_immortal_off");
			if (!(n.Label == text) && !(n.Label == text2) && !(n.Label == text3))
			{
				return n.Label == text4;
			}
			return true;
		}
	}
	internal static class UiStyle
	{
		public static GUIStyle Window;

		public static GUIStyle Title;

		public static GUIStyle Button;

		public static GUIStyle Hover;

		public static GUIStyle Active;

		public static GUIStyle Disabled;

		public static GUIStyle Hint;

		public static GUIStyle Center;

		public static GUIStyle Sector;

		public static GUIStyle SectorActive;

		public static GUIStyle SectorDisabled;

		public static Texture2D Border;

		public static Texture2D Disc;

		private static Texture2D s_bg;

		private static Texture2D s_btn;

		private static Texture2D s_btnHover;

		private static Texture2D s_btnActive;

		private static Font s_font;

		public static float Scale => Mathf.Max(0.75f, (float)Screen.height / 1080f);

		private static Texture2D Tex(Color c)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Expected O, but got Unknown
			Texture2D val = new Texture2D(1, 1)
			{
				hideFlags = (HideFlags)61
			};
			val.SetPixel(0, 0, c);
			val.Apply();
			return val;
		}

		private static Texture2D MakeDisc(int size, Color inner, Color edge)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: 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_008d: 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_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: 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_007f: 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_00c5: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(size, size, (TextureFormat)4, false)
			{
				hideFlags = (HideFlags)61
			};
			float num = (float)size * 0.5f;
			for (int i = 0; i < size; i++)
			{
				for (int j = 0; j < size; j++)
				{
					float num2 = Vector2.Distance(new Vector2((float)j + 0.5f, (float)i + 0.5f), new Vector2(num, num)) / num;
					Color val2 = ((num2 > 1f) ? Color.clear : ((num2 > 0.97f) ? edge : Color.Lerp(inner, new Color(inner.r, inner.g, inner.b, inner.a * 0.55f), num2)));
					if (num2 > 0.985f && num2 <= 1f)
					{
						val2.a *= (1f - num2) / 0.015f;
					}
					val.SetPixel(j, i, val2);
				}
			}
			val.Apply();
			return val;
		}

		public static void Init()
		{
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: 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_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Expected O, but got Unknown
			//IL_0161: Expected O, but got Unknown
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a4: Expected O, but got Unknown
			//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b4: 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_01c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_01df: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ee: Expected O, but got Unknown
			//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0206: Unknown result type (might be due to invalid IL or missing references)
			//IL_020d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0214: Unknown result type (might be due to invalid IL or missing references)
			//IL_0229: Unknown result type (might be due to invalid IL or missing references)
			//IL_0238: Expected O, but got Unknown
			//IL_0238: Unknown result type (might be due to invalid IL or missing references)
			//IL_023d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0248: Unknown result type (might be due to invalid IL or missing references)
			//IL_0250: Unknown result type (might be due to invalid IL or missing references)
			//IL_0257: Unknown result type (might be due to invalid IL or missing references)
			//IL_025e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0268: Expected O, but got Unknown
			//IL_0268: Unknown result type (might be due to invalid IL or missing references)
			//IL_0278: Unknown result type (might be due to invalid IL or missing references)
			//IL_028d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0297: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02dc: Expected O, but got Unknown
			//IL_02e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f6: 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_030b: Expected O, but got Unknown
			//IL_0310: Unknown result type (might be due to invalid IL or missing references)
			//IL_0315: Unknown result type (might be due to invalid IL or missing references)
			//IL_0325: Unknown result type (might be due to invalid IL or missing references)
			//IL_032b: Unknown result type (might be due to invalid IL or missing references)
			//IL_033a: Expected O, but got Unknown
			//IL_033f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0344: Unknown result type (might be due to invalid IL or missing references)
			//IL_0354: Unknown result type (might be due to invalid IL or missing references)
			//IL_0369: Unknown result type (might be due to invalid IL or missing references)
			//IL_0373: Unknown result type (might be due to invalid IL or missing references)
			//IL_0383: Unknown result type (might be due to invalid IL or missing references)
			//IL_0398: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a2: 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_03c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d6: Expected O, but got Unknown
			//IL_03db: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f6: Expected O, but got Unknown
			//IL_03fb: Expected O, but got Unknown
			//IL_0400: Unknown result type (might be due to invalid IL or missing references)
			//IL_0405: Unknown result type (might be due to invalid IL or missing references)
			//IL_040c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0411: Unknown result type (might be due to invalid IL or missing references)
			//IL_041b: Expected O, but got Unknown
			//IL_0420: Expected O, but got Unknown
			//IL_0425: Unknown result type (might be due to invalid IL or missing references)
			//IL_042a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0431: Unknown result type (might be due to invalid IL or missing references)
			//IL_0436: Unknown result type (might be due to invalid IL or missing references)
			//IL_0440: Expected O, but got Unknown
			//IL_0445: Expected O, but got Unknown
			if (Window != null && Object.op_Implicit((Object)(object)s_bg))
			{
				return;
			}
			Font[] array = Resources.FindObjectsOfTypeAll<Font>();
			foreach (Font val in array)
			{
				if (((Object)val).name == "AveriaSerifLibre-Bold")
				{
					s_font = val;
				}
			}
			s_bg = Tex(new Color(0.11f, 0.085f, 0.06f, 0.94f));
			Border = Tex(new Color(0.78f, 0.6f, 0.3f, 1f));
			s_btn = Tex(new Color(0.22f, 0.17f, 0.12f, 0.95f));
			s_btnHover = Tex(new Color(0.36f, 0.27f, 0.17f, 1f));
			s_btnActive = Tex(new Color(0.52f, 0.37f, 0.16f, 1f));
			Disc = MakeDisc(512, new Color(0.08f, 0.06f, 0.04f, 0.85f), new Color(0.78f, 0.6f, 0.3f, 0.9f));
			GUIStyle val2 = new GUIStyle();
			val2.normal.background = s_bg;
			val2.padding = new RectOffset(18, 18, 14, 16);
			Window = val2;
			GUIStyle val3 = new GUIStyle
			{
				font = s_font,
				fontSize = 26,
				alignment = (TextAnchor)4
			};
			val3.normal.textColor = new Color(1f, 0.86f, 0.55f);
			Title = val3;
			GUIStyle val4 = new GUIStyle
			{
				font = s_font,
				fontSize = 15,
				alignment = (TextAnchor)4,
				wordWrap = true
			};
			val4.normal.textColor = new Color(0.75f, 0.7f, 0.62f);
			Hint = val4;
			GUIStyle val5 = new GUIStyle
			{
				font = s_font,
				fontSize = 22,
				alignment = (TextAnchor)4,
				wordWrap = true
			};
			val5.normal.textColor = new Color(0.98f, 0.93f, 0.82f);
			Center = val5;
			GUIStyle val6 = new GUIStyle
			{
				font = s_font,
				fontSize = 19,
				alignment = (TextAnchor)3,
				padding = new RectOffset(14, 10, 6, 6)
			};
			val6.normal.background = s_btn;
			val6.normal.textColor = new Color(0.95f, 0.9f, 0.8f);
			val6.hover.background = s_btnHover;
			val6.hover.textColor = Color.white;
			val6.active.background = s_btnActive;
			val6.active.textColor = Color.white;
			Button = val6;
			GUIStyle val7 = new GUIStyle(Button);
			val7.normal.background = s_btnHover;
			val7.normal.textColor = Color.white;
			Hover = val7;
			GUIStyle val8 = new GUIStyle(Button);
			val8.normal.background = s_btnActive;
			val8.normal.textColor = Color.white;
			Active = val8;
			GUIStyle val9 = new GUIStyle(Button);
			val9.normal.background = s_btn;
			val9.normal.textColor = new Color(0.62f, 0.57f, 0.5f);
			val9.hover.background = s_btn;
			val9.hover.textColor = new Color(0.62f, 0.57f, 0.5f);
			val9.active.background = s_btn;
			val9.active.textColor = new Color(0.62f, 0.57f, 0.5f);
			Disabled = val9;
			Sector = new GUIStyle(Button)
			{
				alignment = (TextAnchor)4,
				padding = new RectOffset(8, 8, 6, 6)
			};
			SectorActive = new GUIStyle(Active)
			{
				alignment = (TextAnchor)4,
				padding = new RectOffset(8, 8, 6, 6)
			};
			SectorDisabled = new GUIStyle(Disabled)
			{
				alignment = (TextAnchor)4,
				padding = new RectOffset(8, 8, 6, 6)
			};
		}
	}
	internal static class CommandWheel
	{
		internal static bool s_rawScroll;

		private const float GotoRange = 120f;

		private static List<HuskarlNpc> s_squad;

		private static GameObject s_target;

		private static string s_targetName = "";

		private static Vector3? s_ground;

		private static readonly Stack<string> s_path = new Stack<string>();

		private static int s_selected;

		private static Vector2 s_lastMouse;

		private static float s_openedAt;

		private static int s_openFrame;

		private static int s_targetMask;

		private static int s_groundMask;

		private static List<OrderNode> s_nodes = new List<OrderNode>();

		private static string s_title = "";

		public static bool IsOpen { get; private set; }

		private static bool ModifierHeld()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Invalid comparison between Unknown and I4
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Invalid comparison between Unknown and I4
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Invalid comparison between Unknown and I4
			KeyCode wheelModifier = Cfg.WheelModifier;
			if ((int)wheelModifier == 0)
			{
				return false;
			}
			if (ZInput.GetKey(wheelModifier, false))
			{
				return true;
			}
			if ((int)wheelModifier == 304)
			{
				return ZInput.GetKey((KeyCode)303, false);
			}
			if ((int)wheelModifier == 306)
			{
				return ZInput.GetKey((KeyCode)305, false);
			}
			if ((int)wheelModifier == 308)
			{
				return ZInput.GetKey((KeyCode)307, false);
			}
			return false;
		}

		private static bool CanOpenNow()
		{
			Player localPlayer = Player.m_localPlayer;
			if (!Object.op_Implicit((Object)(object)localPlayer) || ((Character)localPlayer).IsDead() || ((Character)localPlayer).InPlaceMode() || ((Character)localPlayer).InCutscene())
			{
				return false;
			}
			if (CommandMenu.IsOpen || InventoryGui.IsVisible() || Menu.IsVisible() || TextInput.IsVisible() || Minimap.IsOpen() || Console.IsVisible() || (Object.op_Implicit((Object)(object)Chat.instance) && Chat.instance.HasFocus()) || Hud.InRadial() || Hud.IsPieceSelectionVisible())
			{
				return false;
			}
			return !StoreGui.IsVisible();
		}

		public static bool EatScroll()
		{
			if (s_rawScroll)
			{
				return false;
			}
			if (!IsOpen && !GameWheel.IsOpen)
			{
				if (ModifierHeld())
				{
					return CanOpenNow();
				}
				return false;
			}
			return true;
		}

		private static float RawScroll()
		{
			s_rawScroll = true;
			try
			{
				return ZInput.GetMouseScrollWheel();
			}
			finally
			{
				s_rawScroll = false;
			}
		}

		public static void Update()
		{
			//IL_0092: 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_00cd: 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)
			if (IsOpen)
			{
				Player localPlayer = Player.m_localPlayer;
				s_squad?.RemoveAll((HuskarlNpc n) => !Object.op_Implicit((Object)(object)n) || ((Character)n).IsDead());
				if (!Object.op_Implicit((Object)(object)localPlayer) || ((Character)localPlayer).IsDead() || s_squad == null || s_squad.Count == 0 || InventoryGui.IsVisible() || Menu.IsVisible() || TextInput.IsVisible() || Minimap.IsOpen())
				{
					Close();
				}
				else
				{
					HandleInput();
				}
			}
			else if (GameWheel.IsOpen)
			{
				if ((int)Cfg.WheelKey != 0 && ZInput.GetKeyDown(Cfg.WheelKey, false))
				{
					GameWheel.Close();
				}
			}
			else if (CanOpenNow())
			{
				bool flag = false;
				if (ModifierHeld())
				{
					flag = RawScroll() != 0f;
				}
				if ((int)Cfg.WheelKey != 0 && ZInput.GetKeyDown(Cfg.WheelKey, false))
				{
					flag = true;
				}
				if (flag)
				{
					Open();
				}
			}
		}

		public static void Open()
		{
			Open(classic: false);
		}

		private static void Open(bool classic)
		{
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			s_squad = Orders.Squad(localPlayer, Cfg.SquadRadius);
			if (s_squad.Count == 0)
			{
				((Character)localPlayer).Message((MessageType)2, Localization.instance.Localize("$huskarl_no_squad"), 0, (Sprite)null, false);
				return;
			}
			s_target = PickTarget(s_squad[0], out s_targetName);
			s_ground = (Object.op_Implicit((Object)(object)s_target) ? ((Vector3?)null) : PickGround());
			s_path.Clear();
			s_selected = 0;
			s_lastMouse = new Vector2(-1f, -1f);
			s_openedAt = Time.time;
			s_openFrame = Time.frameCount;
			if (!classic && Cfg.GameStyleWheel && GameWheel.Available())
			{
				string title;
				List<OrderNode> nodes = CurrentNodes(out title);
				s_squad = null;
				s_target = null;
				s_ground = null;
				if (!GameWheel.Open(title, nodes))
				{
					Plugin.Log.LogWarning((object)"The game's radial menu did not open, using the classic wheel");
					Open(classic: true);
				}
			}
			else
			{
				IsOpen = true;
				s_nodes = CurrentNodes(out s_title);
			}
		}

		public static void Close()
		{
			if (IsOpen)
			{
				InputGuard.Arm();
			}
			IsOpen = false;
			s_squad = null;
			s_target = null;
			s_ground = null;
			s_path.Clear();
		}

		private static GameObject PickTarget(HuskarlNpc lead, out string name)
		{
			//IL_009c: 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_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)
			name = "";
			if (!Object.op_Implicit((Object)(object)GameCamera.instance))
			{
				return null;
			}
			if (s_targetMask == 0)
			{
				s_targetMask = LayerMask.GetMask(new string[12]
				{
					"Default", "static_solid", "Default_small", "piece", "piece_nonsolid", "terrain", "character", "character_net", "character_ghost", "hitbox",
					"character_noenv", "vehicle"
				});
			}
			Transform transform = ((Component)GameCamera.instance).transform;
			RaycastHit[] array = Physics.RaycastAll(transform.position, transform.forward, 60f, s_targetMask, (QueryTriggerInteraction)2);
			Array.Sort(array, (RaycastHit a, RaycastHit b) => ((RaycastHit)(ref a)).distance.CompareTo(((RaycastHit)(ref b)).distance));
			Player localPlayer = Player.m_localPlayer;
			RaycastHit[] array2 = array;
			for (int num = 0; num < array2.Length; num++)
			{
				RaycastHit val = array2[num];
				Collider collider = ((RaycastHit)(ref val)).collider;
				GameObject val2 = (Object.op_Implicit((Object)(object)collider.attachedRigidbody) ? ((Component)collider.attachedRigidbody).gameObject : ((Component)collider).gameObject);
				if (Object.op_Implicit((Object)(object)localPlayer) && val2.transform.IsChildOf(((Component)localPlayer).transform))
				{
					continue;
				}
				Character componentInParent = val2.GetComponentInParent<Character>();
				if (Object.op_Implicit((Object)(object)componentInParent))
				{
					if (!(componentInParent is HuskarlNpc) && !componentInParent.IsPlayer())
					{
						if (componentInParent.IsDead() || !BaseAI.IsEnemy((Character)(object)lead, componentInParent))
						{
							return null;
						}
						name = componentInParent.GetHoverName();
						return ((Component)componentInParent).gameObject;
					}
					continue;
				}
				Pickable componentInParent2 = ((Component)collider).GetComponentInParent<Pickable>();
				if (Object.op_Implicit((Object)(object)componentInParent2))
				{
					if (!componentInParent2.CanBePicked())
					{
						return null;
					}
					name = Localization.instance.Localize(componentInParent2.GetHoverName());
					return ((Component)componentInParent2).gameObject;
				}
				if (!collider.isTrigger)
				{
					GameObject val3 = Projectile.FindHitObject(collider);
					if (!Object.op_Implicit((Object)(object)val3) || !Targets.RoleFor(val3, out var role))
					{
						break;
					}
					Hoverable component = val3.GetComponent<Hoverable>();
					string text = ((component != null) ? Localization.instance.Localize(component.GetHoverName()) : "");
					name = ((text.Length > 0) ? text : Localization.instance.Localize((role == Role.Axe) ? "$huskarl_target_tree" : "$huskarl_target_rock"));
					return val3;
				}
			}
			return NearCrosshairCreature(lead, transform, out name);
		}

		private static Vector3? PickGround()
		{
			//IL_0069: 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_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: 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_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: 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_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: 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_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_01da: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)GameCamera.instance))
			{
				return null;
			}
			if (s_groundMask == 0)
			{
				s_groundMask = LayerMask.GetMask(new string[6] { "Default", "static_solid", "Default_small", "piece", "terrain", "vehicle" });
			}
			Transform transform = ((Component)GameCamera.instance).transform;
			RaycastHit[] array = Physics.RaycastAll(transform.position, transform.forward, 120f, s_groundMask, (QueryTriggerInteraction)1);
			Array.Sort(array, (RaycastHit a, RaycastHit b) => ((RaycastHit)(ref a)).distance.CompareTo(((RaycastHit)(ref b)).distance));
			Player localPlayer = Player.m_localPlayer;
			RaycastHit[] array2 = array;
			float num2 = default(float);
			for (int num = 0; num < array2.Length; num++)
			{
				RaycastHit val = array2[num];
				if ((!Object.op_Implicit((Object)(object)localPlayer) || !((Component)((RaycastHit)(ref val)).collider).transform.IsChildOf(((Component)localPlayer).transform)) && !Object.op_Implicit((Object)(object)((Component)((RaycastHit)(ref val)).collider).GetComponentInParent<Character>()))
				{
					Vector3 val2 = ((RaycastHit)(ref val)).point;
					if (((RaycastHit)(ref val)).normal.y < 0.5f)
					{
						Vector3 val3 = val2;
						Vector3 val4 = VectorExtensions.Horizontal(transform.forward);
						val2 = val3 - ((Vector3)(ref val4)).normalized * 1f;
					}
					if (Object.op_Implicit((Object)(object)ZoneSystem.instance) && ZoneSystem.instance.GetSolidHeight(val2 + Vector3.up * 1.5f, ref num2, 1000) && num2 < val2.y + 3f)
					{
						val2.y = num2;
					}
					if (Object.op_Implicit((Object)(object)ZoneSystem.instance) && val2.y < ZoneSystem.instance.m_waterLevel - 0.6f && ((Component)((RaycastHit)(ref val)).collider).gameObject.layer == LayerMask.NameToLayer("terrain"))
					{
						return null;
					}
					return val2;
				}
			}
			return null;
		}

		private static GameObject NearCrosshairCreature(HuskarlNpc lead, Transform cam, out string name)
		{
			//IL_004e: 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_005e: 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_0074: Unknown result type (might be due to invalid IL or missing references)
			name = "";
			Character val = null;
			float num = 4f;
			foreach (Character allCharacter in Character.GetAllCharacters())
			{
				if (!Object.op_Implicit((Object)(object)allCharacter) || allCharacter.IsDead() || allCharacter.IsPlayer() || allCharacter is HuskarlNpc || !BaseAI.IsEnemy((Character)(object)lead, allCharacter))
				{
					continue;
				}
				Vector3 val2 = allCharacter.GetCenterPoint() - cam.position;
				if (!(((Vector3)(ref val2)).magnitude > 60f))
				{
					float num2 = Vector3.Angle(cam.forward, val2);
					if (num2 < num)
					{
						val = allCharacter;
						num = num2;
					}
				}
			}
			if (!Object.op_Implicit((Object)(object)val))
			{
				return null;
			}
			name = val.GetHoverName();
			return ((Component)val).gameObject;
		}

		private static List<OrderNode> CurrentNodes(out string title)
		{
			List<OrderNode> list = Orders.Build(s_squad, s_target, s_targetName, s_ground, single: false);
			title = ((s_squad.Count == 1) ? s_squad[0].GetHelperName() : Localization.instance.Localize("$huskarl_squad", new string[1] { s_squad.Count.ToString() }));
			List<string> list2 = new List<string>(s_path);
			list2.Reverse();
			foreach (string step in list2)
			{
				OrderNode orderNode = list.Find((OrderNode n) => n.Label == step && n.Children != null);
				if (orderNode == null)
				{
					break;
				}
				list = orderNode.Children;
				title = orderNode.Label;
			}
			return list;
		}

		private static void Activate(OrderNode n)
		{
			if (n != null && n.Enabled)
			{
				if (n.Children != null)
				{
					s_path.Push(n.Label);
					s_selected = 0;
				}
				else
				{
					n.Run?.Invoke();
					Close();
				}
			}
		}

		private static void Back()
		{
			if (s_path.Count > 0)
			{
				s_path.Pop();
				s_selected = 0;
			}
			else
			{
				Close();
			}
		}

		private static void HandleInput()
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: 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_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: 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_007f: 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_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			s_nodes = CurrentNodes(out s_title);
			int count = s_nodes.Count;
			if (count == 0)
			{
				return;
			}
			s_selected = Mathf.Clamp(s_selected, 0, count - 1);
			Vector2 val = InputGuard.Pointer();
			if (s_lastMouse.x >= 0f)
			{
				Vector2 val2 = val - s_lastMouse;
				if (((Vector2)(ref val2)).sqrMagnitude > 4f)
				{
					Vector2 val3 = val - new Vector2((float)Screen.width * 0.5f, (float)Screen.height * 0.5f);
					if (((Vector2)(ref val3)).magnitude > 70f * UiStyle.Scale)
					{
						float num = Mathf.Atan2(val3.x, 0f - val3.y) * 57.29578f;
						if (num < 0f)
						{
							num += 360f;
						}
						s_selected = Mathf.RoundToInt(num / (360f / (float)count)) % count;
					}
				}
			}
			s_lastMouse = val;
			if (Time.frameCount == s_openFrame)
			{
				return;
			}
			float num2 = RawScroll();
			if (num2 != 0f)
			{
				s_selected = (s_selected + ((num2 < 0f) ? 1 : (count - 1))) % count;
			}
			if (InputGuard.KeyDown((KeyCode)27) || ZInput.GetButtonDown("JoyButtonB"))
			{
				Close();
			}
			else
			{
				if (Time.time - s_openedAt < 0.1f)
				{
					return;
				}
				if (InputGuard.KeyDown((KeyCode)8) || ZInput.GetMouseButtonDown(1))
				{
					Back();
					return;
				}
				if (ZInput.GetMouseButtonDown(0) || InputGuard.KeyDown((KeyCode)13) || InputGuard.KeyDown((KeyCode)271) || InputGuard.KeyDown((KeyCode)32))
				{
					Activate(s_nodes[s_selected]);
					return;
				}
				int num3 = InputGuard.DigitDown();
				if (num3 >= 0 && num3 < count)
				{
					Activate(s_nodes[num3]);
				}
			}
		}

		public static void OnGUI()
		{
			//IL_005c: 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_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_0256: Unknown result type (might be due to invalid IL or missing references)
			//IL_0263: Unknown result type (might be due to invalid IL or missing references)
			//IL_027a: 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_029b: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0307: Unknown result type (might be due to invalid IL or missing references)
			//IL_0318: Unknown result type (might be due to invalid IL or missing references)
			//IL_0202: Unknown result type (might be due to invalid IL or missing references)
			//IL_0234: Unknown result type (might be due to invalid IL or missing references)
			if (!IsOpen || s_squad == null || s_squad.Count == 0 || s_nodes == null)
			{
				return;
			}
			UiStyle.Init();
			List<OrderNode> list = s_nodes;
			bool flag = s_path.Count > 0;
			int count = list.Count;
			if (count == 0)
			{
				return;
			}
			int num = Mathf.Clamp(s_selected, 0, count - 1);
			float scale = UiStyle.Scale;
			Matrix4x4 matrix = GUI.matrix;
			GUI.matrix = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, new Vector3(scale, scale, 1f));
			Vector2 val = default(Vector2);
			((Vector2)(ref val))..ctor((float)Screen.width / scale * 0.5f, (float)Screen.height / scale * 0.5f);
			float num2 = ((count > 8) ? 240f : 220f);
			float num3 = ((count > 8) ? 345f : 290f);
			float num4 = num2 * 2f + 260f;
			float num5 = num3 * 2f + 260f;
			GUI.DrawTexture(new Rect(val.x - num5 * 0.5f, val.y - num4 * 0.5f, num5, num4), (Texture)(object)UiStyle.Disc);
			Vector2 val2 = default(Vector2);
			Rect val3 = default(Rect);
			for (int i = 0; i < count; i++)
			{
				OrderNode orderNode = list[i];
				float num6 = (float)i * (float)Math.PI * 2f / (float)count;
				((Vector2)(ref val2))..ctor(val.x + Mathf.Sin(num6) * num3, val.y - Mathf.Cos(num6) * num2);
				((Rect)(ref val3))..ctor(val2.x - 115f, val2.y - 22f, 230f, 44f);