Decompiled source of Innangard v0.0.8

plugins/Innangard.dll

Decompiled 6 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Threading;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Innangard.Blueprints;
using Innangard.Jobs;
using Innangard.UI;
using Jotunn;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using Splatform;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.Rendering;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("assembly_guiutils")]
[assembly: IgnoresAccessChecksTo("assembly_valheim")]
[assembly: AssemblyCompany("Innangard")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.0.8.0")]
[assembly: AssemblyInformationalVersion("0.0.8")]
[assembly: AssemblyProduct("Innangard")]
[assembly: AssemblyTitle("Innangard")]
[assembly: IgnoresAccessChecksTo("assembly_utils")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.8.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 Innangard
{
	[HarmonyPatch(typeof(WearNTear), "Destroy")]
	internal static class BaseDestroyedPatch
	{
		[HarmonyPrefix]
		private static void Prefix(WearNTear __instance, HitData hitData)
		{
			if (hitData != null)
			{
				SettlementAlarm.StructureLost(__instance, hitData.GetAttacker());
			}
		}
	}
	[Flags]
	internal enum CaretakerDuties
	{
		None = 0,
		Mending = 1,
		Sorting = 2,
		Fires = 4,
		MachineFuel = 8,
		MachineInput = 0x10,
		Gathering = 0x20,
		All = 0x3F
	}
	internal sealed class ChestSortPanel : MonoBehaviour
	{
		private sealed class ItemChoice
		{
			internal string SharedName;

			internal string DisplayName;

			internal Sprite Icon;

			internal Button Button;
		}

		[HarmonyPatch(typeof(Container), "Interact")]
		private static class OpenPatch
		{
			[HarmonyPrefix]
			private static bool Prefix(Container __instance, Humanoid character, bool hold, ref bool __result)
			{
				if (!hold)
				{
					Player val = (Player)(object)((character is Player) ? character : null);
					if (val != null && !((Object)(object)val != (Object)(object)Player.m_localPlayer))
					{
						if (!ModifierHeld() || !ChestSortRules.CanConfigure(__instance, val.GetPlayerID()))
						{
							return true;
						}
						Toggle(__instance);
						__result = true;
						return false;
					}
				}
				return true;
			}

			private static bool ModifierHeld()
			{
				if (!ZInput.GetButton("Run") && !Input.GetKey((KeyCode)304))
				{
					return Input.GetKey((KeyCode)303);
				}
				return true;
			}
		}

		private const float PanelWidth = 660f;

		private const float PanelHeight = 740f;

		private const float TitleHeight = 40f;

		private const float Edge = 14f;

		private const float Gap = 8f;

		private const float MaxUseDistance = 10f;

		private const float BetweenRefreshes = 0.25f;

		private const float ItemButtonHeight = 40f;

		private const float IconSize = 28f;

		private static readonly (IntakeRoles Role, string LabelKey)[] IntakeChoices = new(IntakeRoles, string)[8]
		{
			(IntakeRoles.Lumberjack, "$inn_trade_lumberjack"),
			(IntakeRoles.Miner, "$inn_trade_miner"),
			(IntakeRoles.Farmer, "$inn_trade_farmer"),
			(IntakeRoles.Forager, "$inn_trade_forager"),
			(IntakeRoles.Hunter, "$inn_trade_hunter"),
			(IntakeRoles.Fisherman, "$inn_role_fisherman"),
			(IntakeRoles.Cook, "$inn_trade_cook"),
			(IntakeRoles.Builder, "$inn_role_builder")
		};

		private static ChestSortPanel _instance;

		private Container _container;

		private GameObject _panel;

		private bool _blocking;

		private float _scaledAt = -1f;

		private float _nextRefresh;

		private bool _wasConfigured;

		private HashSet<string> _selected = new HashSet<string>(StringComparer.Ordinal);

		private readonly List<ItemChoice> _choices = new List<ItemChoice>();

		private Text _intakeState;

		private Text _intakeNoFrithstone;

		private RectTransform _intakeControls;

		private Button _intakeRemove;

		private readonly List<Button> _roleButtons = new List<Button>();

		private Text _origin;

		private InputField _search;

		private RectTransform _grid;

		private Text _noMatch;

		private Text _chosenCount;

		private RectTransform _list;

		private ScrollRect _scroll;

		private static SettlerRole TradeOf(IntakeRoles role)
		{
			return role switch
			{
				IntakeRoles.Lumberjack => SettlerRole.Lumberjack, 
				IntakeRoles.Miner => SettlerRole.Miner, 
				IntakeRoles.Farmer => SettlerRole.Farmer, 
				IntakeRoles.Forager => SettlerRole.Forager, 
				IntakeRoles.Hunter => SettlerRole.Hunter, 
				IntakeRoles.Fisherman => SettlerRole.Fisherman, 
				IntakeRoles.Cook => SettlerRole.Cook, 
				IntakeRoles.Builder => SettlerRole.Builder, 
				_ => SettlerRole.Idle, 
			};
		}

		internal static void Toggle(Container container)
		{
			if ((Object)(object)_instance == (Object)null)
			{
				GameObject val = (((Object)(object)InnangardPlugin.Instance != (Object)null) ? ((Component)InnangardPlugin.Instance).gameObject : null);
				if ((Object)(object)val == (Object)null)
				{
					return;
				}
				_instance = val.AddComponent<ChestSortPanel>();
			}
			if ((Object)(object)_instance._container == (Object)(object)container)
			{
				_instance.Close();
			}
			else
			{
				_instance.Open(container);
			}
		}

		private void Awake()
		{
			GUIManager.OnCustomGUIAvailable += Forget;
		}

		private void OnDestroy()
		{
			GUIManager.OnCustomGUIAvailable -= Forget;
			Release();
			if ((Object)(object)_instance == (Object)(object)this)
			{
				_instance = null;
			}
		}

		private void Forget()
		{
			_panel = null;
			_container = null;
			_choices.Clear();
			_roleButtons.Clear();
			_scaledAt = -1f;
			Release();
		}

		private void Open(Container container)
		{
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null || !ChestSortRules.CanConfigure(container, localPlayer.GetPlayerID()))
			{
				return;
			}
			try
			{
				if (Build())
				{
					_container = container;
					_wasConfigured = ChestSortRules.IsConfigured(container);
					_selected = ChestSortRules.ReadItems(container);
					Populate(BuildChoices(container, _selected));
					_search.text = string.Empty;
					_panel.SetActive(true);
					Block();
					Refresh();
				}
			}
			catch (Exception ex)
			{
				Logger.LogError((object)("Innangard[stores]: the sorting window failed to open: " + ex));
				Close();
			}
		}

		private void Close()
		{
			_container = null;
			if ((Object)(object)_panel != (Object)null)
			{
				_panel.SetActive(false);
			}
			Release();
		}

		private void Block()
		{
			if (!_blocking)
			{
				_blocking = true;
				GUIManager.BlockInput(true);
			}
		}

		private void Release()
		{
			if (_blocking)
			{
				_blocking = false;
				GUIManager.BlockInput(false);
			}
		}

		private void Update()
		{
			//IL_0036: 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)
			if ((Object)(object)_container == (Object)null)
			{
				return;
			}
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null || !((Component)_container).gameObject.activeInHierarchy || Vector3.Distance(((Component)localPlayer).transform.position, ((Component)_container).transform.position) > 10f || Input.GetKeyDown((KeyCode)27))
			{
				Close();
				return;
			}
			Cursor.lockState = (CursorLockMode)0;
			Cursor.visible = true;
			if (Time.unscaledTime >= _nextRefresh)
			{
				_nextRefresh = Time.unscaledTime + 0.25f;
				Refresh();
			}
		}

		private bool Build()
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: 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_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_01a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b1: Expected O, but got Unknown
			//IL_01d1: 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)
			if ((Object)(object)_panel != (Object)null)
			{
				return true;
			}
			Transform val = (((Object)(object)GUIManager.CustomGUIFront != (Object)null) ? GUIManager.CustomGUIFront.transform : null);
			if ((Object)(object)val == (Object)null || GUIManager.Instance == null)
			{
				return false;
			}
			_panel = GUIManager.Instance.CreateWoodpanel(val, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), Vector2.zero, 660f, 740f, true);
			if ((Object)(object)_panel == (Object)null)
			{
				return false;
			}
			((Object)_panel).name = "inn_chest_panel";
			RectTransform obj = Child("inn_chest_title", _panel.transform);
			obj.anchorMin = new Vector2(0f, 1f);
			obj.anchorMax = new Vector2(1f, 1f);
			obj.pivot = new Vector2(0.5f, 1f);
			obj.anchoredPosition = new Vector2(0f, -14f);
			obj.sizeDelta = new Vector2(-28f, 40f);
			InnangardGui.Fill(((Graphic)InnangardGui.Write((Transform)(object)obj, Localization.instance.Localize("$inn_stores_filter_title"), 22, GUIManager.Instance.ValheimOrange, (TextAnchor)4)).rectTransform);
			((UnityEvent)GUIManager.Instance.CreateButton("x", _panel.transform, new Vector2(1f, 1f), new Vector2(1f, 1f), new Vector2(-30f, -30f), 32f, 32f).GetComponent<Button>().onClick).AddListener(new UnityAction(Close));
			RectTransform obj2 = Child("inn_chest_body", _panel.transform);
			obj2.offsetMin = new Vector2(14f, 14f);
			obj2.offsetMax = new Vector2(-14f, -62f);
			RectTransform val2 = InnangardGui.Stack(obj2, 8f, fits: false, (TextAnchor)0);
			BuildIntake(val2);
			BuildFilter(val2);
			for (int i = 0; i < ((Transform)val2).childCount; i++)
			{
				GameObject gameObject = ((Component)((Transform)val2).GetChild(i)).gameObject;
				if ((Object)(object)gameObject != (Object)(object)((Component)_list).gameObject)
				{
					(gameObject.GetComponent<LayoutElement>() ?? gameObject.AddComponent<LayoutElement>()).flexibleHeight = 0f;
				}
			}
			return true;
		}

		private void BuildIntake(RectTransform column)
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			RectTransform val = InnangardGui.Card(InnangardGui.Section(column, "$inn_stores_intake_section"), 4f);
			InnangardGui.Note(val, Localization.instance.Localize("$inn_stores_intake_help"));
			_intakeNoFrithstone = InnangardGui.Note(val, Localization.instance.Localize("$inn_stores_intake_no_frithstone"));
			((Graphic)_intakeNoFrithstone).color = InnangardGui.Warning;
			_intakeControls = InnangardGui.Stack(val, 4f, fits: false, (TextAnchor)0);
			RowWidget rowWidget = InnangardGui.Row(_intakeControls, string.Empty);
			_intakeState = rowWidget.Label;
			rowWidget.Button("$inn_stores_intake_all", 130f, delegate
			{
				RequestIntake(IntakeRoles.All, said: true);
			});
			_intakeRemove = rowWidget.Button("$inn_stores_intake_remove", 190f, delegate
			{
				RequestIntake(IntakeRoles.None, said: false);
			});
			RectTransform parent = InnangardGui.Grid(_intakeControls, 3, 190f, 30f);
			(IntakeRoles, string)[] intakeChoices = IntakeChoices;
			for (int num = 0; num < intakeChoices.Length; num++)
			{
				(IntakeRoles, string) tuple = intakeChoices[num];
				IntakeRoles item = tuple.Item1;
				string item2 = tuple.Item2;
				IntakeRoles which = item;
				Button item3 = InnangardGui.Press(parent, Localization.instance.Localize(item2), 190f, 30f, delegate
				{
					SettlementIntake settlementIntake = CurrentIntake();
					if (settlementIntake != null && (Object)(object)_container != (Object)null)
					{
						IntakeRoles intakeRoles = settlementIntake.RolesOf(_container);
						settlementIntake.Request(_container, ((intakeRoles & which) != IntakeRoles.None) ? (intakeRoles & ~which) : (intakeRoles | which));
					}
				});
				_roleButtons.Add(item3);
			}
		}

		private void BuildFilter(RectTransform column)
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			_origin = InnangardGui.Title(column, string.Empty);
			InnangardGui.Note(column, Localization.instance.Localize("$inn_stores_filter_help"));
			RowWidget rowWidget = InnangardGui.Row(column, "$inn_stores_sort_search", 34f);
			GameObject val = GUIManager.Instance.CreateInputField((Transform)(object)rowWidget.Controls, new Vector2(0f, 0.5f), new Vector2(0f, 0.5f), Vector2.zero, (ContentType)0, string.Empty, 16, 320f, 28f);
			LayoutElement obj = val.AddComponent<LayoutElement>();
			obj.preferredWidth = 320f;
			obj.minWidth = 320f;
			obj.flexibleWidth = 0f;
			obj.preferredHeight = 28f;
			_search = val.GetComponent<InputField>();
			_search.characterLimit = 24;
			((UnityEvent<string>)(object)_search.onValueChanged).AddListener((UnityAction<string>)delegate
			{
				Sort();
			});
			rowWidget.Button("×", 32f, delegate
			{
				_search.text = string.Empty;
				_search.DeactivateInputField();
				Sort();
			});
			RowWidget rowWidget2 = InnangardGui.Row(column, string.Empty, 34f);
			rowWidget2.Button("$inn_stores_filter_from_inside", 280f, delegate
			{
				int count = _selected.Count;
				SelectPresentMaterials();
				Paint();
				Diagnostics.Log($"Innangard[stores]: took the list from the chest - {_selected.Count - count} " + $"new name(s), {_selected.Count} chosen, {_choices.Count} row(s) on offer");
			});
			rowWidget2.Button("$inn_stores_filter_start_over", 150f, delegate
			{
				_selected.Clear();
				Paint();
			});
			RectTransform val2 = InnangardGui.Scroller(column, 4f);
			_scroll = ((Component)val2).GetComponentInParent<ScrollRect>();
			_list = (((Object)(object)_scroll != (Object)null) ? ((Component)_scroll).GetComponent<RectTransform>() : val2);
			Transform val3 = (Transform)(object)val2;
			while ((Object)(object)val3.parent != (Object)null && (Object)(object)val3.parent != (Object)(object)column)
			{
				val3 = val3.parent;
			}
			_list = (RectTransform)(object)((val3 is RectTransform) ? val3 : null);
			_grid = InnangardGui.Grid(val2, 2, 300f, 40f);
			_noMatch = InnangardGui.Note(val2, Localization.instance.Localize("$inn_stores_filter_no_match"));
			RowWidget rowWidget3 = InnangardGui.Row(column, string.Empty, 36f);
			_chosenCount = rowWidget3.Label;
			rowWidget3.Button("$inn_stores_filter_keep", 160f, delegate
			{
				if ((Object)(object)_container != (Object)null)
				{
					ChestSortRules.RequestSet(_container, _selected, configured: true);
					Player localPlayer = Player.m_localPlayer;
					if (localPlayer != null)
					{
						((Character)localPlayer).Message((MessageType)2, "$inn_stores_filter_kept", 0, (Sprite)null, false);
					}
				}
				Close();
			});
			rowWidget3.Button("$inn_stores_filter_use_contents", 220f, delegate
			{
				if ((Object)(object)_container != (Object)null)
				{
					ChestSortRules.RequestSet(_container, Array.Empty<string>(), configured: false);
					Player localPlayer = Player.m_localPlayer;
					if (localPlayer != null)
					{
						((Character)localPlayer).Message((MessageType)2, "$inn_stores_filter_back_to_auto", 0, (Sprite)null, false);
					}
				}
				Close();
			});
			rowWidget3.Button("$inn_tend_close", 90f, Close);
		}

		private void Populate(List<ItemChoice> choices)
		{
			for (int num = ((Transform)_grid).childCount - 1; num >= 0; num--)
			{
				Object.Destroy((Object)(object)((Component)((Transform)_grid).GetChild(num)).gameObject);
			}
			_choices.Clear();
			foreach (ItemChoice choice in choices)
			{
				ItemChoice mine = choice;
				mine.Button = InnangardGui.Press(_grid, choice.DisplayName, 300f, 40f, delegate
				{
					if (!_selected.Remove(mine.SharedName))
					{
						_selected.Add(mine.SharedName);
					}
					Paint();
				});
				IconOn(mine.Button, choice.Icon);
				_choices.Add(mine);
			}
			Sort();
			Paint();
			((MonoBehaviour)this).StartCoroutine(ScrollToTop());
		}

		private IEnumerator ScrollToTop()
		{
			yield return null;
			if ((Object)(object)_scroll != (Object)null)
			{
				Canvas.ForceUpdateCanvases();
				_scroll.verticalNormalizedPosition = 1f;
			}
		}

		private static void IconOn(Button button, Sprite icon)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			Text componentInChildren = ((Component)button).GetComponentInChildren<Text>();
			if ((Object)(object)componentInChildren != (Object)null)
			{
				componentInChildren.alignment = (TextAnchor)3;
				((Graphic)componentInChildren).rectTransform.offsetMin = new Vector2(44f, ((Graphic)componentInChildren).rectTransform.offsetMin.y);
			}
			if (!((Object)(object)icon == (Object)null))
			{
				GameObject val = new GameObject("inn_icon", new Type[2]
				{
					typeof(RectTransform),
					typeof(Image)
				})
				{
					layer = 5
				};
				RectTransform component = val.GetComponent<RectTransform>();
				((Transform)component).SetParent(((Component)button).transform, false);
				((Transform)component).localScale = Vector3.one;
				component.anchorMin = new Vector2(0f, 0.5f);
				component.anchorMax = new Vector2(0f, 0.5f);
				component.pivot = new Vector2(0f, 0.5f);
				component.anchoredPosition = new Vector2(8f, 0f);
				component.sizeDelta = new Vector2(28f, 28f);
				Image component2 = val.GetComponent<Image>();
				component2.sprite = icon;
				component2.preserveAspect = true;
				((Graphic)component2).raycastTarget = false;
			}
		}

		private void Refresh()
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_container == (Object)null || (Object)(object)_panel == (Object)null)
			{
				return;
			}
			float scale = InnGuiSkin.Scale;
			if (!Mathf.Approximately(scale, _scaledAt))
			{
				_scaledAt = scale;
				_panel.transform.localScale = Vector3.one * scale;
			}
			SettlementIntake settlementIntake = CurrentIntake();
			bool flag = settlementIntake != null;
			((Component)_intakeNoFrithstone).gameObject.SetActive(!flag);
			((Component)_intakeControls).gameObject.SetActive(flag);
			if (flag)
			{
				IntakeRoles intakeRoles = settlementIntake.RolesOf(_container);
				bool flag2 = intakeRoles != IntakeRoles.None;
				_intakeState.text = Localization.instance.Localize(flag2 ? "$inn_stores_intake_current" : "$inn_stores_intake_available");
				((Component)_intakeRemove).gameObject.SetActive(flag2);
				for (int i = 0; i < _roleButtons.Count && i < IntakeChoices.Length; i++)
				{
					InnangardGui.Chosen(_roleButtons[i], (intakeRoles & IntakeChoices[i].Role) != 0);
					if (!SettlerRoles.Offered(TradeOf(IntakeChoices[i].Role)))
					{
						InnangardGui.Unusable(_roleButtons[i]);
					}
				}
			}
			_origin.text = Localization.instance.Localize(_wasConfigured ? "$inn_stores_filter_by_hand" : "$inn_stores_filter_from_contents");
		}

		private SettlementIntake CurrentIntake()
		{
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null || (Object)(object)_container == (Object)null)
			{
				return null;
			}
			return SettlementIntake.CandidateFor(_container, localPlayer.GetPlayerID());
		}

		private void RequestIntake(IntakeRoles roles, bool said)
		{
			SettlementIntake settlementIntake = CurrentIntake();
			if (settlementIntake == null || (Object)(object)_container == (Object)null)
			{
				return;
			}
			settlementIntake.Request(_container, roles);
			if (said)
			{
				Player localPlayer = Player.m_localPlayer;
				if (localPlayer != null)
				{
					((Character)localPlayer).Message((MessageType)2, "$inn_stores_intake_saved", 0, (Sprite)null, false);
				}
			}
		}

		private void Paint()
		{
			int num = 0;
			foreach (ItemChoice choice in _choices)
			{
				if (_selected.Contains(choice.SharedName))
				{
					((Component)choice.Button).transform.SetSiblingIndex(num++);
				}
			}
			foreach (ItemChoice choice2 in _choices)
			{
				bool flag = _selected.Contains(choice2.SharedName);
				InnangardGui.Chosen(choice2.Button, flag);
				if (!flag)
				{
					((Component)choice2.Button).transform.SetSiblingIndex(num++);
				}
			}
			_chosenCount.text = string.Format(Localization.instance.Localize("$inn_stores_filter_chosen"), _selected.Count);
			((MonoBehaviour)this).StartCoroutine(ScrollToTop());
		}

		private void Sort()
		{
			string looking = (((Object)(object)_search != (Object)null) ? _search.text : string.Empty).Trim();
			int num = 0;
			foreach (ItemChoice choice in _choices)
			{
				bool flag = Matches(choice, looking);
				if (((Component)choice.Button).gameObject.activeSelf != flag)
				{
					((Component)choice.Button).gameObject.SetActive(flag);
				}
				if (flag)
				{
					num++;
				}
			}
			((Component)_noMatch).gameObject.SetActive(num == 0);
		}

		private static bool Matches(ItemChoice choice, string looking)
		{
			if (string.IsNullOrWhiteSpace(looking))
			{
				return true;
			}
			if (choice.DisplayName.IndexOf(looking, StringComparison.OrdinalIgnoreCase) < 0)
			{
				return choice.SharedName.IndexOf(looking, StringComparison.OrdinalIgnoreCase) >= 0;
			}
			return true;
		}

		private void SelectPresentMaterials()
		{
			Container container = _container;
			Inventory val = ((container != null) ? container.GetInventory() : null);
			if (val == null)
			{
				return;
			}
			foreach (ItemData allItem in val.GetAllItems())
			{
				if (ChestSortRules.IsSortable(allItem))
				{
					_selected.Add(allItem.m_shared.m_name);
				}
			}
		}

		private static List<ItemChoice> BuildChoices(Container container, HashSet<string> selected)
		{
			HashSet<string> hashSet = new HashSet<string>(selected, StringComparer.Ordinal);
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer != (Object)null)
			{
				hashSet.UnionWith(localPlayer.m_knownMaterial);
			}
			Inventory inventory = container.GetInventory();
			if (inventory != null)
			{
				hashSet.UnionWith(from item in inventory.GetAllItems()
					where item != null
					select item.m_shared.m_name);
			}
			List<ItemChoice> list = new List<ItemChoice>();
			if ((Object)(object)ObjectDB.instance == (Object)null)
			{
				return list;
			}
			foreach (GameObject item in ObjectDB.instance.m_items)
			{
				ItemData val = ((item == null) ? null : item.GetComponent<ItemDrop>()?.m_itemData);
				if (ChestSortRules.IsSortable(val) && hashSet.Contains(val.m_shared.m_name))
				{
					list.Add(new ItemChoice
					{
						SharedName = val.m_shared.m_name,
						DisplayName = Localization.instance.Localize(val.m_shared.m_name),
						Icon = val.GetIcon()
					});
				}
			}
			HashSet<string> hashSet2 = new HashSet<string>(list.Select((ItemChoice choice) => choice.SharedName), StringComparer.Ordinal);
			if (inventory != null)
			{
				foreach (ItemData allItem in inventory.GetAllItems())
				{
					if (ChestSortRules.IsSortable(allItem) && hashSet2.Add(allItem.m_shared.m_name))
					{
						list.Add(new ItemChoice
						{
							SharedName = allItem.m_shared.m_name,
							DisplayName = Localization.instance.Localize(allItem.m_shared.m_name),
							Icon = allItem.GetIcon()
						});
						Diagnostics.Log("Innangard[stores]: " + allItem.m_shared.m_name + " is in the chest but not in the item database; offered from the chest itself");
					}
				}
			}
			return (from choice in list
				group choice by choice.SharedName into @group
				select @group.First() into choice
				orderby choice.DisplayName
				select choice).ToList();
		}

		private static RectTransform Child(string name, Transform parent)
		{
			//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_002e: Unknown result type (might be due to invalid IL or missing references)
			RectTransform component = new GameObject(name, new Type[1] { typeof(RectTransform) })
			{
				layer = 5
			}.GetComponent<RectTransform>();
			((Transform)component).SetParent(parent, false);
			((Transform)component).localScale = Vector3.one;
			InnangardGui.Fill(component);
			return component;
		}
	}
	internal static class ChestSortRules
	{
		[HarmonyPatch(typeof(Container), "Awake")]
		private static class RegisterPatch
		{
			[HarmonyPostfix]
			private static void Postfix(Container __instance)
			{
				Register(__instance);
			}
		}

		[HarmonyPatch(typeof(Container), "GetHoverText")]
		private static class HoverPatch
		{
			[HarmonyPostfix]
			private static void Postfix(Container __instance, ref string __result)
			{
				if ((Object)(object)Player.m_localPlayer != (Object)null && IsStationaryPlayerChest(__instance))
				{
					__result = __result + "\n" + Localization.instance.Localize(Localization.instance.Localize("$inn_stores_filter_hover"));
				}
			}
		}

		private const char Separator = '|';

		private const string RpcSetSort = "inn_SetChestSort";

		private const string ZdoConfigured = "inn_sort_configured";

		private const string ZdoItems = "inn_sort_items";

		internal static void Register(Container container)
		{
			ZNetView val = container?.m_nview;
			if (!((Object)(object)val == (Object)null) && val.IsValid() && !(container is SettlerInventory))
			{
				val.Register<long, string>("inn_SetChestSort", (Action<long, long, string>)delegate(long sender, long requesterId, string payload)
				{
					Receive(container, sender, requesterId, payload);
				});
			}
		}

		internal static bool IsConfigured(Container container)
		{
			if (TryGetZdo(container, out var zdo))
			{
				return zdo.GetBool("inn_sort_configured", false);
			}
			return false;
		}

		internal static HashSet<string> ReadItems(Container container)
		{
			HashSet<string> hashSet = new HashSet<string>(StringComparer.Ordinal);
			if (!TryGetZdo(container, out var zdo))
			{
				return hashSet;
			}
			string[] array = zdo.GetString("inn_sort_items", string.Empty).Split(new char[1] { '|' }, StringSplitOptions.RemoveEmptyEntries);
			foreach (string item in array)
			{
				hashSet.Add(item);
			}
			return hashSet;
		}

		internal static bool Accepts(Container container, string sharedName)
		{
			if ((Object)(object)container == (Object)null || string.IsNullOrEmpty(sharedName))
			{
				return false;
			}
			if (IsConfigured(container))
			{
				return ReadItems(container).Contains(sharedName);
			}
			Inventory inventory = container.GetInventory();
			if (inventory != null)
			{
				return inventory.GetAllItems().Any((ItemData held) => held != null && held.m_shared.m_name == sharedName);
			}
			return false;
		}

		internal static bool IsSortable(ItemData item)
		{
			//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_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Invalid comparison between Unknown and I4
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Invalid comparison between Unknown and I4
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Invalid comparison between Unknown and I4
			if (item?.m_shared == null || item.m_shared.m_questItem)
			{
				return false;
			}
			ItemType itemType = item.m_shared.m_itemType;
			if (itemType - 1 <= 1 || (int)itemType == 13 || (int)itemType == 21)
			{
				return true;
			}
			return false;
		}

		internal static void RequestSet(Container container, IEnumerable<string> items, bool configured)
		{
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null || !CanConfigure(container, localPlayer.GetPlayerID()))
			{
				return;
			}
			string text = "0";
			if (configured)
			{
				IOrderedEnumerable<string> values = from name in items.Where((string name) => !string.IsNullOrEmpty(name) && name.IndexOf('|') < 0).Distinct()
					orderby name
					select name;
				text = "1|" + string.Join('|'.ToString(), values);
			}
			if (!container.m_nview.IsOwner())
			{
				container.m_nview.ClaimOwnership();
			}
			container.m_nview.InvokeRPC("inn_SetChestSort", new object[2]
			{
				localPlayer.GetPlayerID(),
				text
			});
		}

		internal static bool IsStationaryPlayerChest(Container container)
		{
			if ((Object)(object)container == (Object)null || container is SettlerInventory || !((Component)container).gameObject.activeInHierarchy)
			{
				return false;
			}
			if ((Object)(object)container.m_nview == (Object)null || !container.m_nview.IsValid())
			{
				return false;
			}
			if ((Object)(object)container.m_wagon != (Object)null || (Object)(object)((Component)container).GetComponentInParent<Ship>() != (Object)null || (Object)(object)((Component)container).GetComponentInParent<Vagon>() != (Object)null)
			{
				return false;
			}
			Piece val = ((Component)container).GetComponent<Piece>() ?? ((Component)container).GetComponentInParent<Piece>();
			if ((Object)(object)val != (Object)null)
			{
				return val.IsPlacedByPlayer();
			}
			return false;
		}

		internal static bool CanConfigure(Container container, long playerId)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			if (playerId == 0L || !IsStationaryPlayerChest(container) || InUse(container) || !container.CheckAccess(playerId))
			{
				return false;
			}
			return PrivateArea.CheckAccess(((Component)container).transform.position, 0f, false, false);
		}

		private static void Receive(Container container, long sender, long requesterId, string payload)
		{
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)container == (Object)null || (Object)(object)container.m_nview == (Object)null || !container.m_nview.IsValid() || requesterId == 0L || !NetworkRequest.AuthenticatePlayer(sender, requesterId, "chest sorting change") || !IsStationaryPlayerChest(container) || !container.CheckAccess(requesterId) || string.IsNullOrEmpty(payload))
			{
				return;
			}
			if (!container.m_nview.IsOwner())
			{
				container.m_nview.ClaimOwnership();
				if (!container.m_nview.IsOwner())
				{
					return;
				}
			}
			string text = "1|";
			bool flag = payload.StartsWith(text, StringComparison.Ordinal);
			string text2 = ((flag && payload.Length > text.Length) ? payload.Substring(text.Length) : string.Empty);
			ZDO zDO = container.m_nview.GetZDO();
			zDO.Set("inn_sort_configured", flag);
			zDO.Set("inn_sort_items", text2);
			Logger.LogInfo((object)$"Innangard[sorting]: chest {zDO.m_uid} configured={flag} items=[{text2}] persisted");
		}

		private static bool TryGetZdo(Container container, out ZDO zdo)
		{
			zdo = null;
			if ((Object)(object)container?.m_nview == (Object)null || !container.m_nview.IsValid())
			{
				return false;
			}
			zdo = container.m_nview.GetZDO();
			return zdo != null;
		}

		private static bool InUse(Container container)
		{
			if (!container.IsInUse())
			{
				return container.m_nview.GetZDO().GetInt(ZDOVars.s_inUse, 0) == 1;
			}
			return true;
		}
	}
	internal sealed class ChopTarget
	{
		private readonly TreeBase _tree;

		private readonly TreeLog _log;

		private readonly Destructible _stump;

		private Collider _aimCollider;

		private bool _aimColliderResolved;

		internal bool IsLog => (Object)(object)_log != (Object)null;

		internal bool IsStump => (Object)(object)_stump != (Object)null;

		internal GameObject GameObject
		{
			get
			{
				if ((Object)(object)_tree != (Object)null)
				{
					return ((Component)_tree).gameObject;
				}
				if ((Object)(object)_log != (Object)null)
				{
					return ((Component)_log).gameObject;
				}
				if (!((Object)(object)_stump != (Object)null))
				{
					return null;
				}
				return ((Component)_stump).gameObject;
			}
		}

		internal int InstanceId
		{
			get
			{
				if (!((Object)(object)GameObject != (Object)null))
				{
					return 0;
				}
				return ((Object)GameObject).GetInstanceID();
			}
		}

		internal Vector3 Center => GameObject.transform.position;

		internal int MinToolTier
		{
			get
			{
				if ((Object)(object)_tree != (Object)null)
				{
					return _tree.m_minToolTier;
				}
				if ((Object)(object)_log != (Object)null)
				{
					return _log.m_minToolTier;
				}
				if (!((Object)(object)_stump != (Object)null))
				{
					return 0;
				}
				return _stump.m_minToolTier;
			}
		}

		internal ChopTarget(TreeBase tree)
		{
			_tree = tree;
		}

		internal ChopTarget(TreeLog log)
		{
			_log = log;
		}

		internal ChopTarget(Destructible stump)
		{
			_stump = stump;
		}

		internal bool IsValid()
		{
			GameObject gameObject = GameObject;
			if ((Object)(object)gameObject != (Object)null)
			{
				return gameObject.activeInHierarchy;
			}
			return false;
		}

		internal Vector3 ClosestPoint(Vector3 from)
		{
			//IL_0010: 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_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: 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)
			GameObject gameObject = GameObject;
			if ((Object)(object)gameObject == (Object)null)
			{
				return from;
			}
			Collider val = ResolveAimCollider(gameObject);
			if ((Object)(object)val == (Object)null)
			{
				return gameObject.transform.position;
			}
			MeshCollider val2 = (MeshCollider)(object)((val is MeshCollider) ? val : null);
			if (val2 != null && !val2.convex)
			{
				return val.ClosestPointOnBounds(from);
			}
			return val.ClosestPoint(from);
		}

		private Collider ResolveAimCollider(GameObject go)
		{
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: 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_007a: Unknown result type (might be due to invalid IL or missing references)
			if (_aimColliderResolved && (Object)(object)_aimCollider != (Object)null)
			{
				return _aimCollider;
			}
			_aimColliderResolved = true;
			_aimCollider = null;
			float num = -1f;
			Collider[] componentsInChildren = go.GetComponentsInChildren<Collider>(false);
			foreach (Collider val in componentsInChildren)
			{
				if (!((Object)(object)val == (Object)null) && !val.isTrigger && val.enabled)
				{
					Bounds bounds = val.bounds;
					Vector3 size = ((Bounds)(ref bounds)).size;
					float num2 = size.x * size.y * size.z;
					if (num2 > num)
					{
						_aimCollider = val;
						num = num2;
					}
				}
			}
			return _aimCollider;
		}

		internal float ReadHealth()
		{
			ZNetView val = (((Object)(object)_tree != (Object)null) ? _tree.m_nview : (((Object)(object)_log != (Object)null) ? _log.m_nview : (((Object)(object)_stump != (Object)null) ? _stump.m_nview : null)));
			float num = (((Object)(object)_tree != (Object)null) ? _tree.m_health : (((Object)(object)_log != (Object)null) ? _log.m_health : (((Object)(object)_stump != (Object)null) ? _stump.m_health : 0f)));
			if ((Object)(object)val == (Object)null || !val.IsValid())
			{
				return num;
			}
			return val.GetZDO().GetFloat(ZDOVars.s_health, num);
		}

		internal void Damage(HitData hit)
		{
			if ((Object)(object)_tree != (Object)null)
			{
				_tree.Damage(hit);
				return;
			}
			if ((Object)(object)_log != (Object)null)
			{
				_log.Damage(hit);
				return;
			}
			Destructible stump = _stump;
			if (stump != null)
			{
				stump.Damage(hit);
			}
		}

		internal static bool IsTreeStump(Destructible destructible)
		{
			if ((Object)(object)destructible == (Object)null || (Object)(object)((Component)destructible).GetComponent<TreeBase>() != (Object)null || (Object)(object)((Component)destructible).GetComponent<TreeLog>() != (Object)null)
			{
				return false;
			}
			string text = MaterialFilters.PrefabName(((Component)destructible).gameObject).ToLowerInvariant();
			if (!text.Contains("stub"))
			{
				return text.Contains("stump");
			}
			return true;
		}
	}
	internal static class CivilPathPlanner
	{
		private readonly struct HeapEntry
		{
			internal readonly int Node;

			internal readonly float Score;

			internal HeapEntry(int node, float score)
			{
				Node = node;
				Score = score;
			}
		}

		private sealed class MinHeap
		{
			private readonly List<HeapEntry> _items = new List<HeapEntry>();

			internal int Count => _items.Count;

			internal void Clear()
			{
				_items.Clear();
			}

			internal void Push(HeapEntry entry)
			{
				_items.Add(entry);
				int num = _items.Count - 1;
				while (num > 0)
				{
					int num2 = (num - 1) / 2;
					if (_items[num2].Score <= entry.Score)
					{
						break;
					}
					_items[num] = _items[num2];
					num = num2;
				}
				_items[num] = entry;
			}

			internal HeapEntry Pop()
			{
				HeapEntry result = _items[0];
				HeapEntry value = _items[_items.Count - 1];
				_items.RemoveAt(_items.Count - 1);
				if (_items.Count == 0)
				{
					return result;
				}
				int num = 0;
				while (true)
				{
					int num2 = num * 2 + 1;
					if (num2 >= _items.Count)
					{
						break;
					}
					int num3 = num2 + 1;
					int num4 = ((num3 < _items.Count && _items[num3].Score < _items[num2].Score) ? num3 : num2);
					if (_items[num4].Score >= value.Score)
					{
						break;
					}
					_items[num] = _items[num4];
					num = num4;
				}
				_items[num] = value;
				return result;
			}
		}

		private const float BaseCellSize = 0.82f;

		private const float BodyRadius = 0.34f;

		private const float MaxStepHeight = 0.85f;

		private const float DoorCrossingCost = 4f;

		private const int MaxExpandedNodes = 4000;

		private const int BudgetCheckInterval = 64;

		private const int MaxSmoothingLookahead = 12;

		private static readonly Stopwatch SearchClock = new Stopwatch();

		private static readonly List<(Vector3 At, float Radius)> Hazards = new List<(Vector3, float)>();

		private static Vector3 _hazardGoal;

		private static Vector3 _hazardStart;

		private static bool _startedInHazard;

		private const float FireClearance = 1.6f;

		private const float HazardGoalExemption = 2.5f;

		private static int _budgetFrame = -1;

		private static float _budgetUsedMilliseconds;

		private static int _turnFrame = -1;

		private static Transform _turnHolder;

		private static Transform _servedLastFrame;

		private static Transform _servedThisFrame;

		private static bool _refusedAnyoneLastFrame;

		private static bool _refusedAnyoneThisFrame;

		private static readonly RaycastHit[] GroundHits = (RaycastHit[])(object)new RaycastHit[32];

		private static readonly Collider[] ClearanceHits = (Collider[])(object)new Collider[32];

		internal static readonly int ObstacleMask = LayerMask.GetMask(new string[8] { "Default", "static_solid", "Default_small", "piece", "terrain", "blocker", "pathblocker", "vehicle" });

		private static int _refusedNoGround;

		private static int _refusedStep;

		private static int _refusedFire;

		private static int _refusedBody;

		private static int _refusedWater;

		private static int _refusedRoof;

		private static string _refusedBodyBy;

		private static int _hazardsInBox;

		private static string _hazardNames;

		private static float _directMilliseconds;

		private static float _searchMilliseconds;

		private static int _summarySearches;

		private static int _summaryFailures;

		private static int _summaryDirect;

		private static int _summaryStarvedFrames;

		private static float _summaryWorstSearchMilliseconds;

		private static int _summaryStarvedFrameStamp = -1;

		private static float _nextSummary;

		private static bool[] _evaluated = Array.Empty<bool>();

		private static bool[] _walkable = Array.Empty<bool>();

		private static bool[] _doorCell = Array.Empty<bool>();

		private static bool[] _closed = Array.Empty<bool>();

		private static float[] _heights = Array.Empty<float>();

		private static float[] _costs = Array.Empty<float>();

		private static int[] _parents = Array.Empty<int>();

		private static readonly MinHeap Heap = new MinHeap();

		private const float DiagonalCost = 1.414214f;

		private const float ClimbCost = 1.5f;

		private static readonly Vector2Int[] EightWays = (Vector2Int[])(object)new Vector2Int[8]
		{
			new Vector2Int(1, 0),
			new Vector2Int(-1, 0),
			new Vector2Int(0, 1),
			new Vector2Int(0, -1),
			new Vector2Int(1, 1),
			new Vector2Int(1, -1),
			new Vector2Int(-1, 1),
			new Vector2Int(-1, -1)
		};

		private const float MarginOfDistance = 0.58f;

		private const float LeastMargin = 8f;

		private const float MostMargin = 24f;

		private const int MostCells = 11000;

		private const float RealBodyRadius = 0.49f;

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

		private const float StandingBodyRadius = 0.42f;

		private const float StillEnough = 0.4f;

		private const float ClearOfTheEnds = 1.7f;

		private const float StandingBodyHeadroom = 1.6f;

		private static bool _standingBodyMattered;

		private const float SampleSpacing = 0.62f;

		internal static float DirectMillisecondsUsed => _directMilliseconds;

		internal static float SearchMillisecondsUsed => _searchMilliseconds;

		internal static float BudgetUsedMilliseconds
		{
			get
			{
				if (Time.frameCount != _budgetFrame)
				{
					return 0f;
				}
				return _budgetUsedMilliseconds;
			}
		}

		internal static void TickSummary()
		{
			if (!(Time.time < _nextSummary))
			{
				bool num = _nextSummary <= 0f;
				_nextSummary = Time.time + 15f;
				if (!num && Diagnostics.Enabled && _summarySearches + _summaryDirect > 0)
				{
					Diagnostics.Log($"Innangard[budget]: 15s - {_summarySearches} grid search(es), {_summaryFailures} of them found nothing, " + $"{_summaryDirect} straight-line test(s); {_searchMilliseconds:0}ms in searches, {_directMilliseconds:0}ms in straight lines, " + $"longest single search {_summaryWorstSearchMilliseconds:0.0}ms, " + $"{_summaryStarvedFrames} frame(s) where somebody had to wait their turn");
				}
				_summarySearches = 0;
				_summaryFailures = 0;
				_summaryDirect = 0;
				_summaryStarvedFrames = 0;
				_summaryWorstSearchMilliseconds = 0f;
				_searchMilliseconds = 0f;
				_directMilliseconds = 0f;
			}
		}

		private static void NoteStarvedFrame()
		{
			if (Time.frameCount != _summaryStarvedFrameStamp)
			{
				_summaryStarvedFrameStamp = Time.frameCount;
				_summaryStarvedFrames++;
			}
		}

		internal static bool HasFrameBudget(Transform claimant)
		{
			if (Time.frameCount != _turnFrame)
			{
				_turnFrame = Time.frameCount;
				_turnHolder = null;
				_servedLastFrame = _servedThisFrame;
				_servedThisFrame = null;
				_refusedAnyoneLastFrame = _refusedAnyoneThisFrame;
				_refusedAnyoneThisFrame = false;
			}
			if ((Object)(object)_turnHolder != (Object)null)
			{
				if ((Object)(object)_turnHolder == (Object)(object)claimant)
				{
					return true;
				}
				return Refuse();
			}
			if ((Object)(object)claimant != (Object)null && (Object)(object)claimant == (Object)(object)_servedLastFrame && _refusedAnyoneLastFrame)
			{
				return Refuse();
			}
			_turnHolder = claimant;
			_servedThisFrame = claimant;
			return true;
		}

		private static bool Refuse()
		{
			_refusedAnyoneThisFrame = true;
			NoteStarvedFrame();
			return false;
		}

		internal static bool HasRoute(Vector3 from, Vector3 to, AgentType agentType)
		{
			//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_0017: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)Pathfinding.instance == (Object)null)
			{
				return true;
			}
			return Pathfinding.instance.GetPath(from, to, (List<Vector3>)null, agentType, true, false, false);
		}

		private static void ChargeFrameBudget(float milliseconds)
		{
			if (Time.frameCount != _budgetFrame)
			{
				_budgetFrame = Time.frameCount;
				_budgetUsedMilliseconds = 0f;
			}
			_budgetUsedMilliseconds += milliseconds;
		}

		private static void EnsureBuffers(int total)
		{
			if (_evaluated.Length < total)
			{
				int num = Mathf.NextPowerOfTwo(total);
				_evaluated = new bool[num];
				_walkable = new bool[num];
				_doorCell = new bool[num];
				_closed = new bool[num];
				_heights = new float[num];
				_costs = new float[num];
				_parents = new int[num];
			}
			else
			{
				Array.Clear(_evaluated, 0, total);
				Array.Clear(_walkable, 0, total);
				Array.Clear(_doorCell, 0, total);
				Array.Clear(_closed, 0, total);
				Array.Clear(_heights, 0, total);
			}
		}

		internal static bool TryBuildPath(Vector3 start, Vector3 goal, Transform mover, string actor, out List<Vector3> waypoints, bool allowPartial = false, float maxMilliseconds = float.PositiveInfinity)
		{
			//IL_0004: 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_001c: 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_003a: 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_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			waypoints = null;
			float num = Utils.DistanceXZ(start, goal);
			if (num < 1.25f)
			{
				waypoints = new List<Vector3> { goal };
				return true;
			}
			if (!HasFrameBudget(mover))
			{
				return false;
			}
			SearchClock.Restart();
			GatherStandingBodies(start, goal, mover);
			_standingBodyMattered = false;
			try
			{
				if (RunSearch(start, goal, mover, actor, num, allowPartial, maxMilliseconds, out waypoints))
				{
					return true;
				}
				if (!_standingBodyMattered)
				{
					return false;
				}
				Diagnostics.Navigation("Innangard[planner]: " + actor + " found no way round " + $"{StandingBodies.Count} resident(s) standing in it; asking again as if " + "they were not there");
				StandingBodies.Clear();
				return RunSearch(start, goal, mover, actor, num, allowPartial, maxMilliseconds, out waypoints);
			}
			finally
			{
				StandingBodies.Clear();
				SearchClock.Stop();
				float num2 = (float)SearchClock.Elapsed.TotalMilliseconds;
				_searchMilliseconds += num2;
				_summarySearches++;
				if (num2 > _summaryWorstSearchMilliseconds)
				{
					_summaryWorstSearchMilliseconds = num2;
				}
				ChargeFrameBudget(num2);
			}
		}

		private static bool RunSearch(Vector3 start, Vector3 goal, Transform mover, string actor, float directDistance, bool allowPartial, float maxMilliseconds, out List<Vector3> waypoints)
		{
			//IL_001c: 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_0030: 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_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: 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_00f7: 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_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_021d: Unknown result type (might be due to invalid IL or missing references)
			//IL_067d: 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_02cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_06c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_06ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_06f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_06a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_031e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0323: Unknown result type (might be due to invalid IL or missing references)
			//IL_0616: Unknown result type (might be due to invalid IL or missing references)
			//IL_0622: Unknown result type (might be due to invalid IL or missing references)
			//IL_0643: Unknown result type (might be due to invalid IL or missing references)
			//IL_046f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0474: Unknown result type (might be due to invalid IL or missing references)
			waypoints = null;
			float num = Mathf.Clamp(directDistance * 0.58f, 8f, 24f);
			float num2 = Mathf.Min(start.x, goal.x) - num;
			float num3 = Mathf.Max(start.x, goal.x) + num;
			float num4 = Mathf.Min(start.z, goal.z) - num;
			float num5 = Mathf.Max(start.z, goal.z) + num;
			float num6 = 0.82f;
			int num7 = Mathf.CeilToInt((num3 - num2) / num6) + 1;
			int num8 = Mathf.CeilToInt((num5 - num4) / num6) + 1;
			int num9 = num7 * num8;
			if (num9 > 11000)
			{
				num6 *= Mathf.Sqrt((float)num9 / 11000f);
				num7 = Mathf.CeilToInt((num3 - num2) / num6) + 1;
				num8 = Mathf.CeilToInt((num5 - num4) / num6) + 1;
				num9 = num7 * num8;
			}
			num2 = start.x - Mathf.Ceil((start.x - num2) / num6) * num6;
			num4 = start.z - Mathf.Ceil((start.z - num4) / num6) * num6;
			num7 = Mathf.CeilToInt((num3 - num2) / num6) + 1;
			num8 = Mathf.CeilToInt((num5 - num4) / num6) + 1;
			num9 = num7 * num8;
			CollectHazards(num2, num3, num4, num5, start, goal);
			_refusedNoGround = 0;
			_refusedStep = 0;
			_refusedFire = 0;
			_refusedBody = 0;
			_refusedWater = 0;
			_refusedRoof = 0;
			_refusedBodyBy = null;
			_hazardsInBox = Hazards.Count;
			EnsureBuffers(num9);
			bool[] evaluated = _evaluated;
			bool[] walkable = _walkable;
			bool[] closed = _closed;
			float[] heights = _heights;
			float[] costs = _costs;
			int[] parents = _parents;
			for (int i = 0; i < num9; i++)
			{
				costs[i] = float.MaxValue;
				parents[i] = -1;
			}
			int num10 = Mathf.Clamp(Mathf.RoundToInt((start.x - num2) / num6), 0, num7 - 1);
			int num11 = Mathf.Clamp(Mathf.RoundToInt((start.z - num4) / num6), 0, num8 - 1) * num7 + num10;
			evaluated[num11] = true;
			walkable[num11] = true;
			heights[num11] = start.y;
			costs[num11] = 0f;
			MinHeap heap = Heap;
			heap.Clear();
			heap.Push(new HeapEntry(num11, directDistance));
			int num12 = 0;
			int num13 = -1;
			bool flag = false;
			int num14 = -1;
			float num15 = float.MaxValue;
			while (heap.Count > 0 && num12 < 4000)
			{
				int node = heap.Pop().Node;
				if (closed[node])
				{
					continue;
				}
				closed[node] = true;
				num12++;
				if (num12 % 64 == 0 && SearchClock.Elapsed.TotalMilliseconds > (double)maxMilliseconds)
				{
					flag = true;
					break;
				}
				int num16 = node % num7;
				int num17 = node / num7;
				Vector3 val = GridPoint(num16, num17, num2, num4, num6, heights[node]);
				float num18 = Utils.DistanceXZ(val, goal);
				if (num18 < num15)
				{
					num15 = num18;
					num14 = node;
				}
				if (num18 <= num6 * 1.5f && SegmentClear(val, goal, mover, num6))
				{
					num13 = node;
					break;
				}
				Vector2Int[] eightWays = EightWays;
				for (int j = 0; j < eightWays.Length; j++)
				{
					Vector2Int val2 = eightWays[j];
					int num19 = num16 + ((Vector2Int)(ref val2)).x;
					int num20 = num17 + ((Vector2Int)(ref val2)).y;
					if (num19 < 0 || num19 >= num7 || num20 < 0 || num20 >= num8)
					{
						continue;
					}
					int num21 = num20 * num7 + num19;
					if (closed[num21])
					{
						continue;
					}
					float expectedHeight = heights[node];
					if (!EvaluateNode(num21, num19, num20, num2, num4, num6, expectedHeight, mover, evaluated, walkable, heights))
					{
						continue;
					}
					bool flag2 = ((Vector2Int)(ref val2)).x != 0 && ((Vector2Int)(ref val2)).y != 0;
					if (flag2)
					{
						int node2 = num17 * num7 + num19;
						int node3 = num20 * num7 + num16;
						if (!EvaluateNode(node2, num19, num17, num2, num4, num6, expectedHeight, mover, evaluated, walkable, heights) || !EvaluateNode(node3, num16, num20, num2, num4, num6, expectedHeight, mover, evaluated, walkable, heights))
						{
							continue;
						}
					}
					float num22 = (flag2 ? (num6 * 1.414214f) : num6);
					float num23 = Mathf.Abs(heights[num21] - heights[node]) * 1.5f;
					float num24 = costs[node] + num22 + num23 + (_doorCell[num21] ? 4f : 0f);
					if (!(num24 >= costs[num21]))
					{
						costs[num21] = num24;
						parents[num21] = node;
						float num25 = Utils.DistanceXZ(GridPoint(num19, num20, num2, num4, num6, heights[num21]), goal);
						heap.Push(new HeapEntry(num21, num24 + num25));
					}
				}
			}
			bool flag3 = false;
			if (num13 < 0)
			{
				bool flag4 = flag || num12 >= 4000;
				if (!(allowPartial && flag4) || num14 < 0 || num14 == num11 || !(directDistance - num15 >= Mathf.Max(3f, directDistance * 0.25f)))
				{
					_summaryFailures++;
					Diagnostics.Navigation("Innangard[planner]: " + actor + " no physical route " + $"({directDistance:0.0}m, expanded={num12}" + (flag ? ", budget exhausted" : (flag4 ? ", node cap" : ", unreachable")) + string.Format(", refused ground={0} body={1} step={2} fire={3} water={4} roof={5}, fires={6} [{7}], startedInFire={8}, first blocker={9}", _refusedNoGround, _refusedBody, _refusedStep, _refusedFire, _refusedWater, _refusedRoof, _hazardsInBox, _hazardNames, _startedInHazard, _refusedBodyBy ?? "none") + ((num12 <= 4) ? $", widest body at its feet={WidestBodyAt(start, mover):0.00}m, ways out {DescribeWaysOut(start, mover)}" : string.Empty) + ((num12 <= 40) ? (", doorway: " + DescribeNearestDoorway(start, mover, num2, num4, num6, num7, num8, evaluated, walkable)) : string.Empty) + ")");
					return false;
				}
				num13 = num14;
				flag3 = true;
			}
			List<Vector3> list = new List<Vector3>();
			if (!flag3)
			{
				list.Add(goal);
			}
			int num26 = num13;
			while (num26 >= 0 && num26 != num11)
			{
				int x = num26 % num7;
				int z = num26 / num7;
				list.Add(GridPoint(x, z, num2, num4, num6, heights[num26]));
				num26 = parents[num26];
			}
			list.Add(start);
			list.Reverse();
			waypoints = Smooth(list, mover, num6);
			if (waypoints.Count > 0 && Utils.DistanceXZ(waypoints[0], start) < 0.65f)
			{
				waypoints.RemoveAt(0);
			}
			Diagnostics.Navigation("Innangard[planner]: " + actor + (flag3 ? " partial route " : " physical route ") + $"{directDistance:0.0}m " + (flag3 ? $"closing to {num15:0.0}m " : string.Empty) + $"with {waypoints.Count} waypoint(s), expanded={num12}" + ((flag3 && flag) ? ", budget exhausted" : string.Empty));
			return waypoints.Count > 0;
		}

		internal static bool TryProjectWalkPoint(Vector3 desired, Transform mover, out Vector3 point, bool avoidFire = false)
		{
			//IL_0009: 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_0015: 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_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: 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_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: 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_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			Vector3[] obj = new Vector3[9]
			{
				Vector3.zero,
				Vector3.forward,
				Vector3.back,
				Vector3.right,
				Vector3.left,
				default(Vector3),
				default(Vector3),
				default(Vector3),
				default(Vector3)
			};
			Vector3 val = new Vector3(1f, 0f, 1f);
			obj[5] = ((Vector3)(ref val)).normalized;
			val = new Vector3(1f, 0f, -1f);
			obj[6] = ((Vector3)(ref val)).normalized;
			val = new Vector3(-1f, 0f, 1f);
			obj[7] = ((Vector3)(ref val)).normalized;
			val = new Vector3(-1f, 0f, -1f);
			obj[8] = ((Vector3)(ref val)).normalized;
			Vector3[] array = (Vector3[])(object)obj;
			float[] array2 = new float[4] { 0f, 0.45f, 0.85f, 1.25f };
			foreach (float num in array2)
			{
				Vector3[] array3 = array;
				foreach (Vector3 val2 in array3)
				{
					if (num == 0f && val2 != Vector3.zero)
					{
						continue;
					}
					Vector3 val3 = desired + val2 * num;
					if (TryGround(val3, desired.y, out var height) && !(Mathf.Abs(height - desired.y) > 2.5f))
					{
						point = new Vector3(val3.x, height, val3.z);
						if (HasBodyClearance(point, mover) && (!avoidFire || !IsBurning(point)))
						{
							return true;
						}
					}
				}
			}
			point = desired;
			return false;
		}

		internal static bool IsBurning(Vector3 ground)
		{
			//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_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 (Object)(object)EffectArea.IsPointInsideArea(ground + Vector3.up * 0.9f, (Type)8, 0f) != (Object)null;
		}

		private static void CollectHazards(float minX, float maxX, float minZ, float maxZ, Vector3 start, Vector3 goal)
		{
			//IL_000e: 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_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: 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_00d8: Unknown result type (might be due to invalid IL or missing references)
			Hazards.Clear();
			int num = 0;
			int num2 = 0;
			_hazardGoal = goal;
			_hazardStart = start;
			Fireplace[] array = SceneObjectCache.Get<Fireplace>(2f);
			foreach (Fireplace val in array)
			{
				if ((Object)(object)val == (Object)null || (Object)(object)val.m_nview == (Object)null || !val.m_nview.IsValid() || val.m_nview.GetZDO().GetFloat(ZDOVars.s_fuel, 0f) <= 0f)
				{
					continue;
				}
				Vector3 position = ((Component)val).transform.position;
				float num3 = BurningRadius(val);
				if (!(position.x < minX - num3) && !(position.x > maxX + num3) && !(position.z < minZ - num3) && !(position.z > maxZ + num3))
				{
					Hazards.Add((position, num3));
					if (((Object)((Component)val).gameObject).name.IndexOf("torch", StringComparison.OrdinalIgnoreCase) >= 0)
					{
						num++;
					}
					else
					{
						num2++;
					}
				}
			}
			_hazardNames = $"{num} torch(es), {num2} other";
			_startedInHazard = Hazards.Count > 0 && InsideAnyHazard(start);
			if (_startedInHazard)
			{
				Diagnostics.Navigation("Innangard[planner]: search begins inside a lit area " + $"({_hazardNames}); the {2.5f:0.0}m around the start is " + "exempt so it can step out");
			}
		}

		private static float BurningRadius(Fireplace fireplace)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			EffectArea[] componentsInChildren = ((Component)fireplace).GetComponentsInChildren<EffectArea>(true);
			foreach (EffectArea val in componentsInChildren)
			{
				if (!((Object)(object)val == (Object)null) && (val.m_type & 8) != 0)
				{
					float radius = val.GetRadius();
					if (radius > 0f)
					{
						return radius;
					}
				}
			}
			return 1.6f;
		}

		private static bool IsHazardous(Vector3 point)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: 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_002a: Unknown result type (might be due to invalid IL or missing references)
			if (Hazards.Count == 0)
			{
				return false;
			}
			if (Utils.DistanceXZ(point, _hazardGoal) <= 2.5f)
			{
				return false;
			}
			if (_startedInHazard && Utils.DistanceXZ(point, _hazardStart) <= 2.5f)
			{
				return false;
			}
			return InsideAnyHazard(point);
		}

		private static bool InsideAnyHazard(Vector3 point)
		{
			//IL_0010: 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_0024: 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)
			for (int i = 0; i < Hazards.Count; i++)
			{
				(Vector3, float) tuple = Hazards[i];
				if (Utils.DistanceXZ(point, tuple.Item1) <= tuple.Item2 && Mathf.Abs(point.y - tuple.Item1.y) <= 2f)
				{
					return true;
				}
			}
			return false;
		}

		private static bool EvaluateNode(int node, int x, int z, float minX, float minZ, float cellSize, float expectedHeight, Transform mover, bool[] evaluated, bool[] walkable, float[] heights)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: 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_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: 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)
			if (evaluated[node])
			{
				if (walkable[node])
				{
					return Mathf.Abs(heights[node] - expectedHeight) <= 0.85f;
				}
				return false;
			}
			evaluated[node] = true;
			Vector3 val = GridPoint(x, z, minX, minZ, cellSize, expectedHeight);
			if (!TryGround(val, expectedHeight, out var height))
			{
				_refusedNoGround++;
				return false;
			}
			heights[node] = height;
			Vector3 val2 = default(Vector3);
			((Vector3)(ref val2))..ctor(val.x, height, val.z);
			if (WorkArea.Submerged(val2))
			{
				_refusedWater++;
				return false;
			}
			if (IsHazardous(val2))
			{
				_refusedFire++;
				return false;
			}
			if (!HasBodyClearance(val2, mover))
			{
				if (!BlockedOnlyByDoor(val2, mover))
				{
					_refusedBody++;
					return false;
				}
				_doorCell[node] = true;
			}
			walkable[node] = true;
			if (Mathf.Abs(height - expectedHeight) > 0.85f)
			{
				_refusedStep++;
				return false;
			}
			return true;
		}

		private static bool IsRoof(RaycastHit hit)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			if (Vector3.Dot(((RaycastHit)(ref hit)).normal, Vector3.up) > 0.97f)
			{
				return false;
			}
			Piece componentInParent = ((Component)((RaycastHit)(ref hit)).collider).GetComponentInParent<Piece>();
			if ((Object)(object)componentInParent == (Object)null)
			{
				return false;
			}
			string name = ((Object)componentInParent).name;
			if (name.IndexOf("stair", StringComparison.OrdinalIgnoreCase) < 0)
			{
				return name.IndexOf("ladder", StringComparison.OrdinalIgnoreCase) < 0;
			}
			return false;
		}

		private static Vector3 GridPoint(int x, int z, float minX, float minZ, float cellSize, float y)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			return new Vector3(minX + (float)x * cellSize, y, minZ + (float)z * cellSize);
		}

		private static bool TryGround(Vector3 point, float expectedHeight, out float height)
		{
			//IL_0007: 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_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			height = 0f;
			int num = Physics.RaycastNonAlloc(new Vector3(point.x, expectedHeight + 2.2f, point.z), Vector3.down, GroundHits, 4.8f, ObstacleMask, (QueryTriggerInteraction)1);
			float num2 = float.MaxValue;
			bool flag = false;
			for (int i = 0; i < num; i++)
			{
				RaycastHit hit = GroundHits[i];
				if ((Object)(object)((RaycastHit)(ref hit)).collider == (Object)null || (Object)(object)((Component)((RaycastHit)(ref hit)).collider).GetComponentInParent<Character>() != (Object)null || Vector3.Dot(((RaycastHit)(ref hit)).normal, Vector3.up) < 0.55f)
				{
					continue;
				}
				if (IsRoof(hit))
				{
					_refusedRoof++;
					continue;
				}
				float num3 = Mathf.Abs(((RaycastHit)(ref hit)).point.y - expectedHeight);
				if (!(num3 >= num2))
				{
					height = ((RaycastHit)(ref hit)).point.y;
					num2 = num3;
					flag = true;
				}
			}
			if (flag)
			{
				return true;
			}
			if ((Object)(object)ZoneSystem.instance != (Object)null)
			{
				return ZoneSystem.instance.GetGroundHeight(point, ref height);
			}
			return false;
		}

		internal static bool IsWedged(Vector3 start, Transform mover, out Vector3 escape)
		{
			//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_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_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_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: 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_00e0: 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_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			escape = Vector3.zero;
			if (WidestBodyAt(start, mover) >= 0.49f)
			{
				return false;
			}
			Vector2Int[] obj = new Vector2Int[8]
			{
				new Vector2Int(1, 0),
				new Vector2Int(1, 1),
				new Vector2Int(0, 1),
				new Vector2Int(-1, 1),
				new Vector2Int(-1, 0),
				new Vector2Int(-1, -1),
				new Vector2Int(0, -1),
				new Vector2Int(1, -1)
			};
			float num = 0f;
			Vector2Int[] array = (Vector2Int[])(object)obj;
			for (int i = 0; i < array.Length; i++)
			{
				Vector2Int val = array[i];
				Vector3 val2 = new Vector3((float)((Vector2Int)(ref val)).x, 0f, (float)((Vector2Int)(ref val)).y);
				Vector3 normalized = ((Vector3)(ref val2)).normalized;
				Vector3 val3 = start + normalized * 0.82f;
				if (TryGround(val3, start.y, out var height) && !(Mathf.Abs(height - start.y) > 0.85f))
				{
					float num2 = WidestBodyAt(new Vector3(val3.x, height, val3.z), mover);
					if (num2 > num)
					{
						num = num2;
						escape = normalized;
					}
				}
			}
			if (num > 0f)
			{
				return ((Vector3)(ref escape)).sqrMagnitude > 0.01f;
			}
			return false;
		}

		internal static string DescribeNearestDoorway(Vector3 start, Transform mover, float minX, float minZ, float cellSize, int width, int height, bool[] evaluated, bool[] walkable)
		{
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: 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_0041: 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_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0132: 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_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0200: Unknown result type (might be due to invalid IL or missing references)
			//IL_020b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0223: Unknown result type (might be due to invalid IL or missing references)
			//IL_022f: Unknown result type (might be due to invalid IL or missing references)
			//IL_023b: Unknown result type (might be due to invalid IL or missing references)
			Door[] array = SceneObjectCache.Get<Door>(1f);
			Door val = null;
			float num = float.MaxValue;
			Door[] array2 = array;
			foreach (Door val2 in array2)
			{
				if (!((Object)(object)val2 == (Object)null) && !((Object)(object)((Component)val2).transform == (Object)null))
				{
					float num2 = Utils.DistanceXZ(start, ((Component)val2).transform.position);
					if (num2 < num && num2 <= 12f && Mathf.Abs(((Component)val2).transform.position.y - start.y) <= 3f)
					{
						num = num2;
						val = val2;
					}
				}
			}
			if ((Object)(object)val == (Object)null)
			{
				return "no doorway within twelve metres";
			}
			Vector3 position = ((Component)val).transform.position;
			float height2;
			bool flag = TryGround(position, start.y, out height2) && HasBodyClearance(new Vector3(position.x, height2, position.z), mover);
			int num3 = Mathf.Clamp(Mathf.RoundToInt((position.x - minX) / cellSize), 0, width - 1);
			int num4 = Mathf.Clamp(Mathf.RoundToInt((position.z - minZ) / cellSize), 0, height - 1);
			int num5 = num4 * width + num3;
			Vector3 val3 = GridPoint(num3, num4, minX, minZ, cellSize, start.y);
			float num6 = Utils.DistanceXZ(val3, position);
			string arg = ((num5 < 0 || num5 >= evaluated.Length || !evaluated[num5]) ? "never looked at" : (walkable[num5] ? "walkable" : "refused"));
			return $"{((Object)((Component)val).gameObject).name} {num:0.0}m away, its middle is " + (flag ? "standable" : "not standable") + ", nearest lattice cell sits " + $"{num6:0.00}m off its centre and was {arg}" + $" [from {start.x:0.0},{start.y:0.0},{start.z:0.0}" + $" door {position.x:0.0},{position.y:0.0},{position.z:0.0}" + $" cell {val3.x:0.0},{val3.y:0.0},{val3.z:0.0}]";
		}

		internal static string DescribeWaysOut(Vector3 start, Transform mover)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: 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_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: 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)
			Vector2Int[] directions = (Vector2Int[])(object)new Vector2Int[8]
			{
				new Vector2Int(1, 0),
				new Vector2Int(1, 1),
				new Vector2Int(0, 1),
				new Vector2Int(-1, 1),
				new Vector2Int(-1, 0),
				new Vector2Int(-1, -1),
				new Vector2Int(0, -1),
				new Vector2Int(1, -1)
			};
			return Ring(start, mover, directions, 0.41f) + " | " + Ring(start, mover, directions, 0.82f);
		}

		private static string Ring(Vector3 start, Transform mover, Vector2Int[] directions, float reach)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: 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_005d: 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_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append($"{reach:0.00}m:");
			Vector3 val2 = default(Vector3);
			for (int i = 0; i < directions.Length; i++)
			{
				Vector2Int val = directions[i];
				((Vector3)(ref val2))..ctor((float)((Vector2Int)(ref val)).x, 0f, (float)((Vector2Int)(ref val)).y);
				Vector3 val3 = start + ((Vector3)(ref val2)).normalized * reach;
				if (stringBuilder[stringBuilder.Length - 1] != ':')
				{
					stringBuilder.Append('/');
				}
				if (!TryGround(val3, start.y, out var height) || Mathf.Abs(height - start.y) > 0.85f)
				{
					stringBuilder.Append("--");
				}
				else
				{
					stringBuilder.Append($"{WidestBodyAt(new Vector3(val3.x, height, val3.z), mover) * 100f:00}");
				}
			}
			return stringBuilder.ToString();
		}

		internal static float WidestBodyAt(Vector3 ground, Transform mover)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			float[] array = new float[7] { 0.55f, 0.49f, 0.45f, 0.4f, 0.34f, 0.28f, 0.22f };
			foreach (float num in array)
			{
				if (HasBodyClearance(ground, mover, num))
				{
					return num;
				}
			}
			return 0f;
		}

		private static void GatherStandingBodies(Vector3 start, Vector3 goal, Transform mover)
		{
			//IL_000a: 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_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: 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_009d: 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_00b9: Unknown result type (might be due to invalid IL or missing references)
			StandingBodies.Clear();
			float num = Utils.DistanceXZ(start, goal) + 24f;
			foreach (SettlerController instance in SettlerController.Instances)
			{
				if (!((Object)(object)instance == (Object)null) && instance.IsValidSettler && !instance.IsRespawning && (!((Object)(object)mover != (Object)null) || !((Object)(object)((Component)instance).transform == (Object)(object)mover)) && (!((Object)(object)mover != (Object)null) || !((Component)instance).transform.IsChildOf(mover)))
				{
					Vector3 position = instance.Position;
					if (!(Utils.DistanceXZ(position, start) < 1.7f) && !(Utils.DistanceXZ(position, goal) < 1.7f) && !(Utils.DistanceXZ(position, start) > num) && instance.StandingStill(0.4f))
					{
						StandingBodies.Add(position);
					}
				}
			}
		}

		private static bool StandingBodyAt(Vector3 ground, float radius)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: 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_0029: 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)
			for (int i = 0; i < StandingBodies.Count; i++)
			{
				Vector3 val = StandingBodies[i];
				if (Mathf.Abs(val.y - ground.y) <= 1.6f && Utils.DistanceXZ(val, ground) < radius + 0.42f)
				{
					return true;
				}
			}
			return false;
		}

		private static bool HasBodyClearance(Vector3 ground, Transform mover)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			return HasBodyClearance(ground, mover, 0.34f);
		}

		private static bool HasBodyClearance(Vector3 ground, Transform mover, float radius)
		{
			//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_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_0016: 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_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: 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_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = ground + Vector3.up * 0.48f;
			Vector3 val2 = ground + Vector3.up * 1.55f;
			int num = Physics.OverlapCapsuleNonAlloc(val, val2, radius, ClearanceHits, ObstacleMask, (QueryTriggerInteraction)1);
			for (int i = 0; i < num; i++)
			{
				Collider val3 = ClearanceHits[i];
				if ((Object)(object)val3 == (Object)null || ((Object)(object)mover != (Object)null && ((Component)val3).transform.IsChildOf(mover)) || (Object)(object)((Component)val3).GetComponentInParent<Character>() != (Object)null || (Object)(object)((Component)val3).GetComponentInParent<Heightmap>() != (Object)null)
				{
					continue;
				}
				Bounds bounds = val3.bounds;
				if (!(((Bounds)(ref bounds)).max.y <= ground.y + 0.28f))
				{
					if (_refusedBodyBy == null)
					{
						_refusedBodyBy = ((Object)val3).name + " [" + LayerMask.LayerToName(((Component)val3).gameObject.layer) + "]";
					}
					return false;
				}
			}
			if (StandingBodyAt(ground, radius))
			{
				_standingBodyMattered = true;
				if (_refusedBodyBy == null)
				{
					_refusedBodyBy = "a resident standing there";
				}
				return false;
			}
			return true;
		}

		private static bool BlockedOnlyByDoor(Vector3 ground, Transform mover)
		{
			//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_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_0016: 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_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: 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_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = ground + Vector3.up * 0.48f;
			Vector3 val2 = ground + Vector3.up * 1.55f;
			int num = Physics.OverlapCapsuleNonAlloc(val, val2, 0.34f, ClearanceHits, ObstacleMask, (QueryTriggerInteraction)1);
			bool flag = false;
			for (int i = 0; i < num; i++)
			{
				Collider val3 = ClearanceHits[i];
				if ((Object)(object)val3 == (Object)null || ((Object)(object)mover != (Object)null && ((Component)val3).transform.IsChildOf(mover)) || (Object)(object)((Component)val3).GetComponentInParent<Character>() != (Object)null || (Object)(object)((Component)val3).GetComponentInParent<Heightmap>() != (Object)null)
				{
					continue;
				}
				Bounds bounds = val3.bounds;
				if (!(((Bounds)(ref bounds)).max.y <= ground.y + 0.28f))
				{
					Door componentInParent = ((Component)val3).GetComponentInParent<Door>();
					if ((Object)(object)componentInParent == (Object)null || (Object)(object)componentInParent.m_nview == (Object)null || !componentInParent.m_nview.IsValid())
					{
						return false;
					}
					flag = true;
				}
			}
			if (flag)
			{
				return !StandingBodyAt(ground, 0.34f);
			}
			return false;
		}

		private static bool SegmentClear(Vector3 from, Vector3 to, Transform mover, float cellSize)
		{
			//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_001d: 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_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: 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_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			float num = Utils.DistanceXZ(from, to);
			int num2 = Mathf.Max(1, Mathf.CeilToInt(num / (cellSize * 0.62f)));
			float num3 = from.y;
			Vector3 val2 = default(Vector3);
			for (int i = 1; i <= num2; i++)
			{
				Vector3 val = Vector3.Lerp(from, to, (float)i / (float)num2);
				if (!TryGround(val, num3, out var height) || Mathf.Abs(height - num3) > 0.85f)
				{
					return false;
				}
				((Vector3)(ref val2))..ctor(val.x, height, val.z);
				if (WorkArea.Submerged(val2) || IsHazardous(val2) || !HasBodyClearance(val2, mover))
				{
					return false;
				}
				num3 = height;
			}
			return true;
		}

		private static List<Vector3> Smooth(IReadOnlyList<Vector3> raw, Transform mover, float cellSize)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: 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_0057: Unknown result type (might be due to invalid IL or missing references)
			List<Vector3> list = new List<Vector3> { raw[0] };
			int num = 0;
			while (num < raw.Count - 1)
			{
				int num2 = num + 1;
				for (int num3 = Mathf.Min(raw.Count - 1, num + 12); num3 > num + 1; num3--)
				{
					if (SegmentClear(raw[num], raw[num3], mover, cellSize))
					{
						num2 = num3;
						break;
					}
				}
				list.Add(raw[num2]);
				num = num2;
			}
			return list;
		}

		internal static float PathLength(IReadOnlyList<Vector3> path, Vector3 start)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: 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_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_0022: 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)
			float num = 0f;
			Vector3 val = start;
			foreach (Vector3 item in path)
			{
				num += Utils.DistanceXZ(val, item);
				val = item;
			}
			return num;
		}
	}
	internal sealed class ConfigurationManagerAttributes
	{
		public bool? IsAdminOnly;
	}
	internal static class CropCatalog
	{
		internal const string AllPermissionsToken = "*";

		internal const string NoPermissionsToken = "-";

		private const char PermissionSeparator = ';';

		private const int MostOfAnything = 10000;

		private const float LeastSpacing = 0.45f;

		private const float BushSpacing = 1.25f;

		private const float UndergrowthSpacing = 0.55f;

		private static readonly List<CropKind> Cache = new List<CropKind>();

		private static ObjectDB _cachedObjectDb;

		private static ZNetScene _cachedZNetScene;

		private static readonly string[] SaplingPrefixes = new string[3] { "piece_", "sapling_", "Pickable_" };

		internal static IReadOnlyList<CropKind> All()
		{
			if ((Object)(object)ObjectDB.instance == (Object)null)
			{
				return Cache;
			}
			if ((Object)(object)_cachedObjectDb == (Object)(object)ObjectDB.instance && (Object)(object)_cachedZNetScene == (Object)(object)ZNetScene.instance && Cache.Count > 0)
			{
				return Cache;
			}
			_cachedObjectDb = ObjectDB.instance;
			_cachedZNetScene = ZNetScene.instance;
			Cache.Clear();
			AddCultivated();
			AddWildRenewables();
			Cache.Sort((CropKind left, CropKind right) => string.Compare(left.Label, right.Label, StringComparison.OrdinalIgnoreCase));
			return Cache;
		}

		private static void AddCultivated()
		{
			GameObject itemPrefab = ObjectDB.instance.GetItemPrefab("Cultivator");
			foreach (GameObject item in ((itemPrefab == null) ? null : itemPrefab.GetComponent<ItemDrop>()?.m_itemData?.m_shared?.m_buildPieces?.m_pieces) ?? new List<GameObject>())
			{
				Plant val = (((Object)(object)item != (Object)null) ? item.GetComponent<Plant>() : null);
				Piece val2 = (((Object)(object)item != (Object)null) ? item.GetComponent<Piece>() : null);
				Requirement val3 = val2?.m_resources?.FirstOrDefault((Func<Requirement, bool>)((Requirement resource) => (Object)(object)resource?.m_resItem != (Object)null && resource.m_amount > 0));
				if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null || val3 == null || val.m_grownPrefabs == null)
				{
					continue;
				}
				List<GameObject> list = val.m_grownPrefabs.Where((GameObject grown) => (Object)(object)grown != (Object)null && (Object)(object)grown.GetComponentInChildren<Pickable>(true) != (Object)null).ToList();
				if (list.Count != 0)
				{
					CropKind cropKind = new CropKind
					{
						SeedlingPrefabName = ((Object)item).name,
						Seedling = item,
						SeedName = val3.m_resItem.m_itemData.m_shared.m_name,
						SeedPrefab = ((Object)((Component)val3.m_resItem).gameObject).name,
						Spacing = Mathf.Max(0.45f, val.m_growRadius)
					};
					DescribeRipeForms(cropKind, list);
					if (string.IsNullOrEmpty(cropKind.Label))
					{
						cropKind.Label = FriendlyName(((Object)item).name);
					}
					Cache.Add(cropKind);
				}
			}
		}

		private static void DescribeRipeForms(CropKind crop, List<GameObject> ripe)
		{
			foreach (GameObject item in ripe)
			{
				crop.RipeForms.Add(CleanPrefabName(((Object)item).name));
				Pickable component