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 ValheimLumberNPC v1.0.0
plugins/ValheimLumberNPC.dll
Decompiled 15 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 ValheimLumberNPC.AI; using ValheimLumberNPC.Commands; using ValheimLumberNPC.Config; using ValheimLumberNPC.HarmonyPatches; using ValheimLumberNPC.Homestead; using ValheimLumberNPC.Inventory; using ValheimLumberNPC.Logging; using ValheimLumberNPC.Lumber; using ValheimLumberNPC.NPC; using ValheimLumberNPC.Networking; using ValheimLumberNPC.Persistence; using ValheimLumberNPC.Pieces; using ValheimLumberNPC.Registration; using ValheimLumberNPC.Resolvers; using ValheimLumberNPC.UI; using ValheimLumberNPC.Utilities; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("ValheimLumberNPC")] [assembly: AssemblyDescription("Autonomous multiplayer-safe lumberjack NPC for Valheim")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("ValheimLumberNPC")] [assembly: AssemblyCopyright("Copyright © 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("c8f5d3b2-0a4e-5f9b-b2d6-7e3a1c9f5b82")] [assembly: AssemblyFileVersion("1.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] namespace ValheimLumberNPC { internal static class Constants { public const int SchemaVersion = 1; public const string HomesteadPrefab = "LumberHomestead"; public const string BoundaryPostPrefab = "LumberBoundaryPost"; public const string NpcPrefab = "LumberNpc"; public const string HomesteadCloneSource = "piece_workbench"; public const string BoundaryPostCloneSource = "wood_pole"; public const string NpcCloneSource = "Troll"; public const string ZdoSchemaVersion = "ln_schema"; public const string ZdoData = "ln_data"; public const string ZdoNpcId = "ln_npc"; public const string ZdoPaused = "ln_paused"; public const string ZdoWorkRadius = "ln_work_radius"; public const string ZdoLumberBag = "ln_bag"; public const string ZdoFarmerBag = "ln_bag"; public const string ZdoLumberBagSet = "ln_bag_set"; public const string ZdoFarmerBagSet = "ln_bag_set"; public const string ZdoInitialNpc = "ln_initial_npc"; public const string RpcTogglePause = "LN_TogglePause"; public const string RpcScanField = "LN_ScanField"; public const string RpcAssignBoundary = "LN_AssignBoundary"; public const string RpcAssignChest = "LN_AssignChest"; public const string RpcUpdateCropConfig = "LN_UpdateCropConfig"; public const string RpcSetWorkRadius = "LN_SetWorkRadius"; public const string RpcSetLayoutMode = "LN_SetLayoutMode"; public const string RpcSetPaused = "LN_SetPaused"; public const string RpcClearChests = "LN_ClearChests"; public const string RpcClearField = "LN_ClearField"; public const string RpcEnsureNpc = "LN_EnsureNpc"; public const float DefaultInteractRange = 3.5f; public const float DefaultWorkRange = 3f; public const float DefaultThinkInterval = 0.5f; public const float DefaultChestAssignRange = 20f; public const float ChestMatchRadius = 0.35f; public const float DefaultWorkRadius = 40f; public const float MinWorkRadius = 10f; public const float MaxWorkRadius = 100f; public const float NpcReclaimRange = 132f; public const float WoodPickupRadius = 14f; public const float WorkScanVerticalExtent = 64f; public const float FarmScanVerticalExtent = 64f; public const float TreeMatchRadius = 0.85f; public const float CropMatchRadius = 0.85f; public const float DefaultStuckSeconds = 8f; public const float InventoryNearlyFullRatio = 0.85f; public static float EffectiveMaxWorkRadius => Mathf.Min(100f, SyncedConfig.MaxWorkRadius); public static float ClampWorkRadius(float radius) { if (radius <= 0f) { return 40f; } return Mathf.Clamp(radius, 10f, EffectiveMaxWorkRadius); } } [BepInPlugin("com.pjanky.valheimlumbernpc", "ValheimLumberNPC", "1.0.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] internal class Plugin : BaseUnityPlugin { public const string PluginGUID = "com.pjanky.valheimlumbernpc"; public const string PluginName = "ValheimLumberNPC"; public const string PluginVersion = "1.0.0"; 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.pjanky.valheimlumbernpc"); try { PlacementPatches.Apply(Harmony); LumberRemovePatches.Apply(Harmony); LumberAudioPatches.Apply(Harmony); LumberFriendlyFirePatches.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("ValheimLumberNPC v1.0.0 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_lumberhomestead", "Lumber Homestead" }, { "piece_lumberhomestead_desc", "Homestead for a friendly troll lumberjack. Spawns one troll on place. Chops trees in a configurable radius and deposits wood in assigned chests. Admin only." }, { "ln_npc_name", "Lumber Troll" }, { "ln_npc_paused", "Lumber troll is paused. Talk to resume." }, { "ln_npc_working", "Lumber troll is working. Talk to pause." } }); } } } namespace ValheimLumberNPC.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)("[LumberNPC] " + message)); } public static void Warning(string message) { Logger.LogWarning((object)("[LumberNPC] " + message)); } public static void Error(string message) { Logger.LogError((object)("[LumberNPC] " + message)); } public static void Debug(string message) { if (SyncedConfig.DebugLogging) { Logger.LogInfo((object)("[LumberNPC: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 ValheimLumberNPC.UI { 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 (LumberNpc item in LumberRoster.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<float> <>9__0_6; public static Func<int, string> <>9__0_7; 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?.RequestAssignChest(); HomesteadUiController.QueueRefresh(); } internal void <BuildMainPage>b__0_5() { HomesteadUiController.Current?.RequestClearChests(); HomesteadUiController.QueueRefresh(); } internal void <BuildMainPage>b__0_6(float v) { HomesteadUiController.OnRadiusChanged(Mathf.RoundToInt(v)); } internal string <BuildMainPage>b__0_7(int value) { return HomesteadRadiusPage.FormatRadiusLabel(value); } } 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_02ee: Unknown result type (might be due to invalid IL or missing references) //IL_02f8: 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_03f6: Unknown result type (might be due to invalid IL or missing references) //IL_0400: Expected O, but got Unknown //IL_0420: Unknown result type (might be due to invalid IL or missing references) //IL_042a: Expected O, but got Unknown HomesteadUiWidgets.CreateTitle(HomesteadUiController.MainPage.transform, "Lumber 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, "Lumberjacks", 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 Troll", 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 Troll", 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, "Troll inventory", ref y, new UnityAction(HomesteadUiController.ShowInventoryPage)); HomesteadUiWidgets.AddSectionHeader(HomesteadUiController.MainPage.transform, "Storage", ref y); Transform transform5 = HomesteadUiController.MainPage.transform; object obj5 = <>c.<>9__0_4; if (obj5 == null) { UnityAction val6 = delegate { HomesteadUiController.Current?.RequestAssignChest(); HomesteadUiController.QueueRefresh(); }; <>c.<>9__0_4 = val6; obj5 = (object)val6; } HomesteadUiWidgets.AddButton(transform5, "Add chest", ref y, (UnityAction)obj5); Transform transform6 = HomesteadUiController.MainPage.transform; object obj6 = <>c.<>9__0_5; if (obj6 == null) { UnityAction val7 = delegate { HomesteadUiController.Current?.RequestClearChests(); HomesteadUiController.QueueRefresh(); }; <>c.<>9__0_5 = val7; obj6 = (object)val7; } HomesteadUiWidgets.AddButton(transform6, "Clear chests", ref y, (UnityAction)obj6); HomesteadUiWidgets.AddButton(HomesteadUiController.MainPage.transform, "Chest inventory", ref y, new UnityAction(HomesteadUiController.ShowChestInventoryPage)); HomesteadUiWidgets.AddSectionHeader(HomesteadUiController.MainPage.transform, "Work area", ref y); HomesteadUiController.RadiusRow = HomesteadUiWidgets.CreateSliderRow(HomesteadUiController.MainPage.transform, "radius", "work", y, 10, (int)Constants.EffectiveMaxWorkRadius, HomesteadUiController.RadiusSliders, HomesteadUiController.RadiusLabels, delegate(float v) { HomesteadUiController.OnRadiusChanged(Mathf.RoundToInt(v)); }, null, (int value3) => HomesteadRadiusPage.FormatRadiusLabel(value3), 0f, 400f); HomesteadUiController.RadiusSlider = (HomesteadUiController.RadiusSliders.TryGetValue("radius", out var value) ? value : null); HomesteadUiController.RadiusLabel = (HomesteadUiController.RadiusLabels.TryGetValue("radius", out var value2) ? value2 : null); y -= 72f; HomesteadUiWidgets.AddSectionHeader(HomesteadUiController.MainPage.transform, "Settings", ref y); HomesteadUiWidgets.AddButton(HomesteadUiController.MainPage.transform, "Lumber settings", ref y, new UnityAction(HomesteadUiController.ShowCropsPage)); y -= 8f; HomesteadUiWidgets.AddButton(HomesteadUiController.MainPage.transform, "Close", ref y, new UnityAction(HomesteadUiController.Hide)); } } internal static class HomesteadRadiusPage { 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_03e8: Unknown result type (might be due to invalid IL or missing references) //IL_03f2: Expected O, but got Unknown HomesteadUiWidgets.CreateTitle(HomesteadUiController.CropsPage.transform, "Lumber settings", 0f, -22f, 20, 500f, (TextAnchor)3); float num = 260f; 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, 260f, 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(390f, -22f); rectTransform.sizeDelta = new Vector2(260f, 24f); } GameObject val2 = (HomesteadUiController.CropsEmptyRoot = GUIManager.Instance.CreateText("No trees grow in this biome.", HomesteadUiController.CropsPage.transform, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, -280f), 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 y = -58f; HomesteadUiWidgets.CreateHelpText(HomesteadUiController.CropsPage.transform, "Left: which trees to chop. Right: which seeds to replant after a stump. Set a priority to 0 to skip. Rows are biome-filtered.", ref y, 44f, 0f, 800f); float num2 = -205f; float num3 = 205f; float num4 = 380f; HomesteadUiWidgets.CreateTitle(HomesteadUiController.CropsPage.transform, "Tree priorities", num2, y, 17, num4, (TextAnchor)3); HomesteadUiWidgets.CreateTitle(HomesteadUiController.CropsPage.transform, "Replant priorities", num3, y, 17, num4, (TextAnchor)3); y -= 28f; RectTransform content; Transform parent = HomesteadUiWidgets.CreateScrollRegion(HomesteadUiController.CropsPage.transform, y, out content); HomesteadUiController.CropsRowsContent = content; HomesteadUiController.CropsRowYStart = 0f; float num5 = 0f; string[] weightCrops = HomesteadUiController.WeightCrops; foreach (string text in weightCrops) { string familyKey = text; string text2 = WoodRegistry.GetOutputItem(text) ?? "Wood"; string iconPrefab = WoodRegistry.GetPlantingInputItem(text) ?? text2; HomesteadUiController.WeightRows[text] = HomesteadUiWidgets.CreateSliderRow(parent, text, "weight", num5, 0, 100, HomesteadUiController.WeightSliders, HomesteadUiController.WeightLabels, delegate(float v) { HomesteadUiController.OnWeightChanged(familyKey, Mathf.RoundToInt(v)); }, text2, (int value2) => FormatWeightLabel(familyKey, value2), num2, num4); HomesteadUiController.ReplantRows[text] = HomesteadUiWidgets.CreateSliderRow(parent, text, "replant", num5, 0, 100, HomesteadUiController.ReplantSliders, HomesteadUiController.ReplantLabels, delegate(float v) { HomesteadUiController.OnReplantWeightChanged(familyKey, Mathf.RoundToInt(v)); }, iconPrefab, (int value2) => FormatReplantLabel(familyKey, value2), num3, num4); if (!WoodRegistry.CanReplant(text) && HomesteadUiController.ReplantRows.TryGetValue(text, out var value) && (Object)(object)value != (Object)null) { (value.GetComponent<CanvasGroup>() ?? value.AddComponent<CanvasGroup>()).interactable = false; } num5 -= 62f; } float y2 = -650f; HomesteadUiWidgets.AddButton(HomesteadUiController.CropsPage.transform, "Back", ref y2, new UnityAction(HomesteadUiController.ShowMainPage)); } internal static string CropDisplayName(string family) { return WoodRegistry.GetDisplayName(family); } internal static string FormatWeightLabel(string family, int value) { return $"{CropDisplayName(family)}: {value}"; } internal static string FormatReplantLabel(string family, int value) { string plantingInputItem = WoodRegistry.GetPlantingInputItem(family); string arg = ((!string.IsNullOrEmpty(plantingInputItem)) ? plantingInputItem : CropDisplayName(family)); return $"{arg}: {value}"; } internal static string FormatReserveLabel(string family, int value) { return $"{CropDisplayName(family)} reserve: {value}"; } internal static string FormatRadiusLabel(int value) { return $"Work radius: {value}m"; } } internal static class HomesteadUiController { internal static readonly string[] WeightCrops = WoodRegistry.AllFamilies; internal static readonly string[] ReserveCrops = Array.Empty<string>(); internal const int UiLayoutVersion = 30; 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 = 820f; internal const float CropsPanelWidth = 860f; internal const float CropsPanelHeight = 700f; internal const float CropsLeftColumnX = -205f; internal const float CropsRightColumnX = 205f; internal const float CropsColumnOffset = 0f; internal const float CropsColumnWidth = 380f; internal const float CropsRowsBottomMargin = 92f; 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 LumberHomestead Current; internal static Text Status; internal static Text CropsBiomeLabel; internal static GameObject CropsEmptyRoot; internal static float CropsRowYStart; internal static RectTransform CropsRowsContent; internal static GameObject RadiusRow; internal static Slider RadiusSlider; internal static Text RadiusLabel; internal static readonly Dictionary<string, Slider> RadiusSliders = new Dictionary<string, Slider>(StringComparer.OrdinalIgnoreCase); internal static readonly Dictionary<string, Text> RadiusLabels = new Dictionary<string, Text>(StringComparer.OrdinalIgnoreCase); 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> ReplantSliders = new Dictionary<string, Slider>(StringComparer.OrdinalIgnoreCase); internal static readonly Dictionary<string, Text> ReplantLabels = new Dictionary<string, Text>(StringComparer.OrdinalIgnoreCase); internal static readonly Dictionary<string, GameObject> ReplantRows = 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(LumberHomestead 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, 820f); 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(860f, 700f); 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_0070: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_01de: 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 = BiomeTreeRules.GetBiome(position); BiomeTreeRules.ApplyToData(data, position); Current.Persist(); if ((Object)(object)CropsBiomeLabel != (Object)null) { CropsBiomeLabel.text = "Biome: " + BiomeTreeRules.GetBiomeDisplayName(biome); } float num = CropsRowYStart; int num2 = 0; string[] weightCrops = WeightCrops; foreach (string text in weightCrops) { bool flag = BiomeTreeRules.IsTreeAllowed(text, biome); float y = num; if (WeightRows.TryGetValue(text, out var value) && (Object)(object)value != (Object)null) { SetCropRowAt(value, flag, -205f, y); } bool show = flag && WoodRegistry.CanReplant(text); if (ReplantRows.TryGetValue(text, out var value2) && (Object)(object)value2 != (Object)null) { SetCropRowAt(value2, show, 205f, y); } SetActiveSafe(WeightLabels, text, flag); SetActiveSafe(WeightSliders, text, flag); SetActiveSafe(ReplantLabels, text, show); SetActiveSafe(ReplantSliders, text, show); if (flag) { num2++; num -= 62f; } } if ((Object)(object)CropsEmptyRoot != (Object)null) { CropsEmptyRoot.SetActive(num2 == 0); } if ((Object)(object)CropsRowsContent != (Object)null) { float num3 = Mathf.Max(80f, (float)num2 * 62f + 20f); CropsRowsContent.sizeDelta = new Vector2(CropsRowsContent.sizeDelta.x, num3); CropsRowsContent.anchoredPosition = new Vector2(0f, 0f); } } 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 SetCropRowAt(GameObject row, bool show, float columnX, float y) { //IL_0051: 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); } } } private static void SetCropRowVisible(GameObject row, bool show, float columnX, ref float y) { SetCropRowAt(row, show, columnX, y); if (show) { 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 = HomesteadRadiusPage.FormatWeightLabel(family, weight); } Current.RequestSetLayoutMode("Weighted"); Current.RequestSetCropWeight(family, weight); RefreshStatus(); } } internal static void OnReplantWeightChanged(string family, int weight) { if (!SuppressSliderEvents && !((Object)(object)Current == (Object)null)) { weight = Mathf.Clamp(weight, 0, 100); if (ReplantLabels.TryGetValue(family, out var value)) { value.text = HomesteadRadiusPage.FormatReplantLabel(family, weight); } Current.RequestSetLayoutMode("Weighted"); Current.RequestSetReplantWeight(family, weight); RefreshStatus(); } } internal static void OnRadiusChanged(int radius) { if (!SuppressSliderEvents && !((Object)(object)Current == (Object)null)) { radius = Mathf.RoundToInt(Constants.ClampWorkRadius(radius)); if ((Object)(object)RadiusLabel != (Object)null) { RadiusLabel.text = HomesteadRadiusPage.FormatRadiusLabel(radius); } Current.RequestSetWorkRadius(radius); 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 = HomesteadRadiusPage.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; } WoodRegistry.EnsureMissingConfigs(homesteadData); SuppressSliderEvents = true; try { int num = Mathf.RoundToInt(homesteadData.GetWorkRadius()); if ((Object)(object)RadiusSlider != (Object)null) { RadiusSlider.minValue = 10f; RadiusSlider.maxValue = Constants.EffectiveMaxWorkRadius; if (Mathf.Abs(RadiusSlider.value - (float)num) >= 0.5f) { RadiusSlider.value = num; } } if ((Object)(object)RadiusLabel != (Object)null) { RadiusLabel.text = HomesteadRadiusPage.FormatRadiusLabel(num); } string[] weightCrops = WeightCrops; foreach (string text in weightCrops) { CropConfigEntry cropConfigEntry = homesteadData.GetCropConfig(text) ?? WoodRegistry.CreateDefaultEntry(text); if (WeightSliders.TryGetValue(text, out var value)) { value.value = Mathf.Clamp(cropConfigEntry.Weight, 0, 100); } if (WeightLabels.TryGetValue(text, out var value2)) { value2.text = HomesteadRadiusPage.FormatWeightLabel(text, Mathf.Clamp(cropConfigEntry.Weight, 0, 100)); } if (ReplantSliders.TryGetValue(text, out var value3)) { value3.value = Mathf.Clamp(cropConfigEntry.ReplantWeight, 0, 100); } if (ReplantLabels.TryGetValue(text, out var value4)) { value4.text = HomesteadRadiusPage.FormatReplantLabel(text, Mathf.Clamp(cropConfigEntry.ReplantWeight, 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($"Trolls: {Current.CountFarmers()}"); stringBuilder.AppendLine($"Radius: {data.GetWorkRadius():0}m"); stringBuilder.Append($"Chests: {data.ChestCount}"); Status.text = stringBuilder.ToString(); } } internal static void ClearCachedUiState() { WeightSliders.Clear(); WeightLabels.Clear(); WeightRows.Clear(); ReplantSliders.Clear(); ReplantLabels.Clear(); ReplantRows.Clear(); ReserveSliders.Clear(); ReserveLabels.Clear(); ReserveRows.Clear(); RadiusSliders.Clear(); RadiusLabels.Clear(); RadiusRow = null; RadiusSlider = null; RadiusLabel = null; CropsBiomeLabel = null; CropsEmptyRoot = null; CropsRowsContent = 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 != 30)) { 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, 820f); HomesteadUiController.Root.SetActive(false); HomesteadUiController.MainPage = CreatePage("MainPage"); HomesteadUiController.CropsPage = CreatePage("CropsPage"); HomesteadUiController.InvPage = CreatePage("InvPage"); HomesteadUiController.ChestInvPage = CreatePage("ChestInvPage"); HomesteadMainPage.BuildMainPage(); HomesteadRadiusPage.BuildCropsPage(); HomesteadInventoryPages.BuildInventoryPage(); HomesteadInventoryPages.BuildChestInventoryPage(); if ((Object)(object)HomesteadUiController.Root.GetComponent<HomesteadUiInput>() == (Object)null) { HomesteadUiController.Root.AddComponent<HomesteadUiInput>(); } HomesteadUiController.BuiltLayoutVersion = 30; 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) ? (-390f) : (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_020d: Unknown result type (might be due to invalid IL or missing references) //IL_021c: Unknown result type (might be due to invalid IL or missing references) //IL_023a: Unknown result type (might be due to invalid IL or missing references) //IL_0250: Unknown result type (might be due to invalid IL or missing references) //IL_0256: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_0194: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_01be: Unknown result type (might be due to invalid IL or missing references) //IL_01cb: Unknown result type (might be due to invalid IL or missing references) //IL_0390: Unknown result type (might be due to invalid IL or missing references) //IL_0397: Expected O, but got Unknown //IL_03bc: Unknown result type (might be due to invalid IL or missing references) //IL_03d1: Unknown result type (might be due to invalid IL or missing references) //IL_03e6: Unknown result type (might be due to invalid IL or missing references) //IL_03f8: Unknown result type (might be due to invalid IL or missing references) //IL_0405: Unknown result type (might be due to invalid IL or missing references) //IL_0463: Unknown result type (might be due to invalid IL or missing references) //IL_0468: Unknown result type (might be due to invalid IL or missing references) //IL_047b: Unknown result type (might be due to invalid IL or missing references) //IL_0482: Unknown result type (might be due to invalid IL or missing references) //IL_048d: Unknown result type (might be due to invalid IL or missing references) //IL_0498: Unknown result type (might be due to invalid IL or missing references) //IL_04a2: Unknown result type (might be due to invalid IL or missing references) //IL_04c9: Unknown result type (might be due to invalid IL or missing references) //IL_04f4: Unknown result type (might be due to invalid IL or missing references) //IL_04fb: Expected O, but got Unknown //IL_0517: Unknown result type (might be due to invalid IL or missing references) //IL_0522: Unknown result type (might be due to invalid IL or missing references) //IL_0537: Unknown result type (might be due to invalid IL or missing references) //IL_054b: Unknown result type (might be due to invalid IL or missing references) //IL_057a: Unknown result type (might be due to invalid IL or missing references) //IL_057f: Unknown result type (might be due to invalid IL or missing references) //IL_0592: Unknown result type (might be due to invalid IL or missing references) //IL_059c: Unknown result type (might be due to invalid IL or missing references) //IL_05a8: Unknown result type (might be due to invalid IL or missing references) //IL_05b4: Unknown result type (might be due to invalid IL or missing references) //IL_05c0: Unknown result type (might be due to invalid IL or missing references) //IL_05e3: Unknown result type (might be due to invalid IL or missing references) //IL_060e: Unknown result type (might be due to invalid IL or missing references) //IL_0615: Expected O, but got Unknown //IL_0631: Unknown result type (might be due to invalid IL or missing references) //IL_063c: Unknown result type (might be due to invalid IL or missing references) //IL_0651: Unknown result type (might be due to invalid IL or missing references) //IL_0665: 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_0699: Unknown result type (might be due to invalid IL or missing references) //IL_06ac: Unknown result type (might be due to invalid IL or missing references) //IL_06c0: Unknown result type (might be due to invalid IL or missing references) //IL_06e3: Unknown result type (might be due to invalid IL or missing references) //IL_0707: Unknown result type (might be due to invalid IL or missing references) //IL_030b: Unknown result type (might be due to invalid IL or missing references) //IL_0320: Unknown result type (might be due to invalid IL or missing references) //IL_0335: Unknown result type (might be due to invalid IL or missing references) //IL_0347: Unknown result type (might be due to invalid IL or missing references) //IL_0358: 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; bool num4 = !string.IsNullOrEmpty(iconPrefab); float num5 = num3 + 24.5f; float num6 = (num4 ? (num3 + 49f + 10f) : (num3 + 8f)); float num7 = (num4 ? (columnWidth - 49f - 16f) : (columnWidth - 16f)); if (num4) { 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(num5, 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(num6 + num7 * 0.5f - columnWidth * 0.25f, 0f), GUIManager.Instance.AveriaSerifBold, 13, GUIManager.Instance.ValheimOrange, true, Color.black, num7, 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(num6, 0f); rectTransform.sizeDelta = new Vector2(num7, 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(num7, 16f); component4.anchoredPosition = new Vector2(num6, 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 Transform CreateScrollRegion(Transform parent, float topPage, out RectTransform content) { //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Expected O, but got Unknown //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_009b: 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_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Expected O, but got Unknown //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_0162: 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_0180: Unknown result type (might be due to invalid IL or missing references) float num = topPage + 700f - 92f; num = Mathf.Max(80f, num); GameObject val = new GameObject("CropsRowsViewport", new Type[3] { typeof(RectTransform), typeof(Image), typeof(RectMask2D) }); 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(860f, num); component.anchoredPosition = new Vector2(0f, topPage); Image component2 = val.GetComponent<Image>(); ((Graphic)component2).color = new Color(0f, 0f, 0f, 0f); ((Graphic)component2).raycastTarget = true; GameObject val2 = new GameObject("CropsRowsContent", new Type[1] { typeof(RectTransform) }); val2.transform.SetParent(val.transform, false); content = val2.GetComponent<RectTransform>(); content.anchorMin = new Vector2(0.5f, 1f); content.anchorMax = new Vector2(0.5f, 1f); content.pivot = new Vector2(0.5f, 1f); content.sizeDelta = new Vector2(860f, num); content.anchoredPosition = Vector2.zero; ScrollRect obj = val.AddComponent<ScrollRect>(); obj.content = content; obj.viewport = component; obj.horizontal = false; obj.vertical = true; obj.movementType = (MovementType)2; obj.scrollSensitivity = 120f; obj.inertia = false; return (Transform)(object)content; } 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 ValheimLumberNPC.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 TreeResolver { public static CropResolveResult Resolve(WorkSlot 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 = TreeScanner.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 = TreeScanner.FindPlantAt(slot.Position); if ((Object)(object)val2 != (Object)null) { return new CropResolveResult(CropResolveStatus.Growing, null, val2); } return new CropResolveResult(CropResolveStatus.Missing); } } internal static class WorkSlotResolver { public static WorkSlot ById(HomesteadData data, string slotId) { if (data?.Slots == null || string.IsNullOrEmpty(slotId)) { return null; } return data.Slots.FirstOrDefault((WorkSlot s) => s != null && s.Id == slotId); } public static WorkSlot Nearest(HomesteadData data, Vector3 from, Func<WorkSlot, 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 ValheimLumberNPC.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("LumberNpc", "Troll"); if ((Object)(object)val == (Object)null) { Log.Error("Failed to clone NPC from Troll"); 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 = "$ln_npc_name"; component2.m_faction = (Faction)0; component2.m_group = "lumber_npc"; component2.m_boss = false; } Humanoid component3 = val.GetComponent<Humanoid>(); if ((Object)(object)component3 != (Object)null) { ((Character)component3).m_faction = (Faction)0; LumberLogWeapon.ApplyToHumanoid(component3); } if ((Object)(object)val.GetComponent<LumberNpc>() == (Object)null) { val.AddComponent<LumberNpc>(); } 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 'LumberNpc' registered (clone of Troll, troll log weapon)"); } } internal static class PieceRegistrar { private static bool _registered; public static void Register() { if (!_registered) { RegisterHomestead(); _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("LumberHomestead", "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<LumberHomestead>() == (Object)null) { val.AddComponent<LumberHomestead>(); } Piece component = val.GetComponent<Piece>(); if ((Object)(object)component != (Object)null) { component.m_name = "$piece_lumberhomestead"; component.m_description = "$piece_lumberhomestead_desc"; component.m_craftingStation = null; } PieceConfig val2 = new PieceConfig { Name = "$piece_lumberhomestead", Description = "$piece_lumberhomestead_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("LumberBoundaryPost", "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.GetCo