Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of ValheimFarmerNPC v1.0.13
plugins/ValheimFarmerNPC.dll
Decompiled 9 hours ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using Jotunn; using Jotunn.Configs; using Jotunn.Entities; using Jotunn.Managers; using Jotunn.Utils; using UnityEngine; using UnityEngine.Events; using UnityEngine.UI; using ValheimFarmerNPC.AI; using ValheimFarmerNPC.Commands; using ValheimFarmerNPC.Config; using ValheimFarmerNPC.Farmer; using ValheimFarmerNPC.Farming; using ValheimFarmerNPC.HarmonyPatches; using ValheimFarmerNPC.Homestead; using ValheimFarmerNPC.Inventory; using ValheimFarmerNPC.NPC; using ValheimFarmerNPC.Networking; using ValheimFarmerNPC.Persistence; using ValheimFarmerNPC.Pieces; using ValheimFarmerNPC.Registration; using ValheimFarmerNPC.Resolvers; using ValheimFarmerNPC.UI; using ValheimFarmerNPC.Utilities; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("ValheimFarmerNPC")] [assembly: AssemblyDescription("Autonomous multiplayer-safe farming NPC for Valheim")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("ValheimFarmerNPC")] [assembly: AssemblyCopyright("Copyright © 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("b7e4c2a1-9f3d-4e8a-a1c5-6d2f0b8e4a71")] [assembly: AssemblyFileVersion("1.0.13")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.13.0")] namespace ValheimFarmerNPC { internal static class Constants { public const int SchemaVersion = 1; public const string HomesteadPrefab = "FarmerHomestead"; public const string BoundaryPostPrefab = "FarmBoundaryPost"; public const string NpcPrefab = "FarmerNpc"; public const string HomesteadCloneSource = "piece_workbench"; public const string BoundaryPostCloneSource = "wood_pole"; public const string NpcCloneSource = "Goblin"; public const string ZdoSchemaVersion = "fj_schema"; public const string ZdoData = "fj_data"; public const string ZdoNpcId = "fj_npc"; public const string ZdoPaused = "fj_paused"; public const string ZdoInitialNpc = "fj_initial_npc"; public const string RpcTogglePause = "FJ_TogglePause"; public const string RpcScanField = "FJ_ScanField"; public const string RpcAssignBoundary = "FJ_AssignBoundary"; public const string RpcAssignChest = "FJ_AssignChest"; public const string RpcUpdateCropConfig = "FJ_UpdateCropConfig"; public const string RpcSetLayoutMode = "FJ_SetLayoutMode"; public const string RpcSetPaused = "FJ_SetPaused"; public const string RpcClearChests = "FJ_ClearChests"; public const string RpcClearField = "FJ_ClearField"; public const string RpcEnsureNpc = "FJ_EnsureNpc"; public const float DefaultInteractRange = 3.5f; public const float DefaultWorkRange = 2f; public const float DefaultThinkInterval = 0.5f; public const float DefaultChestAssignRange = 20f; public const float ChestMatchRadius = 0.35f; public const float FarmScanVerticalExtent = 64f; public const float CropMatchRadius = 0.85f; public const float DefaultStuckSeconds = 8f; public const float InventoryNearlyFullRatio = 0.85f; } [BepInPlugin("com.farmerjohn.valheimfarmernpc", "ValheimFarmerNPC", "1.0.13")] [BepInDependency(/*Could not decode attribute arguments.*/)] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] internal class Plugin : BaseUnityPlugin { public const string PluginGUID = "com.farmerjohn.valheimfarmernpc"; public const string PluginName = "ValheimFarmerNPC"; public const string PluginVersion = "1.0.13"; public static CustomLocalization Localization = LocalizationManager.Instance.GetLocalization(); internal static Plugin Instance { get; private set; } internal static PluginConfig ModConfig { get; private set; } internal static Harmony Harmony { get; private set; } private void Awake() { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Expected O, but got Unknown Instance = this; ModConfig = new PluginConfig(((BaseUnityPlugin)this).Config); SyncedConfig.Init(ModConfig); Harmony = new Harmony("com.farmerjohn.valheimfarmernpc"); try { PlacementPatches.Apply(Harmony); FarmerRemovePatches.Apply(Harmony); FarmerAudioPatches.Apply(Harmony); Harmony.PatchAll(typeof(GameStartPatch).Assembly); } catch (Exception ex) { Log.Warning("Harmony patches failed (plugin will still register pieces): " + ex.Message); } PrefabManager.OnVanillaPrefabsAvailable += OnVanillaPrefabsAvailable; RpcMessages.Register(); ReservationManager.Init(); AddLocalizations(); Log.Info("ValheimFarmerNPC v1.0.13 loaded"); } private void OnDestroy() { PrefabManager.OnVanillaPrefabsAvailable -= OnVanillaPrefabsAvailable; Harmony harmony = Harmony; if (harmony != null) { harmony.UnpatchSelf(); } } private void OnVanillaPrefabsAvailable() { PieceRegistrar.Register(); NpcRegistrar.Register(); ItemRegistrar.Register(); PrefabManager.OnVanillaPrefabsAvailable -= OnVanillaPrefabsAvailable; } private static void AddLocalizations() { CustomLocalization localization = Localization; string text = "English"; localization.AddTranslation(ref text, new Dictionary<string, string> { { "piece_farmerhomestead", "Farmer Homestead" }, { "piece_farmerhomestead_desc", "Homestead for autonomous farmers. Spawns one farmer on place. Admin only." }, { "piece_farmboundarypost", "Farm Boundary Post" }, { "piece_farmboundarypost_desc", "Place two posts to define a rectangular farm field." }, { "fj_npc_name", "Farmer" }, { "fj_npc_paused", "Farmer is paused. Talk to resume." }, { "fj_npc_working", "Farmer is working. Talk to pause." } }); } } } namespace ValheimFarmerNPC.Utilities { internal static class AdminUtil { public static bool IsServer() { if ((Object)(object)ZNet.instance != (Object)null) { return ZNet.instance.IsServer(); } return false; } public static bool LocalPlayerIsAdmin() { if ((Object)(object)ZNet.instance == (Object)null) { return false; } if (!ZNet.instance.IsDedicated() && ZNet.instance.IsServer()) { return true; } try { if (SynchronizationManager.Instance != null && SynchronizationManager.Instance.PlayerIsAdmin) { return true; } } catch { } return false; } public static bool PeerIsAdmin(long peerId) { if ((Object)(object)ZNet.instance == (Object)null) { return false; } if (!ZNet.instance.IsDedicated() && (peerId == 0L || peerId == ZNet.GetUID())) { return true; } ZNetPeer peer = ZNet.instance.GetPeer(peerId); if (peer == null) { if (ZNet.instance.IsDedicated()) { return LocalPlayerIsAdmin(); } return true; } string text = null; try { ISocket socket = peer.m_socket; text = ((socket != null) ? socket.GetHostName() : null); } catch { } if (!string.IsNullOrEmpty(text)) { try { if (ZNet.instance.IsAdmin(text)) { return true; } } catch { } try { if (ZNet.instance.m_adminList != null && ZNet.instance.ListContainsId(ZNet.instance.m_adminList, text)) { return true; } } catch { } } return false; } public static bool CanConfigure(long senderPeerId) { if (!SyncedConfig.AdminOnlyAccess) { return true; } return PeerIsAdmin(senderPeerId); } public static bool LocalPlayerCanAccess() { if (!SyncedConfig.AdminOnlyAccess) { return true; } return LocalPlayerIsAdmin(); } public static void EnsureServerOwnership(ZNetView view) { if (!((Object)(object)view == (Object)null) && view.IsValid() && IsServer() && !view.IsOwner()) { view.ClaimOwnership(); } } } internal static class Log { public static void Info(string message) { Logger.LogInfo((object)("[FarmerNPC] " + message)); } public static void Warning(string message) { Logger.LogWarning((object)("[FarmerNPC] " + message)); } public static void Error(string message) { Logger.LogError((object)("[FarmerNPC] " + message)); } public static void Debug(string message) { if (SyncedConfig.DebugLogging) { Logger.LogInfo((object)("[FarmerNPC:DBG] " + message)); } } } internal static class PhysicsQuery { public const int BufferSize = 256; public static readonly Collider[] Buffer = (Collider[])(object)new Collider[256]; private static int _cropMask = int.MinValue; private static int _defaultMask = int.MinValue; public static int CropMask { get { if (_cropMask == int.MinValue) { _cropMask = LayerMask.GetMask(new string[6] { "Default", "static_solid", "Default_small", "piece", "piece_nonsolid", "item" }); if (_cropMask == 0) { _cropMask = -1; } } return _cropMask; } } public static int DefaultMask { get { if (_defaultMask == int.MinValue) { _defaultMask = CropMask; } return _defaultMask; } } public static int OverlapBoxNonAlloc(Vector3 center, Vector3 halfExtents, Quaternion orientation, int layerMask) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) return Physics.OverlapBoxNonAlloc(center, halfExtents, Buffer, orientation, layerMask, (QueryTriggerInteraction)2); } public static int OverlapSphereNonAlloc(Vector3 position, float radius, int layerMask) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) return Physics.OverlapSphereNonAlloc(position, radius, Buffer, layerMask, (QueryTriggerInteraction)2); } } internal static class PlayerFeedback { public static void Notify(string message) { if (!string.IsNullOrEmpty(message)) { Player localPlayer = Player.m_localPlayer; if (localPlayer != null) { ((Character)localPlayer).Message((MessageType)2, message, 0, (Sprite)null); } AddChat(message); } } public static void Notify(Player user, string message) { Notify((Humanoid)(object)user, message); } public static void Notify(Humanoid user, string message) { if (string.IsNullOrEmpty(message)) { return; } if ((Object)(object)user != (Object)null) { ((Character)user).Message((MessageType)2, message, 0, (Sprite)null); } else { Player localPlayer = Player.m_localPlayer; if (localPlayer != null) { ((Character)localPlayer).Message((MessageType)2, message, 0, (Sprite)null); } } AddChat(message); } private static void AddChat(string message) { if (!SyncedConfig.LogFeedbackToChat || (Object)(object)Chat.instance == (Object)null) { return; } try { ((Terminal)Chat.instance).AddString("<color=#EAAE5B>[Farmer]</color> " + message); } catch { } } } internal static class ZdoIds { public static long ZdoKey(ZDO zdo) { //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) if (zdo == null) { return 0L; } ZDOID uid = zdo.m_uid; return (long)((ulong)((ZDOID)(ref uid)).UserID ^ ((ulong)((ZDOID)(ref uid)).ID << 16) ^ ((ZDOID)(ref uid)).UserKey); } } } namespace ValheimFarmerNPC.UI { internal static class HomesteadCropsPage { internal static void BuildCropsPage() { //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_042f: Unknown result type (might be due to invalid IL or missing references) //IL_0439: Expected O, but got Unknown HomesteadUiWidgets.CreateTitle(HomesteadUiController.CropsPage.transform, "Crop settings", 0f, -22f, 20, 500f, (TextAnchor)3); float num = 280f; GameObject val = GUIManager.Instance.CreateText("Biome: —", HomesteadUiController.CropsPage.transform, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(num, -22f), GUIManager.Instance.AveriaSerifBold, 14, GUIManager.Instance.ValheimOrange, true, Color.black, 280f, 24f, false); HomesteadUiController.CropsBiomeLabel = (((Object)(object)val != (Object)null) ? val.GetComponentInChildren<Text>(true) : null); if ((Object)(object)HomesteadUiController.CropsBiomeLabel != (Object)null) { HomesteadUiController.CropsBiomeLabel.alignment = (TextAnchor)5; RectTransform rectTransform = ((Graphic)HomesteadUiController.CropsBiomeLabel).rectTransform; rectTransform.pivot = new Vector2(1f, 1f); rectTransform.anchorMin = new Vector2(0.5f, 1f); rectTransform.anchorMax = new Vector2(0.5f, 1f); rectTransform.anchoredPosition = new Vector2(420f, -22f); rectTransform.sizeDelta = new Vector2(280f, 24f); } GameObject val2 = (HomesteadUiController.CropsEmptyRoot = GUIManager.Instance.CreateText("No crops grow in this biome.", HomesteadUiController.CropsPage.transform, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, -200f), GUIManager.Instance.AveriaSerifBold, 16, GUIManager.Instance.ValheimOrange, true, Color.black, 600f, 40f, false)); Text val3 = (((Object)(object)val2 != (Object)null) ? val2.GetComponentInChildren<Text>(true) : null); if ((Object)(object)val3 != (Object)null) { val3.alignment = (TextAnchor)4; } if ((Object)(object)HomesteadUiController.CropsEmptyRoot != (Object)null) { HomesteadUiController.CropsEmptyRoot.SetActive(false); } float num2 = -85f; float num3 = -230f; float num4 = 230f; float num5 = num2; HomesteadUiWidgets.CreateTitle(HomesteadUiController.CropsPage.transform, "Weights", num3, num5, 18, 400f, (TextAnchor)3); num5 -= 26f; HomesteadUiWidgets.CreateHelpText(HomesteadUiController.CropsPage.transform, "Relative planting ratios — higher values are planted more often. Set a crop to 0 to skip it. Only crops that grow in this biome are shown.", ref num5, 48f, num3); HomesteadUiController.CropsRowYStart = num5; string[] weightCrops = HomesteadUiController.WeightCrops; foreach (string text in weightCrops) { string iconPrefab = text; if (CropRegistry.TryGet(text, out var def)) { iconPrefab = (def.ProducesSeedItem ? def.SeedItem : def.GrownPrefab); } string cropKey = text; HomesteadUiController.WeightRows[text] = HomesteadUiWidgets.CreateSliderRow(HomesteadUiController.CropsPage.transform, text, "weight", num5, 0, 100, HomesteadUiController.WeightSliders, HomesteadUiController.WeightLabels, delegate(float v) { HomesteadUiController.OnWeightChanged(cropKey, Mathf.RoundToInt(v)); }, iconPrefab, (int value) => FormatWeightLabel(cropKey, value), num3, 400f); num5 -= 62f; } float num6 = num2; HomesteadUiWidgets.CreateTitle(HomesteadUiController.CropsPage.transform, "Reserves", num4, num6, 18, 400f, (TextAnchor)3); num6 -= 26f; HomesteadUiWidgets.CreateHelpText(HomesteadUiController.CropsPage.transform, "Kept in the farmer's bag. When stock falls below this amount, they prioritize seed-crops until the reserve recovers.", ref num6, 48f, num4); weightCrops = HomesteadUiController.ReserveCrops; foreach (string text2 in weightCrops) { CropDefinition def2; string iconPrefab2 = (CropRegistry.TryGet(text2, out def2) ? def2.SeedItem : text2); string cropKey2 = text2; HomesteadUiController.ReserveRows[text2] = HomesteadUiWidgets.CreateSliderRow(HomesteadUiController.CropsPage.transform, text2, "reserve", num6, 0, 100, HomesteadUiController.ReserveSliders, HomesteadUiController.ReserveLabels, delegate(float v) { HomesteadUiController.OnReserveChanged(cropKey2, Mathf.RoundToInt(v)); }, iconPrefab2, (int value) => FormatReserveLabel(cropKey2, value), num4, 400f); num6 -= 62f; } float y = -500f; HomesteadUiWidgets.AddButton(HomesteadUiController.CropsPage.transform, "Back", ref y, new UnityAction(HomesteadUiController.ShowMainPage)); } internal static string CropDisplayName(string family) { if (string.Equals(family, "JotunPuffs", StringComparison.OrdinalIgnoreCase)) { return "Jotun Puffs"; } if (string.Equals(family, "Magecap", StringComparison.OrdinalIgnoreCase)) { return "Magecap"; } return family; } internal static string FormatWeightLabel(string family, int value) { return $"{CropDisplayName(family)}: {value}"; } internal static string FormatReserveLabel(string family, int value) { if (string.Equals(family, "Barley", StringComparison.OrdinalIgnoreCase) || string.Equals(family, "Flax", StringComparison.OrdinalIgnoreCase) || string.Equals(family, "JotunPuffs", StringComparison.OrdinalIgnoreCase) || string.Equals(family, "Magecap", StringComparison.OrdinalIgnoreCase)) { return $"{CropDisplayName(family)}: {value}"; } return $"{CropDisplayName(family)} seeds: {value}"; } } internal static class HomesteadInventoryPages { internal static void BuildInventoryPage() { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: 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_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: Unknown result type (might be due to invalid IL or missing references) //IL_01eb: Unknown result type (might be due to invalid IL or missing references) //IL_01fa: 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_0216: Unknown result type (might be due to invalid IL or missing references) //IL_02ec: Unknown result type (might be due to invalid IL or missing references) //IL_02f6: Expected O, but got Unknown //IL_030e: Unknown result type (might be due to invalid IL or missing references) //IL_0318: Expected O, but got Unknown //IL_0271: Unknown result type (might be due to invalid IL or missing references) //IL_0286: Unknown result type (might be due to invalid IL or missing references) //IL_029b: Unknown result type (might be due to invalid IL or missing references) //IL_02b0: 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) HomesteadUiWidgets.CreateTitle(HomesteadUiController.InvPage.transform, "Farmer inventory", -22f, 20); GameObject val = GUIManager.Instance.CreateText("Loading...", HomesteadUiController.InvPage.transform, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, -55f), GUIManager.Instance.AveriaSerifBold, 14, GUIManager.Instance.ValheimOrange, true, Color.black, 400f, 70f, false); HomesteadUiController.InvStatus = (((Object)(object)val != (Object)null) ? val.GetComponentInChildren<Text>(true) : null); if ((Object)(object)HomesteadUiController.InvStatus != (Object)null) { HomesteadUiController.InvStatus.alignment = (TextAnchor)0; HomesteadUiController.InvStatus.horizontalOverflow = (HorizontalWrapMode)0; HomesteadUiController.InvStatus.verticalOverflow = (VerticalWrapMode)1; RectTransform rectTransform = ((Graphic)HomesteadUiController.InvStatus).rectTransform; rectTransform.pivot = new Vector2(0.5f, 1f); rectTransform.anchorMin = new Vector2(0.5f, 1f); rectTransform.anchorMax = new Vector2(0.5f, 1f); rectTransform.anchoredPosition = new Vector2(0f, -55f); rectTransform.sizeDelta = new Vector2(400f, 70f); } else { Log.Error("HomesteadUI: inventory text control missing"); } GameObject val2 = new GameObject("InvList", new Type[1] { typeof(RectTransform) }); val2.transform.SetParent(HomesteadUiController.InvPage.transform, false); RectTransform component = val2.GetComponent<RectTransform>(); component.anchorMin = Vector2.zero; component.anchorMax = Vector2.one; component.offsetMin = Vector2.zero; component.offsetMax = Vector2.zero; HomesteadUiController.InvListRoot = val2.transform; GameObject val3 = GUIManager.Instance.CreateText("", HomesteadUiController.InvPage.transform, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, -560f), GUIManager.Instance.AveriaSerifBold, 14, GUIManager.Instance.ValheimOrange, true, Color.black, 400f, 24f, false); HomesteadUiController.InvFooter = (((Object)(object)val3 != (Object)null) ? val3.GetComponentInChildren<Text>(true) : null); if ((Object)(object)HomesteadUiController.InvFooter != (Object)null) { HomesteadUiController.InvFooter.alignment = (TextAnchor)0; RectTransform rectTransform2 = ((Graphic)HomesteadUiController.InvFooter).rectTransform; rectTransform2.pivot = new Vector2(0.5f, 1f); rectTransform2.anchorMin = new Vector2(0.5f, 1f); rectTransform2.anchorMax = new Vector2(0.5f, 1f); rectTransform2.anchoredPosition = new Vector2(0f, -560f); rectTransform2.sizeDelta = new Vector2(400f, 24f); } float y = -618f; HomesteadUiWidgets.AddButton(HomesteadUiController.InvPage.transform, "Refresh", ref y, new UnityAction(RefreshInventoryPage)); HomesteadUiWidgets.AddButton(HomesteadUiController.InvPage.transform, "Back", ref y, new UnityAction(HomesteadUiController.ShowMainPage)); } internal static void BuildChestInventoryPage() { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: 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_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: Unknown result type (might be due to invalid IL or missing references) //IL_01eb: Unknown result type (might be due to invalid IL or missing references) //IL_01fa: 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_0216: Unknown result type (might be due to invalid IL or missing references) //IL_02ec: Unknown result type (might be due to invalid IL or missing references) //IL_02f6: Expected O, but got Unknown //IL_030e: Unknown result type (might be due to invalid IL or missing references) //IL_0318: Expected O, but got Unknown //IL_0271: Unknown result type (might be due to invalid IL or missing references) //IL_0286: Unknown result type (might be due to invalid IL or missing references) //IL_029b: Unknown result type (might be due to invalid IL or missing references) //IL_02b0: 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) HomesteadUiWidgets.CreateTitle(HomesteadUiController.ChestInvPage.transform, "Chest inventory", -22f, 20); GameObject val = GUIManager.Instance.CreateText("Loading...", HomesteadUiController.ChestInvPage.transform, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, -55f), GUIManager.Instance.AveriaSerifBold, 14, GUIManager.Instance.ValheimOrange, true, Color.black, 400f, 70f, false); HomesteadUiController.ChestInvStatus = (((Object)(object)val != (Object)null) ? val.GetComponentInChildren<Text>(true) : null); if ((Object)(object)HomesteadUiController.ChestInvStatus != (Object)null) { HomesteadUiController.ChestInvStatus.alignment = (TextAnchor)0; HomesteadUiController.ChestInvStatus.horizontalOverflow = (HorizontalWrapMode)0; HomesteadUiController.ChestInvStatus.verticalOverflow = (VerticalWrapMode)1; RectTransform rectTransform = ((Graphic)HomesteadUiController.ChestInvStatus).rectTransform; rectTransform.pivot = new Vector2(0.5f, 1f); rectTransform.anchorMin = new Vector2(0.5f, 1f); rectTransform.anchorMax = new Vector2(0.5f, 1f); rectTransform.anchoredPosition = new Vector2(0f, -55f); rectTransform.sizeDelta = new Vector2(400f, 70f); } else { Log.Error("HomesteadUI: chest inventory text control missing"); } GameObject val2 = new GameObject("ChestInvList", new Type[1] { typeof(RectTransform) }); val2.transform.SetParent(HomesteadUiController.ChestInvPage.transform, false); RectTransform component = val2.GetComponent<RectTransform>(); component.anchorMin = Vector2.zero; component.anchorMax = Vector2.one; component.offsetMin = Vector2.zero; component.offsetMax = Vector2.zero; HomesteadUiController.ChestInvListRoot = val2.transform; GameObject val3 = GUIManager.Instance.CreateText("", HomesteadUiController.ChestInvPage.transform, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, -560f), GUIManager.Instance.AveriaSerifBold, 14, GUIManager.Instance.ValheimOrange, true, Color.black, 400f, 24f, false); HomesteadUiController.ChestInvFooter = (((Object)(object)val3 != (Object)null) ? val3.GetComponentInChildren<Text>(true) : null); if ((Object)(object)HomesteadUiController.ChestInvFooter != (Object)null) { HomesteadUiController.ChestInvFooter.alignment = (TextAnchor)0; RectTransform rectTransform2 = ((Graphic)HomesteadUiController.ChestInvFooter).rectTransform; rectTransform2.pivot = new Vector2(0.5f, 1f); rectTransform2.anchorMin = new Vector2(0.5f, 1f); rectTransform2.anchorMax = new Vector2(0.5f, 1f); rectTransform2.anchoredPosition = new Vector2(0f, -560f); rectTransform2.sizeDelta = new Vector2(400f, 24f); } float y = -618f; HomesteadUiWidgets.AddButton(HomesteadUiController.ChestInvPage.transform, "Refresh", ref y, new UnityAction(RefreshChestInventoryPage)); HomesteadUiWidgets.AddButton(HomesteadUiController.ChestInvPage.transform, "Back", ref y, new UnityAction(HomesteadUiController.ShowMainPage)); } internal static void RefreshInventoryPage() { //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_029f: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)HomesteadUiController.Current == (Object)null) { return; } if ((Object)(object)HomesteadUiController.InvStatus == (Object)null || (Object)(object)HomesteadUiController.InvListRoot == (Object)null) { Log.Warning("HomesteadUI: inventory page text is null — rebuilding UI"); if ((Object)(object)HomesteadUiController.Root != (Object)null) { Object.Destroy((Object)(object)HomesteadUiController.Root); HomesteadUiController.Root = null; HomesteadUiController.InvPage = null; HomesteadUiController.MainPage = null; HomesteadUiController.CropsPage = null; } HomesteadUiShell.EnsureUi(); HomesteadUiController.ShowInventoryPage(); return; } try { foreach (FarmerNpc item in FarmerRoster.ListNear(((Component)HomesteadUiController.Current).transform.position)) { Humanoid val = (((Object)(object)item != (Object)null) ? ((Component)item).GetComponent<Humanoid>() : null); if ((Object)(object)val != (Object)null && item.Inventory != null) { WorldDropCollector.AbsorbFromHumanoid(item.Inventory, val); } } int num = HomesteadUiController.Current.CountFarmers(); List<CarriedItem> list = HomesteadUiController.Current.GetAggregatedCarriedItems() ?? new List<CarriedItem>(); StringBuilder stringBuilder = new StringBuilder(); stringBuilder.AppendLine($"Farmers: {num}"); stringBuilder.AppendLine($"Item types: {list.Count}"); stringBuilder.Append("(Live farmer bags)"); HomesteadUiController.InvStatus.text = stringBuilder.ToString(); ClearInvList(HomesteadUiController.InvListRoot); float num2 = -140f; int num3 = 0; int num4 = 0; if (list.Count == 0) { if ((Object)(object)HomesteadUiController.InvFooter != (Object)null) { ((Graphic)HomesteadUiController.InvFooter).rectTransform.anchoredPosition = new Vector2(0f, -560f); HomesteadUiController.InvFooter.text = "Inventory empty."; } return; } foreach (CarriedItem item2 in from i in list orderby i.Stack descending, i.Prefab select i) { if (item2 != null && !string.IsNullOrEmpty(item2.Prefab)) { num3 += item2.Stack; if (num2 < -532f) { num4++; continue; } CreateInvItemRow(HomesteadUiController.InvListRoot, item2.Prefab, item2.Stack, num2); num2 -= 46f; } } if ((Object)(object)HomesteadUiController.InvFooter != (Object)null) { ((Graphic)HomesteadUiController.InvFooter).rectTransform.anchoredPosition = new Vector2(0f, -560f); HomesteadUiController.InvFooter.text = ((num4 > 0) ? $"Total items: {num3} (+{num4} more types)" : $"Total items: {num3}"); } } catch (Exception ex) { Log.Error($"HomesteadUI inventory refresh failed: {ex}"); ClearInvList(HomesteadUiController.InvListRoot); HomesteadUiController.InvStatus.text = "Error loading inventory:\n" + ex.Message; if ((Object)(object)HomesteadUiController.InvFooter != (Object)null) { HomesteadUiController.InvFooter.text = string.Empty; } } } internal static void RefreshChestInventoryPage() { //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_0290: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)HomesteadUiController.Current == (Object)null) { return; } if ((Object)(object)HomesteadUiController.ChestInvStatus == (Object)null || (Object)(object)HomesteadUiController.ChestInvListRoot == (Object)null) { Log.Warning("HomesteadUI: chest inventory page missing — rebuilding UI"); if ((Object)(object)HomesteadUiController.Root != (Object)null) { Object.Destroy((Object)(object)HomesteadUiController.Root); HomesteadUiController.Root = null; HomesteadUiController.InvPage = null; HomesteadUiController.ChestInvPage = null; HomesteadUiController.MainPage = null; HomesteadUiController.CropsPage = null; } HomesteadUiShell.EnsureUi(); HomesteadUiController.ShowChestInventoryPage(); return; } try { HomesteadUiController.Current.ReloadDataFromZdo(); HomesteadData data = HomesteadUiController.Current.Data; data?.SyncChestListsFromCsv(); int num = data?.ChestCount ?? 0; List<CarriedItem> list = HomesteadUiController.Current.GetAggregatedChestItems() ?? new List<CarriedItem>(); StringBuilder stringBuilder = new StringBuilder(); stringBuilder.AppendLine($"Chests: {num}"); stringBuilder.AppendLine($"Item types: {list.Count}"); stringBuilder.Append("(Assigned homestead chests)"); HomesteadUiController.ChestInvStatus.text = stringBuilder.ToString(); ClearInvList(HomesteadUiController.ChestInvListRoot); float num2 = -140f; int num3 = 0; int num4 = 0; if (num == 0) { if ((Object)(object)HomesteadUiController.ChestInvFooter != (Object)null) { ((Graphic)HomesteadUiController.ChestInvFooter).rectTransform.anchoredPosition = new Vector2(0f, -560f); HomesteadUiController.ChestInvFooter.text = "No chests assigned."; } return; } if (list.Count == 0) { if ((Object)(object)HomesteadUiController.ChestInvFooter != (Object)null) { ((Graphic)HomesteadUiController.ChestInvFooter).rectTransform.anchoredPosition = new Vector2(0f, -560f); HomesteadUiController.ChestInvFooter.text = "Chests empty."; } return; } foreach (CarriedItem item in from i in list orderby i.Stack descending, i.Prefab select i) { if (item != null && !string.IsNullOrEmpty(item.Prefab)) { num3 += item.Stack; if (num2 < -532f) { num4++; continue; } CreateInvItemRow(HomesteadUiController.ChestInvListRoot, item.Prefab, item.Stack, num2); num2 -= 46f; } } if ((Object)(object)HomesteadUiController.ChestInvFooter != (Object)null) { ((Graphic)HomesteadUiController.ChestInvFooter).rectTransform.anchoredPosition = new Vector2(0f, -560f); HomesteadUiController.ChestInvFooter.text = ((num4 > 0) ? $"Total items: {num3} (+{num4} more types)" : $"Total items: {num3}"); } } catch (Exception ex) { Log.Error($"HomesteadUI chest inventory refresh failed: {ex}"); ClearInvList(HomesteadUiController.ChestInvListRoot); HomesteadUiController.ChestInvStatus.text = "Error loading chests:\n" + ex.Message; if ((Object)(object)HomesteadUiController.ChestInvFooter != (Object)null) { HomesteadUiController.ChestInvFooter.text = string.Empty; } } } internal static void ClearInvList(Transform listRoot) { if (!((Object)(object)listRoot == (Object)null)) { for (int num = listRoot.childCount - 1; num >= 0; num--) { Object.Destroy((Object)(object)((Component)listRoot.GetChild(num)).gameObject); } } } internal static void CreateInvItemRow(Transform parent, string prefab, int stack, float y) { //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_01b8: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Unknown result type (might be due to invalid IL or missing references) float num = y - 20f; Sprite val = HomesteadUiWidgets.TryGetItemIcon(prefab); if ((Object)(object)val != (Object)null) { GameObject val2 = new GameObject(prefab + "_inv_icon", new Type[2] { typeof(RectTransform), typeof(Image) }); val2.transform.SetParent(parent, false); RectTransform component = val2.GetComponent<RectTransform>(); component.pivot = new Vector2(0.5f, 0.5f); component.anchorMin = new Vector2(0.5f, 1f); component.anchorMax = new Vector2(0.5f, 1f); component.sizeDelta = new Vector2(40f, 40f); component.anchoredPosition = new Vector2(-175f, num); Image component2 = val2.GetComponent<Image>(); component2.sprite = val; component2.preserveAspect = true; ((Graphic)component2).raycastTarget = false; } GameObject val3 = GUIManager.Instance.CreateText($"{prefab}: {stack}", parent, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(20f, num), GUIManager.Instance.AveriaSerifBold, 14, GUIManager.Instance.ValheimOrange, true, Color.black, 320f, 22f, false); Text val4 = (((Object)(object)val3 != (Object)null) ? val3.GetComponentInChildren<Text>(true) : null); if ((Object)(object)val4 != (Object)null) { val4.alignment = (TextAnchor)3; RectTransform rectTransform = ((Graphic)val4).rectTransform; rectTransform.pivot = new Vector2(0.5f, 0.5f); rectTransform.anchorMin = new Vector2(0.5f, 1f); rectTransform.anchorMax = new Vector2(0.5f, 1f); rectTransform.anchoredPosition = new Vector2(20f, num); rectTransform.sizeDelta = new Vector2(320f, 22f); } } } internal static class HomesteadMainPage { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static UnityAction <>9__0_0; public static UnityAction <>9__0_1; public static UnityAction <>9__0_2; public static UnityAction <>9__0_3; public static UnityAction <>9__0_4; public static UnityAction <>9__0_5; public static UnityAction <>9__0_6; public static UnityAction <>9__0_7; public static UnityAction <>9__0_8; internal void <BuildMainPage>b__0_0() { HomesteadUiController.Current?.RequestTogglePause(); HomesteadUiController.QueueRefresh(); } internal void <BuildMainPage>b__0_1() { HomesteadUiController.Current?.RequestAddFarmer(); HomesteadUiController.QueueRefresh(); } internal void <BuildMainPage>b__0_2() { HomesteadUiController.Current?.RequestRemoveFarmer(); HomesteadUiController.QueueRefresh(); } internal void <BuildMainPage>b__0_3() { HomesteadUiController.Current?.RequestForceDepositAll(); HomesteadUiController.QueueRefresh(); } internal void <BuildMainPage>b__0_4() { HomesteadUiController.Current?.RequestScan(); HomesteadUiController.QueueRefresh(); } internal void <BuildMainPage>b__0_5() { HomesteadUiController.Current?.RequestClearField(); HomesteadUiController.QueueRefresh(); } internal void <BuildMainPage>b__0_6() { HomesteadUiController.Current?.RequestAssignBoundary(); HomesteadUiController.QueueRefresh(); } internal void <BuildMainPage>b__0_7() { HomesteadUiController.Current?.RequestAssignChest(); HomesteadUiController.QueueRefresh(); } internal void <BuildMainPage>b__0_8() { HomesteadUiController.Current?.RequestClearChests(); HomesteadUiController.QueueRefresh(); } } internal static void BuildMainPage() { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: 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_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Expected O, but got Unknown //IL_01ba: Unknown result type (might be due to invalid IL or missing references) //IL_01bf: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Expected O, but got Unknown //IL_01ef: Unknown result type (might be due to invalid IL or missing references) //IL_01f4: Unknown result type (might be due to invalid IL or missing references) //IL_01fa: Expected O, but got Unknown //IL_024c: Unknown result type (might be due to invalid IL or missing references) //IL_0256: Expected O, but got Unknown //IL_0224: Unknown result type (might be due to invalid IL or missing references) //IL_0229: Unknown result type (might be due to invalid IL or missing references) //IL_022f: Expected O, but got Unknown //IL_0291: Unknown result type (might be due to invalid IL or missing references) //IL_0296: Unknown result type (might be due to invalid IL or missing references) //IL_029c: Expected O, but got Unknown //IL_02c6: Unknown result type (might be due to invalid IL or missing references) //IL_02cb: Unknown result type (might be due to invalid IL or missing references) //IL_02d1: Expected O, but got Unknown //IL_02fb: Unknown result type (might be due to invalid IL or missing references) //IL_0300: Unknown result type (might be due to invalid IL or missing references) //IL_0306: Expected O, but got Unknown //IL_0346: Unknown result type (might be due to invalid IL or missing references) //IL_034b: Unknown result type (might be due to invalid IL or missing references) //IL_0351: Expected O, but got Unknown //IL_03a3: Unknown result type (might be due to invalid IL or missing references) //IL_03ad: Expected O, but got Unknown //IL_03db: Unknown result type (might be due to invalid IL or missing references) //IL_03e5: Expected O, but got Unknown //IL_0405: Unknown result type (might be due to invalid IL or missing references) //IL_040f: Expected O, but got Unknown //IL_037b: Unknown result type (might be due to invalid IL or missing references) //IL_0380: Unknown result type (might be due to invalid IL or missing references) //IL_0386: Expected O, but got Unknown HomesteadUiWidgets.CreateTitle(HomesteadUiController.MainPage.transform, "Farmer Homestead", -22f, 22); GameObject val = GUIManager.Instance.CreateText("", HomesteadUiController.MainPage.transform, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, -58f), GUIManager.Instance.AveriaSerifBold, 13, GUIManager.Instance.ValheimOrange, true, Color.black, 380f, 100f, false); HomesteadUiController.Status = (((Object)(object)val != (Object)null) ? val.GetComponentInChildren<Text>(true) : null); if ((Object)(object)HomesteadUiController.Status != (Object)null) { HomesteadUiController.Status.alignment = (TextAnchor)0; HomesteadUiController.Status.horizontalOverflow = (HorizontalWrapMode)1; HomesteadUiController.Status.verticalOverflow = (VerticalWrapMode)1; RectTransform rectTransform = ((Graphic)HomesteadUiController.Status).rectTransform; rectTransform.pivot = new Vector2(0.5f, 1f); rectTransform.anchorMin = new Vector2(0.5f, 1f); rectTransform.anchorMax = new Vector2(0.5f, 1f); rectTransform.anchoredPosition = new Vector2(0f, -58f); rectTransform.sizeDelta = new Vector2(380f, 100f); } float y = -175f; HomesteadUiWidgets.AddSectionHeader(HomesteadUiController.MainPage.transform, "Farmers", ref y); Transform transform = HomesteadUiController.MainPage.transform; object obj = <>c.<>9__0_0; if (obj == null) { UnityAction val2 = delegate { HomesteadUiController.Current?.RequestTogglePause(); HomesteadUiController.QueueRefresh(); }; <>c.<>9__0_0 = val2; obj = (object)val2; } HomesteadUiWidgets.AddButton(transform, "Toggle Pause", ref y, (UnityAction)obj); Transform transform2 = HomesteadUiController.MainPage.transform; object obj2 = <>c.<>9__0_1; if (obj2 == null) { UnityAction val3 = delegate { HomesteadUiController.Current?.RequestAddFarmer(); HomesteadUiController.QueueRefresh(); }; <>c.<>9__0_1 = val3; obj2 = (object)val3; } HomesteadUiWidgets.AddButton(transform2, "Add Farmer", ref y, (UnityAction)obj2); Transform transform3 = HomesteadUiController.MainPage.transform; object obj3 = <>c.<>9__0_2; if (obj3 == null) { UnityAction val4 = delegate { HomesteadUiController.Current?.RequestRemoveFarmer(); HomesteadUiController.QueueRefresh(); }; <>c.<>9__0_2 = val4; obj3 = (object)val4; } HomesteadUiWidgets.AddButton(transform3, "Remove Farmer", ref y, (UnityAction)obj3); Transform transform4 = HomesteadUiController.MainPage.transform; object obj4 = <>c.<>9__0_3; if (obj4 == null) { UnityAction val5 = delegate { HomesteadUiController.Current?.RequestForceDepositAll(); HomesteadUiController.QueueRefresh(); }; <>c.<>9__0_3 = val5; obj4 = (object)val5; } HomesteadUiWidgets.AddButton(transform4, "Deposit all", ref y, (UnityAction)obj4); HomesteadUiWidgets.AddButton(HomesteadUiController.MainPage.transform, "Farmer inventory", ref y, new UnityAction(HomesteadUiController.ShowInventoryPage)); HomesteadUiWidgets.AddSectionHeader(HomesteadUiController.MainPage.transform, "Field", ref y); Transform transform5 = HomesteadUiController.MainPage.transform; object obj5 = <>c.<>9__0_4; if (obj5 == null) { UnityAction val6 = delegate { HomesteadUiController.Current?.RequestScan(); HomesteadUiController.QueueRefresh(); }; <>c.<>9__0_4 = val6; obj5 = (object)val6; } HomesteadUiWidgets.AddButton(transform5, "Scan Field", ref y, (UnityAction)obj5); Transform transform6 = HomesteadUiController.MainPage.transform; object obj6 = <>c.<>9__0_5; if (obj6 == null) { UnityAction val7 = delegate { HomesteadUiController.Current?.RequestClearField(); HomesteadUiController.QueueRefresh(); }; <>c.<>9__0_5 = val7; obj6 = (object)val7; } HomesteadUiWidgets.AddButton(transform6, "Clear Field", ref y, (UnityAction)obj6); Transform transform7 = HomesteadUiController.MainPage.transform; object obj7 = <>c.<>9__0_6; if (obj7 == null) { UnityAction val8 = delegate { HomesteadUiController.Current?.RequestAssignBoundary(); HomesteadUiController.QueueRefresh(); }; <>c.<>9__0_6 = val8; obj7 = (object)val8; } HomesteadUiWidgets.AddButton(transform7, "Assign Boundary Posts", ref y, (UnityAction)obj7); HomesteadUiWidgets.AddSectionHeader(HomesteadUiController.MainPage.transform, "Storage", ref y); Transform transform8 = HomesteadUiController.MainPage.transform; object obj8 = <>c.<>9__0_7; if (obj8 == null) { UnityAction val9 = delegate { HomesteadUiController.Current?.RequestAssignChest(); HomesteadUiController.QueueRefresh(); }; <>c.<>9__0_7 = val9; obj8 = (object)val9; } HomesteadUiWidgets.AddButton(transform8, "Add chest", ref y, (UnityAction)obj8); Transform transform9 = HomesteadUiController.MainPage.transform; object obj9 = <>c.<>9__0_8; if (obj9 == null) { UnityAction val10 = delegate { HomesteadUiController.Current?.RequestClearChests(); HomesteadUiController.QueueRefresh(); }; <>c.<>9__0_8 = val10; obj9 = (object)val10; } HomesteadUiWidgets.AddButton(transform9, "Clear chests", ref y, (UnityAction)obj9); HomesteadUiWidgets.AddButton(HomesteadUiController.MainPage.transform, "Chest inventory", ref y, new UnityAction(HomesteadUiController.ShowChestInventoryPage)); HomesteadUiWidgets.AddSectionHeader(HomesteadUiController.MainPage.transform, "Crops", ref y); HomesteadUiWidgets.AddButton(HomesteadUiController.MainPage.transform, "Crop settings", ref y, new UnityAction(HomesteadUiController.ShowCropsPage)); y -= 8f; HomesteadUiWidgets.AddButton(HomesteadUiController.MainPage.transform, "Close", ref y, new UnityAction(HomesteadUiController.Hide)); } } internal static class HomesteadUiController { internal static readonly string[] WeightCrops = new string[7] { "Carrot", "Turnip", "Onion", "Barley", "Flax", "JotunPuffs", "Magecap" }; internal static readonly string[] ReserveCrops = new string[7] { "Carrot", "Turnip", "Onion", "Barley", "Flax", "JotunPuffs", "Magecap" }; internal const int UiLayoutVersion = 24; internal const float CropSliderRowStep = 62f; internal const float CropIconSize = 49f; internal const float InvIconSize = 40f; internal const float InvRowStep = 46f; internal const float PanelWidth = 460f; internal const float MainPanelHeight = 860f; internal const float CropsPanelWidth = 920f; internal const float CropsPanelHeight = 550f; internal const float CropsColumnOffset = 230f; internal const float CropsColumnWidth = 400f; internal const float InventoryPanelHeight = 700f; internal const float InvButtonsYStart = -618f; internal const float InvFooterY = -560f; internal const float InvListStopY = -532f; internal const float SectionGap = 7f; internal static int BuiltLayoutVersion; internal static GameObject Root; internal static GameObject MainPage; internal static GameObject CropsPage; internal static GameObject InvPage; internal static GameObject ChestInvPage; internal static FarmerHomestead Current; internal static Text Status; internal static Text CropsBiomeLabel; internal static GameObject CropsEmptyRoot; internal static float CropsRowYStart; internal static Text InvStatus; internal static Text InvFooter; internal static Transform InvListRoot; internal static Text ChestInvStatus; internal static Text ChestInvFooter; internal static Transform ChestInvListRoot; internal static Coroutine RefreshRoutine; internal static readonly Dictionary<string, Slider> WeightSliders = new Dictionary<string, Slider>(StringComparer.OrdinalIgnoreCase); internal static readonly Dictionary<string, Text> WeightLabels = new Dictionary<string, Text>(StringComparer.OrdinalIgnoreCase); internal static readonly Dictionary<string, GameObject> WeightRows = new Dictionary<string, GameObject>(StringComparer.OrdinalIgnoreCase); internal static readonly Dictionary<string, Slider> ReserveSliders = new Dictionary<string, Slider>(StringComparer.OrdinalIgnoreCase); internal static readonly Dictionary<string, Text> ReserveLabels = new Dictionary<string, Text>(StringComparer.OrdinalIgnoreCase); internal static readonly Dictionary<string, GameObject> ReserveRows = new Dictionary<string, GameObject>(StringComparer.OrdinalIgnoreCase); internal static bool SuppressSliderEvents; public static void Show(FarmerHomestead homestead) { if (!((Object)(object)homestead == (Object)null)) { Current = homestead; homestead.TryInitialize(); HomesteadUiShell.EnsureUi(); Root.SetActive(true); ShowMainPage(); SyncSlidersFromData(); RefreshStatus(); GUIManager.BlockInput(true); } } public static void Hide() { if ((Object)(object)Root != (Object)null) { Root.SetActive(false); } Current = null; GUIManager.BlockInput(false); } internal static void ShowMainPage() { HomesteadUiShell.SetPanelSize(460f, 860f); if ((Object)(object)MainPage != (Object)null) { MainPage.SetActive(true); } if ((Object)(object)CropsPage != (Object)null) { CropsPage.SetActive(false); } if ((Object)(object)InvPage != (Object)null) { InvPage.SetActive(false); } if ((Object)(object)ChestInvPage != (Object)null) { ChestInvPage.SetActive(false); } RefreshStatus(); } internal static void ShowCropsPage() { HomesteadUiShell.SetPanelSize(920f, 550f); if ((Object)(object)MainPage != (Object)null) { MainPage.SetActive(false); } if ((Object)(object)CropsPage != (Object)null) { CropsPage.SetActive(true); } if ((Object)(object)InvPage != (Object)null) { InvPage.SetActive(false); } if ((Object)(object)ChestInvPage != (Object)null) { ChestInvPage.SetActive(false); } ApplyBiomeCropUi(); SyncSlidersFromData(); } internal static void ShowInventoryPage() { HomesteadUiShell.SetPanelSize(460f, 700f); if ((Object)(object)MainPage != (Object)null) { MainPage.SetActive(false); } if ((Object)(object)CropsPage != (Object)null) { CropsPage.SetActive(false); } if ((Object)(object)InvPage != (Object)null) { InvPage.SetActive(true); } if ((Object)(object)ChestInvPage != (Object)null) { ChestInvPage.SetActive(false); } HomesteadInventoryPages.RefreshInventoryPage(); } internal static void ShowChestInventoryPage() { HomesteadUiShell.SetPanelSize(460f, 700f); if ((Object)(object)MainPage != (Object)null) { MainPage.SetActive(false); } if ((Object)(object)CropsPage != (Object)null) { CropsPage.SetActive(false); } if ((Object)(object)InvPage != (Object)null) { InvPage.SetActive(false); } if ((Object)(object)ChestInvPage != (Object)null) { ChestInvPage.SetActive(true); } HomesteadInventoryPages.RefreshChestInventoryPage(); } internal static void ApplyBiomeCropUi() { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)Current == (Object)null) { return; } HomesteadData data = Current.Data; if (data == null) { Current.ReloadDataFromZdo(); data = Current.Data; } Vector3 position = ((Component)Current).transform.position; Biome biome = BiomeCropRules.GetBiome(position); BiomeCropRules.ApplyToData(data, position); Current.Persist(); if ((Object)(object)CropsBiomeLabel != (Object)null) { CropsBiomeLabel.text = "Biome: " + BiomeCropRules.GetBiomeDisplayName(biome); } HashSet<string> hashSet = new HashSet<string>(BiomeCropRules.GetAllowedFoodCrops(biome), StringComparer.OrdinalIgnoreCase); float y = CropsRowYStart; float y2 = CropsRowYStart; float columnX = -230f; float columnX2 = 230f; int num = 0; string[] weightCrops = WeightCrops; foreach (string text in weightCrops) { bool flag = hashSet.Contains(text); if (WeightRows.TryGetValue(text, out var value) && (Object)(object)value != (Object)null) { SetCropRowVisible(value, flag, columnX, ref y); if (flag) { num++; } } SetActiveSafe(WeightLabels, text, flag); SetActiveSafe(WeightSliders, text, flag); if (ReserveRows.TryGetValue(text, out var value2) && (Object)(object)value2 != (Object)null) { SetCropRowVisible(value2, flag, columnX2, ref y2); } SetActiveSafe(ReserveLabels, text, flag); SetActiveSafe(ReserveSliders, text, flag); } if ((Object)(object)CropsEmptyRoot != (Object)null) { CropsEmptyRoot.SetActive(num == 0); } } private static void SetActiveSafe(Dictionary<string, Text> map, string crop, bool show) { if (!map.TryGetValue(crop, out var value) || (Object)(object)value == (Object)null) { return; } ((Component)value).gameObject.SetActive(show); Transform parent = ((Component)value).transform.parent; if ((Object)(object)parent != (Object)null) { GameObject cropsPage = CropsPage; if ((Object)(object)parent != (Object)(object)((cropsPage != null) ? cropsPage.transform : null) && ((Object)parent).name.IndexOf("_row", StringComparison.OrdinalIgnoreCase) < 0) { ((Component)parent).gameObject.SetActive(show); } } } private static void SetActiveSafe(Dictionary<string, Slider> map, string crop, bool show) { if (map.TryGetValue(crop, out var value) && (Object)(object)value != (Object)null) { ((Component)value).gameObject.SetActive(show); } } private static void SetCropRowVisible(GameObject row, bool show, float columnX, ref float y) { //IL_0052: Unknown result type (might be due to invalid IL or missing references) row.SetActive(show); CanvasGroup component = row.GetComponent<CanvasGroup>(); if ((Object)(object)component != (Object)null) { component.alpha = (show ? 1f : 0f); component.interactable = show; component.blocksRaycasts = show; } if (show) { RectTransform component2 = row.GetComponent<RectTransform>(); if ((Object)(object)component2 != (Object)null) { component2.anchoredPosition = new Vector2(columnX, y); } y -= 62f; } } internal static void OnWeightChanged(string family, int weight) { if (!SuppressSliderEvents && !((Object)(object)Current == (Object)null)) { weight = Mathf.Clamp(weight, 0, 100); if (WeightLabels.TryGetValue(family, out var value)) { value.text = HomesteadCropsPage.FormatWeightLabel(family, weight); } Current.RequestSetLayoutMode("Weighted"); Current.RequestSetCropWeight(family, weight); RefreshStatus(); } } internal static void OnReserveChanged(string family, int reserve) { if (!SuppressSliderEvents && !((Object)(object)Current == (Object)null)) { reserve = Mathf.Clamp(reserve, 0, 100); if (ReserveLabels.TryGetValue(family, out var value)) { value.text = HomesteadCropsPage.FormatReserveLabel(family, reserve); } Current.RequestSetCropReserve(family, reserve); RefreshStatus(); } } internal static void SyncSlidersFromData() { if (Current?.Data == null) { Current?.ReloadDataFromZdo(); } HomesteadData homesteadData = Current?.Data; if (homesteadData == null) { return; } SuppressSliderEvents = true; try { string[] weightCrops = WeightCrops; foreach (string text in weightCrops) { CropConfigEntry cropConfigEntry = homesteadData.GetCropConfig(text) ?? new CropConfigEntry { Family = text, Weight = 50 }; if (WeightSliders.TryGetValue(text, out var value)) { value.value = Mathf.Clamp(cropConfigEntry.Weight, 0, 100); } if (WeightLabels.TryGetValue(text, out var value2)) { value2.text = HomesteadCropsPage.FormatWeightLabel(text, Mathf.Clamp(cropConfigEntry.Weight, 0, 100)); } } weightCrops = ReserveCrops; foreach (string text2 in weightCrops) { CropConfigEntry cropConfigEntry2 = homesteadData.GetCropConfig(text2) ?? new CropConfigEntry { Family = text2, MinimumSeedReserve = 10 }; if (ReserveSliders.TryGetValue(text2, out var value3)) { value3.value = Mathf.Clamp(cropConfigEntry2.MinimumSeedReserve, 0, 100); } if (ReserveLabels.TryGetValue(text2, out var value4)) { value4.text = HomesteadCropsPage.FormatReserveLabel(text2, Mathf.Clamp(cropConfigEntry2.MinimumSeedReserve, 0, 100)); } } } finally { SuppressSliderEvents = false; } } internal static void QueueRefresh() { if ((Object)(object)Plugin.Instance == (Object)null) { RefreshStatus(); SyncSlidersFromData(); return; } if (RefreshRoutine != null) { ((MonoBehaviour)Plugin.Instance).StopCoroutine(RefreshRoutine); } RefreshRoutine = ((MonoBehaviour)Plugin.Instance).StartCoroutine(RefreshSoon()); } private static IEnumerator RefreshSoon() { RefreshStatus(); yield return (object)new WaitForSeconds(0.4f); Current?.ReloadDataFromZdo(); SyncSlidersFromData(); RefreshStatus(); RefreshRoutine = null; } internal static void RefreshStatus() { if (!((Object)(object)Status == (Object)null) && !((Object)(object)Current == (Object)null)) { HomesteadData data = Current.Data; if (data == null) { Current.ReloadDataFromZdo(); data = Current.Data; } if (data == null) { Status.text = "No data (waiting for network...)"; return; } data.SyncChestListsFromCsv(); StringBuilder stringBuilder = new StringBuilder(); stringBuilder.AppendLine("Status: " + (data.Paused ? "Paused" : "Working")); stringBuilder.AppendLine($"Farmers: {Current.CountFarmers()}"); stringBuilder.AppendLine($"Crops: {data.Slots?.Count ?? 0}"); stringBuilder.AppendLine($"Chests: {data.ChestCount}"); stringBuilder.Append("Boundary: " + (data.HasBoundary ? "set" : "missing")); Status.text = stringBuilder.ToString(); } } internal static void ClearCachedUiState() { WeightSliders.Clear(); WeightLabels.Clear(); WeightRows.Clear(); ReserveSliders.Clear(); ReserveLabels.Clear(); ReserveRows.Clear(); CropsBiomeLabel = null; CropsEmptyRoot = null; InvStatus = null; InvFooter = null; InvListRoot = null; ChestInvStatus = null; ChestInvFooter = null; ChestInvListRoot = null; BuiltLayoutVersion = 0; } } internal static class HomesteadUiShell { private sealed class HomesteadUiInput : MonoBehaviour { private void Update() { if (!((Object)(object)HomesteadUiController.Root == (Object)null) && HomesteadUiController.Root.activeInHierarchy && WasEscapePressed()) { if ((Object)(object)HomesteadUiController.CropsPage != (Object)null && HomesteadUiController.CropsPage.activeSelf) { HomesteadUiController.ShowMainPage(); } else if ((Object)(object)HomesteadUiController.InvPage != (Object)null && HomesteadUiController.InvPage.activeSelf) { HomesteadUiController.ShowMainPage(); } else if ((Object)(object)HomesteadUiController.ChestInvPage != (Object)null && HomesteadUiController.ChestInvPage.activeSelf) { HomesteadUiController.ShowMainPage(); } else { HomesteadUiController.Hide(); } } } private static bool WasEscapePressed() { try { if (ZInput.GetKeyDown((KeyCode)27, true)) { return true; } } catch { } return Input.GetKeyDown((KeyCode)27); } } internal static void EnsureUi() { //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)HomesteadUiController.Root != (Object)null && ((Object)(object)HomesteadUiController.MainPage == (Object)null || (Object)(object)HomesteadUiController.InvPage == (Object)null || (Object)(object)HomesteadUiController.ChestInvPage == (Object)null || (Object)(object)HomesteadUiController.InvStatus == (Object)null || (Object)(object)HomesteadUiController.ChestInvStatus == (Object)null || HomesteadUiController.BuiltLayoutVersion != 24)) { Object.Destroy((Object)(object)HomesteadUiController.Root); HomesteadUiController.Root = null; HomesteadUiController.ClearCachedUiState(); } if (!((Object)(object)HomesteadUiController.Root != (Object)null)) { HomesteadUiController.Root = GUIManager.Instance.CreateWoodpanel(GUIManager.CustomGUIFront.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), Vector2.zero, 460f, 860f); HomesteadUiController.Root.SetActive(false); HomesteadUiController.MainPage = CreatePage("MainPage"); HomesteadUiController.CropsPage = CreatePage("CropsPage"); HomesteadUiController.InvPage = CreatePage("InvPage"); HomesteadUiController.ChestInvPage = CreatePage("ChestInvPage"); HomesteadMainPage.BuildMainPage(); HomesteadCropsPage.BuildCropsPage(); HomesteadInventoryPages.BuildInventoryPage(); HomesteadInventoryPages.BuildChestInventoryPage(); if ((Object)(object)HomesteadUiController.Root.GetComponent<HomesteadUiInput>() == (Object)null) { HomesteadUiController.Root.AddComponent<HomesteadUiInput>(); } HomesteadUiController.BuiltLayoutVersion = 24; HomesteadUiController.ShowMainPage(); } } internal static GameObject CreatePage(string name) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Expected O, but got Unknown GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) }); val.transform.SetParent(HomesteadUiController.Root.transform, false); RectTransform component = val.GetComponent<RectTransform>(); component.anchorMin = Vector2.zero; component.anchorMax = Vector2.one; component.offsetMin = Vector2.zero; component.offsetMax = Vector2.zero; return val; } internal static void SetPanelSize(float width, float height) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)HomesteadUiController.Root == (Object)null)) { RectTransform component = HomesteadUiController.Root.GetComponent<RectTransform>(); if ((Object)(object)component != (Object)null) { component.sizeDelta = new Vector2(width, height); } } } } internal static class HomesteadUiWidgets { internal static void CreateHelpText(Transform parent, string text, ref float y, float height, float columnX = 0f, float width = 400f) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0045: 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_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) GameObject val = GUIManager.Instance.CreateText(text, parent, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(columnX, y), GUIManager.Instance.AveriaSerifBold, 12, GUIManager.Instance.ValheimOrange, true, Color.black, width, height, false); Text val2 = (((Object)(object)val != (Object)null) ? val.GetComponentInChildren<Text>(true) : null); if ((Object)(object)val2 != (Object)null) { val2.alignment = (TextAnchor)0; val2.horizontalOverflow = (HorizontalWrapMode)0; val2.verticalOverflow = (VerticalWrapMode)1; RectTransform rectTransform = ((Graphic)val2).rectTransform; rectTransform.pivot = new Vector2(0.5f, 1f); rectTransform.anchorMin = new Vector2(0.5f, 1f); rectTransform.anchorMax = new Vector2(0.5f, 1f); rectTransform.anchoredPosition = new Vector2(columnX, y); rectTransform.sizeDelta = new Vector2(width, height); } y -= height + 6f; } internal static Sprite TryGetItemIcon(string prefabName) { if (string.IsNullOrEmpty(prefabName) || (Object)(object)ObjectDB.instance == (Object)null) { return null; } GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(prefabName); if ((Object)(object)itemPrefab == (Object)null) { return null; } Sprite[] array = itemPrefab.GetComponent<ItemDrop>()?.m_itemData?.m_shared?.m_icons; if (array == null || array.Length == 0 || (Object)(object)array[0] == (Object)null) { return null; } return array[0]; } internal static void CreateTitle(Transform parent, string text, float y, int fontSize) { CreateTitle(parent, text, 0f, y, fontSize, 420f, (TextAnchor)4); } internal static void CreateTitle(Transform parent, string text, float x, float y, int fontSize, float width, TextAnchor alignment = (TextAnchor)4) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0043: 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_008e: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Invalid comparison between Unknown and I4 //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) GameObject val = GUIManager.Instance.CreateText(text, parent, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(x, y), GUIManager.Instance.AveriaSerifBold, fontSize, GUIManager.Instance.ValheimOrange, true, Color.black, width, 26f, false); Text val2 = (((Object)(object)val != (Object)null) ? val.GetComponentInChildren<Text>(true) : null); if (!((Object)(object)val2 == (Object)null)) { val2.alignment = alignment; RectTransform rectTransform = ((Graphic)val2).rectTransform; rectTransform.pivot = new Vector2(0.5f, 1f); rectTransform.anchorMin = new Vector2(0.5f, 1f); rectTransform.anchorMax = new Vector2(0.5f, 1f); if ((int)alignment == 3 || (int)alignment == 0) { float num = ((Mathf.Abs(x) < 0.01f) ? (-420f) : (x - width * 0.5f)); rectTransform.pivot = new Vector2(0f, 1f); rectTransform.anchoredPosition = new Vector2(num, y); rectTransform.sizeDelta = new Vector2(width, 26f); } else { rectTransform.anchoredPosition = new Vector2(x, y); rectTransform.sizeDelta = new Vector2(width, 26f); } } } internal static void AddSectionHeader(Transform parent, string text, ref float y) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: 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_00ed: Unknown result type (might be due to invalid IL or missing references) y -= 7f; GameObject val = GUIManager.Instance.CreateText(text, parent, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, y), GUIManager.Instance.AveriaSerifBold, 15, GUIManager.Instance.ValheimOrange, true, Color.black, 420f, 22f, false); Text val2 = (((Object)(object)val != (Object)null) ? val.GetComponentInChildren<Text>(true) : null); if ((Object)(object)val2 != (Object)null) { val2.alignment = (TextAnchor)4; RectTransform rectTransform = ((Graphic)val2).rectTransform; rectTransform.pivot = new Vector2(0.5f, 1f); rectTransform.anchorMin = new Vector2(0.5f, 1f); rectTransform.anchorMax = new Vector2(0.5f, 1f); rectTransform.anchoredPosition = new Vector2(0f, y); rectTransform.sizeDelta = new Vector2(420f, 22f); } y -= 37f; } internal static GameObject CreateSliderRow(Transform parent, string crop, string kind, float y, int min, int max, Dictionary<string, Slider> sliders, Dictionary<string, Text> labels, UnityAction<float> onChanged, string iconPrefab, Func<int, string> formatLabel, float columnX, float columnWidth) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Expected O, but got Unknown //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_01e1: Unknown result type (might be due to invalid IL or missing references) //IL_01f0: Unknown result type (might be due to invalid IL or missing references) //IL_020e: Unknown result type (might be due to invalid IL or missing references) //IL_0224: Unknown result type (might be due to invalid IL or missing references) //IL_022a: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0131: 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_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_0364: Unknown result type (might be due to invalid IL or missing references) //IL_036b: Expected O, but got Unknown //IL_0390: Unknown result type (might be due to invalid IL or missing references) //IL_03a5: Unknown result type (might be due to invalid IL or missing references) //IL_03ba: Unknown result type (might be due to invalid IL or missing references) //IL_03cc: Unknown result type (might be due to invalid IL or missing references) //IL_03d9: Unknown result type (might be due to invalid IL or missing references) //IL_0437: Unknown result type (might be due to invalid IL or missing references) //IL_043c: Unknown result type (might be due to invalid IL or missing references) //IL_044f: Unknown result type (might be due to invalid IL or missing references) //IL_0456: Unknown result type (might be due to invalid IL or missing references) //IL_0461: Unknown result type (might be due to invalid IL or missing references) //IL_046c: Unknown result type (might be due to invalid IL or missing references) //IL_0476: Unknown result type (might be due to invalid IL or missing references) //IL_049d: Unknown result type (might be due to invalid IL or missing references) //IL_04c8: Unknown result type (might be due to invalid IL or missing references) //IL_04cf: Expected O, but got Unknown //IL_04eb: Unknown result type (might be due to invalid IL or missing references) //IL_04f6: Unknown result type (might be due to invalid IL or missing references) //IL_050b: Unknown result type (might be due to invalid IL or missing references) //IL_051f: Unknown result type (might be due to invalid IL or missing references) //IL_054e: Unknown result type (might be due to invalid IL or missing references) //IL_0553: Unknown result type (might be due to invalid IL or missing references) //IL_0566: Unknown result type (might be due to invalid IL or missing references) //IL_0570: Unknown result type (might be due to invalid IL or missing references) //IL_057c: Unknown result type (might be due to invalid IL or missing references) //IL_0588: Unknown result type (might be due to invalid IL or missing references) //IL_0594: Unknown result type (might be due to invalid IL or missing references) //IL_05b7: Unknown result type (might be due to invalid IL or missing references) //IL_05e2: Unknown result type (might be due to invalid IL or missing references) //IL_05e9: Expected O, but got Unknown //IL_0605: Unknown result type (might be due to invalid IL or missing references) //IL_0610: Unknown result type (might be due to invalid IL or missing references) //IL_0625: Unknown result type (might be due to invalid IL or missing references) //IL_0639: Unknown result type (might be due to invalid IL or missing references) //IL_0668: Unknown result type (might be due to invalid IL or missing references) //IL_066d: Unknown result type (might be due to invalid IL or missing references) //IL_0680: Unknown result type (might be due to invalid IL or missing references) //IL_0694: Unknown result type (might be due to invalid IL or missing references) //IL_06b7: Unknown result type (might be due to invalid IL or missing references) //IL_06db: Unknown result type (might be due to invalid IL or missing references) //IL_02df: Unknown result type (might be due to invalid IL or missing references) //IL_02f4: Unknown result type (might be due to invalid IL or missing references) //IL_0309: Unknown result type (might be due to invalid IL or missing references) //IL_031b: Unknown result type (might be due to invalid IL or missing references) //IL_032c: Unknown result type (might be due to invalid IL or missing references) float num = -26f; float num2 = num - 8f; GameObject val = new GameObject(crop + "_" + kind + "_row", new Type[2] { typeof(RectTransform), typeof(CanvasGroup) }); val.transform.SetParent(parent, false); RectTransform component = val.GetComponent<RectTransform>(); component.anchorMin = new Vector2(0.5f, 1f); component.anchorMax = new Vector2(0.5f, 1f); component.pivot = new Vector2(0.5f, 1f); component.sizeDelta = new Vector2(columnWidth, 62f); component.anchoredPosition = new Vector2(columnX, y); float num3 = 0f - columnWidth * 0.5f; float num4 = num3 + 24.5f; float num5 = num3 + 49f + 10f; float num6 = columnWidth - 49f - 16f; Sprite val2 = TryGetItemIcon(iconPrefab); if ((Object)(object)val2 != (Object)null) { GameObject val3 = new GameObject(crop + "_" + kind + "_icon", new Type[2] { typeof(RectTransform), typeof(Image) }); val3.transform.SetParent(val.transform, false); RectTransform component2 = val3.GetComponent<RectTransform>(); component2.pivot = new Vector2(0.5f, 0.5f); component2.anchorMin = new Vector2(0.5f, 1f); component2.anchorMax = new Vector2(0.5f, 1f); component2.sizeDelta = new Vector2(49f, 49f); component2.anchoredPosition = new Vector2(num4, num2); Image component3 = val3.GetComponent<Image>(); component3.sprite = val2; component3.preserveAspect = true; ((Graphic)component3).raycastTarget = false; } GameObject val4 = GUIManager.Instance.CreateText(formatLabel(min), val.transform, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(num5 + num6 * 0.5f - columnWidth * 0.25f, 0f), GUIManager.Instance.AveriaSerifBold, 13, GUIManager.Instance.ValheimOrange, true, Color.black, num6, 18f, false); if ((Object)(object)val4 != (Object)null && (Object)(object)val4.transform.parent != (Object)(object)val.transform) { val4.transform.SetParent(val.transform, false); } Text val5 = (((Object)(object)val4 != (Object)null) ? val4.GetComponentInChildren<Text>(true) : null); if ((Object)(object)val5 != (Object)null) { if ((Object)(object)val4 != (Object)null && (Object)(object)((Component)val5).gameObject != (Object)(object)val4) { val4.transform.SetParent(val.transform, false); } val5.alignment = (TextAnchor)3; RectTransform rectTransform = ((Graphic)val5).rectTransform; rectTransform.pivot = new Vector2(0f, 1f); rectTransform.anchorMin = new Vector2(0.5f, 1f); rectTransform.anchorMax = new Vector2(0.5f, 1f); rectTransform.anchoredPosition = new Vector2(num5, 0f); rectTransform.sizeDelta = new Vector2(num6, 18f); labels[crop] = val5; } GameObject val6 = new GameObject(crop + "_" + kind + "_slider", new Type[1] { typeof(RectTransform) }); val6.transform.SetParent(val.transform, false); RectTransform component4 = val6.GetComponent<RectTransform>(); component4.anchorMin = new Vector2(0.5f, 1f); component4.anchorMax = new Vector2(0.5f, 1f); component4.pivot = new Vector2(0f, 1f); component4.sizeDelta = new Vector2(num6, 16f); component4.anchoredPosition = new Vector2(num5, num); Slider val7 = val6.AddComponent<Slider>(); val7.minValue = min; val7.maxValue = max; val7.wholeNumbers = true; val7.value = min; GameObject val8 = new GameObject("Background", new Type[2] { typeof(RectTransform), typeof(Image) }); val8.transform.SetParent(val6.transform, false); RectTransform component5 = val8.GetComponent<RectTransform>(); component5.anchorMin = Vector2.zero; component5.anchorMax = Vector2.one; component5.offsetMin = Vector2.zero; component5.offsetMax = Vector2.zero; Image component6 = val8.GetComponent<Image>(); ((Graphic)component6).color = new Color(0.15f, 0.12f, 0.1f, 0.9f); ((Selectable)val7).targetGraphic = (Graphic)(object)component6; GameObject val9 = new GameObject("Fill Area", new Type[1] { typeof(RectTransform) }); val9.transform.SetParent(val6.transform, false); RectTransform component7 = val9.GetComponent<RectTransform>(); component7.anchorMin = Vector2.zero; component7.anchorMax = Vector2.one; component7.offsetMin = new Vector2(4f, 4f); component7.offsetMax = new Vector2(-4f, -4f); GameObject val10 = new GameObject("Fill", new Type[2] { typeof(RectTransform), typeof(Image) }); val10.transform.SetParent(val9.transform, false); RectTransform component8 = val10.GetComponent<RectTransform>(); component8.anchorMin = Vector2.zero; component8.anchorMax = Vector2.one; component8.offsetMin = Vector2.zero; component8.offsetMax = Vector2.zero; ((Graphic)val10.GetComponent<Image>()).color = new Color(0.75f, 0.45f, 0.15f, 1f); val7.fillRect = component8; GameObject val11 = new GameObject("Handle Slide Area", new Type[1] { typeof(RectTransform) }); val11.transform.SetParent(val6.transform, false); RectTransform component9 = val11.GetComponent<RectTransform>(); component9.anchorMin = Vector2.zero; component9.anchorMax = Vector2.one; component9.offsetMin = new Vector2(8f, 0f); component9.offsetMax = new Vector2(-8f, 0f); GameObject val12 = new GameObject("Handle", new Type[2] { typeof(RectTransform), typeof(Image) }); val12.transform.SetParent(val11.transform, false); RectTransform component10 = val12.GetComponent<RectTransform>(); component10.sizeDelta = new Vector2(14f, 18f); ((Graphic)val12.GetComponent<Image>()).color = new Color(0.95f, 0.8f, 0.45f, 1f); val7.handleRect = component10; try { GUIManager.Instance.ApplySliderStyle(val7, new Vector2(14f, 18f)); } catch { } ((UnityEvent<float>)(object)val7.onValueChanged).AddListener(onChanged); sliders[crop] = val7; return val; } internal static void AddButton(Transform parent, string label, ref float y, UnityAction action) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) ((UnityEvent)GUIManager.Instance.CreateButton(label, parent, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, y), 300f, 28f).GetComponentInChildren<Button>().onClick).AddListener(action); y -= 32f; } } } namespace ValheimFarmerNPC.Resolvers { internal static class ChestResolver { public static Container ResolveNearest(HomesteadData data, Vector3 from) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) if (data == null) { return null; } data.SyncChestListsFromCsv(); return (from c in ChestAssignments.ResolveFromPositions(data.ChestPositions) orderby Vector3.Distance(@from, ((Component)c).transform.position) select c).FirstOrDefault(); } public static bool IsValid(Container container) { if ((Object)(object)container != (Object)null) { return container.GetInventory() != null; } return false; } } internal enum CropResolveStatus { Missing, Growing, Ready, WrongCrop, Destroyed } internal readonly struct CropResolveResult { public readonly CropResolveStatus Status; public readonly Pickable Pickable; public readonly Plant Plant; public CropResolveResult(CropResolveStatus status, Pickable pickable = null, Plant plant = null) { Status = status; Pickable = pickable; Plant = plant; } } internal static class CropResolver { public static CropResolveResult Resolve(FarmSlot slot) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) if (slot == null) { return new CropResolveResult(CropResolveStatus.Missing); } Pickable val = FarmScanner.FindPickableAt(slot.Position); if ((Object)(object)val != (Object)null) { if (val.m_picked) { return new CropResolveResult(CropResolveStatus.Destroyed); } return new CropResolveResult(CropResolveStatus.Ready, val); } Plant val2 = FarmScanner.FindPlantAt(slot.Position); if ((Object)(object)val2 != (Object)null) { return new CropResolveResult(CropResolveStatus.Growing, null, val2); } return new CropResolveResult(CropResolveStatus.Missing); } } internal static class SlotResolver { public static FarmSlot ById(HomesteadData data, string slotId) { if (data?.Slots == null || string.IsNullOrEmpty(slotId)) { return null; } return data.Slots.FirstOrDefault((FarmSlot s) => s != null && s.Id == slotId); } public static FarmSlot Nearest(HomesteadData data, Vector3 from, Func<FarmSlot, bool> predicate) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) if (data?.Slots == null) { return null; } return (from s in data.Slots where s != null && (predicate == null || predicate(s)) orderby Vector3.Distance(@from, s.Position) select s).FirstOrDefault(); } } } namespace ValheimFarmerNPC.Registration { internal static class ItemRegistrar { public static void Register() { Log.Debug("ItemRegistrar: no custom items in MVP"); } } internal static class NpcRegistrar { private static bool _registered; public static void Register() { //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) if (_registered) { return; } GameObject val = PrefabManager.Instance.CreateClonedPrefab("FarmerNpc", "Goblin"); if ((Object)(object)val == (Object)null) { Log.Error("Failed to clone NPC from Goblin"); return; } MonsterAI[] componentsInChildren = val.GetComponentsInChildren<MonsterAI>(true); foreach (MonsterAI val2 in componentsInChildren) { ((Behaviour)val2).enabled = false; try { val2.m_enableHuntPlayer = false; } catch { } } BaseAI[] componentsInChildren2 = val.GetComponentsInChildren<BaseAI>(true); for (int i = 0; i < componentsInChildren2.Length; i++) { ((Behaviour)componentsInChildren2[i]).enabled = false; } CharacterDrop component = val.GetComponent<CharacterDrop>(); if ((Object)(object)component != (Object)null) { ((Behaviour)component).enabled = false; } Character component2 = val.GetComponent<Character>(); if ((Object)(object)component2 != (Object)null) { component2.m_name = "$fj_npc_name"; component2.m_faction = (Faction)0; component2.m_group = "farmer_npc"; component2.m_boss = false; } Humanoid component3 = val.GetComponent<Humanoid>(); if ((Object)(object)component3 != (Object)null) { ((Character)component3).m_faction = (Faction)0; } if ((Object)(object)val.GetComponent<FarmerNpc>() == (Object)null) { val.AddComponent<FarmerNpc>(); } ZNetView component4 = val.GetComponent<ZNetView>(); if ((Object)(object)component4 != (Object)null) { component4.m_persistent = true; component4.m_distant = false; } PrefabManager.Instance.AddPrefab(val); _registered = true; Log.Info("NPC prefab 'FarmerNpc' registered (clone of Goblin)"); } } internal static class PieceRegistrar { private static bool _registered; public static void Register() { if (!_registered) { RegisterHomestead(); RegisterBoundaryPost(); _registered = true; Log.Info("Custom pieces registered"); } } private static void RegisterHomestead() { //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0088: 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_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Expected O, but got Unknown //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Expected O, but got Unknown //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Expected O, but got Unknown //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Expected O, but got Unknown GameObject val = PrefabManager.Instance.CreateClonedPrefab("FarmerHomestead", "piece_workbench"); if ((Object)(object)val == (Object)null) { Log.Error("Failed to clone homestead from piece_workbench"); return; } StripComponent<MapTable>(val); StripComponent<CraftingStation>(val); StripComponent<StationExtension>(val); StripComponent<CircleProjector>(val); if ((Object)(object)val.GetComponent<FarmerHomestead>() == (Object)null) { val.AddComponent<FarmerHomestead>(); } Piece component = val.GetComponent<Piece>(); if ((Object)(object)component != (Object)null) { component.m_name = "$piece_farmerhomestead"; component.m_description = "$piece_farmerhomestead_desc"; component.m_craftingStation = null; } PieceConfig val2 = new PieceConfig { Name = "$piece_farmerhomestead", Description = "$piece_farmerhomestead_desc", PieceTable = PieceTables.Hammer, Category = PieceCategories.Misc }; val2.AddRequirement(new RequirementConfig("Wood", 10, 0, true)); val2.AddRequirement(new RequirementConfig("Stone", 5, 0, true)); PieceManager.Instance.AddPiece(new CustomPiece(val, false, val2)); } private static void RegisterBoundaryPost() { //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Expected O, but got Unknown //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Expected O, but got Unknown //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Expected O, but got Unknown GameObject val = PrefabManager.Instance.CreateClonedPrefab("FarmBoundaryPost", "wood_pole"); if ((Object)(object)val == (Object)null) { Log.Error("Failed to clone boundary post from wood_pole"); return; } if ((Object)(object)val.GetComponent<BoundaryPost>() == (Object)null) { val.AddComponent<BoundaryPost>(); } Piece component = val.GetComponent<Piece>(); if ((Object)(object)component != (Object)null) { component.m_name = "$piece_farmboundarypost"; component.m_description = "$piece_farmboundarypost_desc"; } PieceConfig val2 = new PieceConfig { Name = "$piece_farmboundarypost", Description = "$piece_farmboundarypost_desc", PieceTable = PieceTables.Hammer, Category = PieceCategories.Misc }; val2.AddRequirement(new RequirementConfig("Wood", 2, 0, true)); PieceManager.Instance.AddPiece(new CustomPiece(val, false, val2)); } private static void StripComponent<T>(GameObject prefab) where T : Component { T[] array = prefab.GetComponentsInChildren<T>(true).ToArray(); for (int i = 0; i < array.Length; i++) { Object.DestroyImmediate((Object)(object)array[i]); } } } } namespace ValheimFarmerNPC.Pieces { public class BoundaryPost : MonoBehaviour { private ZNetView _nview; private void Awake() { _nview = ((Component)this).GetComponent<ZNetView>(); } public long GetKey() { if ((Object)(object)_nview == (Object)null || !_nview.IsValid()) { return 0L; } return ZdoIds.ZdoKey(_nview.GetZDO()); } public string GetHoverText() { return Localization.instance.Localize("$piece_farmboundarypost"); } } internal static class FarmerCleanup { public const string ZdoMarker = "fj_farmer"; public static void MarkAsFarmer(ZDO zdo) { FarmerDestroyer.MarkAsFarmer(zdo); } public static void Register(ZDOID id) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) FarmerDestroyer.Register(id); } public static bool LooksLikeFarmerCharacter(Character character) { return FarmerIdentity.LooksLikeFarmerCharacter(character); } public static List<ZDOID> CollectLocalFarmerIds(Vector3 pos, float range) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) return FarmerDestroyer.CollectLocalFarmerIds(pos, range); } public static int DestroyLocalFarmerViews(Vector3 pos, float range) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) return FarmerDestroyer.DestroyLocalFarmerViews(pos, range); } public static int ClearNear(Vector3 pos, float range, bool keepOne, List<ZDOID> extraIds = null) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) return FarmerDestroyer.ClearNear(pos, range, keepOne, extraIds); } public static bool DestroyById(ZDOID id) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) return FarmerDestroyer.DestroyById(id); } } public class FarmerHomestead : MonoBehaviour, Hoverable, Interactable { private static readonly List<FarmerHomestead> Instances = new List<FarmerHomestead>(); private ZNetView _nview; private HomesteadData _data; private FarmerNpc _npc; private InventoryManager _pendingInventory; private bool _initialized; private bool _rpcsRegistered; private float _initRetryLogTimer; private bool _starterPending; private float _starterNextTry; private int _starterAttempts; public HomesteadData Data => _data; public ZNetView NetView => _nview; public long HomesteadKey { get { if (!((Object)(object)_nview != (Object)null) || !_nview.IsValid()) { return 0L; } return ZdoIds.ZdoKey(_nview.GetZDO()); } } public bool IsReady { get { if (_initialized && (Object)(object)_nview != (Object)null) { return _nview.IsValid(); } return false; } } public static IReadOnlyList<FarmerHomestead> All => Instances; private void Awake() { _nview = ((Component)this).GetComponent<ZNetView>(); Instances.Add(this); } private void Start() { TryInitialize(); } private void Update() { if (!_initialized) { TryInitialize(); } else if (_starterPending && Time.time >= _starterNextTry) { _starterNextTry = Time.time + 0.5f; EnsureStarterFarmer(); } } public bool TryInitialize() { //IL_00cd: Unknown result type (might be due to invalid IL or missing references) if (_initialized) { return true; } if ((Object)(object)_nview == (Object)null) { _nview = ((Component)this).GetComponent<ZNetView>(); } if ((Object)(object)_nview == (Object)null || !_nview.IsValid()) { _initRetryLogTimer += Time.deltaTime; if (_initRetryLogTimer >= 2f) { _initRetryLogTimer = 0f; Log.Debug("FarmerHomestead waiting for valid ZNetView..."); } return false; } try { if (!_rpcsRegistered) { RegisterRpcs(); _rpcsRegistered = true; } if (_data == null) { _data = SaveManager.Load(_nview); _pendingInventory =