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.Recipes;
using Eremite.View.UI.Wiki;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.InputSystem;
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 = 130f;
private const float ROW_HEIGHT = 50f;
private GameObject root;
private RectTransform panel;
private readonly List<GameObject> rows = new List<GameObject>();
private void Awake()
{
//IL_009e: Unknown result type (might be due to invalid IL or missing references)
//IL_00a4: Expected O, but got Unknown
//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
//IL_0123: Unknown result type (might be due to invalid IL or missing references)
//IL_012d: Expected O, but got Unknown
//IL_0181: Unknown result type (might be due to invalid IL or missing references)
//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
//IL_0241: Unknown result type (might be due to invalid IL or missing references)
Instance = this;
Canvas val = null;
Canvas[] array = Object.FindObjectsOfType<Canvas>();
foreach (Canvas val2 in array)
{
if (((Object)val2).name.Contains("HUD") || ((Object)val2).name.Contains("Hud") || ((Object)val2).name.Contains("UI"))
{
val = val2;
break;
}
}
if ((Object)(object)val == (Object)null)
{
val = Object.FindObjectOfType<Canvas>();
}
GameObject val3 = new GameObject("BuildingRecipeTooltipCanvas", new Type[1] { typeof(RectTransform) });
val3.transform.SetParent(((Component)val).transform, false);
Canvas val4 = val3.AddComponent<Canvas>();
val4.overrideSorting = true;
val4.sortingOrder = 50000;
CanvasScaler val5 = val3.AddComponent<CanvasScaler>();
val5.uiScaleMode = (ScaleMode)1;
val5.referenceResolution = new Vector2(1920f, 1080f);
val5.matchWidthOrHeight = 0.5f;
val3.AddComponent<GraphicRaycaster>();
root = new GameObject("BuildingRecipeTooltipRoot", new Type[1] { typeof(RectTransform) });
root.transform.SetParent(val3.transform, false);
root.SetActive(false);
CanvasGroup val6 = root.AddComponent<CanvasGroup>();
val6.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 val7 = ((Component)panel).gameObject.AddComponent<CanvasGroup>();
val7.blocksRaycasts = false;
Image val8 = ((Component)panel).gameObject.AddComponent<Image>();
((Graphic)val8).color = new Color(0.02f, 0.02f, 0.02f, 0.85f);
((Graphic)val8).raycastTarget = false;
panel.SetSizeWithCurrentAnchors((Axis)0, 130f);
}
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, 130f);
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(70f, 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
{
public static void Init(Harmony harmony)
{
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
//IL_002d: Expected O, but got Unknown
harmony.PatchAll(typeof(BuildingRecipeTooltipSystem));
if ((Object)(object)BuildingRecipeTooltip.Instance == (Object)null)
{
GameObject val = new GameObject("BuildingRecipeTooltip");
val.AddComponent<BuildingRecipeTooltip>();
}
}
[HarmonyPatch(typeof(RecipesPopupWorkshopPreviewSlot), "SetUp")]
[HarmonyPostfix]
private static void PreviewSlot_SetUp_Postfix(RecipesPopupWorkshopPreviewSlot __instance, BuildingModel workshop, WorkshopRecipeModel recipe, Action<IRecipeSlot> interactionCallback)
{
if ((Object)(object)workshop == (Object)null)
{
return;
}
object? obj = typeof(RecipesPopupWorkshopPreviewSlot).GetField("buildingIcon", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(__instance);
Image val = (Image)((obj is Image) ? obj : null);
if ((Object)(object)val == (Object)null)
{
return;
}
GameObject gameObject = ((Component)val).gameObject;
BuildingRecipeTooltipTrigger buildingRecipeTooltipTrigger = gameObject.GetComponent<BuildingRecipeTooltipTrigger>();
if ((Object)(object)buildingRecipeTooltipTrigger == (Object)null)
{
buildingRecipeTooltipTrigger = gameObject.AddComponent<BuildingRecipeTooltipTrigger>();
}
buildingRecipeTooltipTrigger.BuildingModel = workshop;
((Graphic)val).raycastTarget = true;
Image[] componentsInChildren = ((Component)__instance).GetComponentsInChildren<Image>();
foreach (Image val2 in componentsInChildren)
{
if ((Object)(object)val2 != (Object)(object)val)
{
((Graphic)val2).raycastTarget = false;
}
}
}
}
public static class CopyBuildingsHotkey
{
public static void OnUpdate()
{
//IL_001c: 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)
if (!GameController.IsGameActive || ShouldIgnoreInput())
{
return;
}
IInputService inputService = MB.InputService;
DefaultActions inputConfig = MB.InputConfig;
if (inputService.WasTriggered(((DefaultActions)(ref inputConfig)).CopyBuilding, false))
{
IMapObject value = GameMB.GameInputService.MouseoverObject.Value;
if (value != null)
{
TryCopyBuildingFor(value);
}
}
}
private static bool ShouldIgnoreInput()
{
return (Object)(object)BuildingPanel.currentBuilding != (Object)null || !GameMB.ModeService.Idle.Value || MB.InputService.IsOverUI();
}
private static void TryCopyBuildingFor(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 (GameMB.GameContentService.IsUnlocked(building) && GameMB.ConstructionService.CanConstruct(building))
{
GameMB.GameBlackboardService.BuildingConstructionRequested.OnNext(building);
return true;
}
return false;
}
}
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;
}
private static void RefreshList()
{
List<BuildingModel> unbuiltBuildings = GetUnbuiltBuildings();
if (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.Count != 0)
{
index = (index + 1) % unbuilt.Count;
ShowBuilding(unbuilt[index]);
}
}
private static void CyclePrev()
{
RefreshList();
if (cyclingMode && 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(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 FarmerLeave
{
private static readonly FieldInfo WorkersToUnassignField = typeof(WorkerLeave).GetField("workersToUnassign", BindingFlags.Static | BindingFlags.NonPublic);
private static readonly FieldInfo ActorField = typeof(ActorTask).GetField("actor", BindingFlags.Instance | BindingFlags.NonPublic);
private static HashSet<int> WorkersToUnassign => WorkersToUnassignField?.GetValue(null) as HashSet<int>;
private static Actor GetActor(object instance)
{
if (instance == null || ActorField == null)
{
return null;
}
object? value = ActorField.GetValue(instance);
return (Actor)((value is Actor) ? value : null);
}
private static bool TryConsumeQueuedWorker(int id)
{
return WorkersToUnassign?.Remove(id) ?? false;
}
private static void UnassignFarmer(Actor actor)
{
if ((Object)(object)actor == (Object)null)
{
return;
}
int id = actor.Id;
if (!TryConsumeQueuedWorker(id))
{
return;
}
IVillagersService villagersService = GameMB.VillagersService;
if (villagersService != null)
{
Villager villager = villagersService.GetVillager(id);
if ((Object)(object)villager != (Object)null)
{
villagersService.ReleaseFromProfession(villager, false);
}
}
}
[HarmonyPatch(typeof(Plow), "OnComplete")]
[HarmonyPostfix]
public static void Plow_OnComplete(Plow __instance)
{
UnassignFarmer(GetActor(__instance));
}
[HarmonyPatch(typeof(Plant), "OnComplete")]
[HarmonyPostfix]
public static void Plant_OnComplete(Plant __instance)
{
UnassignFarmer(GetActor(__instance));
}
[HarmonyPatch(typeof(Harvest), "OnComplete")]
[HarmonyPostfix]
public static void Harvest_OnComplete(Harvest __instance)
{
Actor actor = GetActor(__instance);
if (!((Object)(object)actor == (Object)null))
{
UnassignFarmer(actor);
}
}
}
[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> KeySpecies;
public static ConfigEntry<KeyboardShortcut> KeyTradingPost;
public static ConfigEntry<KeyboardShortcut> KeyCycleUnbuiltForward;
public static ConfigEntry<KeyboardShortcut> KeyCycleUnbuiltBackward;
private static WikiPopup wikiPopup;
private static WikiBasicPanel panelGeneral;
private static WikiBuildingsPanel panelBuildings;
private static WikiEffectsPanel panelCornerstones;
private static WikiTradersPanel panelTraders;
private static WikiRacesPanel panelSpecies;
static HotkeyManager()
{
//IL_001c: Unknown result type (might be due to invalid IL or missing references)
//IL_0045: Unknown result type (might be due to invalid IL or missing references)
//IL_006e: Unknown result type (might be due to invalid IL or missing references)
//IL_0097: Unknown result type (might be due to invalid IL or missing references)
//IL_00c0: 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_010c: 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)
ConfigFile configFile = MoreHotkeysPlugin.ConfigFile;
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");
KeySpecies = configFile.Bind<KeyboardShortcut>("Hotkeys", "EncyclopediaSpecies", new KeyboardShortcut((KeyCode)286, Array.Empty<KeyCode>()), "Open Encyclopedia → Species");
KeyTradingPost = configFile.Bind<KeyboardShortcut>("Hotkeys", "OpenTradingPost", new KeyboardShortcut((KeyCode)106, Array.Empty<KeyCode>()), "Toggle the Trading Post window");
KeyCycleUnbuiltForward = configFile.Bind<KeyboardShortcut>("Hotkeys", "CycleUnbuiltForward", new KeyboardShortcut((KeyCode)99, Array.Empty<KeyCode>()), "Cycle forward through unbuilt buildings");
KeyCycleUnbuiltBackward = configFile.Bind<KeyboardShortcut>("Hotkeys", "CycleUnbuiltBackward", new KeyboardShortcut((KeyCode)120, Array.Empty<KeyCode>()), "Cycle backward through unbuilt buildings");
}
[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;
}
WikiRacesPanel val6 = (WikiRacesPanel)(object)((val is WikiRacesPanel) ? val : null);
if (val6 != null)
{
panelSpecies = val6;
}
}
}
public static void OnUpdate()
{
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
//IL_004a: Unknown result type (might be due to invalid IL or missing references)
//IL_004f: Unknown result type (might be due to invalid IL or missing references)
//IL_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_008e: 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_00b1: 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_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_00f8: 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)
if (GameController.IsGameActive && !MB.InputService.IsLocked())
{
SuperSpeedHotkey.OnUpdate();
KeyboardShortcut 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 = KeySpecies.Value;
if (((KeyboardShortcut)(ref value)).IsDown())
{
ToggleWiki((WikiCategoryPanel)(object)panelSpecies);
}
value = KeyTradingPost.Value;
if (((KeyboardShortcut)(ref value)).IsDown())
{
TryOpenTradingPost();
}
CopyBuildingsHotkey.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;
}
}
}
}
[BepInPlugin("MoreHotkeys", "More Hotkeys", "1.0.1")]
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");
val.PatchAll();
BuildingRecipeTooltipSystem.Init(val);
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);
}
}
}
[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", "FiveXSpeed", 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);
}
}
[HarmonyPatch]
public static class WorkerLeave
{
private static readonly string MARKER_NAME = "WorkerLeaveMarker";
private static Sprite markerSprite = null;
private static readonly HashSet<int> workersToUnassign = new HashSet<int>();
[HarmonyPatch(typeof(BuildingWorkerSlot), "OnRightClick")]
[HarmonyPrefix]
public static bool BuildingWorkerSlot_OnRightClick_Prefix(BuildingWorkerSlot __instance)
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
IInputService inputService = MB.InputService;
DefaultActions inputConfig = MB.InputConfig;
if (inputService != null && inputService.IsTriggering(((DefaultActions)(ref inputConfig)).InputModifierControl))
{
QueueToggleUnassign(__instance);
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(ProductionBuilding), "DispatchProductionFinished")]
[HarmonyPostfix]
public static void ProductionBuilding_DispatchProductionFinished_Postfix(ProductionBuilding __instance, ProductionState production)
{
if (production != null && !(__instance is Farm))
{
TryUnassign(production);
}
}
[HarmonyPatch(typeof(VillagersService), "RemoveFromProfession")]
[HarmonyPostfix]
public static void VillagersService_RemoveFromProfession_Postfix(Villager villager)
{
if ((Object)(object)villager != (Object)null)
{
Remove(villager);
}
}
private static void QueueToggleUnassign(BuildingWorkerSlot slot)
{
PutMarkerIn(slot);
int id = slot.actor.Id;
if (!workersToUnassign.Remove(id))
{
workersToUnassign.Add(id);
}
}
private static void TryUnassign(ProductionState production)
{
int worker = production.worker;
if (!workersToUnassign.Remove(worker))
{
return;
}
IVillagersService villagersService = GameMB.VillagersService;
if (villagersService != null)
{
Villager villager = villagersService.GetVillager(worker);
if ((Object)(object)villager != (Object)null)
{
villagersService.ReleaseFromProfession(villager, false);
}
}
}
private static void Remove(Villager villager)
{
int id = ((Actor)villager).Id;
workersToUnassign.Remove(id);
}
private static void PutMarkerIn(BuildingWorkerSlot slot)
{
//IL_0047: Unknown result type (might be due to invalid IL or missing references)
//IL_004d: Expected O, but got Unknown
//IL_0078: Unknown result type (might be due to invalid IL or missing references)
Transform val = ((Component)slot).transform.Find("StatusIcon");
if ((Object)(object)val == (Object)null)
{
return;
}
Transform val2 = val.Find(MARKER_NAME);
if ((Object)(object)val2 != (Object)null)
{
return;
}
GameObject val3 = new GameObject(MARKER_NAME);
val3.transform.SetParent(val, false);
val3.SetActive(false);
val3.transform.localPosition = new Vector3(-10f, 10f, 0f);
TransformExtensions.SetScale(val3.transform, 0.2f);
Image val4 = val3.AddComponent<Image>();
if ((Object)(object)markerSprite == (Object)null)
{
GameObject val5 = GameObject.Find("/HUD/GoodsHUD/SacrificeMarker/Content");
if ((Object)(object)val5 != (Object)null)
{
Image component = val5.GetComponent<Image>();
if ((Object)(object)component != (Object)null)
{
markerSprite = component.sprite;
}
}
}
val4.sprite = markerSprite;
}
private static bool UpdateMarkerStatus(WorkerStatusSlot slot)
{
Transform val = ((Component)slot).transform.Find("StatusIcon/" + MARKER_NAME);
if ((Object)(object)val == (Object)null || (Object)(object)slot.actor == (Object)null)
{
return false;
}
bool flag = workersToUnassign.Contains(slot.actor.Id);
ComponentExtensions.SetActive((Component)(object)val, flag);
return flag;
}
}
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)
{
}
}
}