Decompiled source of AgeOfJarls v0.8.0

plugins/AgeOfJarls/AgeOfJarls.dll

Decompiled 2 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Cryptography;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using AgeOfJarls.AI;
using AgeOfJarls.AI.Jobs;
using AgeOfJarls.Army;
using AgeOfJarls.Commands;
using AgeOfJarls.Core;
using AgeOfJarls.Core.Defs;
using AgeOfJarls.Net;
using AgeOfJarls.Portals;
using AgeOfJarls.Recruitment;
using AgeOfJarls.Settlement;
using AgeOfJarls.Settlers;
using AgeOfJarls.Sieges;
using AgeOfJarls.UI;
using AgeOfJarls.Work;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Extensions;
using Jotunn.Managers;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using Splatform;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Networking;
using UnityEngine.UI;
using Valheim.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("assembly_valheim")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("AgeOfJarls")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Settlements, settlers, work, sieges and co-op management for Valheim")]
[assembly: AssemblyFileVersion("0.8.0.0")]
[assembly: AssemblyInformationalVersion("0.8.0+bee682e7d97558da3d5feb3e09243a79bd346b9b")]
[assembly: AssemblyProduct("AgeOfJarls")]
[assembly: AssemblyTitle("AgeOfJarls")]
[assembly: InternalsVisibleTo("AgeOfJarls.Tests")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.8.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace AgeOfJarls
{
	[BepInPlugin("com.damia.ageofjarls", "AgeOfJarls", "0.8.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		private Harmony _harmony;

		private float _nextUpdateErrorAt;

		private void Awake()
		{
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Expected O, but got Unknown
			Log.Init(((BaseUnityPlugin)this).Logger);
			AoJConfig.Bind(((BaseUnityPlugin)this).Config);
			string directoryName = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location);
			ModPaths.Init(directoryName);
			AutoUpdate.Init((MonoBehaviour)(object)this, directoryName);
			TranslationLoader.Load();
			DefsRegistry.LoadLocal();
			DefsSync.Register();
			SettlerPrefab.Register();
			JarlTablePiece.Register();
			SettlementPieces.Register();
			CaptiveCage.Register();
			ConsoleCommands.Register();
			CommandWheel.RegisterKey();
			SettlerCollision.Init();
			_harmony = new Harmony("com.damia.ageofjarls");
			_harmony.PatchAll(typeof(Plugin).Assembly);
			Log.Info("Core", "AgeOfJarls 0.8.0 loaded");
		}

		private void Update()
		{
			try
			{
				ItemDelivery.Update();
				HelpWindow.Poll();
			}
			catch (Exception arg)
			{
				if (Time.time >= _nextUpdateErrorAt)
				{
					_nextUpdateErrorAt = Time.time + 30f;
					Log.Error("Core", $"Frame update failed: {arg}");
				}
			}
		}

		private void OnDestroy()
		{
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}
	}
	internal static class PluginInfo
	{
		public const string Guid = "com.damia.ageofjarls";

		public const string Name = "AgeOfJarls";

		public const string Version = "0.8.0";
	}
}
namespace AgeOfJarls.Work
{
	public enum JobType
	{
		None,
		Woodcutter,
		Hauler,
		Miner,
		Smelter,
		Builder,
		Farmer,
		Cook
	}
	internal enum ToolKind
	{
		None,
		Axe,
		Pickaxe,
		Hammer
	}
	internal static class JobInfo
	{
		internal static readonly JobType[] All = new JobType[7]
		{
			JobType.Woodcutter,
			JobType.Hauler,
			JobType.Miner,
			JobType.Smelter,
			JobType.Builder,
			JobType.Farmer,
			JobType.Cook
		};

		internal static string Token(JobType job)
		{
			return "$aoj_job_" + job.ToString().ToLowerInvariant();
		}

		internal static string UnlockId(JobType job)
		{
			return job.ToString().ToLowerInvariant();
		}

		internal static bool IsUnlocked(JobType job, int tier)
		{
			string item = UnlockId(job);
			List<TierDef> tiers = DefsRegistry.Current.Tiers;
			bool flag = false;
			foreach (TierDef item2 in tiers)
			{
				if (item2.Unlocks.Contains(item))
				{
					flag = true;
					if (item2.Level <= tier)
					{
						return true;
					}
				}
			}
			return !flag;
		}

		internal static ToolKind RequiredTool(JobType job)
		{
			return job switch
			{
				JobType.Woodcutter => ToolKind.Axe, 
				JobType.Miner => ToolKind.Pickaxe, 
				JobType.Builder => ToolKind.Hammer, 
				_ => ToolKind.None, 
			};
		}

		internal static string ToolToken(ToolKind tool)
		{
			return "$aoj_tool_" + tool.ToString().ToLowerInvariant();
		}

		internal static bool Fits(ItemData item, ToolKind tool)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Invalid comparison between Unknown and I4
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Invalid comparison between Unknown and I4
			if (item == null)
			{
				return false;
			}
			SharedData shared = item.m_shared;
			switch (tool)
			{
			case ToolKind.Axe:
				if (item.IsWeapon())
				{
					if ((int)shared.m_skillType != 7)
					{
						return shared.m_damages.m_chop > 0f;
					}
					return true;
				}
				return false;
			case ToolKind.Pickaxe:
				if (item.IsWeapon())
				{
					if ((int)shared.m_skillType != 12)
					{
						return shared.m_damages.m_pickaxe > 0f;
					}
					return true;
				}
				return false;
			case ToolKind.Hammer:
				return shared.m_name == "$item_hammer";
			default:
				return false;
			}
		}

		internal static ItemData BestTool(Inventory inventory, ToolKind tool)
		{
			ItemData val = null;
			foreach (ItemData allItem in inventory.GetAllItems())
			{
				if (Fits(allItem, tool) && (val == null || allItem.m_shared.m_toolTier > val.m_shared.m_toolTier || (allItem.m_shared.m_toolTier == val.m_shared.m_toolTier && Power(allItem, tool) > Power(val, tool))))
				{
					val = allItem;
				}
			}
			return val;
		}

		private static float Power(ItemData item, ToolKind tool)
		{
			//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_0012: 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)
			DamageTypes damage = item.GetDamage();
			if (tool != ToolKind.Pickaxe)
			{
				return damage.m_chop;
			}
			return damage.m_pickaxe;
		}
	}
	internal static class Reservations
	{
		private const float DefaultSeconds = 30f;

		private static readonly Dictionary<int, (long owner, float until)> s_taken = new Dictionary<int, (long, float)>();

		private static readonly List<int> s_expired = new List<int>();

		internal static bool IsFree(Object target, long worker)
		{
			if (target == (Object)null)
			{
				return false;
			}
			if (s_taken.TryGetValue(target.GetInstanceID(), out (long, float) value) && value.Item1 != worker)
			{
				return Time.time > value.Item2;
			}
			return true;
		}

		internal static bool Take(Object target, long worker, float seconds = 30f)
		{
			if (!IsFree(target, worker))
			{
				return false;
			}
			s_taken[target.GetInstanceID()] = (worker, Time.time + seconds);
			if (s_taken.Count > 256)
			{
				Prune();
			}
			return true;
		}

		internal static void Release(Object target, long worker)
		{
			if (target != (Object)null && s_taken.TryGetValue(target.GetInstanceID(), out (long, float) value) && value.Item1 == worker)
			{
				s_taken.Remove(target.GetInstanceID());
			}
		}

		private static void Prune()
		{
			s_expired.Clear();
			foreach (KeyValuePair<int, (long, float)> item in s_taken)
			{
				if (Time.time > item.Value.Item2)
				{
					s_expired.Add(item.Key);
				}
			}
			foreach (int item2 in s_expired)
			{
				s_taken.Remove(item2);
			}
		}
	}
	internal static class WorkScanner
	{
		private const float CacheSeconds = 5f;

		private const int MaxHits = 32768;

		private static Collider[] s_hits = (Collider[])(object)new Collider[1024];

		private static readonly Dictionary<(long, Type), (float time, List<Component> found)> s_cache = new Dictionary<(long, Type), (float, List<Component>)>();

		private static readonly HashSet<Component> s_seen = new HashSet<Component>();

		private static readonly List<(long, Type)> s_stale = new List<(long, Type)>();

		private static int s_mask;

		private static int s_solidMask;

		private const float TrunkRadius = 0.5f;

		private const float TrunkMinHeight = 0.4f;

		private const int ApproachSides = 8;

		private const float StandOff = 0.8f;

		private static readonly List<Vector3> s_approachPath = new List<Vector3>();

		internal static List<Component> Find<T>(WorkTotem totem, float margin = 0f) where T : Component
		{
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			(long, Type) key = (totem.Id, typeof(T));
			if (s_cache.TryGetValue(key, out (float, List<Component>) value) && Time.time - value.Item1 < 5f)
			{
				value.Item2.RemoveAll((Component c) => (Object)(object)c == (Object)null);
				return value.Item2;
			}
			if (s_mask == 0)
			{
				s_mask = LayerMask.GetMask(new string[6] { "Default", "static_solid", "Default_small", "piece", "piece_nonsolid", "vehicle" });
			}
			List<Component> list = new List<Component>();
			s_seen.Clear();
			int num;
			while ((num = Physics.OverlapSphereNonAlloc(((Component)totem).transform.position, totem.Radius + margin, s_hits, s_mask)) == s_hits.Length && s_hits.Length < 32768)
			{
				s_hits = (Collider[])(object)new Collider[s_hits.Length * 2];
			}
			for (int num2 = 0; num2 < num; num2++)
			{
				T componentInParent = ((Component)s_hits[num2]).GetComponentInParent<T>();
				if ((Object)(object)componentInParent != (Object)null && s_seen.Add((Component)(object)componentInParent))
				{
					list.Add((Component)(object)componentInParent);
				}
			}
			s_seen.Clear();
			s_cache[key] = (Time.time, list);
			if (s_cache.Count > 128)
			{
				s_cache.Clear();
			}
			return list;
		}

		internal static void Forget(WorkTotem totem)
		{
			long id = totem.Id;
			s_stale.Clear();
			foreach (var key in s_cache.Keys)
			{
				if (key.Item1 == id)
				{
					s_stale.Add(key);
				}
			}
			foreach (var item in s_stale)
			{
				s_cache.Remove(item);
			}
			s_stale.Clear();
		}

		internal static Collider[] SolidColliders(Component target)
		{
			if ((Object)(object)target == (Object)null)
			{
				return (Collider[])(object)new Collider[0];
			}
			if (s_solidMask == 0)
			{
				s_solidMask = LayerMask.GetMask(new string[7] { "Default", "static_solid", "Default_small", "piece", "piece_nonsolid", "terrain", "vehicle" });
			}
			return Array.FindAll(target.GetComponentsInChildren<Collider>(), (Collider c) => !c.isTrigger && (s_solidMask & (1 << ((Component)c).gameObject.layer)) != 0);
		}

		internal static Vector3 StrikePoint(Component target, Collider[] colliders, Vector3 chest)
		{
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: 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_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0059: 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)
			if (target is TreeBase)
			{
				Vector3 position = target.transform.position;
				Vector3 val = chest - position;
				val.y = 0f;
				Vector3 result = ((((Vector3)(ref val)).sqrMagnitude < 0.01f) ? position : (position + ((Vector3)(ref val)).normalized * 0.5f));
				result.y = Mathf.Max(chest.y, position.y + 0.4f);
				return result;
			}
			return NearestPoint(colliders, chest, target.transform.position);
		}

		internal static Vector3 NearestPoint(Collider[] colliders, Vector3 from, Vector3 fallback)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: 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_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			Vector3 result = fallback;
			float num = float.MaxValue;
			foreach (Collider val in colliders)
			{
				if (!((Object)(object)val == (Object)null) && val.enabled && ((Component)val).gameObject.activeInHierarchy)
				{
					Vector3 val2 = ClosestOn(val, from);
					Vector3 val3 = val2 - from;
					float sqrMagnitude = ((Vector3)(ref val3)).sqrMagnitude;
					if (sqrMagnitude < num)
					{
						result = val2;
						num = sqrMagnitude;
					}
				}
			}
			return result;
		}

		private static Vector3 ClosestOn(Collider collider, Vector3 from)
		{
			//IL_0013: 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_001b: 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_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			MeshCollider val = (MeshCollider)(object)((collider is MeshCollider) ? collider : null);
			if (val == null || val.convex)
			{
				return collider.ClosestPoint(from);
			}
			Bounds bounds = collider.bounds;
			Vector3 val2 = ((Bounds)(ref bounds)).center - from;
			float magnitude = ((Vector3)(ref val2)).magnitude;
			RaycastHit val3 = default(RaycastHit);
			if (magnitude > 0.01f && collider.Raycast(new Ray(from, val2 / magnitude), ref val3, magnitude))
			{
				return ((RaycastHit)(ref val3)).point;
			}
			return ((Bounds)(ref bounds)).ClosestPoint(from);
		}

		internal static bool FindApproach(Vector3 from, Collider[] colliders, Vector3 fallback, float reach, AgentType agent, out Vector3 spot)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: 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_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_00b3: 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_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: 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_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: 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_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a1: 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)
			spot = fallback;
			if ((Object)(object)Pathfinding.instance == (Object)null)
			{
				return false;
			}
			Bounds val = default(Bounds);
			((Bounds)(ref val))..ctor(fallback, Vector3.zero);
			foreach (Collider val2 in colliders)
			{
				if ((Object)(object)val2 != (Object)null && val2.enabled && ((Component)val2).gameObject.activeInHierarchy)
				{
					((Bounds)(ref val)).Encapsulate(val2.bounds);
				}
			}
			Vector3 center = ((Bounds)(ref val)).center;
			Vector2 val3 = new Vector2(((Bounds)(ref val)).extents.x, ((Bounds)(ref val)).extents.z);
			float num = ((Vector2)(ref val3)).magnitude + 2f;
			float shortest = float.MaxValue;
			float num2 = default(float);
			for (int j = 0; j < 8; j++)
			{
				Vector3 val4 = center + Quaternion.Euler(0f, (float)j * 360f / 8f, 0f) * Vector3.forward * num;
				Vector3 val5 = NearestPoint(colliders, val4, fallback);
				Vector3 val6 = val4 - val5;
				val6.y = 0f;
				Vector3 val7 = ((((Vector3)(ref val6)).sqrMagnitude > 0.0001f) ? (val5 + ((Vector3)(ref val6)).normalized * 0.8f) : val4);
				val7.y = ((Bounds)(ref val)).min.y + 0.2f;
				TryApproach(from, val7, colliders, fallback, reach, agent, ref shortest, ref spot);
				if ((Object)(object)ZoneSystem.instance != (Object)null && ZoneSystem.instance.GetGroundHeight(val7, ref num2) && num2 < ((Bounds)(ref val)).min.y - 1f)
				{
					val7.y = num2;
					TryApproach(from, val7, colliders, fallback, reach, agent, ref shortest, ref spot);
				}
			}
			s_approachPath.Clear();
			return shortest < float.MaxValue;
		}

		private static void TryApproach(Vector3 from, Vector3 stand, Collider[] colliders, Vector3 fallback, float reach, AgentType agent, ref float shortest, ref Vector3 spot)
		{
			//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_000c: 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_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			if (!Pathfinding.instance.GetPath(from, stand, s_approachPath, agent, true, false, false) || s_approachPath.Count == 0)
			{
				return;
			}
			Vector3 val = s_approachPath[s_approachPath.Count - 1];
			if (!(Vector3.Distance(val, NearestPoint(colliders, val, fallback)) > reach))
			{
				float num = 0f;
				for (int i = 1; i < s_approachPath.Count; i++)
				{
					num += Vector3.Distance(s_approachPath[i - 1], s_approachPath[i]);
				}
				if (num < shortest)
				{
					shortest = num;
					spot = val;
				}
			}
		}
	}
	public class WorkTotem : MonoBehaviour, Hoverable, Interactable
	{
		private enum TotemAction
		{
			Radius = 1,
			AllDay,
			Priority,
			Replant,
			Upgrade
		}

		private const string Module = "Work";

		internal const float MinRadius = 8f;

		internal const float MaxRadius = 30f;

		internal const float DefaultRadius = 15f;

		internal const float Overreach = 10f;

		private const float MarkerSeconds = 0.5f;

		internal static readonly List<WorkTotem> Loaded = new List<WorkTotem>();

		public JobType m_job;

		public CircleProjector m_areaMarker;

		private ZNetView _nview;

		private Piece _piece;

		private const float LooksSeconds = 2f;

		private int _shownLevel = 1;

		private int _paidFromLevel;

		private float _paidUntil;

		private const float RefundWaitSeconds = 30f;

		internal const int LowPriority = 0;

		internal const int NormalPriority = 1;

		internal const int HighPriority = 2;

		private static List<TotemLevelDef> LevelDefs => DefsRegistry.Current.Totems.Levels;

		internal static int MaxLevel => 1 + LevelDefs.Count;

		internal int Level
		{
			get
			{
				if (!((Object)(object)_nview != (Object)null) || !_nview.IsValid())
				{
					return 1;
				}
				return Mathf.Clamp(_nview.GetZDO().GetInt(Keys.ZdoTotemLevel, 1), 1, MaxLevel);
			}
		}

		internal float PaceBonus => 1f + (LevelDef(Level)?.PaceBonus ?? 0f);

		internal int ExtraPlaces => LevelDef(Level)?.ExtraPlaces ?? 0;

		internal bool Replants
		{
			get
			{
				if (m_job == JobType.Woodcutter && (Object)(object)_nview != (Object)null && _nview.IsValid())
				{
					return _nview.GetZDO().GetBool(Keys.ZdoTotemReplant, false);
				}
				return false;
			}
		}

		internal JobType Job => m_job;

		internal int Priority
		{
			get
			{
				if (!((Object)(object)_nview != (Object)null) || !_nview.IsValid())
				{
					return 1;
				}
				return Mathf.Clamp(_nview.GetZDO().GetInt(Keys.ZdoTotemPriority, 1), 0, 2);
			}
		}

		internal long Id
		{
			get
			{
				if (!((Object)(object)_nview != (Object)null) || !_nview.IsValid())
				{
					return 0L;
				}
				return _nview.GetZDO().GetLong(Keys.ZdoTotemId, 0L);
			}
		}

		internal float Radius
		{
			get
			{
				if (!((Object)(object)_nview != (Object)null) || !_nview.IsValid())
				{
					return 15f;
				}
				return Mathf.Clamp(_nview.GetZDO().GetFloat(Keys.ZdoTotemRadius, 15f), 8f, 30f);
			}
		}

		internal bool AllDay
		{
			get
			{
				if ((Object)(object)_nview != (Object)null && _nview.IsValid())
				{
					return _nview.GetZDO().GetBool(Keys.ZdoTotemAllDay, false);
				}
				return false;
			}
		}

		internal bool IsWorkTime
		{
			get
			{
				if (!AllDay)
				{
					return !EnvMan.IsNight();
				}
				return true;
			}
		}

		internal JarlTable Settlement => JarlTable.FindServing(((Component)this).transform.position, AoJConfig.TotemReach.Value);

		internal int Capacity
		{
			get
			{
				JarlTable settlement = Settlement;
				SettlementData settlementData = (((Object)(object)settlement != (Object)null) ? settlement.Data : null);
				int num = settlementData?.Tier ?? 0;
				return Mathf.Min(AoJConfig.TotemBaseSlots.Value + num / 2, AoJConfig.TotemMaxSlots.Value) + AoJConfig.TotemSlotsPerMember.Value * JarlTable.ExtraMembers(settlementData) + (JarlTable.HasUnlock(settlementData, "totem_slot") ? 1 : 0) + ExtraPlaces;
			}
		}

		private static TotemLevelDef LevelDef(int level)
		{
			if (level < 2 || level - 2 >= LevelDefs.Count)
			{
				return null;
			}
			return LevelDefs[level - 2];
		}

		internal static List<TierCost> UpgradeCost(int level)
		{
			return LevelDef(level)?.Cost ?? new List<TierCost>();
		}

		private void UpdateLooks()
		{
			int level = Level;
			if (level != _shownLevel)
			{
				_shownLevel = level;
				FreeStandingBanner.ShowLevel(((Component)this).transform, level);
			}
		}

		internal static string PriorityToken(int priority)
		{
			return priority switch
			{
				0 => "$aoj_priority_low", 
				2 => "$aoj_priority_high", 
				_ => "$aoj_priority_normal", 
			};
		}

		internal static WorkTotem FindById(long id)
		{
			if (id == 0L)
			{
				return null;
			}
			foreach (WorkTotem item in Loaded)
			{
				if (item.Id == id)
				{
					return item;
				}
			}
			return null;
		}

		private void Awake()
		{
			_nview = ((Component)this).GetComponent<ZNetView>();
			_piece = ((Component)this).GetComponent<Piece>();
			SetMarkerRadius(15f);
			if (!((Object)(object)_nview == (Object)null) && _nview.IsValid())
			{
				Loaded.Add(this);
				HideMarker();
				_nview.Register<ZPackage>("AoJ_TotemConfig", (Action<long, ZPackage>)RPC_Config);
				_nview.Register<int>("AoJ_TotemRefund", (Action<long, int>)RPC_Refund);
				((MonoBehaviour)this).InvokeRepeating("UpdateLooks", 0.5f, 2f);
			}
		}

		private void Start()
		{
			if ((Object)(object)_nview != (Object)null && _nview.IsValid() && _nview.IsOwner() && _nview.GetZDO().GetLong(Keys.ZdoTotemId, 0L) == 0L)
			{
				_nview.GetZDO().Set(Keys.ZdoTotemId, Keys.NewId());
			}
		}

		private void OnDestroy()
		{
			Loaded.Remove(this);
		}

		internal List<Settler> Workers()
		{
			long id = Id;
			if (id != 0L)
			{
				return Settler.Loaded.Where((Settler s) => s.JobId == id).ToList();
			}
			return new List<Settler>();
		}

		internal int WorkerCount()
		{
			long id = Id;
			int num = 0;
			if (id != 0L)
			{
				foreach (Settler item in Settler.Loaded)
				{
					if ((Object)(object)item != (Object)null && item.JobId == id)
					{
						num++;
					}
				}
			}
			return num;
		}

		internal Settler NearestFreeSettler()
		{
			JarlTable settlement = Settlement;
			long settlementId = (((Object)(object)settlement != (Object)null) ? settlement.SettlementId : 0);
			if (settlementId == 0L)
			{
				return null;
			}
			return (from s in Settler.Loaded
				where s.Identity != null && s.HomeId == settlementId && s.JobId == 0
				orderby Vector3.Distance(((Component)s).transform.position, ((Component)this).transform.position)
				select s).FirstOrDefault();
		}

		internal void RequestRadius(float radius)
		{
			Send(TotemAction.Radius, delegate(ZPackage p)
			{
				p.Write(Mathf.Clamp(radius, 8f, 30f));
			});
		}

		internal void RequestAllDay(bool allDay)
		{
			Send(TotemAction.AllDay, delegate(ZPackage p)
			{
				p.Write(allDay);
			});
		}

		internal void RequestPriority(int priority)
		{
			Send(TotemAction.Priority, delegate(ZPackage p)
			{
				p.Write(Mathf.Clamp(priority, 0, 2));
			});
		}

		internal void RequestReplant(bool replant)
		{
			Send(TotemAction.Replant, delegate(ZPackage p)
			{
				p.Write(replant);
			});
		}

		internal string TryUpgrade(Player player)
		{
			int level = Level;
			if (level >= MaxLevel)
			{
				return "$aoj_totem_max_level";
			}
			if (!MayManage(player))
			{
				return Permissions.Denied(SettlementRight.Manage);
			}
			List<TierCost> list = UpgradeCost(level + 1);
			if (!player.NoCostCheat())
			{
				string text = MissingText(((Humanoid)player).GetInventory(), list);
				if (text.Length > 0)
				{
					return "$aoj_msg_totem_missing " + text;
				}
				foreach (TierCost item in list)
				{
					((Humanoid)player).GetInventory().RemoveItem(SharedName(item.Item), item.Amount, -1, true);
				}
				_paidFromLevel = level;
				_paidUntil = Time.time + 30f;
			}
			Send(TotemAction.Upgrade, delegate(ZPackage p)
			{
				p.Write(level);
			});
			return null;
		}

		internal static string CostText(List<TierCost> cost)
		{
			return string.Join(", ", cost.Select((TierCost c) => $"{c.Amount} {SharedName(c.Item)}"));
		}

		private static string MissingText(Inventory inventory, List<TierCost> cost)
		{
			return string.Join(", ", from c in cost
				where inventory.CountItems(SharedName(c.Item), -1, true) < c.Amount
				select $"{c.Amount - inventory.CountItems(SharedName(c.Item), -1, true)} {SharedName(c.Item)}");
		}

		private static string SharedName(string prefab)
		{
			GameObject val = (((Object)(object)ObjectDB.instance != (Object)null) ? ObjectDB.instance.GetItemPrefab(prefab) : null);
			ItemDrop val2 = (((Object)(object)val != (Object)null) ? val.GetComponent<ItemDrop>() : null);
			if (!((Object)(object)val2 != (Object)null))
			{
				return prefab;
			}
			return val2.m_itemData.m_shared.m_name;
		}

		private void RPC_Refund(long sender, int fromLevel)
		{
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null || fromLevel != _paidFromLevel || Time.time > _paidUntil)
			{
				return;
			}
			_paidUntil = 0f;
			foreach (TierCost item in UpgradeCost(fromLevel + 1))
			{
				((Humanoid)localPlayer).GetInventory().AddItem(item.Item, item.Amount, 1, 0, 0L, "", false, false);
			}
			((Character)localPlayer).Message((MessageType)2, Localize("$aoj_msg_totem_refund"), 0, (Sprite)null, false);
		}

		private void Send(TotemAction action, Action<ZPackage> write)
		{
			//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((int)action);
			write(val);
			_nview.InvokeRPC("AoJ_TotemConfig", new object[1] { val });
		}

		internal bool MayManage(Player player)
		{
			if ((Object)(object)player == (Object)null)
			{
				return false;
			}
			JarlTable settlement = Settlement;
			if ((Object)(object)settlement != (Object)null && settlement.Data != null)
			{
				return settlement.RoleOf(player).Allows(SettlementRight.Manage);
			}
			if ((Object)(object)_piece != (Object)null)
			{
				return _piece.GetCreator() == player.GetPlayerID();
			}
			return false;
		}

		private void RPC_Config(long sender, ZPackage package)
		{
			if (!OwnerRpc.Handles(_nview, "AoJ_TotemConfig", package))
			{
				return;
			}
			try
			{
				TotemAction totemAction = (TotemAction)package.ReadInt();
				if (!MayManage(Peers.FindPlayer(sender)))
				{
					Log.Warning("Work", $"Totem settings from peer {sender} refused: not the Jarl or a Hersir here");
					if (totemAction == TotemAction.Upgrade)
					{
						_nview.InvokeRPC(sender, "AoJ_TotemRefund", new object[1] { package.ReadInt() });
					}
					return;
				}
				ZDO zDO = _nview.GetZDO();
				switch (totemAction)
				{
				case TotemAction.Upgrade:
				{
					int num = package.ReadInt();
					if (num == Level && num < MaxLevel)
					{
						zDO.Set(Keys.ZdoTotemLevel, num + 1, false);
						break;
					}
					_nview.InvokeRPC(sender, "AoJ_TotemRefund", new object[1] { num });
					break;
				}
				case TotemAction.Radius:
					zDO.Set(Keys.ZdoTotemRadius, Mathf.Clamp(package.ReadSingle(), 8f, 30f));
					break;
				case TotemAction.AllDay:
					zDO.Set(Keys.ZdoTotemAllDay, package.ReadBool());
					break;
				case TotemAction.Priority:
					zDO.Set(Keys.ZdoTotemPriority, Mathf.Clamp(package.ReadInt(), 0, 2), false);
					break;
				case TotemAction.Replant:
					zDO.Set(Keys.ZdoTotemReplant, package.ReadBool());
					break;
				default:
					Log.Warning("Work", $"Unknown totem action {(int)totemAction} from peer {sender}");
					break;
				}
			}
			catch (Exception ex) when (ex is IOException || ex is ArgumentException)
			{
				Log.Error("Work", $"Malformed totem settings from peer {sender}: {ex.Message}");
			}
		}

		public string GetHoverText()
		{
			ShowMarker();
			if ((Object)(object)_nview == (Object)null || !_nview.IsValid())
			{
				return Localize(JobInfo.Token(m_job));
			}
			List<Settler> list = Workers();
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append("<b>$aoj_totem: ").Append(JobInfo.Token(m_job)).Append("</b> · $aoj_totem_level ")
				.Append(Level)
				.Append('/')
				.Append(MaxLevel)
				.Append('\n');
			stringBuilder.Append("$aoj_workers: ").Append((list.Count == 0) ? "-" : string.Join(", ", list.Select((Settler w) => w.DisplayName))).Append($" ({list.Count}/{Capacity})\n");
			stringBuilder.Append("$aoj_radius ").Append(Mathf.RoundToInt(Radius)).Append(" m · ")
				.Append(AllDay ? "$aoj_hours_allday" : "$aoj_hours_day")
				.Append(" · $aoj_priority: ")
				.Append(PriorityToken(Priority));
			ToolKind toolKind = JobInfo.RequiredTool(m_job);
			if (toolKind != ToolKind.None)
			{
				stringBuilder.Append(" · $aoj_needs ").Append(JobInfo.ToolToken(toolKind));
			}
			string value = list.Select((Settler w) => w.JobProblem).FirstOrDefault((string p) => p.Length > 0);
			if (!string.IsNullOrEmpty(value))
			{
				stringBuilder.Append("\n<color=#ff9060>").Append(value).Append("</color>");
			}
			if ((Object)(object)Settlement == (Object)null)
			{
				stringBuilder.Append("\n<color=#ff9060>$aoj_totem_outside</color>");
			}
			stringBuilder.Append("\n[<color=yellow><b>$KEY_Use</b></color>] $aoj_manage_totem");
			return Localize(stringBuilder.ToString());
		}

		public string GetHoverName()
		{
			return Localize(JobInfo.Token(m_job));
		}

		public float GetHoverOffset()
		{
			return 0f;
		}

		public bool Interact(Humanoid user, bool hold, bool alt)
		{
			if (hold || !(user is Player) || (Object)(object)_nview == (Object)null || !_nview.IsValid())
			{
				return false;
			}
			TotemWindow.Open(this);
			return true;
		}

		public bool UseItem(Humanoid user, ItemData item)
		{
			return false;
		}

		internal void ShowMarker()
		{
			if (!((Object)(object)m_areaMarker == (Object)null))
			{
				SetMarkerRadius(Radius);
				((Component)m_areaMarker).gameObject.SetActive(true);
				((MonoBehaviour)this).CancelInvoke("HideMarker");
				((MonoBehaviour)this).Invoke("HideMarker", 0.5f);
			}
		}

		private void HideMarker()
		{
			if ((Object)(object)m_areaMarker != (Object)null)
			{
				((Component)m_areaMarker).gameObject.SetActive(false);
			}
		}

		private void SetMarkerRadius(float radius)
		{
			if ((Object)(object)m_areaMarker != (Object)null)
			{
				m_areaMarker.m_radius = radius;
				m_areaMarker.m_nrOfSegments = Mathf.Max(24, Mathf.RoundToInt(radius * 4f));
			}
		}

		private static string Localize(string text)
		{
			if (Localization.instance == null)
			{
				return text;
			}
			return Localization.instance.Localize(text);
		}
	}
}
namespace AgeOfJarls.UI
{
	internal abstract class AojWindow : MonoBehaviour
	{
		protected const float ButtonHeight = 40f;

		protected static readonly Vector2 Center = new Vector2(0.5f, 0.5f);

		private const float RefreshSeconds = 0.5f;

		private bool _blockingInput;

		private float _refreshTimer;

		protected InputField TextEntry;

		private const float ScreenMargin = 40f;

		private readonly List<(Text label, GameObject page)> _tabs = new List<(Text, GameObject)>();

		protected const float TabHeight = 34f;

		protected const float RowButtonHeight = 30f;

		protected int ActiveTab { get; private set; }

		protected static T CreateWindow<T>(string name, float width, float height) where T : AojWindow
		{
			//IL_000f: 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_00bf: 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_004e: 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_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_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_009d: 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)
			GameObject val = GUIManager.Instance.CreateWoodpanel(GUIManager.CustomGUIFront.transform, Center, Center, Vector2.zero, width, height, false);
			((Object)val).name = name;
			float num = AoJConfig.UiScale.Value;
			RectTransform component = GUIManager.CustomGUIFront.GetComponent<RectTransform>();
			if ((Object)(object)component != (Object)null)
			{
				Rect rect = component.rect;
				if (((Rect)(ref rect)).width > 0f)
				{
					rect = component.rect;
					if (((Rect)(ref rect)).height > 0f)
					{
						float[] obj = new float[3] { num, 0f, 0f };
						rect = component.rect;
						obj[1] = (((Rect)(ref rect)).width - 40f) / width;
						rect = component.rect;
						obj[2] = (((Rect)(ref rect)).height - 40f) / height;
						num = Mathf.Min(obj);
					}
				}
			}
			((Transform)val.GetComponent<RectTransform>()).localScale = Vector3.one * Mathf.Max(0.5f, num);
			T val2 = val.AddComponent<T>();
			val2.Build(val.transform);
			val.SetActive(false);
			return val2;
		}

		protected abstract void Build(Transform root);

		protected abstract bool IsTargetValid();

		protected abstract void Refresh();

		protected virtual void OnHidden()
		{
		}

		protected void ShowWindow()
		{
			((Component)this).gameObject.SetActive(true);
			if (!_blockingInput)
			{
				GUIManager.BlockInput(true);
				_blockingInput = true;
			}
			RefreshNow();
		}

		internal void Hide()
		{
			((Component)this).gameObject.SetActive(false);
			ReleaseInput();
			OnHidden();
		}

		protected void RefreshNow()
		{
			_refreshTimer = 0.5f;
			long start = Perf.Start();
			Refresh();
			Perf.Stop(Perf.Section.Windows, start);
		}

		protected void Update()
		{
			if (!IsTargetValid())
			{
				Hide();
				return;
			}
			bool flag = (Object)(object)TextEntry != (Object)null && TextEntry.isFocused;
			if (ZInput.GetKeyDown((KeyCode)27, true) || ZInput.GetButtonDown("JoyButtonB") || (!flag && ZInput.GetButtonDown("Use")))
			{
				Hide();
				return;
			}
			_refreshTimer -= Time.deltaTime;
			if (_refreshTimer <= 0f)
			{
				RefreshNow();
			}
		}

		protected void OnDestroy()
		{
			ReleaseInput();
		}

		private void ReleaseInput()
		{
			if (_blockingInput)
			{
				GUIManager.BlockInput(false);
				_blockingInput = false;
			}
		}

		protected static Text Label(Transform parent, Vector2 position, int size, Color color, float width, float height, TextAnchor alignment)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: 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)
			Text component = GUIManager.Instance.CreateText("", parent, Center, Center, position, GUIManager.Instance.AveriaSerifBold, size, color, true, Color.black, width, height, false).GetComponent<Text>();
			component.alignment = alignment;
			return component;
		}

		protected static Text Button(Transform parent, string token, Vector2 position, float width, Action onClick, float height = 40f)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Expected O, but got Unknown
			GameObject obj = GUIManager.Instance.CreateButton(Localize(token), parent, Center, Center, position, width, height);
			((UnityEvent)obj.GetComponent<Button>().onClick).AddListener((UnityAction)delegate
			{
				onClick();
			});
			return obj.GetComponentInChildren<Text>();
		}

		protected static Transform Page(Transform root, string name)
		{
			//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)
			GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) });
			val.transform.SetParent(root, false);
			return val.transform;
		}

		protected void Tabs(Transform root, float y, float tabWidth, params (string token, Transform page)[] tabs)
		{
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			float num = (float)(-(tabs.Length - 1)) * (tabWidth + 8f) / 2f;
			for (int i = 0; i < tabs.Length; i++)
			{
				int index = i;
				Text item = Button(root, tabs[i].token, new Vector2(num + (float)i * (tabWidth + 8f), y), tabWidth, delegate
				{
					ShowTab(index);
				}, 34f);
				_tabs.Add((item, ((Component)tabs[i].page).gameObject));
			}
			ShowTab(0);
		}

		protected void ShowTab(int index)
		{
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			ActiveTab = index;
			for (int i = 0; i < _tabs.Count; i++)
			{
				_tabs[i].page.SetActive(i == index);
				((Graphic)_tabs[i].label).color = ((i == index) ? GUIManager.Instance.ValheimOrange : GUIManager.Instance.ValheimBeige);
			}
			if (((Component)this).gameObject.activeSelf && IsTargetValid())
			{
				RefreshNow();
			}
		}

		protected static InputField TextInput(Transform parent, string placeholderToken, Vector2 position, float width)
		{
			//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_0010: Unknown result type (might be due to invalid IL or missing references)
			return GUIManager.Instance.CreateInputField(parent, Center, Center, position, (ContentType)0, Localize(placeholderToken), 16, width, 40f).GetComponent<InputField>();
		}

		protected static string Localize(string text, params string[] words)
		{
			if (Localization.instance == null)
			{
				return text;
			}
			return Localization.instance.Localize(text, words);
		}
	}
	internal sealed class CommandWheel : IRadialConfig
	{
		private enum Order
		{
			Follow,
			Wait,
			Attack,
			FallBack,
			GoHome
		}

		[HarmonyPatch(typeof(Player), "CheckKeyboardRadialPressed")]
		private static class WheelKeyPatch
		{
			[HarmonyPostfix]
			private static void Postfix(ref bool __result)
			{
				if (!__result && KeyDown())
				{
					__result = true;
				}
			}
		}

		[HarmonyPatch(typeof(RadialConfigHelper), "SetItemInteractionControls")]
		private static class WheelKeyControlsPatch
		{
			[HarmonyPostfix]
			private static void Postfix(RadialBase radial)
			{
				Func<bool> releaseToUse = radial.GetReleaseToUse;
				Func<bool> close = radial.GetClose;
				radial.GetReleaseToUse = () => (releaseToUse != null && releaseToUse()) || (RadialData.SO.EnableReleaseToUseMode && KeyReleasedAfterHold());
				radial.GetClose = () => (close != null && close()) || KeyDown() || (!RadialData.SO.EnableReleaseToUseMode && KeyReleasedAfterHold());
			}
		}

		[HarmonyPatch(typeof(OpenRadialConfig), "TryOpenNonDefaultRadials")]
		private static class OpenWheelPatch
		{
			[HarmonyPrefix]
			private static bool Prefix(RadialBase radial, ref bool __result)
			{
				Player localPlayer = Player.m_localPlayer;
				if ((Object)(object)localPlayer == (Object)null || (Object)(object)radial == (Object)null || (Object)(object)RadialData.SO == (Object)null)
				{
					return true;
				}
				bool flag = KeyHeld();
				Settler settler = LookedAtSettler(localPlayer, flag);
				if ((Object)(object)settler != (Object)null)
				{
					radial.Open((IRadialConfig)(object)new CommandWheel(settler, null), (IRadialConfig)(object)(flag ? null : RadialData.SO.MainGroupConfig));
				}
				else
				{
					if (!flag)
					{
						return true;
					}
					radial.Open((IRadialConfig)(object)new CommandWheel(null, LookedAtEnemy(localPlayer)), (IRadialConfig)null);
				}
				__result = true;
				return false;
			}
		}

		[HarmonyPatch(typeof(RadialBase), "ConstructRadial")]
		private static class MainWheelPatch
		{
			[HarmonyPrefix]
			private static void Prefix(RadialBase __instance, List<RadialMenuElement> elements)
			{
				Player localPlayer = Player.m_localPlayer;
				if (elements != null && __instance.CurrentConfig is ValheimRadialConfig && !((Object)(object)localPlayer == (Object)null) && !((Object)(object)RadialData.SO == (Object)null) && !((Object)(object)RadialData.SO.GroupElement == (Object)null))
				{
					GroupElement val = Object.Instantiate<GroupElement>(RadialData.SO.GroupElement);
					val.Init((IRadialConfig)(object)new CommandWheel(null, LookedAtEnemy(localPlayer)), __instance.CurrentConfig, __instance);
					elements.Insert(Mathf.Min(5, elements.Count), (RadialMenuElement)(object)val);
				}
			}
		}

		private const float LooseAimDegrees = 6f;

		private const float EnemyAimDegrees = 20f;

		private const float SettlerAttackRange = 25f;

		private const float WindowSlack = 10f;

		private const int ShowDistanceFrom = 6;

		private const int MainWheelSlot = 5;

		private static ButtonConfig s_key;

		private static int s_sightMask;

		private readonly bool _one;

		private readonly Settler _single;

		private readonly Character _target;

		public string LocalizedName
		{
			get
			{
				//IL_0037: Unknown result type (might be due to invalid IL or missing references)
				if (!_one)
				{
					return Localize("$aoj_cmd_group");
				}
				if ((Object)(object)_single == (Object)null)
				{
					return "";
				}
				int num = DistanceTo(((Component)_single).transform.position);
				if (num < 6)
				{
					return _single.DisplayName;
				}
				return $"{_single.DisplayName} ({num} m)";
			}
		}

		public Sprite Sprite => GestureSprite((Emotes)6);

		internal static string KeyName => ((object)AoJConfig.CommandWheelKey.Value/*cast due to .constrained prefix*/).ToString();

		internal static string HoverHint
		{
			get
			{
				//IL_0005: Unknown result type (might be due to invalid IL or missing references)
				if ((int)AoJConfig.CommandWheelKey.Value != 0)
				{
					return "[<color=yellow><b>" + KeyName + "</b></color>] $aoj_cmd_wheel_hover\n";
				}
				return "";
			}
		}

		private CommandWheel(Settler single, Character target)
		{
			_one = (Object)(object)single != (Object)null;
			_single = single;
			_target = target;
		}

		internal static void RegisterKey()
		{
			//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_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			s_key = new ButtonConfig
			{
				Name = "AoJ_CommandWheel",
				Config = AoJConfig.CommandWheelKey
			};
			InputManager.Instance.AddButton("com.damia.ageofjarls", s_key);
		}

		public void InitRadialConfig(RadialBase radial)
		{
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			List<RadialMenuElement> list = new List<RadialMenuElement>();
			if (_one)
			{
				list.Add(Element((Emotes)13, "$aoj_cmd_call", "$aoj_cmd_call_desc", () => Give(Order.Follow, (Emotes)13, "$aoj_cmd_call")));
				list.Add(Element((Emotes)6, "$aoj_cmd_stay", "$aoj_cmd_stay_desc", () => Give(Order.Wait, (Emotes)6, "$aoj_cmd_stay")));
				list.Add(Element((Emotes)2, "$aoj_cmd_attack", "$aoj_cmd_attack_one", () => Give(Order.Attack, (Emotes)2, "$aoj_cmd_attack")));
				list.Add(Element((Emotes)4, "$aoj_cmd_fallback", "$aoj_cmd_fallback_one", () => Give(Order.FallBack, (Emotes)4, "$aoj_cmd_fallback")));
				if ((Object)(object)_single != (Object)null && _single.HasHome)
				{
					list.Add(Element((Emotes)0, "$aoj_cmd_home", "$aoj_cmd_home_one", () => Give(Order.GoHome, (Emotes)0, "$aoj_cmd_home")));
				}
				list.Add(Element((Emotes)5, "$aoj_cmd_details", "$aoj_cmd_details_desc", OpenDetails));
			}
			else
			{
				string description = (((Object)(object)_target != (Object)null) ? Localize("$aoj_cmd_attack_target", _target.GetHoverName(), DistanceTo(((Component)_target).transform.position).ToString()) : "$aoj_cmd_attack_desc");
				list.Add(Element((Emotes)13, "$aoj_cmd_follow", "$aoj_cmd_follow_desc", () => Give(Order.Follow, (Emotes)13, "$aoj_cmd_follow")));
				list.Add(Element((Emotes)6, "$aoj_cmd_wait", "$aoj_cmd_wait_desc", () => Give(Order.Wait, (Emotes)6, "$aoj_cmd_wait")));
				list.Add(Element((Emotes)2, "$aoj_cmd_attack", description, () => Give(Order.Attack, (Emotes)2, "$aoj_cmd_attack")));
				list.Add(Element((Emotes)4, "$aoj_cmd_fallback", "$aoj_cmd_fallback_desc", () => Give(Order.FallBack, (Emotes)4, "$aoj_cmd_fallback")));
				list.Add(Element((Emotes)0, "$aoj_cmd_home", "$aoj_cmd_home_desc", () => Give(Order.GoHome, (Emotes)0, "$aoj_cmd_home")));
			}
			radial.ConstructRadial(list);
		}

		private static RadialMenuElement Element(Emotes icon, string name, string description, Func<bool> action)
		{
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			EmoteElement obj = Object.Instantiate<EmoteElement>(RadialData.SO.EmoteElement);
			((RadialMenuElement)obj).Name = Localize(name);
			((RadialMenuElement)obj).Description = Localize(description);
			((RadialMenuElement)obj).Interact = action;
			((RadialMenuElement)obj).CloseOnInteract = () => true;
			Sprite val = GestureSprite(icon);
			((Component)((RadialMenuElement)obj).m_icon).gameObject.SetActive((Object)(object)val != (Object)null);
			((RadialMenuElement)obj).m_icon.sprite = val;
			return (RadialMenuElement)(object)obj;
		}

		private bool Give(Order order, Emotes gesture, string label)
		{
			//IL_0101: 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)
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				return false;
			}
			if (_one && ((Object)(object)_single == (Object)null || _single.IsCaptive))
			{
				((Character)localPlayer).Message((MessageType)2, Localize("$aoj_msg_cmd_lost"), 0, (Sprite)null, false);
				return true;
			}
			int refused;
			List<Settler> list = Targets(order, localPlayer, out refused);
			if (list.Count == 0)
			{
				string text = (_one ? Localize("$aoj_msg_cmd_not_yours", _single.DisplayName) : ((refused > 0) ? Localize("$aoj_msg_cmd_refused") : Localize((order == Order.Follow) ? "$aoj_msg_cmd_nobody_near" : "$aoj_msg_cmd_nobody")));
				((Character)localPlayer).Message((MessageType)2, text, 0, (Sprite)null, false);
				return true;
			}
			Character val = null;
			if (order == Order.Attack)
			{
				val = (_one ? NearestEnemy(((Component)_single).transform.position) : (IsValidEnemy(_target) ? _target : LookedAtEnemy(localPlayer)));
				if ((Object)(object)val == (Object)null)
				{
					((Character)localPlayer).Message((MessageType)2, _one ? Localize("$aoj_msg_cmd_no_target_near", _single.DisplayName) : Localize("$aoj_msg_cmd_no_target"), 0, (Sprite)null, false);
					return true;
				}
			}
			foreach (Settler item in list)
			{
				switch (order)
				{
				case Order.Follow:
					item.SendFollow(localPlayer);
					break;
				case Order.Wait:
					item.SendWait();
					break;
				case Order.Attack:
					item.SendAttack(val);
					break;
				case Order.FallBack:
					item.SendFallBack(localPlayer);
					break;
				case Order.GoHome:
					item.SendGoHome();
					break;
				}
			}
			if (AoJConfig.CommandGestures.Value)
			{
				Emote.DoEmote(gesture);
			}
			string text2 = Localize(label);
			((Character)localPlayer).Message((MessageType)2, (list.Count == 1) ? Localize("$aoj_msg_cmd_one", list[0].DisplayName, text2) : Localize("$aoj_msg_cmd_many", text2, list.Count.ToString()), 0, (Sprite)null, false);
			Log.Debug("UI", string.Format("Order {0} to {1} settler(s){2}", order, list.Count, ((Object)(object)val != (Object)null) ? (" against " + val.m_name) : ""));
			return true;
		}

		private bool OpenDetails()
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_single == (Object)null)
			{
				Player localPlayer = Player.m_localPlayer;
				if (localPlayer != null)
				{
					((Character)localPlayer).Message((MessageType)2, Localize("$aoj_msg_cmd_lost"), 0, (Sprite)null, false);
				}
				return true;
			}
			SettlerWindow.Open(_single, (float)DistanceTo(((Component)_single).transform.position) + 10f);
			return true;
		}

		private List<Settler> Targets(Order order, Player player, out int refused)
		{
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			List<Settler> list = new List<Settler>();
			refused = 0;
			if (_one)
			{
				if (Accepts(_single, order, player))
				{
					list.Add(_single);
				}
				else
				{
					refused = 1;
				}
				return list;
			}
			long playerID = player.GetPlayerID();
			float value = AoJConfig.CommandRange.Value;
			foreach (Settler item in Settler.Loaded)
			{
				if ((Object)(object)item == (Object)null || item.Identity == null || item.IsCaptive)
				{
					continue;
				}
				long followedPlayerId = item.FollowedPlayerId;
				bool num = followedPlayerId == playerID;
				bool flag = order == Order.Follow && followedPlayerId == 0L && Vector3.Distance(((Component)item).transform.position, ((Component)player).transform.position) <= value;
				if ((num || flag) && (order != Order.GoHome || item.HasHome))
				{
					if (Accepts(item, order, player))
					{
						list.Add(item);
					}
					else
					{
						refused++;
					}
				}
			}
			return list;
		}

		private static bool Accepts(Settler settler, Order order, Player player)
		{
			bool flag = settler.FollowedPlayerId == player.GetPlayerID();
			switch (order)
			{
			case Order.Attack:
				if (!flag)
				{
					return settler.MayBeOrderedBy(player, SettlementRight.Military);
				}
				return true;
			case Order.GoHome:
				if (settler.HasHome)
				{
					if (!flag)
					{
						return settler.MayBeOrderedBy(player, SettlementRight.Live);
					}
					return true;
				}
				return false;
			default:
				return true;
			}
		}

		internal static Settler LookedAtSettler(Player player, bool loose)
		{
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: 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)
			float value = AoJConfig.CommandLookRange.Value;
			GameObject hoverObject = ((Humanoid)player).GetHoverObject();
			Settler settler = (((Object)(object)hoverObject != (Object)null) ? hoverObject.GetComponentInParent<Settler>() : null);
			if (!Commandable(settler, player, value))
			{
				Character hoverCreature = player.GetHoverCreature();
				settler = (((Object)(object)hoverCreature != (Object)null) ? ((Component)hoverCreature).GetComponent<Settler>() : null);
			}
			if (Commandable(settler, player, value))
			{
				return settler;
			}
			if (!loose || (Object)(object)GameCamera.instance == (Object)null)
			{
				return null;
			}
			Transform transform = ((Component)GameCamera.instance).transform;
			Settler result = null;
			float num = 6f;
			foreach (Settler item in Settler.Loaded)
			{
				Character val = (Commandable(item, player, value) ? ((Component)item).GetComponent<Character>() : null);
				if (!((Object)(object)val == (Object)null))
				{
					Vector3 centerPoint = val.GetCenterPoint();
					float num2 = Vector3.Angle(transform.forward, centerPoint - transform.position);
					if (num2 < num && InSight(transform.position, centerPoint))
					{
						result = item;
						num = num2;
					}
				}
			}
			return result;
		}

		private static bool Commandable(Settler settler, Player player, float range)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)settler != (Object)null && settler.Identity != null && !settler.IsCaptive)
			{
				return Vector3.Distance(((Component)settler).transform.position, ((Component)player).transform.position) <= range;
			}
			return false;
		}

		private static Character LookedAtEnemy(Player player)
		{
			//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_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			float value = AoJConfig.CommandLookRange.Value;
			Character hoverCreature = player.GetHoverCreature();
			if (IsValidEnemy(hoverCreature) && Vector3.Distance(((Component)hoverCreature).transform.position, ((Component)player).transform.position) <= value)
			{
				return hoverCreature;
			}
			Transform val = (((Object)(object)GameCamera.instance != (Object)null) ? ((Component)GameCamera.instance).transform : null);
			Vector3 val2 = (((Object)(object)val != (Object)null) ? val.position : (((Object)(object)((Character)player).m_eye != (Object)null) ? ((Character)player).m_eye.position : ((Component)player).transform.position));
			Vector3 val3 = (((Object)(object)val != (Object)null) ? val.forward : ((Character)player).GetLookDir());
			Character result = null;
			float num = 20f;
			foreach (Character allCharacter in Character.GetAllCharacters())
			{
				if (IsValidEnemy(allCharacter) && !(Vector3.Distance(((Component)allCharacter).transform.position, ((Component)player).transform.position) > value))
				{
					Vector3 centerPoint = allCharacter.GetCenterPoint();
					float num2 = Vector3.Angle(val3, centerPoint - val2);
					if (num2 < num && InSight(val2, centerPoint))
					{
						result = allCharacter;
						num = num2;
					}
				}
			}
			return result;
		}

		private static Character NearestEnemy(Vector3 position)
		{
			//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_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Invalid comparison between Unknown and I4
			Character result = null;
			float num = float.MaxValue;
			foreach (Character allCharacter in Character.GetAllCharacters())
			{
				if (IsValidEnemy(allCharacter))
				{
					float num2 = Vector3.Distance(((Component)allCharacter).transform.position, position);
					float num3 = num2 + (((int)allCharacter.m_faction == 1) ? 25f : 0f);
					if (num2 <= 25f && num3 < num)
					{
						result = allCharacter;
						num = num3;
					}
				}
			}
			return result;
		}

		private static bool IsValidEnemy(Character character)
		{
			if ((Object)(object)character != (Object)null && !character.IsPlayer() && !character.IsTamed() && !character.IsDead())
			{
				return (Object)(object)((Component)character).GetComponent<Settler>() == (Object)null;
			}
			return false;
		}

		private static bool InSight(Vector3 from, Vector3 to)
		{
			//IL_003f: 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)
			if (s_sightMask == 0)
			{
				s_sightMask = LayerMask.GetMask(new string[5] { "Default", "static_solid", "piece", "terrain", "vehicle" });
			}
			return !Physics.Linecast(from, to, s_sightMask, (QueryTriggerInteraction)1);
		}

		private static int DistanceTo(Vector3 position)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			if (!((Object)(object)localPlayer != (Object)null))
			{
				return 0;
			}
			return Mathf.RoundToInt(Vector3.Distance(((Component)localPlayer).transform.position, position));
		}

		private static Sprite GestureSprite(Emotes emote)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)RadialData.SO != (Object)null) || !((Object)(object)RadialData.SO.EmoteMappings != (Object)null))
			{
				return null;
			}
			return RadialData.SO.EmoteMappings.GetMapping(emote).Sprite;
		}

		private static string Localize(string text, params string[] words)
		{
			if (Localization.instance == null)
			{
				return text;
			}
			return Localization.instance.Localize(text, words);
		}

		private static bool KeyDown()
		{
			if (s_key != null)
			{
				return ZInput.GetButtonDown(s_key.Name);
			}
			return false;
		}

		private static bool KeyHeld()
		{
			if (s_key != null)
			{
				return ZInput.GetButton(s_key.Name);
			}
			return false;
		}

		private static bool KeyReleasedAfterHold()
		{
			if (s_key != null && ZInput.GetButtonLastPressedTimer(s_key.Name) > RadialData.SO.HoldCloseDelay)
			{
				return ZInput.GetButtonUp(s_key.Name);
			}
			return false;
		}
	}
	internal sealed class DebugOverlay : MonoBehaviour
	{
		private const float Range = 40f;

		private const float RefreshSeconds = 0.5f;

		private static readonly Vector3 Offset = new Vector3(0f, 2.4f, 0f);

		private static DebugOverlay s_instance;

		private float _timer;

		internal static bool Enabled => (Object)(object)s_instance != (Object)null;

		internal static bool Toggle()
		{
			//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_0039: Expected O, but got Unknown
			if ((Object)(object)s_instance != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)s_instance).gameObject);
				s_instance = null;
				ClearTexts();
				return false;
			}
			GameObject val = new GameObject("AoJ_DebugOverlay");
			Object.DontDestroyOnLoad((Object)val);
			s_instance = val.AddComponent<DebugOverlay>();
			return true;
		}

		private void Update()
		{
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			_timer -= Time.deltaTime;
			if (_timer > 0f)
			{
				return;
			}
			_timer = 0.5f;
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null || (Object)(object)Chat.instance == (Object)null)
			{
				return;
			}
			foreach (Settler item in Settler.Loaded)
			{
				if ((Object)(object)item != (Object)null && Vector3.Distance(((Component)item).transform.position, ((Component)localPlayer).transform.position) <= 40f)
				{
					Show(((Component)item).gameObject, item.DebugText());
				}
			}
		}

		private static void Show(GameObject settler, string text)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			NpcText val = Chat.instance.FindNpcText(settler);
			if (val != null)
			{
				val.m_text = text;
				val.m_ttl = 1.5f;
				val.UpdateText();
			}
			else
			{
				Chat.instance.SetNpcText(settler, Offset, 40f, 1.5f, "", text, false);
			}
		}

		private static void ClearTexts()
		{
			if ((Object)(object)Chat.instance == (Object)null)
			{
				return;
			}
			foreach (Settler item in Settler.Loaded)
			{
				if ((Object)(object)item != (Object)null)
				{
					Chat.instance.ClearNpcText(((Component)item).gameObject);
				}
			}
		}
	}
	internal sealed class HelpWindow : AojWindow
	{
		private const float Width = 1000f;

		private const float Height = 680f;

		private const float ChapterWidth = 230f;

		private const float ChapterHeight = 32f;

		private const float PaneWidth = 700f;

		private const float PaneHeight = 540f;

		private const int BodySize = 16;

		private static readonly string[] Chapters = new string[14]
		{
			"start", "settlers", "orders", "work", "storage", "needs", "army", "map", "portals", "coop",
			"keys", "console", "settings", "about"
		};

		private static HelpWindow s_instance;

		private readonly List<Text> _chapterLabels = new List<Text>();

		private Text _title;

		private Text _body;

		private RectTransform _bodyRect;

		private RectTransform _content;

		private ScrollRect _scroll;

		private int _chapter = -1;

		internal static void Poll()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			if (AoJConfig.HelpKey != null && (int)AoJConfig.HelpKey.Value != 0 && !((Object)(object)Player.m_localPlayer == (Object)null) && ZInput.GetKeyDown(AoJConfig.HelpKey.Value, true))
			{
				if ((Object)(object)s_instance != (Object)null && ((Component)s_instance).gameObject.activeSelf)
				{
					s_instance.Hide();
				}
				else if (!Console.IsVisible() && (!((Object)(object)Chat.instance != (Object)null) || !Chat.instance.HasFocus()) && !TextInput.IsVisible() && !Minimap.InTextInput() && !Menu.IsVisible() && !InventoryGui.IsVisible() && !StoreGui.IsVisible())
				{
					Open();
				}
			}
		}

		internal static void Open()
		{
			if (!((Object)(object)GUIManager.CustomGUIFront == (Object)null))
			{
				if ((Object)(object)s_instance == (Object)null)
				{
					s_instance = AojWindow.CreateWindow<HelpWindow>("AoJ_HelpWindow", 1000f, 680f);
				}
				s_instance.ShowWindow();
				s_instance.ShowChapter(Mathf.Max(0, s_instance._chapter));
			}
		}

		protected override void Build(Transform root)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: 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_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Expected O, but got Unknown
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Expected O, but got Unknown
			//IL_0174: 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_017a: 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_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_019b: 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_01d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ff: Expected O, but got Unknown
			//IL_021b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0225: Expected O, but got Unknown
			//IL_0235: Unknown result type (might be due to invalid IL or missing references)
			//IL_024f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0269: Unknown result type (might be due to invalid IL or missing references)
			//IL_0279: Unknown result type (might be due to invalid IL or missing references)
			//IL_0293: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e2: 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_0316: 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_03c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0401: Unknown result type (might be due to invalid IL or missing references)
			Color valheimBeige = GUIManager.Instance.ValheimBeige;
			Color valheimOrange = GUIManager.Instance.ValheimOrange;
			AojWindow.Label(root, new Vector2(0f, 306f), 26, valheimOrange, 960f, 40f, (TextAnchor)4).text = AojWindow.Localize("$aoj_help_title", "0.8.0");
			float num = -355f;
			float num2 = 250f;
			for (int i = 0; i < Chapters.Length; i++)
			{
				int index = i;
				Text item = AojWindow.Button(root, "$aoj_help_" + Chapters[i], new Vector2(num, num2 - (float)i * 38f), 230f, delegate
				{
					ShowChapter(index);
				}, 32f);
				_chapterLabels.Add(item);
			}
			float num3 = 120f;
			_title = AojWindow.Label(root, new Vector2(num3, 256f), 22, valheimOrange, 700f, 36f, (TextAnchor)3);
			GameObject val = new GameObject("Pane", new Type[4]
			{
				typeof(RectTransform),
				typeof(Image),
				typeof(RectMask2D),
				typeof(ScrollRect)
			});
			val.transform.SetParent(root, false);
			RectTransform val2 = (RectTransform)val.transform;
			Vector2 val3 = (val2.pivot = AojWindow.Center);
			Vector2 anchorMin = (val2.anchorMax = val3);
			val2.anchorMin = anchorMin;
			val2.anchoredPosition = new Vector2(num3, -40f);
			val2.sizeDelta = new Vector2(700f, 540f);
			((Graphic)val.GetComponent<Image>()).color = new Color(0f, 0f, 0f, 0.25f);
			GameObject val5 = new GameObject("Content", new Type[1] { typeof(RectTransform) });
			val5.transform.SetParent(val.transform, false);
			_content = (RectTransform)val5.transform;
			_content.anchorMin = new Vector2(0f, 1f);
			_content.anchorMax = new Vector2(1f, 1f);
			_content.pivot = new Vector2(0.5f, 1f);
			_content.anchoredPosition = Vector2.zero;
			_content.sizeDelta = new Vector2(0f, 540f);
			_body = AojWindow.Label((Transform)(object)_content, Vector2.zero, 16, valheimBeige, 676f, 540f, (TextAnchor)0);
			_bodyRect = ((Component)_body).GetComponent<RectTransform>();
			_bodyRect.anchorMin = new Vector2(0.5f, 1f);
			_bodyRect.anchorMax = new Vector2(0.5f, 1f);
			_bodyRect.pivot = new Vector2(0.5f, 1f);
			_bodyRect.anchoredPosition = new Vector2(0f, -8f);
			_body.horizontalOverflow = (HorizontalWrapMode)0;
			_body.verticalOverflow = (VerticalWrapMode)1;
			_scroll = val.GetComponent<ScrollRect>();
			_scroll.content = _content;
			_scroll.viewport = val2;
			_scroll.horizontal = false;
			_scroll.vertical = true;
			_scroll.movementType = (MovementType)2;
			_scroll.scrollSensitivity = 40f;
			_scroll.inertia = true;
			AojWindow.Label(root, new Vector2(num3, -298f), 13, valheimBeige, 700f, 24f, (TextAnchor)3).text = AojWindow.Localize("$aoj_help_scroll_hint");
			AojWindow.Button(root, "$aoj_btn_close", new Vector2(395f, -300f), 150f, base.Hide);
		}

		protected override bool IsTargetValid()
		{
			return (Object)(object)Player.m_localPlayer != (Object)null;
		}

		protected override void Refresh()
		{
		}

		private void ShowChapter(int index)
		{
			//IL_0070: 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_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			if (index >= 0 && index < Chapters.Length && !((Object)(object)_body == (Object)null))
			{
				_chapter = index;
				string text = Chapters[index];
				_title.text = AojWindow.Localize("$aoj_help_" + text);
				string text2 = AojWindow.Localize("$aoj_help_" + text + "_text").Replace("{wheel}", KeyName(AoJConfig.CommandWheelKey.Value)).Replace("{zone}", KeyName(AoJConfig.ZoneKey.Value))
					.Replace("{help}", KeyName(AoJConfig.HelpKey.Value))
					.Replace("{version}", "0.8.0")
					.Replace("{config}", "com.damia.ageofjarls.cfg");
				_body.text = text2;
				float num = Mathf.Max(540f, _body.preferredHeight + 24f);
				_bodyRect.sizeDelta = new Vector2(676f, num);
				_content.sizeDelta = new Vector2(0f, num);
				_scroll.verticalNormalizedPosition = 1f;
				for (int i = 0; i < _chapterLabels.Count; i++)
				{
					((Graphic)_chapterLabels[i]).color = ((i == index) ? GUIManager.Instance.ValheimOrange : GUIManager.Instance.ValheimBeige);
				}
			}
		}

		private unsafe static string KeyName(KeyCode key)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			if ((int)key != 0)
			{
				return ((object)(*(KeyCode*)(&key))/*cast due to .constrained prefix*/).ToString();
			}
			return "-";
		}
	}
	internal sealed class JarlTableWindow : AojWindow
	{
		private sealed class MemberRow
		{
			internal GameObject Root;

			internal Text Name;

			internal Text Rank;

			internal GameObject Up;

			internal GameObject Down;

			internal GameObject Jarl;

			internal Text JarlLabel;

			internal GameObject Remove;

			internal Text RemoveLabel;

			internal long PlayerId;
		}

		private sealed class CandidateRow
		{
			internal GameObject Root;

			internal Text Name;

			internal GameObject Admit;

			internal GameObject CoJarl;

			internal Player Player;
		}

		private sealed class Row
		{
			internal GameObject Root;

			internal Text Name;

			internal Text Status;

			internal GameObject Buttons;

			internal GameObject Dismiss;

			internal Text DismissLabel;

			internal long Uid;
		}

		private const float Width = 840f;

		private const float Height = 680f;

		private const float MaxDistance = 12f;

		private const float CandidateRange = 20f;

		private const int RowsPerPage = 8;

		private const float RowHeight = 46f;

		private const float FirstRowY = 160f;

		private const float ConfirmSeconds = 3f;

		private const int MaxChestLines = 12;

		private const int MaxTotals = 24;

		private static JarlTableWindow s_instance;

		private readonly List<Container> _chests = new List<Container>();

		private readonly Row[] _rows = new Row[8];

		private JarlTable _table;

		private Text _title;

		private Text _summary;

		private Text _hint;

		private GameObject _liveControls;

		private GameObject _manageControls;

		private const int MemberRows = 6;

		private const float MemberRowHeight = 40f;

		private const float FirstMemberY = 135f;

		private const int MaxCandidates = 2;

		private readonly MemberRow[] _memberRows = new MemberRow[6];

		private readonly CandidateRow[] _candidateRows = new CandidateRow[2];

		private Text _membersHeader;

		private Text _membersBonus;

		private Text _candidatesLabel;

		private GameObject _memberPager;

		private Text _memberPageLabel;

		private int _memberPage;

		private long _confirmMember;

		private string _confirmAction = "";

		private float _confirmMemberUntil;

		private Text _rosterHeader;

		private Text _pageLabel;

		private int _page;

		private long _confirmUid;

		private float _confirmUntil;

		private Text _totals;

		private Text _chestList;

		private Text _work;

		private GameObject _workControls;

		private Text _manualWorkLabel;

		private Text _defense;

		private Text _alarmLabel;

		private GameObject _defenseControls;

		private Text _chronicle;

		internal static void Open(JarlTable table)
		{
			if (!((Object)(object)GUIManager.CustomGUIFront == (Object)null) && !((Object)(object)table == (Object)null))
			{
				if ((Object)(object)s_instance == (Object)null)
				{
					s_instance = AojWindow.CreateWindow<JarlTableWindow>("AoJ_JarlTableWindow", 840f, 680f);
				}
				s_instance._table = table;
				s_instance._page = 0;
				s_instance._memberPage = 0;
				s_instance.TextEntry.text = "";
				s_instance.ShowWindow();
			}
		}

		protected override void Build(Transform root)
		{
			//IL_000c: 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_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			_title = AojWindow.Label(root, new Vector2(0f, 300f), 26, GUIManager.Instance.ValheimOrange, 800f, 40f, (TextAnchor)4);
			Transform val = AojWindow.Page(root, "Overview");
			Transform val2 = AojWindow.Page(root, "Members");
			Transform val3 = AojWindow.Page(root, "Settlers");
			Transform val4 = AojWindow.Page(root, "Work");
			Transform val5 = AojWindow.Page(root, "Storage");
			Transform val6 = AojWindow.Page(root, "Defense");
			Transform val7 = AojWindow.Page(root, "Chronicle");
			BuildOverview(val);
			BuildMembers(val2);
			BuildSettlers(val3);
			BuildStorage(val5);
			_work = AojWindow.Label(val4, new Vector2(0f, 0f), 15, GUIManager.Instance.ValheimBeige, 780f, 430f, (TextAnchor)0);
			_workControls = ((Component)AojWindow.Page(val4, "WorkControls")).gameObject;
			_manualWorkLabel = AojWindow.Button(_workControls.transform, "", new Vector2(0f, -245f), 420f, ToggleManualWork, 30f);
			BuildDefense(val6);
			_chronicle = AojWindow.Label(val7, new Vector2(0f, -20f), 15, GUIManager.Instance.ValheimBeige, 780f, 470f, (TextAnchor)0);
			AojWindow.Button(root, "$aoj_close", new Vector2(0f, -300f), 200f, base.Hide);
			Tabs(root, 252f, 106f, ("$aoj_tab_overview", val), ("$aoj_tab_members", val2), ("$aoj_tab_settlers", val3), ("$aoj_tab_work", val4), ("$aoj_tab_storage", val5), ("$aoj_tab_defense", val6), ("$aoj_tab_chronicle", val7));
		}

		private void BuildDefense(Transform page)
		{
			//IL_000c: 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_0063: Unknown result type (might be due to invalid IL or missing references)
			_defense = AojWindow.Label(page, new Vector2(0f, -10f), 15, GUIManager.Instance.ValheimBeige, 780f, 420f, (TextAnchor)0);
			_defenseControls = ((Component)AojWindow.Page(page, "DefenseControls")).gameObject;
			_alarmLabel = AojWindow.Button(_defenseControls.transform, "", new Vector2(0f, -240f), 300f, ToggleAlarm);
		}

		private void ToggleAlarm()
		{
			if ((Object)(object)_table != (Object)null)
			{
				_table.RequestAlarm(!_table.AlarmOn);
			}
		}

		private void BuildOverview(Transform page)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: 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_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			Color valheimBeige = GUIManager.Instance.ValheimBeige;
			_summary = AojWindow.Label(page, new Vector2(-170f, 20f), 17, valheimBeige, 440f, 360f, (TextAnchor)0);
			_hint = AojWindow.Label(page, new Vector2(0f, -240f), 15, valheimBeige, 780f, 30f, (TextAnchor)4);
			_liveControls = ((Component)AojWindow.Page(page, "Live")).gameObject;
			_manageControls = ((Component)AojWindow.Page(page, "Manage")).gameObject;
			Transform transform = _liveControls.transform;
			Transform transform2 = _manageControls.transform;
			AojWindow.Button(transform, "$aoj_accept_followers_short", new Vector2(235f, 170f), 300f, delegate
			{
				Act(delegate(JarlTable t)
				{
					t.AcceptFollowers(Player.m_localPlayer);
				});
			});
			AojWindow.Button(transform2, "$aoj_upgrade", new Vector2(235f, 120f), 300f, delegate
			{
				Act(delegate(JarlTable t)
				{
					t.TryUpgrade(Player.m_localPlayer);
				});
			});
			TextEntry = AojWindow.TextInput(transform2, "$aoj_settlement_name", new Vector2(235f, 50f), 300f);
			AojWindow.Button(transform2, "$aoj_rename_settlement", new Vector2(235f, 2f), 300f, Rename);
			AojWindow.Button(transform, "$aoj_feast", new Vector2(235f, -48f), 300f, delegate
			{
				Act(delegate(JarlTable t)
				{
					t.TryFeast(Player.m_localPlayer);
				});
			});
		}

		private void BuildMembers(Transform page)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_023f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0246: Unknown result type (might be due to invalid IL or missing references)
			//IL_028c: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_038e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0395: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0445: Unknown result type (might be due to invalid IL or missing references)
			//IL_044c: Unknown result type (might be due to invalid IL or missing references)
			Color valheimBeige = GUIManager.Instance.ValheimBeige;
			Color valheimOrange = GUIManager.Instance.ValheimOrange;
			_membersHeader = AojWindow.Label(page, new Vector2(0f, 205f), 16, valheimOrange, 780f, 30f, (TextAnchor)3);
			_membersBonus = AojWindow.Label(page, new Vector2(0f, 176f), 14, valheimBeige, 780f, 28f, (TextAnchor)3);
			for (int i = 0; i < 6; i++)
			{
				int index = i;
				float num = 135f - (float)i * 40f;
				MemberRow memberRow = new MemberRow
				{
					Root = ((Component)AojWindow.Page(page, "Member" + i)).gameObject
				};
				Transform transform = memberRow.Root.transform;
				memberRow.Name = AojWindow.Label(transform, new Vector2(-290f, num), 17, valheimOrange, 220f, 40f, (TextAnchor)3);
				memberRow.Rank = AojWindow.Label(transform, new Vector2(-115f, num), 15, valheimBeige, 120f, 40f, (TextAnchor)3);
				memberRow.Up = ButtonObject(AojWindow.Button(transform, "$aoj_btn_promote", new Vector2(20f, num), 84f, delegate
				{
					ChangeRank(index, 1);
				}, 30f));
				memberRow.Down = ButtonObject(AojWindow.Button(transform, "$aoj_btn_demote", new Vector2(110f, num), 84f, delegate
				{
					ChangeRank(index, -1);
				}, 30f));
				memberRow.JarlLabel = AojWindow.Button(transform, "$aoj_btn_cojarl", new Vector2(200f, num), 84f, delegate
				{
					MemberJarl(index);
				}, 30f);
				memberRow.Jarl = ButtonObject(memberRow.JarlLabel);
				memberRow.RemoveLabel = AojWindow.Button(transform, "$aoj_btn_remove", new Vector2(290f, num), 84f, delegate
				{
					MemberRemove(index);
				}, 30f);
				memberRow.Remove = ButtonObject(memberRow.RemoveLabel);
				_memberRows[i] = memberRow;
			}
			_candidatesLabel = AojWindow.Label(page, new Vector2(-190f, -100f), 15, valheimOrange, 400f, 28f, (TextAnchor)3);
			_memberPager = ((Component)AojWindow.Page(page, "Pager")).gameObject;
			AojWindow.Button(_memberPager.transform, "<", new Vector2(250f, -100f), 50f, delegate
			{
				TurnMemberPage(-1);
			}, 30f);
			_memberPageLabel = AojWindow.Label(_memberPager.transform, new Vector2(315f, -100f), 16, valheimBeige, 70f, 28f, (TextAnchor)4);
			AojWindow.Button(_memberPager.transform, ">", new Vector2(380f, -100f), 50f, delegate
			{
				TurnMemberPage(1);
			}, 30f);
			for (int num2 = 0; num2 < 2; num2++)
			{
				int index2 = num2;
				float num3 = -135f - (float)num2 * 40f;
				CandidateRow candidateRow = new CandidateRow
				{
					Root = ((Component)AojWindow.Page(page, "Candidate" + num2)).gameObject
				};
				Transform transform2 = candidateRow.Root.transform;
				candidateRow.Name = AojWindow.Label(transform2, new Vector2(-290f, num3), 16, valheimBeige, 220f, 40f, (TextAnchor)3);
				candidateRow.Admit = ButtonObject(AojWindow.Button(transform2, "$aoj_btn_admit", new Vector2(65f, num3), 174f, delegate
				{
					Admit(index2, SettlementRole.Karl);
				}, 30f));
				candidateRow.CoJarl = ButtonObject(AojWindow.Button(transform2, "$aoj_btn_admit_jarl", new Vector2(245f, num3), 174f, delegate
				{
					Admit(index2, SettlementRole.Jarl);
				}, 30f));
				_candidateRows[num2] = candidateRow;
			}
			AojWindow.Label(page, new Vector2(0f, -228f), 13, valheimBeige, 780f, 56f, (TextAnchor)0).text = AojWindow.Localize("$aoj_ranks_help");
		}

		private static GameObject ButtonObject(Text label)
		{
			return ((Component)((Component)label).GetComponentInParent<Button>()).gameObject;
		}

		private void BuildSettlers(Transform page)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: 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_00e5: 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_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0203: Unknown result type (might be due to invalid IL or missing references)
			//IL_0230: Unknown result type (might be due to invalid IL or missing references)
			//IL_0237: Unknown result type (might be due to invalid IL or missing references)
			//IL_025d: Unknown result type (might be due to invalid IL or missing references)
			Color valheimBeige = GUIManager.Instance.ValheimBeige;
			_rosterHeader = AojWindow.Label(page, new Vector2(0f, 205f), 16, GUIManager.Instance.ValheimOrange, 780f, 30f, (TextAnchor)3);
			for (int i = 0; i < 8; i++)
			{
				int index = i;
				float num = 160f - (float)i * 46f;
				Row row = new Row
				{
					Root = ((Component)AojWindow.Page(page, "Row" + i)).gameObject
				};
				row.Name = AojWindow.Label(row.Root.transform, new Vector2(-265f, num), 17, GUIManager.Instance.ValheimOrange, 250f, 46f, (TextAnchor)3);
				row.Status = AojWindow.Label(row.Root.transform, new Vector2(-15f, num), 14, valheimBeige, 250f, 46f, (TextAnchor)3);
				row.Buttons = ((Component)AojWindow.Page(row.Root.transform, "Buttons")).gameObject;
				AojWindow.Button(row.Buttons.transform, "$aoj_btn_follow", new Vector2(175f, num), 84f, delegate
				{
					RowFollow(index);
				}, 30f);
				AojWindow.Button(row.Buttons.transform, "$aoj_btn_home", new Vector2(265f, num), 84f, delegate
				{
					RowGoHome(index);
				}, 30f);
				row.DismissLabel = AojWindow.Button(row.Buttons.transform, "$aoj_btn_dismiss", new Vector2(355f, num), 84f, delegate
				{
					RowDismiss(index);
				}, 30f);
				row.Dismiss = ButtonObject(row.DismissLabel);
				_rows[i] = row;
			}
			AojWindow.Button(page, "<", new Vector2(-90f, -230f), 60f, delegate
			{
				TurnPage(-1);
			}, 30f);
			_pageLabel = AojWindow.Label(page, new Vector2(0f, -230f), 16, valheimBeige, 120f, 30f, (TextAnchor)4);
			AojWindow.Button(page, ">", new Vector2(90f, -230f), 60f, delegate
			{
				TurnPage(1);
			}, 30f);
		}

		private void BuildStorage(Transform page)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: 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_0047: Unknown result type (might be due to invalid IL or missing references)
			Color valheimBeige = GUIManager.Instance.ValheimBeige;
			_totals = AojWindow.Label(page, new Vector2(0f, 175f), 16, valheimBeige, 780f, 70f, (TextAnchor)0);
			_chestList = AojWindow.Label(page, new Vector2(0f, -40f), 14, valheimBeige, 780f, 340f, (TextAnchor)0);
		}

		protected override bool IsTargetValid()
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)_table != (Object)null && _table.Data != null && (Object)(object)localPlayer != (Object)null && !((Character)localPlayer).IsDead())
			{
				return Vector3.Distance(((Component)localPlayer).transform.position, ((Component)_table).transform.position) <= 12f;
			}
			return false;
		}

		protected override void Refresh()
		{
			SettlementData data = _table.Data;
			_title.text = JarlTable.DisplayName(data);
			switch (base.ActiveTab)
			{
			case 0:
				RefreshOverview(data);
				break;
			case 1:
				RefreshMembers(data);
				break;
			case 2:
				RefreshSettlers(data);
				break;
			case 3:
				_work.text = AojWindow.Localize(WorkText(data));
				_workControls.SetActive(May(SettlementRight.Manage));
				_manualWorkLabel.text = AojWindow.Localize(_table.ManualWork ? "$aoj_work_manual" : "$aoj_work_auto");
				break;
			case 4:
				RefreshStorage(data);
				break;
			case 5:
				RefreshDefense(data);
				break;
			default:
				_chronicle.text = Chronicle.Describe(_table.NetView.GetZDO(), 22);
				break;
			}
		}

		protected override void OnHidden()
		{
			_table = null;
			_chests.Clear();
			CandidateRow[] candidateRows = _candidateRows;
			for (int i = 0; i < candidateRows.Length; i++)
			{
				candidateRows[i].Player = null;
			}
		}

		private bool May(SettlementRight right)
		{
			if ((Object)(object)_table != (Object)null)
			{
				return _table.RoleOf(Player.m_localPlayer).Allows(right);
			}
			return false;
		}

		private void RefreshOverview(SettlementData data)
		{
			SettlementRole role = _table.RoleOf(Player.m_localPlayer);
			List<Settler> list = (from s in data.Settlers
				select Settler.FindByUid(s.Uid) into s
				where (Object)(object)s != (Object)null && s.Zdo != null
				select s).ToList();
			int num = list.Count((Settler s) => s.IsAtHome);
			float num2 = ((list.Count > 0) ? list.Average((Settler s) => Needs.Morale(s.Zdo)) : 0f);
			float radius = JarlTable.RadiusOf(data);
			int num3 = SettlementCauldron.Loaded.Where((SettlementCauldron c) => (Object)(object)c != (Object)null && Vector3.Distance(((Component)c).transform.position, ((Component)_table).transform.position) <= radius).Sum((SettlementCauldron c) => c.Servings());
			float num4 = ((data.Settlers.Count > 0) ? ((float)num3 / ((float)data.Settlers.Count * 2f)) : 0f);
			List<string> list2 = new List<string>();
			int num5 = data.Settlers.Count - data.SettlersWithBed;
			if (num5 > 0)
			{
				list2.Add(AojWindow.Localize("$aoj_alert_beds", num5.ToString()));
			}
			if (data.Settlers.Count > 0 && num3 == 0)
			{
				list2.Add(AojWindow.Localize("$aoj_alert_food"));
			}
			if (list.Any((Settler s) => s.JobProblem.Length > 0))
			{
				list2.Add(AojWindow.Localize("$aoj_alert_work"));
			}
			string text = ((_table.FeastUntil > WorldClock.Now) ? "  ·  $aoj_feast_on" : "");
			_summary.text = AojWindow.Localize(_table.BuildSummary(data) + "\n\n$aoj_settlers: " + JarlTable.BuildRosterText(data) + $"\n$aoj_at_home: {num}/{data.Settlers.Count}  ·  $aoj_morale: {Mathf.RoundToInt(num2)}{text}" + $"\n$aoj_food: {num3} ($aoj_food_days {num4:0.0})" + ((list2.Count > 0) ? ("\n<color=#ff9060>" + string.Join("\n", list2) + "</color>") : ""));
			bool flag = role.Allows(SettlementRight.Live);
			bool flag2 = role.Allows(SettlementRight.Manage);
			_liveControls.SetActive(flag);
			_manageControls.SetActive(flag2);
			_hint.text = ((!flag) ? AojWindow.Localize("$aoj_read_only") : ((!flag2) ? AojWindow.Localize("$aoj_rank_hint", AojWindow.Localize(Permissions.Token(role))) : ""));
		}

		private void RefreshMembers(SettlementData data)
		{
			Player me = Player.m_localPlayer;
			long num = (((Object)(object)me != (Object)null) ? me.GetPlayerID() : 0);
			int num2 = JarlTable.ExtraMembers(data);
			_membersHeader.text = AojWindow.Localize("$aoj_members_header", data.Members.Count.ToString(), data.JarlCount.ToString(), AoJConfig.MaxJarls.Value.ToString());
			_membersBonus.text = AojWindow.Localize("$aoj_members_bonus", JarlTable.CapacityOf(data).ToString(), JarlTable.CapacityFor(data.Tier).ToString(), Mathf.RoundToInt(JarlTable.RadiusOf(data)).ToString(), Mathf.RoundToInt(JarlTable.RadiusFor(da