Decompiled source of MoreHotkeys v1.0.3

MoreHotkeys.dll

Decompiled a month ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Eremite;
using Eremite.Buildings;
using Eremite.Buildings.UI;
using Eremite.Buildings.UI.Trade;
using Eremite.Characters;
using Eremite.Characters.Behaviours;
using Eremite.Characters.Villagers;
using Eremite.Controller;
using Eremite.MapObjects;
using Eremite.Model;
using Eremite.Services;
using Eremite.View;
using Eremite.View.HUD;
using Eremite.View.HUD.Woodcutters;
using Eremite.View.Popups;
using Eremite.View.Popups.Consumption;
using Eremite.View.Popups.Recipes;
using Eremite.View.UI.Wiki;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.InputSystem;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: AssemblyCompany("MoreHotkeys")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("MoreHotkeys")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+d6ada77561ccfe85ca4c2c807fd24c8c3fc0d51c")]
[assembly: AssemblyProduct("MoreHotkeys")]
[assembly: AssemblyTitle("MoreHotkeys")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace MoreHotkeys
{
	public class BuildingRecipeTooltip : MonoBehaviour
	{
		public static BuildingRecipeTooltip Instance;

		private const float ROW_WIDTH = 120f;

		private const float ROW_HEIGHT = 50f;

		private GameObject root;

		private RectTransform panel;

		private readonly List<GameObject> rows = new List<GameObject>();

		private void Awake()
		{
			Instance = this;
			InitializeWhenCanvasExists();
		}

		private void InitializeWhenCanvasExists()
		{
			Canvas val = Object.FindObjectOfType<Canvas>();
			if ((Object)(object)val == (Object)null)
			{
				SceneManager.sceneLoaded += OnSceneLoaded;
			}
			else
			{
				InitializeTooltipCanvas(val);
			}
		}

		private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
		{
			SceneManager.sceneLoaded -= OnSceneLoaded;
			Canvas val = Object.FindObjectOfType<Canvas>();
			if ((Object)(object)val != (Object)null)
			{
				InitializeTooltipCanvas(val);
			}
		}

		private void InitializeTooltipCanvas(Canvas hudCanvas)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Expected O, but got Unknown
			//IL_0067: 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_00a8: Expected O, but got Unknown
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("BuildingRecipeTooltipCanvas", new Type[1] { typeof(RectTransform) });
			val.transform.SetParent(((Component)hudCanvas).transform, false);
			Canvas val2 = val.AddComponent<Canvas>();
			val2.overrideSorting = true;
			val2.sortingOrder = 50000;
			CanvasScaler val3 = val.AddComponent<CanvasScaler>();
			val3.uiScaleMode = (ScaleMode)1;
			val3.referenceResolution = new Vector2(1920f, 1080f);
			val3.matchWidthOrHeight = 0.5f;
			val.AddComponent<GraphicRaycaster>();
			root = new GameObject("BuildingRecipeTooltipRoot", new Type[1] { typeof(RectTransform) });
			root.transform.SetParent(val.transform, false);
			root.SetActive(false);
			CanvasGroup val4 = root.AddComponent<CanvasGroup>();
			val4.blocksRaycasts = false;
			panel = new GameObject("Panel", new Type[1] { typeof(RectTransform) }).GetComponent<RectTransform>();
			((Component)panel).transform.SetParent(root.transform, false);
			panel.anchorMin = new Vector2(0f, 1f);
			panel.anchorMax = new Vector2(0f, 1f);
			panel.pivot = new Vector2(0f, 1f);
			CanvasGroup val5 = ((Component)panel).gameObject.AddComponent<CanvasGroup>();
			val5.blocksRaycasts = false;
			Image val6 = ((Component)panel).gameObject.AddComponent<Image>();
			((Graphic)val6).color = new Color(0.02f, 0.02f, 0.02f, 0.85f);
			((Graphic)val6).raycastTarget = false;
			panel.SetSizeWithCurrentAnchors((Axis)0, 120f);
		}

		public void Show(BuildingModel building)
		{
			Hide();
			InternalShow(building);
		}

		private void Update()
		{
			if ((Object)(object)root != (Object)null && root.activeSelf)
			{
				UpdatePosition();
			}
		}

		private void InternalShow(BuildingModel building)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Expected O, but got Unknown
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			foreach (Transform item in ((Component)panel).transform)
			{
				Transform val = item;
				Object.Destroy((Object)(object)((Component)val).gameObject);
			}
			rows.Clear();
			if ((Object)(object)panel == (Object)null)
			{
				return;
			}
			WorkshopModel val2 = (WorkshopModel)(object)((building is WorkshopModel) ? building : null);
			if ((Object)(object)val2 == (Object)null || val2.recipes == null)
			{
				return;
			}
			List<WorkshopRecipeModel> list = (from g in val2.recipes.GroupBy(delegate(WorkshopRecipeModel r)
				{
					GoodRef producedGood = r.producedGood;
					object result;
					if (producedGood == null)
					{
						result = null;
					}
					else
					{
						GoodModel good = producedGood.good;
						result = ((good != null) ? ((Object)good).name : null);
					}
					return (string)result;
				})
				select g.First()).ToList();
			float num = 0f;
			int num2 = 0;
			foreach (WorkshopRecipeModel item2 in list)
			{
				GameObject val3 = CreateRow(item2, num2);
				RectTransform component = val3.GetComponent<RectTransform>();
				component.anchoredPosition = new Vector2(0f, 0f - num);
				num += 50f;
				rows.Add(val3);
				num2++;
			}
			panel.SetSizeWithCurrentAnchors((Axis)1, num + 6f);
			root.SetActive(true);
			UpdatePosition();
		}

		private GameObject CreateRow(WorkshopRecipeModel recipe, int rowIndex)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Expected O, but got Unknown
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: 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_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: 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_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Expected O, but got Unknown
			//IL_01f4: 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_0222: Unknown result type (might be due to invalid IL or missing references)
			//IL_0239: Unknown result type (might be due to invalid IL or missing references)
			//IL_0275: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cb: Expected O, but got Unknown
			//IL_02f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_030b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0322: Unknown result type (might be due to invalid IL or missing references)
			//IL_0339: Unknown result type (might be due to invalid IL or missing references)
			//IL_0359: Unknown result type (might be due to invalid IL or missing references)
			//IL_035e: Unknown result type (might be due to invalid IL or missing references)
			//IL_037e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0383: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b3: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject($"RecipeRow_{rowIndex}", new Type[1] { typeof(RectTransform) });
			val.transform.SetParent((Transform)(object)panel, false);
			RectTransform component = val.GetComponent<RectTransform>();
			component.anchorMin = new Vector2(0f, 1f);
			component.anchorMax = new Vector2(0f, 1f);
			component.pivot = new Vector2(0f, 1f);
			component.SetSizeWithCurrentAnchors((Axis)0, 120f);
			component.SetSizeWithCurrentAnchors((Axis)1, 50f);
			Image val2 = val.AddComponent<Image>();
			((Graphic)val2).color = new Color(0.05f, 0.05f, 0.05f, 0.95f);
			((Graphic)val2).raycastTarget = false;
			Outline val3 = val.AddComponent<Outline>();
			((Shadow)val3).effectColor = new Color(0.55f, 0.45f, 0.2f, 1f);
			((Shadow)val3).effectDistance = new Vector2(1f, -1f);
			Outline val4 = val.AddComponent<Outline>();
			((Shadow)val4).effectColor = new Color(0.12f, 0.12f, 0.1f, 1f);
			((Shadow)val4).effectDistance = new Vector2(-1f, 1f);
			Shadow val5 = val.AddComponent<Shadow>();
			val5.effectColor = new Color(0f, 0f, 0f, 0.7f);
			val5.effectDistance = new Vector2(2f, -2f);
			Sprite sprite = recipe.producedGood?.good?.icon;
			GameObject val6 = new GameObject("Icon", new Type[1] { typeof(RectTransform) });
			val6.transform.SetParent(val.transform, false);
			RectTransform component2 = val6.GetComponent<RectTransform>();
			component2.anchorMin = new Vector2(0f, 0.5f);
			component2.anchorMax = new Vector2(0f, 0.5f);
			component2.pivot = new Vector2(0f, 0.5f);
			component2.anchoredPosition = new Vector2(8f, 0f);
			component2.SetSizeWithCurrentAnchors((Axis)0, 48f);
			component2.SetSizeWithCurrentAnchors((Axis)1, 48f);
			Image val7 = val6.AddComponent<Image>();
			val7.sprite = sprite;
			((Graphic)val7).color = Color.white;
			if ((Object)(object)((RecipeModel)recipe).grade != (Object)null && (Object)(object)((RecipeModel)recipe).grade.icon != (Object)null)
			{
				GameObject val8 = new GameObject("GradeBar", new Type[1] { typeof(RectTransform) });
				val8.transform.SetParent(val.transform, false);
				RectTransform component3 = val8.GetComponent<RectTransform>();
				component3.anchorMin = new Vector2(0f, 0.5f);
				component3.anchorMax = new Vector2(0f, 0.5f);
				component3.pivot = new Vector2(0f, 0.5f);
				component3.anchoredPosition = new Vector2(60f, 0f);
				float num = 1f;
				Rect rect = ((RecipeModel)recipe).grade.icon.rect;
				component3.SetSizeWithCurrentAnchors((Axis)0, ((Rect)(ref rect)).width * num);
				rect = ((RecipeModel)recipe).grade.icon.rect;
				component3.SetSizeWithCurrentAnchors((Axis)1, ((Rect)(ref rect)).height * num);
				Image val9 = val8.AddComponent<Image>();
				val9.sprite = ((RecipeModel)recipe).grade.icon;
				((Graphic)val9).color = Color.white;
			}
			return val;
		}

		public void Hide()
		{
			if ((Object)(object)root == (Object)null)
			{
				return;
			}
			foreach (GameObject row in rows)
			{
				if ((Object)(object)row != (Object)null)
				{
					Object.Destroy((Object)(object)row);
				}
			}
			rows.Clear();
			root.SetActive(false);
		}

		private void UpdatePosition()
		{
			//IL_001d: 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_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)panel == (Object)null))
			{
				Vector2 val = ((InputControl<Vector2>)(object)((Pointer)Mouse.current).position).ReadValue();
				val.x += 40f;
				val.y += 40f;
				((Transform)panel).position = Vector2.op_Implicit(val);
			}
		}
	}
	public class BuildingRecipeTooltipTrigger : MonoBehaviour, IPointerEnterHandler, IEventSystemHandler, IPointerExitHandler
	{
		public BuildingModel BuildingModel;

		public void OnPointerEnter(PointerEventData eventData)
		{
			if ((Object)(object)BuildingModel != (Object)null)
			{
				BuildingRecipeTooltip.Instance?.Show(BuildingModel);
			}
		}

		public void OnPointerExit(PointerEventData eventData)
		{
			BuildingRecipeTooltip.Instance?.Hide();
		}
	}
	[HarmonyPatch]
	public static class BuildingRecipeTooltipSystem
	{
		[HarmonyPatch(typeof(RecipesPopupWorkshopPreviewSlot), "SetUp")]
		[HarmonyPostfix]
		private static void PreviewSlot_SetUp_Postfix(RecipesPopupWorkshopPreviewSlot __instance, BuildingModel workshop, WorkshopRecipeModel recipe, Action<IRecipeSlot> interactionCallback)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected O, but got Unknown
			if ((Object)(object)workshop == (Object)null)
			{
				return;
			}
			if ((Object)(object)BuildingRecipeTooltip.Instance == (Object)null)
			{
				GameObject val = new GameObject("BuildingRecipeTooltip");
				val.AddComponent<BuildingRecipeTooltip>();
			}
			object? obj = typeof(RecipesPopupWorkshopPreviewSlot).GetField("buildingIcon", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(__instance);
			Image val2 = (Image)((obj is Image) ? obj : null);
			if ((Object)(object)val2 == (Object)null)
			{
				return;
			}
			GameObject gameObject = ((Component)val2).gameObject;
			BuildingRecipeTooltipTrigger buildingRecipeTooltipTrigger = gameObject.GetComponent<BuildingRecipeTooltipTrigger>();
			if ((Object)(object)buildingRecipeTooltipTrigger == (Object)null)
			{
				buildingRecipeTooltipTrigger = gameObject.AddComponent<BuildingRecipeTooltipTrigger>();
			}
			buildingRecipeTooltipTrigger.BuildingModel = workshop;
			((Graphic)val2).raycastTarget = true;
			Image[] componentsInChildren = ((Component)__instance).GetComponentsInChildren<Image>();
			foreach (Image val3 in componentsInChildren)
			{
				if ((Object)(object)val3 != (Object)(object)val2)
				{
					((Graphic)val3).raycastTarget = false;
				}
			}
		}
	}
	public class ConditionsHUDSync : MonoBehaviour
	{
		private class PopupInfo
		{
			public GameObject Blend;

			public GameObject Content;
		}

		private static GameObject gmBlend;

		private static GameObject gmContent;

		private static GameObject main;

		private static PopupInfo[] popups;

		private static bool hudReady;

		private static bool lastPopupOpen;

		public static ConfigEntry<bool> ConditionsHUD;

		public static void Init(ConfigFile config, Harmony harmony, GameObject host)
		{
			ConditionsHUD = config.Bind<bool>("ConditionsHUD", "ConditionsHUD", true, "ConditionsHUD and DeedsHUD pops up alongside every popup from Orders to Trends.");
			host.AddComponent<ConditionsHUDSync>();
		}

		private void Update()
		{
			if (ConditionsHUD != null && !ConditionsHUD.Value)
			{
				return;
			}
			if (!hudReady)
			{
				TryResolveHUD();
			}
			if (hudReady && !((Object)(object)gmContent == (Object)null) && !((Object)(object)gmBlend == (Object)null))
			{
				bool flag = IsAnyPopupVisible();
				bool flag2 = gmBlend.activeSelf && !flag;
				if (flag && !lastPopupOpen)
				{
					gmContent.SetActive(true);
					main.SetActive(false);
				}
				else if (!flag && lastPopupOpen)
				{
					gmContent.SetActive(false);
					main.SetActive(true);
				}
				lastPopupOpen = flag;
				if (!flag2)
				{
				}
			}
		}

		private static void TryResolveHUD()
		{
			GameObject val = GameObject.Find("HUD");
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			FixHierarchy(val);
			Transform val2 = val.transform.Find("GameMenuPopup");
			if ((Object)(object)val2 == (Object)null)
			{
				return;
			}
			Transform obj = val2.Find("Blend");
			gmBlend = ((obj != null) ? ((Component)obj).gameObject : null);
			Transform obj2 = val2.Find("Content");
			gmContent = ((obj2 != null) ? ((Component)obj2).gameObject : null);
			if (!((Object)(object)gmBlend == (Object)null) && !((Object)(object)gmContent == (Object)null))
			{
				Transform obj3 = gmContent.transform.Find("Main");
				main = ((obj3 != null) ? ((Component)obj3).gameObject : null);
				if (!((Object)(object)main == (Object)null))
				{
					popups = new PopupInfo[6]
					{
						ResolvePopup(val, "OrdersPopup"),
						ResolvePopup(val, "TraderPanel"),
						ResolvePopup(val, "TradeRoutesPopup"),
						ResolvePopup(val, "RecipesPopup"),
						ResolvePopup(val, "ConsumptionPopup"),
						ResolvePopup(val, "TrendsPopup")
					};
					hudReady = true;
				}
			}
		}

		private static void FixHierarchy(GameObject hud)
		{
			Transform val = hud.transform.Find("RecipesPopup");
			Transform val2 = hud.transform.Find("ConsumptionPopup");
			if ((Object)(object)val != (Object)null && (Object)(object)val2 != (Object)null)
			{
				val2.SetSiblingIndex(val.GetSiblingIndex() + 1);
			}
			Transform val3 = hud.transform.Find("GameMenuPopup");
			Transform val4 = hud.transform.Find("OrderPickPopup");
			if ((Object)(object)val3 != (Object)null && (Object)(object)val4 != (Object)null)
			{
				val4.SetSiblingIndex(val3.GetSiblingIndex());
			}
		}

		private static PopupInfo ResolvePopup(GameObject hud, string name)
		{
			Transform val = hud.transform.Find(name);
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			Transform val2 = val.Find("Blend");
			Transform val3 = val.Find("Content");
			return new PopupInfo
			{
				Blend = (((Object)(object)val2 != (Object)null) ? ((Component)val2).gameObject : null),
				Content = (((Object)(object)val3 != (Object)null) ? ((Component)val3).gameObject : null)
			};
		}

		private static bool IsAnyPopupVisible()
		{
			if (popups == null)
			{
				return false;
			}
			PopupInfo[] array = popups;
			foreach (PopupInfo popupInfo in array)
			{
				if (popupInfo != null && !((Object)(object)popupInfo.Blend == (Object)null) && !((Object)(object)popupInfo.Content == (Object)null) && popupInfo.Blend.activeSelf && popupInfo.Content.activeSelf)
				{
					return true;
				}
			}
			return false;
		}
	}
	public static class ConsumptionControl
	{
		private static bool _active = false;

		internal static ConsumptionPopup ActivePopup;

		private static readonly HashSet<NeedModel> OptimizedFoodNeeds = new HashSet<NeedModel>();

		internal static GameObject _needsControlRow;

		internal static GameObject _needsControlColumn;

		internal static MasterToggle _needsToggle;

		private static float toggleShiftX = 717f;

		private static float toggleShiftY = 45f;

		private static float headerLocalShiftY = 0f;

		private static float toggleLocalShiftY = 45f;

		internal static void InjectNeedsControlUI(ConsumptionPopup popup)
		{
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Expected O, but got Unknown
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: 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_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: Expected O, but got Unknown
			//IL_01e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0210: Unknown result type (might be due to invalid IL or missing references)
			//IL_0227: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b4: Expected O, but got Unknown
			//IL_02e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_030f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0326: Unknown result type (might be due to invalid IL or missing references)
			//IL_0345: Unknown result type (might be due to invalid IL or missing references)
			//IL_034a: Unknown result type (might be due to invalid IL or missing references)
			//IL_036e: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0401: Unknown result type (might be due to invalid IL or missing references)
			//IL_040b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0418: Unknown result type (might be due to invalid IL or missing references)
			//IL_041d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0431: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_04cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ec: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)popup == (Object)null || (Object)(object)((Component)popup).gameObject == (Object)null)
			{
				return;
			}
			Transform val = ((Component)popup).transform.Find("Content");
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			Transform val2 = val.Find("SlotsHeader");
			Transform val3 = val.Find("RawFood");
			if ((Object)(object)val2 == (Object)null || (Object)(object)val3 == (Object)null)
			{
				return;
			}
			if ((Object)(object)_needsControlRow != (Object)null)
			{
				RefreshNeedsToggleVisual();
				return;
			}
			_needsControlRow = new GameObject("NeedsControlRow", new Type[1] { typeof(RectTransform) });
			_needsControlRow.transform.SetParent(val, false);
			int siblingIndex = val2.GetSiblingIndex() + 1;
			_needsControlRow.transform.SetSiblingIndex(siblingIndex);
			RectTransform component = _needsControlRow.GetComponent<RectTransform>();
			component.anchorMin = new Vector2(0f, 1f);
			component.anchorMax = new Vector2(1f, 1f);
			component.pivot = new Vector2(0.5f, 1f);
			component.sizeDelta = new Vector2(0f, 0f);
			HorizontalLayoutGroup val4 = _needsControlRow.AddComponent<HorizontalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)val4).childForceExpandWidth = false;
			((HorizontalOrVerticalLayoutGroup)val4).childForceExpandHeight = false;
			((HorizontalOrVerticalLayoutGroup)val4).spacing = 0f;
			((LayoutGroup)val4).padding.top = 250;
			_needsControlColumn = new GameObject("NeedsControlColumn", new Type[1] { typeof(RectTransform) });
			_needsControlColumn.transform.SetParent(_needsControlRow.transform, false);
			RectTransform component2 = _needsControlColumn.GetComponent<RectTransform>();
			component2.anchorMin = new Vector2(0.5f, 1f);
			component2.anchorMax = new Vector2(0.5f, 1f);
			component2.pivot = new Vector2(0.5f, 1f);
			component2.sizeDelta = new Vector2(0f, 0f);
			VerticalLayoutGroup val5 = _needsControlColumn.AddComponent<VerticalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)val5).childControlWidth = false;
			((HorizontalOrVerticalLayoutGroup)val5).childControlHeight = false;
			((HorizontalOrVerticalLayoutGroup)val5).childForceExpandWidth = false;
			((HorizontalOrVerticalLayoutGroup)val5).childForceExpandHeight = false;
			((HorizontalOrVerticalLayoutGroup)val5).spacing = 2f;
			LayoutElement val6 = _needsControlColumn.AddComponent<LayoutElement>();
			val6.preferredWidth = 200f;
			val6.minWidth = 200f;
			GameObject val7 = new GameObject("NeedsControlContainer", new Type[1] { typeof(RectTransform) });
			val7.transform.SetParent(_needsControlColumn.transform, false);
			RectTransform component3 = val7.GetComponent<RectTransform>();
			component3.anchorMin = new Vector2(0.5f, 1f);
			component3.anchorMax = new Vector2(0.5f, 1f);
			component3.pivot = new Vector2(0.5f, 1f);
			component3.sizeDelta = new Vector2(200f, 0f);
			LayoutElement val8 = val7.AddComponent<LayoutElement>();
			val8.ignoreLayout = true;
			Vector2 anchoredPosition = component3.anchoredPosition;
			anchoredPosition.x += toggleShiftX;
			anchoredPosition.y += toggleShiftY;
			component3.anchoredPosition = anchoredPosition;
			Transform val9 = val3.Find("Header Text");
			if ((Object)(object)val9 == (Object)null)
			{
				return;
			}
			GameObject val10 = Object.Instantiate<GameObject>(((Component)val9).gameObject, val7.transform);
			((Object)val10).name = "NeedsControlHeader";
			TMP_Text component4 = val10.GetComponent<TMP_Text>();
			component4.text = "Needs Control";
			((Graphic)component4).color = new Color(0.9137f, 0.7961f, 0.4863f, 1f);
			RectTransform component5 = val10.GetComponent<RectTransform>();
			component5.sizeDelta = new Vector2(200f, component5.sizeDelta.y);
			Vector2 anchoredPosition2 = component5.anchoredPosition;
			anchoredPosition2.y += headerLocalShiftY;
			component5.anchoredPosition = anchoredPosition2;
			Transform val11 = val.Find("SlotsHeader/NeedCategorySlot");
			if ((Object)(object)val11 == (Object)null)
			{
				Debug.LogError((object)"[MoreHotkeys] ComplexFood NeedCategorySlot not found.");
				return;
			}
			MasterToggle componentInChildren = ((Component)val11).GetComponentInChildren<MasterToggle>(true);
			if ((Object)(object)componentInChildren == (Object)null)
			{
				Debug.LogError((object)"[MoreHotkeys] No MasterToggle found under ComplexFood.");
				return;
			}
			GameObject val12 = Object.Instantiate<GameObject>(((Component)componentInChildren).gameObject, val7.transform);
			((Object)val12).name = "NeedsControlToggle";
			_needsToggle = val12.GetComponent<MasterToggle>();
			RectTransform component6 = val12.GetComponent<RectTransform>();
			Vector2 anchoredPosition3 = component6.anchoredPosition;
			anchoredPosition3.y += toggleLocalShiftY;
			anchoredPosition3.x = 0f;
			component6.anchoredPosition = anchoredPosition3;
			_needsToggle.SetUp((MasterToggleState)(_active ? 2 : 0), true, (Action<bool>)delegate(bool isOn)
			{
				_active = isOn;
				if (_active)
				{
					ApplyOptimized();
				}
				else
				{
					ApplyDefault();
				}
				RefreshPopup();
			});
		}

		private static void RefreshNeedsToggleVisual()
		{
			if ((Object)(object)_needsToggle == (Object)null)
			{
				return;
			}
			_needsToggle.SetUp((MasterToggleState)(_active ? 2 : 0), true, (Action<bool>)delegate(bool isOn)
			{
				_active = isOn;
				if (_active)
				{
					ApplyOptimized();
				}
				else
				{
					ApplyDefault();
				}
				RefreshPopup();
			});
		}

		private static void RefreshPopup()
		{
			if ((Object)(object)ActivePopup != (Object)null && ((Popup)ActivePopup).IsShown())
			{
				ActivePopup.Show(false);
			}
		}

		private static bool IsFoodNeed(NeedModel need)
		{
			return (Object)(object)need != (Object)null && need.canBeProhibited && (Object)(object)need.referenceGood != (Object)null && need.referenceGood.eatable && (!((Object)(object)need.category != (Object)null) || !need.category.isHouseBased);
		}

		private static void ApplyOptimized()
		{
			OptimizedFoodNeeds.Clear();
			Dictionary<string, bool> rawFoodConsumptionPermits = GameMB.StateService.Actors.rawFoodConsumptionPermits;
			foreach (string item in new List<string>(rawFoodConsumptionPermits.Keys))
			{
				GameMB.NeedsService.SetPermision(item, false);
			}
			RaceModel[] races = GameMB.RacesService.Races;
			HashSet<NeedModel> hashSet = new HashSet<NeedModel>();
			NeedModel[] needs = MB.Settings.Needs;
			foreach (NeedModel val in needs)
			{
				if (IsFoodNeed(val))
				{
					hashSet.Add(val);
				}
			}
			foreach (NeedModel item2 in hashSet)
			{
				bool flag = false;
				RaceModel[] array = races;
				foreach (RaceModel val2 in array)
				{
					if ((Object)(object)val2 != (Object)null && GameMB.RacesService.IsRevealed(val2) && val2.HasNeed(item2))
					{
						flag = true;
						break;
					}
				}
				RaceModel[] array2 = races;
				foreach (RaceModel val3 in array2)
				{
					if (!((Object)(object)val3 == (Object)null) && GameMB.RacesService.IsRevealed(val3))
					{
						bool flag2 = !flag || val3.HasNeed(item2);
						OptimizedFoodNeeds.Add(item2);
						GameMB.NeedsService.SetPermision(val3, item2, flag2);
					}
				}
			}
		}

		private static void ApplyDefault()
		{
			Dictionary<string, bool> rawFoodConsumptionPermits = GameMB.StateService.Actors.rawFoodConsumptionPermits;
			foreach (string item in new List<string>(rawFoodConsumptionPermits.Keys))
			{
				GameMB.NeedsService.SetPermision(item, true);
			}
			RaceModel[] races = GameMB.RacesService.Races;
			RaceModel[] array = races;
			foreach (RaceModel val in array)
			{
				if ((Object)(object)val == (Object)null || !GameMB.RacesService.IsRevealed(val))
				{
					continue;
				}
				foreach (NeedModel optimizedFoodNeed in OptimizedFoodNeeds)
				{
					if ((Object)(object)optimizedFoodNeed != (Object)null)
					{
						GameMB.NeedsService.SetPermision(val, optimizedFoodNeed, true);
					}
				}
			}
		}
	}
	[HarmonyPatch(typeof(ConsumptionPopup), "Show", new Type[] { typeof(bool) })]
	public static class ConsumptionControl_ConsumptionPopup_Show_Patch
	{
		private static void Postfix(ConsumptionPopup __instance)
		{
			ConsumptionControl.ActivePopup = __instance;
			ConsumptionControl.InjectNeedsControlUI(__instance);
		}
	}
	public static class CtrlClickResourceToIngredientPanel
	{
		[HarmonyPatch(typeof(GameInputService), "PickTarget")]
		public static class PickTargetPatch
		{
			private static bool Prefix(GameInputService __instance)
			{
				//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)
				IInputService inputService = MB.InputService;
				DefaultActions inputConfig = MB.InputConfig;
				if (!inputService.IsTriggering(((DefaultActions)(ref inputConfig)).InputModifierControl))
				{
					return true;
				}
				IMapObject value = __instance.MouseoverObject.Value;
				if (value == null)
				{
					return true;
				}
				if (TryOpenIngredientPanel(value))
				{
					return false;
				}
				return true;
			}
		}

		[HarmonyPatch(typeof(RecipesPopup), "Show")]
		public static class ForceIngredientModePatch
		{
			private static void Postfix(RecipesPopup __instance, RecipesPopupRequest request)
			{
				if (!((Object)(object)lastRequestedGood == (Object)null))
				{
					__instance.Search(lastRequestedGood, (SearchType)1);
					lastRequestedGood = null;
				}
			}
		}

		private static GoodModel lastRequestedGood;

		private static bool TryOpenIngredientPanel(IMapObject obj)
		{
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			GoodModel val = null;
			NaturalResource val2 = (NaturalResource)(object)((obj is NaturalResource) ? obj : null);
			if (val2 != null)
			{
				val = val2.Model.refGood;
			}
			else
			{
				ResourceDeposit val3 = (ResourceDeposit)(object)((obj is ResourceDeposit) ? obj : null);
				if (val3 != null)
				{
					val = MB.Settings.GetGood(val3.GetProducedGood());
				}
				else
				{
					Lake val4 = (Lake)(object)((obj is Lake) ? obj : null);
					if (val4 == null)
					{
						return false;
					}
					val = ((ResourceModel)val4.Model).production.good;
				}
			}
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			lastRequestedGood = val;
			RecipesPopupRequest val5 = default(RecipesPopupRequest);
			((RecipesPopupRequest)(ref val5))..ctor(val, true);
			GameMB.GameBlackboardService.RecipesPopupRequested.OnNext(val5);
			return true;
		}
	}
	public static class CycleUnbuiltBuildingsHotkey
	{
		private static bool cyclingMode;

		private static List<BuildingModel> unbuilt;

		private static int index;

		public static void OnUpdate(KeyboardShortcut forwardKey, KeyboardShortcut backwardKey)
		{
			//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)
			if (!GameController.IsGameActive || MB.InputService.IsLocked())
			{
				return;
			}
			if (((KeyboardShortcut)(ref forwardKey)).IsDown())
			{
				if (!cyclingMode)
				{
					EnterMode();
				}
				else
				{
					CycleNext();
				}
			}
			else if (((KeyboardShortcut)(ref backwardKey)).IsDown())
			{
				if (!cyclingMode)
				{
					EnterMode();
				}
				else
				{
					CyclePrev();
				}
			}
			else if (cyclingMode)
			{
				IInputService inputService = MB.InputService;
				DefaultActions inputConfig = MB.InputConfig;
				if (inputService.WasTriggered(((DefaultActions)(ref inputConfig)).Cancel, false))
				{
					ExitMode();
				}
			}
		}

		private static void EnterMode()
		{
			unbuilt = GetUnbuiltBuildings();
			if (unbuilt.Count != 0)
			{
				cyclingMode = true;
				index = 0;
				ShowBuilding(unbuilt[index]);
			}
		}

		private static void ExitMode()
		{
			cyclingMode = false;
			unbuilt = null;
			index = 0;
		}

		public static void OnBlueprintUnlocked(BuildingModel model)
		{
			if (cyclingMode)
			{
				RefreshList();
			}
		}

		private static void RefreshList()
		{
			List<BuildingModel> unbuiltBuildings = GetUnbuiltBuildings();
			if (unbuilt == null || unbuiltBuildings.Count != unbuilt.Count)
			{
				unbuilt = unbuiltBuildings;
				if (unbuilt.Count == 0)
				{
					ExitMode();
				}
				else
				{
					index = Mathf.Clamp(index, 0, unbuilt.Count - 1);
				}
			}
		}

		private static void CycleNext()
		{
			RefreshList();
			if (cyclingMode && unbuilt != null && unbuilt.Count != 0)
			{
				index = (index + 1) % unbuilt.Count;
				ShowBuilding(unbuilt[index]);
			}
		}

		private static void CyclePrev()
		{
			RefreshList();
			if (cyclingMode && unbuilt != null && unbuilt.Count != 0)
			{
				index = (index - 1 + unbuilt.Count) % unbuilt.Count;
				ShowBuilding(unbuilt[index]);
			}
		}

		private static void ShowBuilding(BuildingModel model)
		{
			if (GameMB.GameContentService.IsUnlocked(model) && GameMB.ConstructionService.CanConstruct(model))
			{
				GameMB.GameBlackboardService.BuildingConstructionRequested.OnNext(model);
			}
		}

		private static List<BuildingModel> GetUnbuiltBuildings()
		{
			List<BuildingModel> value = GameMB.GameContentService.Buildings.Value;
			HashSet<string> builtNames = new HashSet<string>(GameMB.BuildingsService.Buildings.Values.Select((Building b) => ((Object)b.BuildingModel).name));
			BuildingCategoryModel[] buildingCategories = MB.Settings.BuildingCategories;
			BuildingCategoryModel item = ((IEnumerable<BuildingCategoryModel>)buildingCategories).FirstOrDefault((Func<BuildingCategoryModel, bool>)((BuildingCategoryModel c) => ((SO)c).Name == "Food Production"));
			BuildingCategoryModel item2 = ((IEnumerable<BuildingCategoryModel>)buildingCategories).FirstOrDefault((Func<BuildingCategoryModel, bool>)((BuildingCategoryModel c) => ((SO)c).Name == "Industry"));
			BuildingCategoryModel item3 = ((IEnumerable<BuildingCategoryModel>)buildingCategories).FirstOrDefault((Func<BuildingCategoryModel, bool>)((BuildingCategoryModel c) => ((SO)c).Name == "City Buildings"));
			HashSet<BuildingCategoryModel> allowedCategories = new HashSet<BuildingCategoryModel> { item, item2, item3 };
			HashSet<string> excludedNames = new HashSet<string> { "Temporary Hearth (buildable)", "Storage (buildable)", "Hydrant" };
			IEnumerable<BuildingModel> source = value.Where((BuildingModel model) => (Object)(object)model != (Object)null && (Object)(object)model.category != (Object)null && allowedCategories.Contains(model.category) && !excludedNames.Contains(((SO)model).Name) && GameMB.ConstructionService.ShouldShowInShop(model) && GameMB.GameContentService.IsUnlocked(model) && GameMB.ConstructionService.CanConstruct(model) && !builtNames.Contains(((Object)model).name) && (model.tags == null || !model.tags.Any((BuildingTagModel t) => t.iconTag == "Pipe" || t.iconTag == "Resource")));
			return (from m in source
				orderby m.category.order, m.Order, ((SO)m).Name
				select m).ToList();
		}
	}
	[HarmonyPatch(typeof(GameContentService), "Unlock")]
	public static class Patch_GameContentService_Unlock
	{
		public static void Postfix(BuildingModel building)
		{
			CycleUnbuiltBuildingsHotkey.OnBlueprintUnlocked(building);
		}
	}
	[HarmonyPatch(typeof(RecipesOverlaysManager), "OnHighlightStarted")]
	public static class DisableRecipeOverlayWhenWorkplaceOverlayOpen
	{
		private static bool Prefix()
		{
			BuildingWorkersOverlay val = Object.FindObjectOfType<BuildingWorkersOverlay>();
			if ((Object)(object)val != (Object)null && ((Component)val).gameObject.activeInHierarchy)
			{
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch]
	public static class HotkeyManager
	{
		public static ConfigEntry<KeyboardShortcut> KeyGeneral;

		public static ConfigEntry<KeyboardShortcut> KeyBuildings;

		public static ConfigEntry<KeyboardShortcut> KeyCornerstones;

		public static ConfigEntry<KeyboardShortcut> KeyTraders;

		public static ConfigEntry<KeyboardShortcut> KeyEvents;

		public static ConfigEntry<KeyboardShortcut> KeySpecies;

		public static ConfigEntry<KeyboardShortcut> KeyTradingPost;

		public static ConfigEntry<KeyboardShortcut> KeyCycleUnbuiltForward;

		public static ConfigEntry<KeyboardShortcut> KeyCycleUnbuiltBackward;

		public static ConfigEntry<KeyboardShortcut> KeyConsumptionControl;

		private static WikiPopup wikiPopup;

		private static WikiBasicPanel panelGeneral;

		private static WikiBuildingsPanel panelBuildings;

		private static WikiEffectsPanel panelCornerstones;

		private static WikiTradersPanel panelTraders;

		private static WikiRelicsPanel panelEvents;

		private static WikiRacesPanel panelSpecies;

		public static ConfigEntry<KeyboardShortcut> KeyToggleConditionsHUD;

		static HotkeyManager()
		{
			//IL_0019: 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_006b: 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_00bd: 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_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			ConfigFile configFile = MoreHotkeysPlugin.ConfigFile;
			KeyToggleConditionsHUD = configFile.Bind<KeyboardShortcut>("Hotkeys", "ToggleConditionsHUD", new KeyboardShortcut((KeyCode)108, Array.Empty<KeyCode>()), "Toggle the Conditions HUD sync on/off");
			KeyGeneral = configFile.Bind<KeyboardShortcut>("Hotkeys", "EncyclopediaGeneral", new KeyboardShortcut((KeyCode)282, Array.Empty<KeyCode>()), "Open Encyclopedia → General");
			KeyBuildings = configFile.Bind<KeyboardShortcut>("Hotkeys", "EncyclopediaBuildings", new KeyboardShortcut((KeyCode)283, Array.Empty<KeyCode>()), "Open Encyclopedia → Buildings");
			KeyCornerstones = configFile.Bind<KeyboardShortcut>("Hotkeys", "EncyclopediaCornerstones", new KeyboardShortcut((KeyCode)284, Array.Empty<KeyCode>()), "Open Encyclopedia → Cornerstones");
			KeyTraders = configFile.Bind<KeyboardShortcut>("Hotkeys", "EncyclopediaTraders", new KeyboardShortcut((KeyCode)285, Array.Empty<KeyCode>()), "Open Encyclopedia → Traders");
			KeyEvents = configFile.Bind<KeyboardShortcut>("Hotkeys", "EncyclopediaEvents", new KeyboardShortcut((KeyCode)286, Array.Empty<KeyCode>()), "Open Encyclopedia → Events");
			KeySpecies = configFile.Bind<KeyboardShortcut>("Hotkeys", "EncyclopediaSpecies", new KeyboardShortcut((KeyCode)287, Array.Empty<KeyCode>()), "Open Encyclopedia → Species");
			KeyTradingPost = configFile.Bind<KeyboardShortcut>("Hotkeys", "OpenTradingPost", new KeyboardShortcut((KeyCode)106, Array.Empty<KeyCode>()), "Toggle the Trading Post window");
			KeyCycleUnbuiltBackward = configFile.Bind<KeyboardShortcut>("Hotkeys", "CycleUnbuiltBackward", new KeyboardShortcut((KeyCode)120, Array.Empty<KeyCode>()), "Cycle backward through unbuilt buildings");
			KeyCycleUnbuiltForward = configFile.Bind<KeyboardShortcut>("Hotkeys", "CycleUnbuiltForward", new KeyboardShortcut((KeyCode)99, Array.Empty<KeyCode>()), "Cycle forward through unbuilt buildings");
		}

		private static void ToggleConditionsHUD()
		{
			if (ConditionsHUDSync.ConditionsHUD == null)
			{
				return;
			}
			bool flag = !ConditionsHUDSync.ConditionsHUD.Value;
			ConditionsHUDSync.ConditionsHUD.Value = flag;
			GameObject val = GameObject.Find("HUD");
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			Transform val2 = val.transform.Find("GameMenuPopup");
			if ((Object)(object)val2 == (Object)null)
			{
				return;
			}
			Transform obj = val2.Find("Content");
			GameObject val3 = ((obj != null) ? ((Component)obj).gameObject : null);
			object obj2;
			if (val3 == null)
			{
				obj2 = null;
			}
			else
			{
				Transform obj3 = val3.transform.Find("Main");
				obj2 = ((obj3 != null) ? ((Component)obj3).gameObject : null);
			}
			GameObject val4 = (GameObject)obj2;
			if (!((Object)(object)val3 == (Object)null) && !((Object)(object)val4 == (Object)null))
			{
				if (!flag)
				{
					val3.SetActive(false);
					val4.SetActive(true);
				}
				else if (IsAnyPopupVisible())
				{
					val3.SetActive(true);
					val4.SetActive(false);
				}
			}
		}

		private static bool IsAnyPopupVisible()
		{
			return ConditionsHUDSync.ConditionsHUD != null && ConditionsHUDSync.ConditionsHUD.Value && (bool)typeof(ConditionsHUDSync).GetMethod("IsAnyPopupVisible", BindingFlags.Static | BindingFlags.NonPublic).Invoke(null, null);
		}

		[HarmonyPatch(typeof(WikiPopup), "SetUp")]
		[HarmonyPostfix]
		private static void WikiPopup_SetUp(WikiPopup __instance)
		{
			wikiPopup = __instance;
			WikiCategoryPanel[] panels = __instance.panels;
			foreach (WikiCategoryPanel val in panels)
			{
				WikiBasicPanel val2 = (WikiBasicPanel)(object)((val is WikiBasicPanel) ? val : null);
				if (val2 != null)
				{
					panelGeneral = val2;
					continue;
				}
				WikiBuildingsPanel val3 = (WikiBuildingsPanel)(object)((val is WikiBuildingsPanel) ? val : null);
				if (val3 != null)
				{
					panelBuildings = val3;
					continue;
				}
				WikiEffectsPanel val4 = (WikiEffectsPanel)(object)((val is WikiEffectsPanel) ? val : null);
				if (val4 != null)
				{
					panelCornerstones = val4;
					continue;
				}
				WikiTradersPanel val5 = (WikiTradersPanel)(object)((val is WikiTradersPanel) ? val : null);
				if (val5 != null)
				{
					panelTraders = val5;
					continue;
				}
				WikiRelicsPanel val6 = (WikiRelicsPanel)(object)((val is WikiRelicsPanel) ? val : null);
				if (val6 != null)
				{
					panelEvents = val6;
					continue;
				}
				WikiRacesPanel val7 = (WikiRacesPanel)(object)((val is WikiRacesPanel) ? val : null);
				if (val7 != null)
				{
					panelSpecies = val7;
				}
			}
		}

		public static void OnUpdate()
		{
			//IL_000d: 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_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_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			KeyboardShortcut value;
			if (ConditionsHUDSync.ConditionsHUD != null)
			{
				value = KeyToggleConditionsHUD.Value;
				if (((KeyboardShortcut)(ref value)).IsDown())
				{
					ToggleConditionsHUD();
				}
			}
			if (GameController.IsGameActive && !MB.InputService.IsLocked())
			{
				SuperSpeedHotkey.OnUpdate();
				value = KeyGeneral.Value;
				if (((KeyboardShortcut)(ref value)).IsDown())
				{
					ToggleWiki((WikiCategoryPanel)(object)panelGeneral);
				}
				value = KeyBuildings.Value;
				if (((KeyboardShortcut)(ref value)).IsDown())
				{
					ToggleWiki((WikiCategoryPanel)(object)panelBuildings);
				}
				value = KeyCornerstones.Value;
				if (((KeyboardShortcut)(ref value)).IsDown())
				{
					ToggleWiki((WikiCategoryPanel)(object)panelCornerstones);
				}
				value = KeyTraders.Value;
				if (((KeyboardShortcut)(ref value)).IsDown())
				{
					ToggleWiki((WikiCategoryPanel)(object)panelTraders);
				}
				value = KeyEvents.Value;
				if (((KeyboardShortcut)(ref value)).IsDown())
				{
					ToggleWiki((WikiCategoryPanel)(object)panelEvents);
				}
				value = KeySpecies.Value;
				if (((KeyboardShortcut)(ref value)).IsDown())
				{
					ToggleWiki((WikiCategoryPanel)(object)panelSpecies);
				}
				value = KeyTradingPost.Value;
				if (((KeyboardShortcut)(ref value)).IsDown())
				{
					TryOpenTradingPost();
				}
				ShiftCopyBuilding.OnUpdate();
				CycleUnbuiltBuildingsHotkey.OnUpdate(KeyCycleUnbuiltForward.Value, KeyCycleUnbuiltBackward.Value);
			}
		}

		private static void ToggleWiki(WikiCategoryPanel panel)
		{
			if (!((Object)(object)panel == (Object)null) && !((Object)(object)wikiPopup == (Object)null))
			{
				if (((Popup)wikiPopup).IsShown() && (Object)(object)wikiPopup.current == (Object)(object)panel)
				{
					((Popup)wikiPopup).Hide();
				}
				else
				{
					wikiPopup.OnCategoryRequested(panel);
				}
			}
		}

		private static void TryOpenTradingPost()
		{
			if ((Object)(object)SimplePanel.Instance != (Object)null && ((PreviewPanel)SimplePanel.Instance).IsActive())
			{
				((PreviewPanel)SimplePanel.Instance).Hide();
				return;
			}
			if ((Object)(object)TraderPanel.Instance != (Object)null && ((Popup)TraderPanel.Instance).IsShown())
			{
				((Popup)TraderPanel.Instance).Hide();
				return;
			}
			IBuildingsService buildingsService = GameMB.BuildingsService;
			Dictionary<int, Building> dictionary = ((buildingsService != null) ? buildingsService.Buildings : null);
			if (dictionary == null)
			{
				return;
			}
			foreach (KeyValuePair<int, Building> item in dictionary)
			{
				Building value = item.Value;
				TradingPost val = (TradingPost)(object)((value is TradingPost) ? value : null);
				if (val != null)
				{
					GameMB.GameInputService.Pick((IMapObject)(object)val);
					break;
				}
			}
		}
	}
	[HarmonyPatch]
	public static class LeaveManager
	{
		private static readonly string MARKER_NAME = "WorkerLeaveMarker";

		private static Sprite markerSprite;

		private static readonly Dictionary<int, int> leaveMode = new Dictionary<int, int>();

		private static readonly HashSet<int> markedVillagers = new HashSet<int>();

		private static readonly Dictionary<int, Dictionary<string, bool>> userForcedDelivery = new Dictionary<int, Dictionary<string, bool>>();

		private static readonly MethodInfo GetActiveTaskMI = typeof(ActorBrain).GetMethod("GetActiveTask", BindingFlags.Instance | BindingFlags.NonPublic);

		private static readonly HashSet<int> FdPendingWorkers = new HashSet<int>();

		private static int GetMode(int id)
		{
			int value;
			return leaveMode.TryGetValue(id, out value) ? value : 0;
		}

		private static void SetMode(int id, int mode)
		{
			if (mode == 0)
			{
				leaveMode.Remove(id);
				markedVillagers.Remove(id);
			}
			else
			{
				leaveMode[id] = mode;
				markedVillagers.Add(id);
			}
		}

		private static Actor GetActorFromTask(object task)
		{
			return (task == null) ? null : Traverse.Create(task).Field("actor").GetValue<Actor>();
		}

		private static bool IsFarmer(Villager v)
		{
			return ((v != null) ? ((Actor)v).GetWorkplace() : null) is Farm;
		}

		private static bool IsGatherer(Villager v)
		{
			return ((v != null) ? ((Actor)v).GetWorkplace() : null) is GathererHut;
		}

		private static bool IsWoodcutter(Villager v)
		{
			return ((v != null) ? ((Actor)v).GetWorkplace() : null) is Camp;
		}

		private static void MarkForLeave(Villager v, Building b)
		{
			if (!((Object)(object)v == (Object)null))
			{
				int id = ((Actor)v).Id;
				SetMode(id, (GetMode(id) + 1) % 2);
				ActorBrain brain = ((Actor)v).brain;
				if (brain != null)
				{
					object? obj = GetActiveTaskMI.Invoke(brain, null);
					ActorTask val = (ActorTask)((obj is ActorTask) ? obj : null);
					string arg = ((val != null) ? ((object)val).GetType().Name : "None");
					Debug.Log((object)$"[LeaveMark] Marked villager {id} at building {((b != null) ? new int?(b.Id) : null)} | CurrentBehavior={arg}");
				}
			}
		}

		private static void TryUnassign(int id, string seam)
		{
			if (GetMode(id) == 0)
			{
				return;
			}
			IVillagersService villagersService = GameMB.VillagersService;
			if (villagersService != null)
			{
				Villager villager = villagersService.GetVillager(id);
				if (!((Object)(object)villager == (Object)null))
				{
					villagersService.ReleaseFromProfession(villager, false);
					leaveMode.Remove(id);
					markedVillagers.Remove(id);
				}
			}
		}

		private static void Remove(Villager v)
		{
			if (!((Object)(object)v == (Object)null))
			{
				int id = ((Actor)v).Id;
				leaveMode.Remove(id);
				markedVillagers.Remove(id);
			}
		}

		private static bool HasAnyUserForcedDelivery(ProductionBuilding pb)
		{
			if (!userForcedDelivery.TryGetValue(((Building)pb).Id, out var value))
			{
				return false;
			}
			foreach (KeyValuePair<string, bool> item in value)
			{
				if (item.Value)
				{
					return true;
				}
			}
			return false;
		}

		private static void PutMarkerIn(BuildingWorkerSlot slot)
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Expected O, but got Unknown
			//IL_0074: 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: Expected O, but got Unknown
			Transform val = ((Component)slot).transform.Find("StatusIcon");
			if ((Object)(object)val == (Object)null || (Object)(object)val.Find(MARKER_NAME) != (Object)null)
			{
				return;
			}
			GameObject val2 = new GameObject(MARKER_NAME);
			val2.transform.SetParent(val, false);
			val2.SetActive(false);
			val2.transform.localPosition = new Vector3(-28f, 0f, 0f);
			TransformExtensions.SetScale(val2.transform, 0.4f);
			Image val3 = val2.AddComponent<Image>();
			((Graphic)val3).material = new Material(Shader.Find("UI/Default"));
			if ((Object)(object)markerSprite == (Object)null)
			{
				GameObject val4 = GameObject.Find("/HUD/RacesHUD/Slots/RaceHUDSlot (1)/BuildersIcon/Icon");
				if ((Object)(object)val4 != (Object)null)
				{
					Image component = val4.GetComponent<Image>();
					markerSprite = ((component != null) ? component.sprite : null);
				}
			}
			val3.sprite = markerSprite;
		}

		private static void UpdateMarkerStatus(WorkerStatusSlot slot)
		{
			Transform val = ((Component)slot).transform.Find("StatusIcon/" + MARKER_NAME);
			if (!((Object)(object)val == (Object)null) && !((Object)(object)slot.actor == (Object)null))
			{
				ComponentExtensions.SetActive((Component)(object)val, GetMode(slot.actor.Id) > 0);
			}
		}

		[HarmonyPatch(typeof(BuildingWorkerSlot), "OnRightClick")]
		[HarmonyPrefix]
		public static bool BuildingWorkerSlot_OnRightClick_Prefix(BuildingWorkerSlot __instance)
		{
			//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)
			Actor actor = __instance.actor;
			Villager val = (Villager)(object)((actor is Villager) ? actor : null);
			if ((Object)(object)val == (Object)null)
			{
				return true;
			}
			IInputService inputService = MB.InputService;
			DefaultActions inputConfig = MB.InputConfig;
			if (inputService != null && inputService.IsTriggering(((DefaultActions)(ref inputConfig)).InputModifierControl))
			{
				PutMarkerIn(__instance);
				MarkForLeave(val, (Building)(object)__instance.building);
				return false;
			}
			return true;
		}

		[HarmonyPatch(typeof(BuildingWorkerSlot), "SetUpActor")]
		[HarmonyPrefix]
		public static void BuildingWorkerSlot_SetUpActor_Prefix(BuildingWorkerSlot __instance)
		{
			PutMarkerIn(__instance);
		}

		[HarmonyPatch(typeof(WorkerStatusSlot), "SetUpActor")]
		[HarmonyPrefix]
		public static void WorkerStatusSlot_SetUpActor_Prefix(WorkerStatusSlot __instance)
		{
			UpdateMarkerStatus(__instance);
		}

		[HarmonyPatch(typeof(VillagersService), "RemoveFromProfession")]
		[HarmonyPostfix]
		public static void VillagersService_RemoveFromProfession_Postfix(Villager villager)
		{
			if ((Object)(object)villager != (Object)null)
			{
				Remove(villager);
			}
		}

		[HarmonyPatch(typeof(VillagersService), "ReleaseFromProfession")]
		[HarmonyPostfix]
		public static void VillagersService_ReleaseFromProfession_Postfix(Villager villager)
		{
			if ((Object)(object)villager != (Object)null)
			{
				Remove(villager);
			}
		}

		[HarmonyPatch(typeof(ActorTask), "Start")]
		[HarmonyPostfix]
		public static void ActorTask_Start_Postfix(ActorTask __instance)
		{
			if (__instance != null && __instance.GetState() != null)
			{
				Actor actorFromTask = GetActorFromTask(__instance);
				Villager val = (Villager)(object)((actorFromTask is Villager) ? actorFromTask : null);
				if (val != null && GetMode(((Actor)val).Id) == 1 && ((object)__instance).GetType() == typeof(IdleWalk) && !(((Actor)val).GetWorkplace() is FishingHut) && ((Actor)val).GetWorkplace() is ProductionBuilding)
				{
					TryUnassign(((Actor)val).Id, "IdleWalk");
				}
			}
		}

		private static bool AnyDeliveryForced(Building b)
		{
			if ((Object)(object)b == (Object)null)
			{
				return false;
			}
			BuildingStorage component = ((Component)b).GetComponent<BuildingStorage>();
			if ((Object)(object)component == (Object)null)
			{
				return false;
			}
			if (component.Goods == null)
			{
				return false;
			}
			if (component.Goods.delivery == null)
			{
				return false;
			}
			foreach (KeyValuePair<string, GoodDeliveryState> item in component.Goods.delivery)
			{
				if (item.Value != null && item.Value.deliveryForced)
				{
					return true;
				}
			}
			return false;
		}

		[HarmonyPatch(typeof(GoToActiveHearth), "OnStart")]
		[HarmonyPostfix]
		public static void GoToActiveHearth_OnStart_UniversalExit(GoToActiveHearth __instance)
		{
			Actor actorFromTask = GetActorFromTask(__instance);
			Villager val = (Villager)(object)((actorFromTask is Villager) ? actorFromTask : null);
			if (!((Object)(object)val == (Object)null) && GetMode(((Actor)val).Id) == 1)
			{
				Building workplace = ((Actor)val).GetWorkplace();
				if (!((Object)(object)workplace == (Object)null) && !AnyDeliveryForced(workplace) && !FdPendingWorkers.Contains(((Actor)val).Id))
				{
					TryUnassign(((Actor)val).Id, "GoToActiveHearth");
				}
			}
		}

		[HarmonyPatch(typeof(Rest), "OnSetUp")]
		[HarmonyPostfix]
		public static void Rest_OnSetUp_UniversalExit(Rest __instance)
		{
			Actor actorFromTask = GetActorFromTask(__instance);
			Villager val = (Villager)(object)((actorFromTask is Villager) ? actorFromTask : null);
			if (!((Object)(object)val == (Object)null) && GetMode(((Actor)val).Id) == 1)
			{
				Building workplace = ((Actor)val).GetWorkplace();
				if (!((Object)(object)workplace == (Object)null) && !AnyDeliveryForced(workplace) && !FdPendingWorkers.Contains(((Actor)val).Id))
				{
					TryUnassign(((Actor)val).Id, "Rest");
				}
			}
		}

		[HarmonyPatch(typeof(ActorTask), "OnComplete")]
		[HarmonyPostfix]
		public static void ActorTask_OnComplete_ReturnToStore_Postfix(ActorTask __instance)
		{
			if (!(__instance is ReturnToStore))
			{
				return;
			}
			Actor actorFromTask = GetActorFromTask(__instance);
			Villager val = (Villager)(object)((actorFromTask is Villager) ? actorFromTask : null);
			if (val == null)
			{
				return;
			}
			int id = ((Actor)val).Id;
			if (GetMode(id) != 1)
			{
				return;
			}
			Building workplace = ((Actor)val).GetWorkplace();
			if (!((Object)(object)workplace == (Object)null))
			{
				if (AnyDeliveryForced(workplace))
				{
					FdPendingWorkers.Add(id);
				}
				else if (!IsFarmer(val))
				{
					TryUnassign(id, "ReturnToStore");
				}
			}
		}

		private static void FarmerExit(Villager v, string seam)
		{
			if (GetMode(((Actor)v).Id) == 1)
			{
				TryUnassign(((Actor)v).Id, seam);
			}
		}

		[HarmonyPatch(typeof(Plow), "OnComplete")]
		[HarmonyPostfix]
		public static void Plow_OnComplete_Postfix(Plow __instance)
		{
			Actor actorFromTask = GetActorFromTask(__instance);
			Villager val = (Villager)(object)((actorFromTask is Villager) ? actorFromTask : null);
			if ((Object)(object)val != (Object)null && IsFarmer(val))
			{
				FarmerExit(val, "Plow");
			}
		}

		[HarmonyPatch(typeof(Plant), "OnComplete")]
		[HarmonyPostfix]
		public static void Plant_OnComplete_Postfix(Plant __instance)
		{
			Actor actorFromTask = GetActorFromTask(__instance);
			Villager val = (Villager)(object)((actorFromTask is Villager) ? actorFromTask : null);
			if ((Object)(object)val != (Object)null && IsFarmer(val))
			{
				FarmerExit(val, "Plant");
			}
		}

		[HarmonyPatch(typeof(Harvest), "OnComplete")]
		[HarmonyPostfix]
		public static void Harvest_OnComplete_Postfix(Harvest __instance)
		{
			Actor actorFromTask = GetActorFromTask(__instance);
			Villager val = (Villager)(object)((actorFromTask is Villager) ? actorFromTask : null);
			if (!((Object)(object)val == (Object)null) && IsFarmer(val) && GetMode(((Actor)val).Id) != 0)
			{
				Building workplace = ((Actor)val).GetWorkplace();
				ProductionBuilding val2 = (ProductionBuilding)(object)((workplace is ProductionBuilding) ? workplace : null);
				if (!((Object)(object)val2 == (Object)null) && !AnyDeliveryForced((Building)(object)val2))
				{
					TryUnassign(((Actor)val).Id, "Harvest");
				}
			}
		}

		[HarmonyPatch(typeof(EmptyLakeStorage), "OnComplete")]
		[HarmonyPostfix]
		public static void EmptyLakeStorage_OnComplete_FishermanUnassign(EmptyLakeStorage __instance)
		{
			Actor actorFromTask = GetActorFromTask(__instance);
			Villager val = (Villager)(object)((actorFromTask is Villager) ? actorFromTask : null);
			if (!((Object)(object)val == (Object)null) && GetMode(((Actor)val).Id) == 1)
			{
				Building workplace = ((Actor)val).GetWorkplace();
				FishingHut val2 = (FishingHut)(object)((workplace is FishingHut) ? workplace : null);
				if (!((Object)(object)val2 == (Object)null) && !AnyDeliveryForced((Building)(object)val2) && !FdPendingWorkers.Contains(((Actor)val).Id))
				{
					TryUnassign(((Actor)val).Id, "Fisherman");
				}
			}
		}

		[HarmonyPatch(typeof(EmptyBuildingStorage), "OnComplete")]
		[HarmonyPostfix]
		public static void EmptyBuildingStorage_OnComplete_FDUnassign(EmptyBuildingStorage __instance)
		{
			Actor actorFromTask = GetActorFromTask(__instance);
			Villager val = (Villager)(object)((actorFromTask is Villager) ? actorFromTask : null);
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			int id = ((Actor)val).Id;
			if (GetMode(id) == 1 && FdPendingWorkers.Contains(id))
			{
				Building workplace = ((Actor)val).GetWorkplace();
				if (!((Object)(object)workplace == (Object)null) && !AnyDeliveryForced(workplace))
				{
					FdPendingWorkers.Remove(id);
					TryUnassign(id, "FD.Final");
				}
			}
		}

		private static void ProductionBuildingExit(ActorTask task, string seam)
		{
			Actor actorFromTask = GetActorFromTask(task);
			Villager val = (Villager)(object)((actorFromTask is Villager) ? actorFromTask : null);
			if ((Object)(object)val == (Object)null || GetMode(((Actor)val).Id) != 1)
			{
				return;
			}
			Building workplace = ((Actor)val).GetWorkplace();
			ProductionBuilding val2 = (ProductionBuilding)(object)((workplace is ProductionBuilding) ? workplace : null);
			if (!((Object)(object)val2 == (Object)null) && (val2 is Workshop || val2 is FishingHut || val2 is RainCatcher || val2 is Extractor || val2 is BlightPost || val2 is Mine))
			{
				if (val2 is BlightPost)
				{
					TryUnassign(((Actor)val).Id, seam);
				}
				else if (!AnyDeliveryForced((Building)(object)val2) && !FdPendingWorkers.Contains(((Actor)val).Id) && !HasAnyUserForcedDelivery(val2))
				{
					TryUnassign(((Actor)val).Id, seam);
				}
			}
		}

		[HarmonyPatch(typeof(BaseMoveTask), "OnStart")]
		[HarmonyPostfix]
		public static void BaseMoveTask_OnStart_ProductionBuildingExit(BaseMoveTask __instance)
		{
			if (__instance is GoToWorkplace)
			{
				ProductionBuildingExit((ActorTask)(object)__instance, "GoToWorkplace");
			}
		}

		[HarmonyPatch(typeof(CollectIngredients), "OnStart")]
		[HarmonyPostfix]
		public static void CollectIngredients_OnStart_ProductionBuildingExit(CollectIngredients __instance)
		{
			ProductionBuildingExit((ActorTask)(object)__instance, "CollectIngredients");
		}

		[HarmonyPatch(typeof(EmptyBuildingStorage), "OnComplete")]
		[HarmonyPostfix]
		public static void EmptyBuildingStorage_OnComplete_Unassign(EmptyBuildingStorage __instance)
		{
			Actor actorFromTask = GetActorFromTask(__instance);
			Villager val = (Villager)(object)((actorFromTask is Villager) ? actorFromTask : null);
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			int id = ((Actor)val).Id;
			if (GetMode(id) == 1)
			{
				Building workplace = ((Actor)val).GetWorkplace();
				if (!((Object)(object)workplace == (Object)null) && !AnyDeliveryForced(workplace) && !FdPendingWorkers.Contains(id) && (IsFarmer(val) || IsGatherer(val) || IsWoodcutter(val)))
				{
					TryUnassign(id, "EmptyBuildingStorage");
				}
			}
		}

		[HarmonyPatch(typeof(ExecuteWorkingOnRelic), "OnStart")]
		[HarmonyPostfix]
		public static void ExecuteWorkingOnRelic_OnStart_Postfix(ExecuteWorkingOnRelic __instance)
		{
			Actor actorFromTask = GetActorFromTask(__instance);
			Villager val = (Villager)(object)((actorFromTask is Villager) ? actorFromTask : null);
			if (!((Object)(object)val == (Object)null) && GetMode(((Actor)val).Id) == 1)
			{
				Building workplace = ((Actor)val).GetWorkplace();
				if (!((Object)(object)workplace == (Object)null) && !AnyDeliveryForced(workplace))
				{
					TryUnassign(((Actor)val).Id, "Scout");
				}
			}
		}
	}
	[BepInPlugin("MoreHotkeys", "More Hotkeys", "1.0.3")]
	public class MoreHotkeysPlugin : BaseUnityPlugin
	{
		public static ManualLogSource Log;

		public static ConfigFile ConfigFile;

		private void Awake()
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			ConfigFile = ((BaseUnityPlugin)this).Config;
			Harmony val = new Harmony("MoreHotkeys");
			ConditionsHUDSync.Init(ConfigFile, val, ((Component)this).gameObject);
			val.PatchAll();
			Log.LogInfo((object)"MoreHotkeys loaded successfully.");
		}

		private void Update()
		{
			HotkeyManager.OnUpdate();
		}
	}
	[HarmonyPatch(typeof(RaceNeedSlot))]
	[HarmonyPatch("UnityEngine.EventSystems.IPointerClickHandler.OnPointerClick")]
	public static class RaceNeedSlot_HousingClick_Patch
	{
		private static bool Prefix(RaceNeedSlot __instance, PointerEventData eventData)
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Expected O, but got Unknown
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Expected O, but got Unknown
			FieldInfo fieldInfo = AccessTools.Field(typeof(RaceNeedSlot), "race");
			FieldInfo fieldInfo2 = AccessTools.Field(typeof(RaceNeedSlot), "need");
			RaceModel val = (RaceModel)fieldInfo.GetValue(__instance);
			NeedModel val2 = (NeedModel)fieldInfo2.GetValue(__instance);
			if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null)
			{
				return true;
			}
			Debug.Log((object)("[MoreHotkeys] CLICK: race=" + ((SO)val).Name + ", need=" + ((SO)val2).Name));
			if ((Object)(object)val2.referenceGood != (Object)null)
			{
				Debug.Log((object)"[MoreHotkeys] Food need → letting vanilla handle it");
				return true;
			}
			if (IsHousingNeed(val2))
			{
				Debug.Log((object)("[MoreHotkeys] Housing need clicked: " + ((SO)val2).Name));
				BuildingModel houseForNeed = GetHouseForNeed(val, val2);
				if ((Object)(object)houseForNeed == (Object)null)
				{
					Debug.Log((object)"[MoreHotkeys] No house found for this need");
					return false;
				}
				TryBuild(houseForNeed);
				return false;
			}
			return true;
		}

		private static bool IsHousingNeed(NeedModel need)
		{
			string name = ((SO)need).Name;
			return name == "Any Housing" || name.EndsWith("Housing");
		}

		private static BuildingModel GetHouseForNeed(RaceModel race, NeedModel need)
		{
			if (((SO)need).Name == "Any Housing")
			{
				return MB.Settings.GetBuilding("Shelter");
			}
			return (BuildingModel)(((SO)race).Name switch
			{
				"Human" => MB.Settings.GetBuilding("Human House"), 
				"Beaver" => MB.Settings.GetBuilding("Beaver House"), 
				"Lizard" => MB.Settings.GetBuilding("Lizard House"), 
				"Harpy" => MB.Settings.GetBuilding("Harpy House"), 
				"Foxes" => MB.Settings.GetBuilding("Fox House"), 
				"Frog" => MB.Settings.GetBuilding("Frog House"), 
				"Bat" => MB.Settings.GetBuilding("Bat House"), 
				_ => null, 
			});
		}

		private static void TryBuild(BuildingModel building)
		{
			if (!((Object)(object)building == (Object)null))
			{
				if (!GameMB.GameContentService.IsUnlocked(building))
				{
					Debug.Log((object)("[MoreHotkeys] House locked: " + ((SO)building).Name));
					return;
				}
				if (!GameMB.ConstructionService.CanConstruct(building))
				{
					Debug.Log((object)("[MoreHotkeys] Cannot construct: " + ((SO)building).Name));
					return;
				}
				Debug.Log((object)("[MoreHotkeys] Requesting construction: " + ((SO)building).Name));
				GameMB.GameBlackboardService.BuildingConstructionRequested.OnNext(building);
			}
		}
	}
	public static class ShiftCopyBuilding
	{
		public static void OnUpdate()
		{
			//IL_001e: 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)
			if (!GameController.IsGameActive || ShouldIgnoreInput())
			{
				return;
			}
			IInputService inputService = MB.InputService;
			DefaultActions inputConfig = MB.InputConfig;
			if (!inputService.WasTriggered(((DefaultActions)(ref inputConfig)).CopyBuilding, false))
			{
				return;
			}
			IMapObject value = GameMB.GameInputService.MouseoverObject.Value;
			if (value != null)
			{
				Building val = (Building)(object)((value is Building) ? value : null);
				if (val != null)
				{
					TryCopyMainBuilding(val);
				}
				else
				{
					TryCopyResourceBuilding(value);
				}
			}
		}

		private static bool ShouldIgnoreInput()
		{
			return (Object)(object)BuildingPanel.currentBuilding != (Object)null || !GameMB.ModeService.Idle.Value || MB.InputService.IsOverUI();
		}

		private static void TryCopyMainBuilding(Building building)
		{
			switch (((SO)building.BuildingModel).Name)
			{
			case "Small Hearth":
				BuildConditional(MB.Settings.GetBuilding("Temporary Hearth (buildable)"));
				break;
			case "Main Storage (not-buildable)":
				BuildConditional(MB.Settings.GetBuilding("Storage (buildable)"));
				break;
			case "Path":
				BuildConditional(MB.Settings.GetBuilding("Path"));
				break;
			case "Paved Road":
				BuildConditional(MB.Settings.GetBuilding("Paved Road"));
				break;
			case "Reinforced Road":
				BuildConditional(MB.Settings.GetBuilding("Reinforced Road"));
				break;
			}
		}

		private static void TryCopyResourceBuilding(IMapObject obj)
		{
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			ResourceDeposit val = (ResourceDeposit)(object)((obj is ResourceDeposit) ? obj : null);
			if (val != null)
			{
				if (!val.State.isAvailable || !GameMB.DepositsService.HutsMatrix.ContainsKey(val.Model))
				{
					return;
				}
				foreach (GathererHutModel item in GameMB.DepositsService.HutsMatrix[val.Model])
				{
					if (BuildConditional((BuildingModel)(object)item))
					{
						return;
					}
				}
			}
			NaturalResource val2 = (NaturalResource)(object)((obj is NaturalResource) ? obj : null);
			if (val2 != null && val2.State.isAvailable)
			{
				BuildConditional(MB.Settings.GetBuilding("Woodcutters Camp"));
				return;
			}
			Spring val3 = (Spring)(object)((obj is Spring) ? obj : null);
			if (val3 != null && val3.State.isAvailable)
			{
				BuildConditional((BuildingModel)(object)MB.Settings.rainpunkConfig.extractor);
				return;
			}
			Field val4 = (Field)(object)((obj is Field) ? obj : null);
			if (val4 != null)
			{
				if (!GameMB.OreService.HasAvailableOre(val4.Pos))
				{
					return;
				}
				Ore ore = GameMB.OreService.GetOre(val4.Pos);
				foreach (MineModel item2 in GameMB.OreService.MinesMatrix[ore.Model.refGood.Name])
				{
					if (BuildConditional((BuildingModel)(object)item2))
					{
						return;
					}
				}
			}
			Lake val5 = (Lake)(object)((obj is Lake) ? obj : null);
			if (val5 != null)
			{
				if (val5.State.isAvailable && !BuildConditional(MB.Settings.GetBuilding("Fishing Hut")))
				{
					BuildConditional(MB.Settings.GetBuilding("Primitive Fishing Hut"));
				}
			}
			else if (obj is Ore)
			{
				BuildConditional(MB.Settings.GetBuilding("Mine"));
			}
		}

		private static bool BuildConditional(BuildingModel building)
		{
			if ((Object)(object)building == (Object)null)
			{
				return false;
			}
			if (GameMB.GameContentService.IsUnlocked(building) && GameMB.ConstructionService.CanConstruct(building))
			{
				GameMB.GameBlackboardService.BuildingConstructionRequested.OnNext(building);
				return true;
			}
			return false;
		}
	}
	[HarmonyPatch]
	internal static class SuperSpeedHotkey
	{
		public const float SUPER_SPEED_SCALE = 5f;

		public static ConfigEntry<KeyboardShortcut> KeyFiveX;

		static SuperSpeedHotkey()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			KeyFiveX = MoreHotkeysPlugin.ConfigFile.Bind<KeyboardShortcut>("Hotkeys", "5XSpeed", new KeyboardShortcut((KeyCode)53, Array.Empty<KeyCode>()), "Instantly set game speed to 5×");
		}

		public static void OnUpdate()
		{
			//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)
			KeyboardShortcut value = KeyFiveX.Value;
			if (((KeyboardShortcut)(ref value)).IsDown())
			{
				GameMB.TimeScaleService.Change(5f, true, false);
			}
		}

		[HarmonyPatch(typeof(TimeScalePanel), "SetUp")]
		[HarmonyPostfix]
		private static void TimeScalePanel_SetUp(TimeScalePanel __instance)
		{
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			Transform transform = ((Component)__instance).transform;
			Transform val = transform.Find("Slot (5)");
			if (!((Object)(object)val == (Object)null))
			{
				Transform val2 = Object.Instantiate<Transform>(val, transform);
				((Object)val2).name = "Slot (6)";
				val2.localPosition = new Vector3(90f, 90f, 0f);
				TimeScaleSlot component = ((Component)val2).GetComponent<TimeScaleSlot>();
				component.timeScale = 5f;
				TextMeshProUGUI component2 = ((Component)val2.Find("Desc")).GetComponent<TextMeshProUGUI>();
				((TMP_Text)component2).text = "x5";
			}
		}

		[HarmonyPatch(typeof(TimeScaleService), "SpeedUp")]
		[HarmonyPrefix]
		private static bool TimeScaleService_SpeedUp(TimeScaleService __instance)
		{
			float value = __instance.Scale.Value;
			if (value == 5f)
			{
				Serviceable.SoundsManager.PlayFailedSound();
				return false;
			}
			if (value == TimeScaleService.Speeds.Last())
			{
				__instance.Change(5f, true, false);
				return false;
			}
			return true;
		}

		[HarmonyPatch(typeof(TimeScaleService), "SlowDown")]
		[HarmonyPrefix]
		private static bool TimeScaleService_SlowDown(TimeScaleService __instance)
		{
			float value = __instance.Scale.Value;
			if (value == 5f)
			{
				__instance.Change(TimeScaleService.Speeds.Last(), true, false);
				return false;
			}
			return true;
		}

		[HarmonyPatch(typeof(WoodcuttersHUD), "SetUp")]
		[HarmonyPostfix]
		private static void MoveWoodcuttersHUD(WoodcuttersHUD __instance)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			((Component)__instance).transform.localPosition = new Vector3(120f, -71f, 0f);
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "MoreHotkeys";

		public const string PLUGIN_NAME = "MoreHotkeys";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}