using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using Hearthfolk.Jobs; using Jotunn; using Jotunn.Configs; using Jotunn.Entities; using Jotunn.Managers; using Jotunn.Utils; using Microsoft.CodeAnalysis; using Splatform; using UnityEngine; using UnityEngine.Rendering; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: IgnoresAccessChecksTo("assembly_valheim")] [assembly: AssemblyCompany("Hearthfolk")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("Hearthfolk")] [assembly: AssemblyTitle("Hearthfolk")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace Hearthfolk { [HarmonyPatch(typeof(WearNTear), "ApplyDamage")] internal static class BaseDamageDefensePatch { [HarmonyPostfix] private static void Postfix(WearNTear __instance, float damage, HitData hitData, bool __result) { if (__result && !(damage <= 0f) && hitData != null) { ExilesHearth.ReportBaseDamage(__instance, hitData.GetAttacker()); } } } [HarmonyPatch(typeof(Chair), "Interact")] internal static class ChairInteractPatch { private static bool Prefix(Chair __instance, Humanoid human, bool hold, ref bool __result) { if (hold || !SettlerController.IsSeatReserved(__instance)) { return true; } Player val = (Player)(object)((human is Player) ? human : null); if (val != null && (Object)(object)val == (Object)(object)Player.m_localPlayer) { ((Character)val).Message((MessageType)2, "$msg_blocked", 0, (Sprite)null); } __result = false; return false; } } internal sealed class ChestSortPanel : MonoBehaviour { private sealed class ItemChoice { internal string SharedName; internal string DisplayName; internal Sprite Icon; } private const float PanelWidth = 620f; private const float PanelHeight = 690f; private const float MaxUseDistance = 10f; private static ChestSortPanel _instance; private Container _container; private Rect _rect; private Vector2 _scroll; private string _search = string.Empty; private bool _wasConfigured; private HashSet _selected = new HashSet(StringComparer.Ordinal); private List _choices = new List(); internal static void Toggle(Container container) { if ((Object)(object)_instance == (Object)null) { GameObject val = (((Object)(object)HearthfolkPlugin.Instance != (Object)null) ? ((Component)HearthfolkPlugin.Instance).gameObject : null); if ((Object)(object)val == (Object)null) { return; } _instance = val.AddComponent(); } if ((Object)(object)_instance._container == (Object)(object)container) { _instance.Close(); } else { _instance.Open(container); } } private void Open(Container container) { //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if (!((Object)(object)localPlayer == (Object)null) && ChestSortRules.CanConfigure(container, localPlayer.GetPlayerID())) { _container = container; _wasConfigured = ChestSortRules.IsConfigured(container); _selected = ChestSortRules.ReadItems(container); _choices = BuildChoices(container, _selected); _search = string.Empty; _scroll = Vector2.zero; _rect = new Rect(((float)Screen.width - 620f) / 2f, ((float)Screen.height - 690f) / 2f, 620f, 690f); GUIManager.BlockInput(true); } } private void Close() { _container = null; GUIManager.BlockInput(false); } private void OnDestroy() { if ((Object)(object)_container != (Object)null) { GUIManager.BlockInput(false); } } private void Update() { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_container == (Object)null)) { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || (Object)(object)_container == (Object)null || !((Component)_container).gameObject.activeInHierarchy || Vector3.Distance(((Component)localPlayer).transform.position, ((Component)_container).transform.position) > 10f || Input.GetKeyDown((KeyCode)27)) { Close(); return; } Cursor.lockState = (CursorLockMode)0; Cursor.visible = true; } } private void OnGUI() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Expected O, but got Unknown //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_container == (Object)null)) { GUISkin skin = GUI.skin; GUI.skin = HfGuiSkin.Get(); _rect = GUILayout.Window(((Object)this).GetInstanceID(), _rect, new WindowFunction(DrawWindow), Localization.instance.Localize("$hf_chest_sort_title"), Array.Empty()); GUI.skin = skin; } } private void DrawWindow(int id) { //IL_012b: 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_013f: Unknown result type (might be due to invalid IL or missing references) //IL_02f4: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_container == (Object)null) { return; } GUILayout.Space(4f); DrawIntakeStorageSection(); GUILayout.Space(8f); GUILayout.Label(Localization.instance.Localize(_wasConfigured ? "$hf_chest_sort_mode_explicit" : "$hf_chest_sort_mode_auto"), Array.Empty()); GUILayout.Label(Localization.instance.Localize("$hf_chest_sort_desc"), Array.Empty()); GUILayout.Space(5f); GUILayout.BeginHorizontal(Array.Empty()); GUILayout.Label(Localization.instance.Localize("$hf_chest_sort_search"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(80f) }); _search = GUILayout.TextField(_search ?? string.Empty, Array.Empty()); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(Array.Empty()); if (GUILayout.Button(Localization.instance.Localize("$hf_chest_sort_select_present"), Array.Empty())) { SelectPresentMaterials(); } if (GUILayout.Button(Localization.instance.Localize("$hf_chest_sort_clear"), Array.Empty())) { _selected.Clear(); } GUILayout.EndHorizontal(); GUILayout.Space(5f); _scroll = GUILayout.BeginScrollView(_scroll, GUI.skin.box); List list = _choices.Where(MatchesSearch).ToList(); for (int i = 0; i < list.Count; i += 2) { GUILayout.BeginHorizontal(Array.Empty()); DrawChoice(list[i]); if (i + 1 < list.Count) { DrawChoice(list[i + 1]); } else { GUILayout.FlexibleSpace(); } GUILayout.EndHorizontal(); } if (list.Count == 0) { GUILayout.Label(Localization.instance.Localize("$hf_chest_sort_no_items"), Array.Empty()); } GUILayout.EndScrollView(); GUILayout.Space(6f); GUILayout.Label(string.Format(Localization.instance.Localize("$hf_chest_sort_selected"), _selected.Count), Array.Empty()); GUILayout.BeginHorizontal(Array.Empty()); if (GUILayout.Button(Localization.instance.Localize("$hf_chest_sort_save"), Array.Empty())) { ChestSortRules.RequestSet(_container, _selected, configured: true); Player localPlayer = Player.m_localPlayer; if (localPlayer != null) { ((Character)localPlayer).Message((MessageType)2, "$hf_chest_sort_saved", 0, (Sprite)null); } Close(); } if (GUILayout.Button(Localization.instance.Localize("$hf_chest_sort_use_auto"), Array.Empty())) { ChestSortRules.RequestSet(_container, Array.Empty(), configured: false); Player localPlayer2 = Player.m_localPlayer; if (localPlayer2 != null) { ((Character)localPlayer2).Message((MessageType)2, "$hf_chest_sort_auto_restored", 0, (Sprite)null); } Close(); } if (GUILayout.Button(Localization.instance.Localize("$hf_panel_close"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(90f) })) { Close(); } GUILayout.EndHorizontal(); GUI.DragWindow(new Rect(0f, 0f, 10000f, 20f)); } private void DrawIntakeStorageSection() { Player localPlayer = Player.m_localPlayer; long ownerId = (((Object)(object)localPlayer != (Object)null) ? localPlayer.GetPlayerID() : 0); ExilesHearth exilesHearth = ExilesHearth.IntakeCandidateFor(_container, ownerId); GUILayout.BeginVertical(GUI.skin.box, Array.Empty()); GUILayout.Label(Localization.instance.Localize("$hf_chest_intake_section"), HfGuiSkin.CardTitle, Array.Empty()); GUILayout.Label(Localization.instance.Localize("$hf_chest_intake_desc"), HfGuiSkin.MutedLabel, Array.Empty()); if ((Object)(object)exilesHearth == (Object)null) { GUILayout.Label(Localization.instance.Localize("$hf_chest_intake_no_hearth"), Array.Empty()); GUILayout.EndVertical(); return; } IntakeRoles intakeRoles = exilesHearth.IntakeRolesFor(_container); bool flag = intakeRoles != IntakeRoles.None; GUILayout.BeginHorizontal(Array.Empty()); GUILayout.Label(Localization.instance.Localize(flag ? "$hf_chest_intake_current" : "$hf_chest_intake_available"), Array.Empty()); GUILayout.FlexibleSpace(); if (GUILayout.Button(Localization.instance.Localize("$hf_chest_intake_all"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(120f) })) { exilesHearth.RequestSetIntakeStorageRoles(_container, IntakeRoles.All); if (localPlayer != null) { ((Character)localPlayer).Message((MessageType)2, "$hf_chest_intake_saved", 0, (Sprite)null); } } if (flag && GUILayout.Button(Localization.instance.Localize("$hf_chest_intake_remove"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(120f) })) { exilesHearth.RequestSetIntakeStorageRoles(_container, IntakeRoles.None); } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(Array.Empty()); DrawIntakeRoleToggle(exilesHearth, intakeRoles, IntakeRoles.Lumberjack, "$hf_role_lumberjack"); DrawIntakeRoleToggle(exilesHearth, intakeRoles, IntakeRoles.Miner, "$hf_role_miner"); DrawIntakeRoleToggle(exilesHearth, intakeRoles, IntakeRoles.Farmer, "$hf_role_farmer"); GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); GUILayout.EndVertical(); } private void DrawIntakeRoleToggle(ExilesHearth hearth, IntakeRoles roles, IntakeRoles role, string labelKey) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) bool flag = (roles & role) != 0; Color contentColor = GUI.contentColor; if (!flag) { GUI.contentColor = new Color(0.55f, 0.5f, 0.42f); } if (GUILayout.Button((flag ? "✓ " : "— ") + Localization.instance.Localize(labelKey), Array.Empty())) { hearth.RequestSetIntakeStorageRoles(_container, flag ? (roles & ~role) : (roles | role)); } GUI.contentColor = contentColor; } private void DrawChoice(ItemChoice choice) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0030: 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_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_018e: 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_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Invalid comparison between Unknown and I4 //IL_0100: 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_017f: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) bool flag = _selected.Contains(choice.SharedName); Color backgroundColor = GUI.backgroundColor; Color contentColor = GUI.contentColor; if (flag) { GUI.backgroundColor = new Color(2.4f, 2f, 1.1f); GUI.contentColor = new Color(1f, 0.85f, 0.45f); } if (GUILayout.Button((flag ? "✓ " : string.Empty) + choice.DisplayName, (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.Width(275f), GUILayout.Height(42f) })) { if (flag) { _selected.Remove(choice.SharedName); } else { _selected.Add(choice.SharedName); } } Rect lastRect = GUILayoutUtility.GetLastRect(); if ((Object)(object)choice.Icon != (Object)null && (Object)(object)choice.Icon.texture != (Object)null && (int)Event.current.type == 7) { Rect textureRect = choice.Icon.textureRect; Texture2D texture = choice.Icon.texture; Rect val = default(Rect); ((Rect)(ref val))..ctor(((Rect)(ref textureRect)).x / (float)((Texture)texture).width, ((Rect)(ref textureRect)).y / (float)((Texture)texture).height, ((Rect)(ref textureRect)).width / (float)((Texture)texture).width, ((Rect)(ref textureRect)).height / (float)((Texture)texture).height); GUI.DrawTextureWithTexCoords(new Rect(((Rect)(ref lastRect)).x + 6f, ((Rect)(ref lastRect)).y + 5f, 32f, 32f), (Texture)(object)texture, val, true); } GUI.backgroundColor = backgroundColor; GUI.contentColor = contentColor; } private bool MatchesSearch(ItemChoice choice) { if (!string.IsNullOrWhiteSpace(_search) && choice.DisplayName.IndexOf(_search, StringComparison.OrdinalIgnoreCase) < 0) { return choice.SharedName.IndexOf(_search, StringComparison.OrdinalIgnoreCase) >= 0; } return true; } private void SelectPresentMaterials() { Container container = _container; Inventory val = ((container != null) ? container.GetInventory() : null); if (val == null) { return; } foreach (ItemData allItem in val.GetAllItems()) { if (ChestSortRules.IsSortable(allItem)) { _selected.Add(allItem.m_shared.m_name); } } } private static List BuildChoices(Container container, HashSet selected) { HashSet hashSet = new HashSet(selected, StringComparer.Ordinal); Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer != (Object)null) { hashSet.UnionWith(localPlayer.m_knownMaterial); } Inventory inventory = container.GetInventory(); if (inventory != null) { hashSet.UnionWith(from item in inventory.GetAllItems() where item != null select item.m_shared.m_name); } List list = new List(); if ((Object)(object)ObjectDB.instance == (Object)null) { return list; } foreach (GameObject item in ObjectDB.instance.m_items) { ItemData val = ((item != null) ? item.GetComponent() : null)?.m_itemData; if (ChestSortRules.IsSortable(val) && hashSet.Contains(val.m_shared.m_name)) { list.Add(new ItemChoice { SharedName = val.m_shared.m_name, DisplayName = Localization.instance.Localize(val.m_shared.m_name), Icon = val.GetIcon() }); } } return (from choice in list group choice by choice.SharedName into @group select @group.First() into choice orderby choice.DisplayName select choice).ToList(); } } internal static class ChestSortRules { private const char Separator = '|'; internal static void Register(Container container) { ZNetView val = container?.m_nview; if (!((Object)(object)val == (Object)null) && val.IsValid() && !(container is SettlerInventory)) { val.Register("hf_SetChestSort", (Action)delegate(long sender, long requesterId, string payload) { Receive(container, requesterId, payload); }); } } internal static bool IsConfigured(Container container) { if (TryGetZdo(container, out var zdo)) { return zdo.GetBool("hf_sort_configured", false); } return false; } internal static HashSet ReadItems(Container container) { HashSet hashSet = new HashSet(StringComparer.Ordinal); if (!TryGetZdo(container, out var zdo)) { return hashSet; } string[] array = zdo.GetString("hf_sort_items", string.Empty).Split(new char[1] { '|' }, StringSplitOptions.RemoveEmptyEntries); foreach (string item in array) { hashSet.Add(item); } return hashSet; } internal static bool Accepts(Container container, string sharedName) { if ((Object)(object)container == (Object)null || string.IsNullOrEmpty(sharedName)) { return false; } if (IsConfigured(container)) { return ReadItems(container).Contains(sharedName); } Inventory inventory = container.GetInventory(); if (inventory != null) { return inventory.GetAllItems().Any((ItemData item) => item != null && item.m_shared.m_name == sharedName); } return false; } internal static bool IsSortable(ItemData item) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Invalid comparison between Unknown and I4 //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Invalid comparison between Unknown and I4 //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Invalid comparison between Unknown and I4 if (item == null || item.m_shared == null || item.m_shared.m_questItem) { return false; } ItemType itemType = item.m_shared.m_itemType; if (itemType - 1 <= 1 || (int)itemType == 13 || (int)itemType == 21) { return true; } return false; } internal static void RequestSet(Container container, IEnumerable items, bool configured) { Player localPlayer = Player.m_localPlayer; if (!((Object)(object)localPlayer == (Object)null) && CanConfigure(container, localPlayer.GetPlayerID())) { string text = (configured ? ("1|" + string.Join('|'.ToString(), from name in items.Where((string name) => !string.IsNullOrEmpty(name) && name.IndexOf('|') < 0).Distinct() orderby name select name)) : "0"); container.m_nview.InvokeRPC("hf_SetChestSort", new object[2] { localPlayer.GetPlayerID(), text }); } } internal static bool IsStationaryPlayerChest(Container container) { if ((Object)(object)container == (Object)null || container is SettlerInventory || !((Component)container).gameObject.activeInHierarchy || (Object)(object)container.m_nview == (Object)null || !container.m_nview.IsValid() || (Object)(object)container.m_wagon != (Object)null || (Object)(object)((Component)container).GetComponentInParent() != (Object)null || (Object)(object)((Component)container).GetComponentInParent() != (Object)null) { return false; } Piece val = ((Component)container).GetComponent() ?? ((Component)container).GetComponentInParent(); if ((Object)(object)val != (Object)null) { return val.IsPlacedByPlayer(); } return false; } internal static bool CanConfigure(Container container, long playerId) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) if (playerId != 0L && IsStationaryPlayerChest(container) && !ContainerInUse(container) && container.CheckAccess(playerId)) { return PrivateArea.CheckAccess(((Component)container).transform.position, 0f, false, false); } return false; } private static void Receive(Container container, long requesterId, string payload) { if (!((Object)(object)container == (Object)null) && !((Object)(object)container.m_nview == (Object)null) && container.m_nview.IsValid() && container.m_nview.IsOwner() && requesterId != 0L && IsStationaryPlayerChest(container) && container.CheckAccess(requesterId) && !string.IsNullOrEmpty(payload)) { bool flag = payload.StartsWith("1|", StringComparison.Ordinal); string text = ((flag && payload.Length > 2) ? payload.Substring(2) : string.Empty); ZDO zDO = container.m_nview.GetZDO(); zDO.Set("hf_sort_configured", flag); zDO.Set("hf_sort_items", text); Diagnostics.Log($"Hearthfolk[sorting]: chest={((Object)((Component)container).gameObject).name} configured={flag} items={text}"); } } private static bool TryGetZdo(Container container, out ZDO zdo) { zdo = null; if ((Object)(object)container == (Object)null || (Object)(object)container.m_nview == (Object)null || !container.m_nview.IsValid()) { return false; } zdo = container.m_nview.GetZDO(); return zdo != null; } private static bool ContainerInUse(Container container) { if (!container.IsInUse()) { return container.m_nview.GetZDO().GetInt(ZDOVars.s_inUse, 0) == 1; } return true; } } internal sealed class ChopTarget { private readonly TreeBase _tree; private readonly TreeLog _log; internal bool IsLog => (Object)(object)_log != (Object)null; internal GameObject GameObject { get { if (!((Object)(object)_tree != (Object)null)) { if (!((Object)(object)_log != (Object)null)) { return null; } return ((Component)_log).gameObject; } return ((Component)_tree).gameObject; } } internal int InstanceId { get { if (!((Object)(object)GameObject != (Object)null)) { return 0; } return ((Object)GameObject).GetInstanceID(); } } internal Vector3 Center => GameObject.transform.position; internal int MinToolTier { get { if (!((Object)(object)_tree != (Object)null)) { if (!((Object)(object)_log != (Object)null)) { return 0; } return _log.m_minToolTier; } return _tree.m_minToolTier; } } internal ChopTarget(TreeBase tree) { _tree = tree; } internal ChopTarget(TreeLog log) { _log = log; } internal bool IsValid() { GameObject gameObject = GameObject; if ((Object)(object)gameObject != (Object)null) { return gameObject.activeInHierarchy; } return false; } internal Vector3 ClosestPoint(Vector3 from) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) GameObject gameObject = GameObject; if ((Object)(object)gameObject == (Object)null) { return from; } Collider componentInChildren = gameObject.GetComponentInChildren(); if ((Object)(object)componentInChildren == (Object)null) { return gameObject.transform.position; } MeshCollider val = (MeshCollider)(object)((componentInChildren is MeshCollider) ? componentInChildren : null); if ((Object)(object)val != (Object)null && !val.convex) { return componentInChildren.ClosestPointOnBounds(from); } return componentInChildren.ClosestPoint(from); } internal float ReadHealth() { ZNetView val = (((Object)(object)_tree != (Object)null) ? _tree.m_nview : (((Object)(object)_log != (Object)null) ? _log.m_nview : null)); float num = (((Object)(object)_tree != (Object)null) ? _tree.m_health : (((Object)(object)_log != (Object)null) ? _log.m_health : 0f)); if (!((Object)(object)val != (Object)null) || !val.IsValid()) { return num; } return val.GetZDO().GetFloat(ZDOVars.s_health, num); } internal void Damage(HitData hit) { if ((Object)(object)_tree != (Object)null) { _tree.Damage(hit); return; } TreeLog log = _log; if (log != null) { log.Damage(hit); } } } internal static class CivilPathPlanner { private readonly struct HeapEntry { internal readonly int Node; internal readonly float Score; internal HeapEntry(int node, float score) { Node = node; Score = score; } } private sealed class MinHeap { private readonly List _items = new List(); internal int Count => _items.Count; internal void Push(HeapEntry entry) { _items.Add(entry); int num = _items.Count - 1; while (num > 0) { int num2 = (num - 1) / 2; if (_items[num2].Score <= entry.Score) { break; } _items[num] = _items[num2]; num = num2; } _items[num] = entry; } internal HeapEntry Pop() { HeapEntry result = _items[0]; HeapEntry value = _items[_items.Count - 1]; _items.RemoveAt(_items.Count - 1); if (_items.Count == 0) { return result; } int num = 0; while (true) { int num2 = num * 2 + 1; if (num2 >= _items.Count) { break; } int num3 = num2 + 1; int num4 = ((num3 < _items.Count && _items[num3].Score < _items[num2].Score) ? num3 : num2); if (_items[num4].Score >= value.Score) { break; } _items[num] = _items[num4]; num = num4; } _items[num] = value; return result; } } private const float BaseCellSize = 0.82f; private const float BodyRadius = 0.34f; private const float MaxStepHeight = 0.85f; private const int MaxExpandedNodes = 4000; private static readonly int ObstacleMask = LayerMask.GetMask(new string[6] { "Default", "static_solid", "Default_small", "piece", "piece_nonsolid", "terrain" }); internal static bool TryBuildPath(Vector3 start, Vector3 goal, Transform mover, string actor, out List waypoints) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_003c: 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_0050: 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_0064: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: Unknown result type (might be due to invalid IL or missing references) //IL_01e1: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: Unknown result type (might be due to invalid IL or missing references) //IL_01ef: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Unknown result type (might be due to invalid IL or missing references) //IL_01fd: Unknown result type (might be due to invalid IL or missing references) //IL_0206: Unknown result type (might be due to invalid IL or missing references) //IL_020b: Unknown result type (might be due to invalid IL or missing references) //IL_0214: Unknown result type (might be due to invalid IL or missing references) //IL_0219: Unknown result type (might be due to invalid IL or missing references) //IL_0222: Unknown result type (might be due to invalid IL or missing references) //IL_0227: Unknown result type (might be due to invalid IL or missing references) //IL_0230: Unknown result type (might be due to invalid IL or missing references) //IL_0235: Unknown result type (might be due to invalid IL or missing references) //IL_023e: Unknown result type (might be due to invalid IL or missing references) //IL_0243: Unknown result type (might be due to invalid IL or missing references) //IL_0490: Unknown result type (might be due to invalid IL or missing references) //IL_028f: Unknown result type (might be due to invalid IL or missing references) //IL_0294: 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_0298: Unknown result type (might be due to invalid IL or missing references) //IL_04da: Unknown result type (might be due to invalid IL or missing references) //IL_02a8: Unknown result type (might be due to invalid IL or missing references) //IL_02aa: Unknown result type (might be due to invalid IL or missing references) //IL_0503: Unknown result type (might be due to invalid IL or missing references) //IL_0508: Unknown result type (might be due to invalid IL or missing references) //IL_04bc: Unknown result type (might be due to invalid IL or missing references) //IL_02ce: Unknown result type (might be due to invalid IL or missing references) //IL_02d3: Unknown result type (might be due to invalid IL or missing references) //IL_0410: Unknown result type (might be due to invalid IL or missing references) //IL_0415: Unknown result type (might be due to invalid IL or missing references) waypoints = null; float num = Utils.DistanceXZ(start, goal); if (num < 1.25f) { waypoints = new List { goal }; return true; } float num2 = Mathf.Clamp(num * 0.58f, 8f, 24f); float num3 = Mathf.Min(start.x, goal.x) - num2; float num4 = Mathf.Max(start.x, goal.x) + num2; float num5 = Mathf.Min(start.z, goal.z) - num2; float num6 = Mathf.Max(start.z, goal.z) + num2; float num7 = 0.82f; int num8 = Mathf.CeilToInt((num4 - num3) / num7) + 1; int num9 = Mathf.CeilToInt((num6 - num5) / num7) + 1; int num10 = num8 * num9; if (num10 > 11000) { num7 *= Mathf.Sqrt((float)num10 / 11000f); num8 = Mathf.CeilToInt((num4 - num3) / num7) + 1; num9 = Mathf.CeilToInt((num6 - num5) / num7) + 1; num10 = num8 * num9; } bool[] array = new bool[num10]; bool[] array2 = new bool[num10]; bool[] array3 = new bool[num10]; float[] array4 = new float[num10]; float[] array5 = new float[num10]; int[] array6 = new int[num10]; for (int i = 0; i < num10; i++) { array5[i] = float.MaxValue; array6[i] = -1; } int num11 = Mathf.Clamp(Mathf.RoundToInt((start.x - num3) / num7), 0, num8 - 1); int num12 = Mathf.Clamp(Mathf.RoundToInt((start.z - num5) / num7), 0, num9 - 1) * num8 + num11; array[num12] = true; array2[num12] = true; array4[num12] = start.y; array5[num12] = 0f; MinHeap minHeap = new MinHeap(); minHeap.Push(new HeapEntry(num12, num)); int num13 = 0; int num14 = -1; Vector2Int[] array7 = (Vector2Int[])(object)new Vector2Int[8] { new Vector2Int(1, 0), new Vector2Int(-1, 0), new Vector2Int(0, 1), new Vector2Int(0, -1), new Vector2Int(1, 1), new Vector2Int(1, -1), new Vector2Int(-1, 1), new Vector2Int(-1, -1) }; while (minHeap.Count > 0 && num13 < 4000) { int node = minHeap.Pop().Node; if (array3[node]) { continue; } array3[node] = true; num13++; int num15 = node % num8; int num16 = node / num8; Vector3 val = GridPoint(num15, num16, num3, num5, num7, array4[node]); if (Utils.DistanceXZ(val, goal) <= num7 * 1.5f && SegmentClear(val, goal, mover, num7)) { num14 = node; break; } Vector2Int[] array8 = array7; for (int j = 0; j < array8.Length; j++) { Vector2Int val2 = array8[j]; int num17 = num15 + ((Vector2Int)(ref val2)).x; int num18 = num16 + ((Vector2Int)(ref val2)).y; if (num17 < 0 || num17 >= num8 || num18 < 0 || num18 >= num9) { continue; } int num19 = num18 * num8 + num17; if (array3[num19]) { continue; } float expectedHeight = array4[node]; if (!EvaluateNode(num19, num17, num18, num3, num5, num7, expectedHeight, mover, array, array2, array4)) { continue; } if (((Vector2Int)(ref val2)).x != 0 && ((Vector2Int)(ref val2)).y != 0) { int node2 = num16 * num8 + num17; int node3 = num18 * num8 + num15; if (!EvaluateNode(node2, num17, num16, num3, num5, num7, expectedHeight, mover, array, array2, array4) || !EvaluateNode(node3, num15, num18, num3, num5, num7, expectedHeight, mover, array, array2, array4)) { continue; } } float num20 = ((((Vector2Int)(ref val2)).x != 0 && ((Vector2Int)(ref val2)).y != 0) ? (num7 * 1.414214f) : num7); float num21 = Mathf.Abs(array4[num19] - array4[node]) * 1.5f; float num22 = array5[node] + num20 + num21; if (!(num22 >= array5[num19])) { array5[num19] = num22; array6[num19] = node; float num23 = Utils.DistanceXZ(GridPoint(num17, num18, num3, num5, num7, array4[num19]), goal); minHeap.Push(new HeapEntry(num19, num22 + num23)); } } } if (num14 < 0) { Diagnostics.Navigation("Hearthfolk[planner]: " + actor + " no physical route " + $"({num:0.0}m, expanded={num13})"); return false; } List list = new List { goal }; int num24 = num14; while (num24 >= 0 && num24 != num12) { int x = num24 % num8; int z = num24 / num8; list.Add(GridPoint(x, z, num3, num5, num7, array4[num24])); num24 = array6[num24]; } list.Add(start); list.Reverse(); waypoints = Smooth(list, mover, num7); if (waypoints.Count > 0 && Utils.DistanceXZ(waypoints[0], start) < 0.65f) { waypoints.RemoveAt(0); } Diagnostics.Navigation("Hearthfolk[planner]: " + actor + " physical route " + $"{num:0.0}m " + $"with {waypoints.Count} waypoint(s), expanded={num13}"); return waypoints.Count > 0; } internal static bool TryProjectWalkPoint(Vector3 desired, Transform mover, out Vector3 point) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_019d: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) Vector3[] obj = new Vector3[9] { Vector3.zero, Vector3.forward, Vector3.back, Vector3.right, Vector3.left, default(Vector3), default(Vector3), default(Vector3), default(Vector3) }; Vector3 val = new Vector3(1f, 0f, 1f); obj[5] = ((Vector3)(ref val)).normalized; val = new Vector3(1f, 0f, -1f); obj[6] = ((Vector3)(ref val)).normalized; val = new Vector3(-1f, 0f, 1f); obj[7] = ((Vector3)(ref val)).normalized; val = new Vector3(-1f, 0f, -1f); obj[8] = ((Vector3)(ref val)).normalized; Vector3[] array = (Vector3[])(object)obj; float[] array2 = new float[4] { 0f, 0.45f, 0.85f, 1.25f }; foreach (float num in array2) { Vector3[] array3 = array; foreach (Vector3 val2 in array3) { if (num == 0f && val2 != Vector3.zero) { continue; } Vector3 val3 = desired + val2 * num; if (TryGround(val3, desired.y, out var height) && !(Mathf.Abs(height - desired.y) > 2.5f)) { point = new Vector3(val3.x, height, val3.z); if (HasBodyClearance(point, mover)) { return true; } } } } point = desired; return false; } private static bool EvaluateNode(int node, int x, int z, float minX, float minZ, float cellSize, float expectedHeight, Transform mover, bool[] evaluated, bool[] walkable, float[] heights) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) if (evaluated[node]) { if (walkable[node]) { return Mathf.Abs(heights[node] - expectedHeight) <= 0.85f; } return false; } evaluated[node] = true; Vector3 val = GridPoint(x, z, minX, minZ, cellSize, expectedHeight); if (!TryGround(val, expectedHeight, out var height)) { return false; } heights[node] = height; walkable[node] = Mathf.Abs(height - expectedHeight) <= 0.85f && HasBodyClearance(new Vector3(val.x, height, val.z), mover); return walkable[node]; } private static Vector3 GridPoint(int x, int z, float minX, float minZ, float cellSize, float y) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) return new Vector3(minX + (float)x * cellSize, y, minZ + (float)z * cellSize); } private static bool TryGround(Vector3 point, float expectedHeight, out float height) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0043: 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_006f: 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_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) height = 0f; RaycastHit[] array = Physics.RaycastAll(new Vector3(point.x, expectedHeight + 2.2f, point.z), Vector3.down, 4.8f, ObstacleMask, (QueryTriggerInteraction)1); float num = float.MaxValue; bool flag = false; RaycastHit[] array2 = array; for (int i = 0; i < array2.Length; i++) { RaycastHit val = array2[i]; if (!((Object)(object)((RaycastHit)(ref val)).collider == (Object)null) && !((Object)(object)((Component)((RaycastHit)(ref val)).collider).GetComponentInParent() != (Object)null) && !(Vector3.Dot(((RaycastHit)(ref val)).normal, Vector3.up) < 0.55f)) { float num2 = Mathf.Abs(((RaycastHit)(ref val)).point.y - expectedHeight); if (!(num2 >= num)) { height = ((RaycastHit)(ref val)).point.y; num = num2; flag = true; } } } if (flag) { return true; } if ((Object)(object)ZoneSystem.instance != (Object)null) { return ZoneSystem.instance.GetGroundHeight(point, ref height); } return false; } private static bool HasBodyClearance(Vector3 ground, Transform mover) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) Vector3 val = ground + Vector3.up * 0.48f; Vector3 val2 = ground + Vector3.up * 1.55f; Collider[] array = Physics.OverlapCapsule(val, val2, 0.34f, ObstacleMask, (QueryTriggerInteraction)1); foreach (Collider val3 in array) { if (!((Object)(object)val3 == (Object)null) && (!((Object)(object)mover != (Object)null) || !((Component)val3).transform.IsChildOf(mover)) && !((Object)(object)((Component)val3).GetComponentInParent() != (Object)null) && !((Object)(object)((Component)val3).GetComponentInParent() != (Object)null)) { Bounds bounds = val3.bounds; if (!(((Bounds)(ref bounds)).max.y <= ground.y + 0.28f)) { return false; } } } return true; } private static bool SegmentClear(Vector3 from, Vector3 to, Transform mover, float cellSize) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) float num = Utils.DistanceXZ(from, to); int num2 = Mathf.Max(1, Mathf.CeilToInt(num / (cellSize * 0.62f))); float num3 = from.y; for (int i = 1; i <= num2; i++) { float num4 = (float)i / (float)num2; Vector3 val = Vector3.Lerp(from, to, num4); if (!TryGround(val, num3, out var height) || Mathf.Abs(height - num3) > 0.85f || !HasBodyClearance(new Vector3(val.x, height, val.z), mover)) { return false; } num3 = height; } return true; } private static List Smooth(IReadOnlyList raw, Transform mover, float cellSize) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) List list = new List(); int num = 0; list.Add(raw[0]); while (num < raw.Count - 1) { int num2 = num + 1; for (int num3 = raw.Count - 1; num3 > num + 1; num3--) { if (SegmentClear(raw[num], raw[num3], mover, cellSize)) { num2 = num3; break; } } list.Add(raw[num2]); num = num2; } return list; } internal static float PathLength(IReadOnlyList path, Vector3 start) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) float num = 0f; Vector3 val = start; foreach (Vector3 item in path) { num += Utils.DistanceXZ(val, item); val = item; } return num; } } [HarmonyPatch(typeof(Container), "Awake")] internal static class ContainerAwakePatch { [HarmonyPostfix] private static void Postfix(Container __instance) { ChestSortRules.Register(__instance); } } [HarmonyPatch(typeof(Container), "Interact")] internal static class ContainerInteractPatch { [HarmonyPrefix] private static bool Prefix(Container __instance, Humanoid character, bool hold, ref bool __result) { Player val = (Player)(object)((character is Player) ? character : null); if (hold || (Object)(object)val == (Object)null || (Object)(object)val != (Object)(object)Player.m_localPlayer || !ControlHeld() || !ChestSortRules.CanConfigure(__instance, val.GetPlayerID())) { return true; } ChestSortPanel.Toggle(__instance); __result = true; return false; } private static bool ControlHeld() { if (!Input.GetKey((KeyCode)306)) { return Input.GetKey((KeyCode)305); } return true; } } [HarmonyPatch(typeof(Container), "GetHoverText")] internal static class ContainerHoverPatch { [HarmonyPostfix] private static void Postfix(Container __instance, ref string __result) { if ((Object)(object)Player.m_localPlayer != (Object)null && ChestSortRules.IsStationaryPlayerChest(__instance)) { __result = __result + "\n" + Localization.instance.Localize("$hf_chest_sort_hover"); } } } internal static class Diagnostics { internal static bool Enabled { get { if (HfConfig.DebugLog != null) { return HfConfig.DebugLog.Value; } return false; } } internal static void Log(string message) { if (Enabled) { Logger.LogInfo((object)message); } } internal static void Navigation(string message) { Logger.LogInfo((object)message); } } internal static class DormantSettlerRegistry { internal sealed class Record { internal readonly ZDO Zdo; internal ZDOID Id { get { //IL_0014: 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 (Zdo == null) { return ZDOID.None; } return Zdo.m_uid; } } internal string Name { get { if (Zdo == null) { return Localization.instance.Localize("$hf_settler"); } return Zdo.GetString("hf_name", Localization.instance.Localize("$hf_settler")); } } internal SettlerRole Role { get { if (Zdo == null) { return SettlerRole.Idle; } return (SettlerRole)Zdo.GetInt("hf_role", 0); } } internal long RespawnAt { get { if (Zdo == null) { return 0L; } return Zdo.GetLong("hf_respawn_at", 0L); } } internal string StatusText => SettlerController.FormatRespawnStatus(RespawnAt); internal Record(ZDO zdo) { Zdo = zdo; } } private const float RefreshInterval = 0.75f; private static readonly List Cached = new List(); private static float _nextRefresh; internal static List ForHearth(ExilesHearth hearth, IEnumerable instantiatedIds) { if ((Object)(object)hearth == (Object)null) { return new List(); } Refresh(); HashSet liveIds = new HashSet(instantiatedIds); return (from zdo in Cached where zdo.GetBool("hf_respawning", false) && BelongsTo(zdo, hearth) && !liveIds.Contains(zdo.m_uid) select new Record(zdo)).OrderBy((Record record) => record.Name, StringComparer.CurrentCultureIgnoreCase).ToList(); } internal static void WakeExpired(ExilesHearth hearth) { //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0107: 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_0116: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)hearth == (Object)null || !hearth.IsNetworkOwner || ZDOMan.instance == null || (Object)(object)ZNetScene.instance == (Object)null) { return; } Refresh(); long now = DateTime.UtcNow.Ticks; int num = 0; foreach (ZDO item in Cached.Where((ZDO zdo) => zdo.GetBool("hf_respawning", false) && BelongsTo(zdo, hearth) && zdo.GetLong("hf_respawn_at", 0L) <= now)) { if (!((Object)(object)ZNetScene.instance.FindInstance(item.m_uid) != (Object)null)) { if (!item.HasOwner()) { item.SetOwner(ZDOMan.GetSessionID()); } if (item.IsOwner()) { Vector3 position = ((Component)hearth).transform.position + ((Component)hearth).transform.right * (2.2f + (float)num * 0.65f) + Vector3.up * 0.5f; item.SetPosition(position); num++; Diagnostics.Log($"Hearthfolk[respawn]: waking unloaded settler ZDO {item.m_uid}"); } } } } internal static void RecallDisconnectedFollowers(ExilesHearth hearth) { //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: 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) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0139: 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_0151: 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_0160: 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_016a: 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_0191: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)hearth == (Object)null || !hearth.IsNetworkOwner || ZDOMan.instance == null || (Object)(object)ZNetScene.instance == (Object)null) { return; } Refresh(); int num = 0; foreach (ZDO item in Cached.Where((ZDO zdo) => BelongsTo(zdo, hearth) && zdo.GetInt("hf_role", 0) == 5 && zdo.GetInt("hf_follower_mode", 0) == 1 && zdo.GetLong("hf_follower_target", 0L) != 0)) { long num2 = item.GetLong("hf_follower_target", 0L); if (SettlerController.IsPlayerConnected(num2) || (Object)(object)ZNetScene.instance.FindInstance(item.m_uid) != (Object)null) { continue; } Vector3 vec = item.GetVec3("hf_home", ((Component)hearth).transform.position); if (!(Vector3.Distance(item.GetPosition(), vec) <= 6f) || !(item.GetString("hf_status", string.Empty) == "$hf_status_follower_waiting_for_player")) { if (!item.HasOwner()) { item.SetOwner(ZDOMan.GetSessionID()); } if (item.IsOwner()) { Vector3 position = vec + ((Component)hearth).transform.right * (2.2f + (float)num * 0.65f) + Vector3.up * 0.5f; item.Set("hf_status", "$hf_status_follower_waiting_for_player"); item.SetPosition(position); num++; Diagnostics.Log($"Hearthfolk[follower]: recalled unloaded settler ZDO {item.m_uid} " + $"while preserving player {num2}"); } } } } private static bool BelongsTo(ZDO zdo, ExilesHearth hearth) { //IL_0038: 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_0048: Unknown result type (might be due to invalid IL or missing references) if (zdo == null || !zdo.IsValid()) { return false; } long num = zdo.GetLong("hf_owner", 0L); if (num != 0L && hearth.OwnerId != 0L && num != hearth.OwnerId) { return false; } return Vector3.Distance(zdo.GetVec3("hf_home", zdo.GetPosition()), ((Component)hearth).transform.position) <= 6f; } private static void Refresh() { if (!(Time.unscaledTime < _nextRefresh) && ZDOMan.instance != null) { _nextRefresh = Time.unscaledTime + 0.75f; List list = new List(); int num = 0; bool flag = false; int num2 = 0; while (!flag && num2++ < 2048) { flag = ZDOMan.instance.GetAllZDOsWithPrefabIterative("hf_settler", list, ref num); } Cached.Clear(); Cached.AddRange(from zdo in list where zdo != null && zdo.IsValid() group zdo by zdo.m_uid into @group select @group.First()); } } } internal sealed class ExilesHearth : MonoBehaviour, Interactable, Hoverable { private sealed class SavedRouteEntry { internal ZDOID Id; internal Vector3 Position; internal string Prefab; internal long Creator; } internal static readonly List Instances = new List(); private static readonly string[] SettlerNames = new string[12] { "Astrid", "Birger", "Eira", "Freydis", "Gorm", "Hakon", "Ingrid", "Kari", "Leif", "Runa", "Sigrid", "Torsten" }; private ZNetView _nview; private Piece _piece; private float _nextDormantSettlerCheck; private List _availableGatewayCache; private float _availableGatewayCacheAt; private List _intakeStorageCache; private float _intakeStorageCacheUntil; internal ZDOID PersistentId { get { //IL_001b: 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) if (!((Object)(object)_nview != (Object)null) || !_nview.IsValid()) { return ZDOID.None; } return _nview.GetZDO().m_uid; } } internal bool IsNetworkOwner { get { if ((Object)(object)_nview != (Object)null && _nview.IsValid()) { return _nview.IsOwner(); } return false; } } internal long OwnerId { get { if (!((Object)(object)_piece != (Object)null)) { return 0L; } return _piece.GetCreator(); } } internal bool AlertActive { get { if ((Object)(object)_nview != (Object)null && _nview.IsValid()) { return _nview.GetZDO().GetBool("hf_settlement_alert", false); } return false; } } internal bool RaidActive => RaidAt(((Component)this).transform.position); internal bool DefenseThreatActive { get { if ((Object)(object)_nview != (Object)null && _nview.IsValid()) { return _nview.GetZDO().GetLong("hf_defense_threat_until", 0L) > DateTime.UtcNow.Ticks; } return false; } } internal List PatrolRoute => PatrolPoint.RouteFor(this); internal int PatrolPointCount => PatrolRoute.Count; internal int AvailablePatrolPointCount => PatrolPoint.PointsFor(this).Count; internal List AvailablePatrolPoints => PatrolPoint.PointsFor(this); internal bool PatrolRouteConfigured { get { if ((Object)(object)_nview != (Object)null && _nview.IsValid()) { return _nview.GetZDO().GetBool("hf_patrol_route_configured", false); } return false; } } internal List SavedPatrolRoute => ResolveSavedRoute("hf_patrol_route", "hf_patrol_route_identity", PatrolPoint.PointsFor(this).Select(PatrolRouteEntry), "patrol"); internal List CurrentPatrolRouteIds => PatrolPoint.RouteIdsFor(this); internal bool GatewayDoorsConfigured { get { if (!((Object)(object)_nview != (Object)null) || !_nview.IsValid() || !_nview.GetZDO().GetBool("hf_gateway_doors_configured", false)) { return TaggedGatewayDoors().Count > 0; } return true; } } internal List SavedGatewayDoorIds { get { List list = ResolveSavedRoute("hf_gateway_doors", "hf_gateway_doors_identity", AvailableGatewayDoors.Select(GatewayRouteEntry), "gateway"); List list2 = TaggedGatewayDoors(); if (list.Count > 0) { if (list2.Count == 0 && (Object)(object)_nview != (Object)null && _nview.IsValid() && _nview.IsOwner()) { PersistGatewayMarkers(AvailableGatewayDoors, list); } return list; } if (list2.Count == 0) { return list; } List list3 = list2.Select((Door door) => door.m_nview.GetZDO().m_uid).Distinct().Take(32) .ToList(); if ((Object)(object)_nview != (Object)null && _nview.IsValid() && _nview.IsOwner()) { ZDO zDO = _nview.GetZDO(); zDO.Set("hf_gateway_doors", EncodePatrolRoute(list3)); StoreRouteIdentity(zDO, "hf_gateway_doors_identity", list3, list2.Select(GatewayRouteEntry)); zDO.Set("hf_gateway_doors_configured", true); Logger.LogInfo((object)$"Hearthfolk[gateway]: restored {list3.Count} entrance(s) from their door markers."); } return list3; } } internal List AvailableGatewayDoors { get { if (_availableGatewayCache == null || Time.time >= _availableGatewayCacheAt) { _availableGatewayCache = FindAvailableGatewayDoors(); _availableGatewayCacheAt = Time.time + 1f; } return _availableGatewayCache; } } internal int AvailableGatewayDoorCount => AvailableGatewayDoors.Count; internal List ConfiguredGatewayDoors { get { Dictionary byId = AvailableGatewayDoors.Where((Door door) => (Object)(object)door?.m_nview != (Object)null && door.m_nview.IsValid()).ToDictionary((Door door) => door.m_nview.GetZDO().m_uid); return (from id in SavedGatewayDoorIds.Where(byId.ContainsKey) select byId[id]).ToList(); } } internal ZDOID IntakeStorageId { get { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) Container? obj = ResolveIntakeStorages().FirstOrDefault(); ZDOID? obj2; if (obj == null) { obj2 = null; } else { ZNetView nview = obj.m_nview; obj2 = ((nview != null) ? new ZDOID?(nview.GetZDO().m_uid) : ((ZDOID?)null)); } return (ZDOID)(((??)obj2) ?? ZDOID.None); } } internal bool HasIntakeStorage => ResolveIntakeStorages().Count > 0; internal int RecruitCost => Mathf.Max(0, HfConfig.RecruitCoins.Value); private void Awake() { _nview = ((Component)this).GetComponent(); _piece = ((Component)this).GetComponent(); if ((Object)(object)_nview != (Object)null && _nview.IsValid()) { _nview.Register("hf_ToggleSettlementAlert", (Action)RPC_ToggleAlert); _nview.Register("hf_SignalDefenseThreat", (Action)RPC_SignalDefenseThreat); _nview.Register("hf_SetPatrolRoute", (Action)RPC_SetPatrolRoute); _nview.Register("hf_SetIntakeStorage", (Action)RPC_SetIntakeStorage); _nview.Register("hf_SetIntakeStorageRoles", (Action)RPC_SetIntakeStorageRoles); _nview.Register("hf_SetGatewayDoors", (Action)RPC_SetGatewayDoors); } if (!Instances.Contains(this)) { Instances.Add(this); } } private void OnDestroy() { Instances.Remove(this); } private void Update() { if (!(Time.time < _nextDormantSettlerCheck)) { _nextDormantSettlerCheck = Time.time + 1f; DormantSettlerRegistry.WakeExpired(this); DormantSettlerRegistry.RecallDisconnectedFollowers(this); } } public string GetHoverName() { return Localization.instance.Localize("$piece_hf_hearth"); } public string GetHoverText() { return Localization.instance.Localize("$piece_hf_hearth\n[$KEY_Use] $hf_manage"); } public bool Interact(Humanoid user, bool hold, bool alt) { if (!hold) { Player val = (Player)(object)((user is Player) ? user : null); if (val != null && !((Object)(object)val != (Object)(object)Player.m_localPlayer)) { if ((Object)(object)_nview == (Object)null || !_nview.IsValid()) { return false; } long num = (((Object)(object)_piece != (Object)null) ? _piece.GetCreator() : 0); if (num != 0L && num != val.GetPlayerID()) { ((Character)val).Message((MessageType)2, "$msg_cantopen", 0, (Sprite)null); return true; } HearthPanel.Toggle(this); return true; } } return false; } internal void RequestToggleAlert() { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer != (Object)null && (Object)(object)_nview != (Object)null && _nview.IsValid()) { _nview.InvokeRPC("hf_ToggleSettlementAlert", new object[1] { localPlayer.GetPlayerID() }); } } private void RPC_ToggleAlert(long sender, long requesterId) { if (_nview.IsOwner() && (OwnerId == 0L || OwnerId == requesterId)) { ZDO zDO = _nview.GetZDO(); zDO.Set("hf_settlement_alert", !zDO.GetBool("hf_settlement_alert", false)); } } internal void RequestSetPatrolRoute(IList route) { Player localPlayer = Player.m_localPlayer; if (!((Object)(object)localPlayer == (Object)null) && !((Object)(object)_nview == (Object)null) && _nview.IsValid()) { _nview.InvokeRPC("hf_SetPatrolRoute", new object[3] { localPlayer.GetPlayerID(), 1, EncodePatrolRoute(route) }); } } internal void RequestAutomaticPatrolRoute() { Player localPlayer = Player.m_localPlayer; if (!((Object)(object)localPlayer == (Object)null) && !((Object)(object)_nview == (Object)null) && _nview.IsValid()) { _nview.InvokeRPC("hf_SetPatrolRoute", new object[3] { localPlayer.GetPlayerID(), 0, string.Empty }); } } private void RPC_SetPatrolRoute(long sender, long requesterId, int configured, string encodedRoute) { if (!_nview.IsOwner() || (OwnerId != 0L && OwnerId != requesterId)) { return; } ZDO zDO = _nview.GetZDO(); if (configured == 0) { zDO.Set("hf_patrol_route_configured", false); zDO.Set("hf_patrol_route", string.Empty); zDO.Set("hf_patrol_route_identity", string.Empty); return; } List source = PatrolPoint.PointsFor(this); HashSet validIds = new HashSet(source.Select((PatrolPoint point) => point.PersistentId)); List list = (from id in DecodePatrolRoute(encodedRoute) where id != ZDOID.None && validIds.Contains(id) select id).Distinct().Take(64).ToList(); zDO.Set("hf_patrol_route", EncodePatrolRoute(list)); StoreRouteIdentity(zDO, "hf_patrol_route_identity", list, source.Select(PatrolRouteEntry)); zDO.Set("hf_patrol_route_configured", true); Diagnostics.Log($"Hearthfolk[patrol]: saved {list.Count} persistent route point(s)."); } internal void RequestSetGatewayDoors(IList doors) { Player localPlayer = Player.m_localPlayer; if (!((Object)(object)localPlayer == (Object)null) && !((Object)(object)_nview == (Object)null) && _nview.IsValid()) { _nview.InvokeRPC("hf_SetGatewayDoors", new object[3] { localPlayer.GetPlayerID(), 1, EncodePatrolRoute(doors) }); } } internal void RequestAutomaticGatewayDoors() { Player localPlayer = Player.m_localPlayer; if (!((Object)(object)localPlayer == (Object)null) && !((Object)(object)_nview == (Object)null) && _nview.IsValid()) { _nview.InvokeRPC("hf_SetGatewayDoors", new object[3] { localPlayer.GetPlayerID(), 0, string.Empty }); } } private void RPC_SetGatewayDoors(long sender, long requesterId, int configured, string encodedDoors) { if (!_nview.IsOwner() || (OwnerId != 0L && OwnerId != requesterId)) { return; } ZDO zDO = _nview.GetZDO(); if (configured == 0) { ClearGatewayMarkers(AvailableGatewayDoors); zDO.Set("hf_gateway_doors_configured", false); zDO.Set("hf_gateway_doors", string.Empty); zDO.Set("hf_gateway_doors_identity", string.Empty); return; } List availableGatewayDoors = AvailableGatewayDoors; HashSet validIds = new HashSet(from door in availableGatewayDoors where (Object)(object)door?.m_nview != (Object)null && door.m_nview.IsValid() select door.m_nview.GetZDO().m_uid); List list = (from id in DecodePatrolRoute(encodedDoors) where id != ZDOID.None && validIds.Contains(id) select id).Distinct().Take(32).ToList(); if (list.Count != 0) { zDO.Set("hf_gateway_doors", EncodePatrolRoute(list)); StoreRouteIdentity(zDO, "hf_gateway_doors_identity", list, availableGatewayDoors.Select(GatewayRouteEntry)); zDO.Set("hf_gateway_doors_configured", true); PersistGatewayMarkers(availableGatewayDoors, list); Logger.LogInfo((object)$"Hearthfolk[gateway]: saved {list.Count} persistent entrance(s)."); } } private List TaggedGatewayDoors() { return AvailableGatewayDoors.Where(GatewayMarkerMatches).ToList(); } private bool GatewayMarkerMatches(Door door) { //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)door?.m_nview == (Object)null || !door.m_nview.IsValid()) { return false; } ZDO zDO = door.m_nview.GetZDO(); if (zDO.GetBool("hf_gateway_marker", false) && zDO.GetLong("hf_gateway_creator", 0L) == OwnerId) { return Vector3.Distance(zDO.GetVec3("hf_gateway_hearth", Vector3.zero), ((Component)this).transform.position) <= 0.75f; } return false; } private void PersistGatewayMarkers(IEnumerable available, ICollection selected) { //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) HashSet hashSet = new HashSet(selected); foreach (Door item in available) { if ((Object)(object)item?.m_nview == (Object)null || !item.m_nview.IsValid()) { continue; } ZDO zDO = item.m_nview.GetZDO(); bool flag = hashSet.Contains(zDO.m_uid); if (flag || GatewayMarkerMatches(item)) { if (!item.m_nview.IsOwner()) { item.m_nview.ClaimOwnership(); } if (!item.m_nview.IsOwner()) { Logger.LogWarning((object)("Hearthfolk[gateway]: could not persist marker on " + ((Object)item).name + "; door is owned by another peer.")); continue; } zDO = item.m_nview.GetZDO(); zDO.Set("hf_gateway_marker", flag); zDO.Set("hf_gateway_hearth", flag ? ((Component)this).transform.position : Vector3.zero); zDO.Set("hf_gateway_creator", flag ? OwnerId : 0); } } } private void ClearGatewayMarkers(IEnumerable available) { PersistGatewayMarkers(available, new List()); } internal List ResolveIntakeStorages(Component self = null) { //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_nview == (Object)null || !_nview.IsValid()) { return new List(); } if (_intakeStorageCache == null || Time.time >= _intakeStorageCacheUntil) { _intakeStorageCache = (from container in SceneObjectCache.Get(1f) where (Object)(object)container != (Object)null && (Object)(object)container.m_nview != (Object)null && container.m_nview.IsValid() && ChestSortRules.IsStationaryPlayerChest(container) && container.m_nview.GetZDO().GetZDOID("hf_intake_hearth") == PersistentId && container.m_nview.GetZDO().GetInt("hf_intake_roles", 0) != 0 select container).ToList(); Container val = StorageLink.Resolve(_nview.GetZDO(), (Component)(object)this); if ((Object)(object)val != (Object)null && !_intakeStorageCache.Contains(val)) { _intakeStorageCache.Add(val); } _intakeStorageCacheUntil = Time.time + 1f; } Vector3 origin = (((Object)(object)self != (Object)null) ? self.transform.position : ((Component)this).transform.position); return (from container in _intakeStorageCache where (Object)(object)container != (Object)null && ((Component)container).gameObject.activeInHierarchy orderby Vector3.Distance(origin, ((Component)container).transform.position) select container).ToList(); } internal Container ResolveIntakeStorage(Component self = null) { SettlerController settlerController = self as SettlerController; IntakeRoles required = (((Object)(object)settlerController != (Object)null) ? IntakeRoleFor(settlerController.CurrentRole) : IntakeRoles.All); List source = ResolveIntakeStorages(self); if ((Object)(object)settlerController != (Object)null && settlerController.CurrentRole == SettlerRole.Caretaker) { return source.FirstOrDefault(); } return ((IEnumerable)source).FirstOrDefault((Func)((Container container) => (IntakeRolesFor(container) & required) != 0)); } internal bool HasIntakeStorageFor(SettlerRole role) { if (role == SettlerRole.Caretaker) { return HasIntakeStorage; } IntakeRoles required = IntakeRoleFor(role); if (required != IntakeRoles.None) { return ResolveIntakeStorages().Any((Container container) => (IntakeRolesFor(container) & required) != 0); } return false; } internal IntakeRoles IntakeRolesFor(Container container) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)container?.m_nview == (Object)null || !container.m_nview.IsValid()) { return IntakeRoles.None; } ZDO zDO = container.m_nview.GetZDO(); if (zDO.GetZDOID("hf_intake_hearth") == PersistentId) { return (IntakeRoles)(zDO.GetInt("hf_intake_roles", 0) & 7); } if (!(StorageLink.GetId(_nview.GetZDO()) == zDO.m_uid)) { return IntakeRoles.None; } return IntakeRoles.All; } internal void RequestSetIntakeStorage(Container container) { RequestSetIntakeStorageRoles(container, IntakeRoles.All); } internal void RequestSetIntakeStorageRoles(Container container, IntakeRoles roles) { //IL_008c: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if (!((Object)(object)localPlayer == (Object)null) && !((Object)(object)container?.m_nview == (Object)null) && container.m_nview.IsValid() && !((Object)(object)_nview == (Object)null) && _nview.IsValid() && !((Object)(object)IntakeCandidateFor(container, localPlayer.GetPlayerID()) != (Object)(object)this)) { _nview.InvokeRPC("hf_SetIntakeStorageRoles", new object[3] { localPlayer.GetPlayerID(), container.m_nview.GetZDO().m_uid, (int)(roles & IntakeRoles.All) }); } } private void RPC_SetIntakeStorage(long sender, long requesterId, ZDOID containerId) { //IL_004f: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_nview == (Object)null) && _nview.IsValid() && _nview.IsOwner() && requesterId != 0L && (OwnerId == 0L || OwnerId == requesterId) && !((Object)(object)ZNetScene.instance == (Object)null)) { GameObject val = ZNetScene.instance.FindInstance(containerId); Container val2 = (((Object)(object)val != (Object)null) ? (val.GetComponent() ?? val.GetComponentInChildren(true)) : null); if (ChestSortRules.IsStationaryPlayerChest(val2) && val2.CheckAccess(requesterId) && !((Object)(object)IntakeHearthWithinRange(val2, requesterId) != (Object)(object)this)) { SetIntakeStorageRoles(val2, IntakeRoles.All); } } } private void RPC_SetIntakeStorageRoles(long sender, long requesterId, ZDOID containerId, int requestedRoles) { //IL_004f: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_nview == (Object)null) && _nview.IsValid() && _nview.IsOwner() && requesterId != 0L && (OwnerId == 0L || OwnerId == requesterId) && !((Object)(object)ZNetScene.instance == (Object)null)) { GameObject val = ZNetScene.instance.FindInstance(containerId); Container val2 = (((Object)(object)val != (Object)null) ? (val.GetComponent() ?? val.GetComponentInChildren(true)) : null); if (ChestSortRules.IsStationaryPlayerChest(val2) && val2.CheckAccess(requesterId) && !((Object)(object)IntakeHearthWithinRange(val2, requesterId) != (Object)(object)this)) { SetIntakeStorageRoles(val2, (IntakeRoles)(requestedRoles & 7)); } } } private void SetIntakeStorageRoles(Container container, IntakeRoles roles) { //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)container?.m_nview == (Object)null) && container.m_nview.IsValid()) { Container val = StorageLink.Resolve(_nview.GetZDO(), (Component)(object)this); if ((Object)(object)val?.m_nview != (Object)null && val.m_nview.IsValid() && (Object)(object)val != (Object)(object)container) { SetPhysicalIntakeRoles(val, IntakeRoles.All); } StorageLink.Clear(_nview.GetZDO()); SetPhysicalIntakeRoles(container, roles); _intakeStorageCache = null; _intakeStorageCacheUntil = 0f; Diagnostics.Log($"Hearthfolk[storage]: intake chest {container.m_nview.GetZDO().m_uid} roles={(int)roles} hearth={PersistentId}"); } } private void SetPhysicalIntakeRoles(Container container, IntakeRoles roles) { //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0033: 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) if (!container.m_nview.IsOwner()) { container.m_nview.ClaimOwnership(); } ZDO zDO = container.m_nview.GetZDO(); if (roles == IntakeRoles.None) { if (zDO.GetZDOID("hf_intake_hearth") == PersistentId) { zDO.Set("hf_intake_hearth", ZDOID.None); zDO.Set("hf_intake_roles", 0); } } else { zDO.Set("hf_intake_hearth", PersistentId); zDO.Set("hf_intake_roles", (int)(roles & IntakeRoles.All)); } } private static IntakeRoles IntakeRoleFor(SettlerRole role) { return role switch { SettlerRole.Lumberjack => IntakeRoles.Lumberjack, SettlerRole.Miner => IntakeRoles.Miner, SettlerRole.Farmer => IntakeRoles.Farmer, _ => IntakeRoles.None, }; } private List ResolveSavedRoute(string routeKey, string identityKey, IEnumerable available, string label) { //IL_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_01f5: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: 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) if ((Object)(object)_nview == (Object)null || !_nview.IsValid()) { return new List(); } ZDO zDO = _nview.GetZDO(); List list = DecodePatrolRoute(zDO.GetString(routeKey, string.Empty)); if (list.Count == 0) { return list; } List source = (from entry in available where entry != null && entry.Id != ZDOID.None group entry by entry.Id into @group select @group.First()).ToList(); Dictionary dictionary = source.ToDictionary((SavedRouteEntry entry) => entry.Id); Dictionary dictionary2 = (from entry in DecodeRouteIdentity(zDO.GetString(identityKey, string.Empty)) where entry != null && entry.Id != ZDOID.None group entry by entry.Id).ToDictionary((IGrouping group) => group.Key, (IGrouping group) => group.First()); HashSet used = new HashSet(); List list2 = new List(); bool flag = false; foreach (ZDOID item in list) { SavedRouteEntry identity; if (dictionary.TryGetValue(item, out var value) && used.Add(value.Id)) { list2.Add(value); } else if (dictionary2.TryGetValue(item, out identity) && !string.IsNullOrEmpty(identity.Prefab)) { SavedRouteEntry savedRouteEntry = (from candidate in source where !used.Contains(candidate.Id) && candidate.Creator == identity.Creator && string.Equals(candidate.Prefab, identity.Prefab, StringComparison.Ordinal) && Vector3.Distance(candidate.Position, identity.Position) <= 0.85f orderby Vector3.Distance(candidate.Position, identity.Position) select candidate).FirstOrDefault(); if (savedRouteEntry != null) { used.Add(savedRouteEntry.Id); list2.Add(savedRouteEntry); flag = true; } } } if (list2.Count == list.Count && _nview.IsOwner()) { List list3 = list2.Select((SavedRouteEntry entry) => entry.Id).ToList(); if (flag || !list.SequenceEqual(list3)) { zDO.Set(routeKey, EncodePatrolRoute(list3)); } zDO.Set(identityKey, EncodeRouteIdentity(list2)); if (flag) { Diagnostics.Log($"Hearthfolk[{label}]: restored {list2.Count} saved selection(s) after ZDO identity changed."); } } return list2.Select((SavedRouteEntry entry) => entry.Id).ToList(); } private static void StoreRouteIdentity(ZDO zdo, string identityKey, IEnumerable route, IEnumerable available) { Dictionary candidates = (from entry in available where entry != null && entry.Id != ZDOID.None group entry by entry.Id).ToDictionary((IGrouping group) => group.Key, (IGrouping group) => group.First()); List entries = (from id in route.Where(candidates.ContainsKey) select candidates[id]).ToList(); zdo.Set(identityKey, EncodeRouteIdentity(entries)); } private static SavedRouteEntry PatrolRouteEntry(PatrolPoint point) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)point == (Object)null) { return null; } Piece val = ((Component)point).GetComponent() ?? ((Component)point).GetComponentInParent(); return new SavedRouteEntry { Id = point.PersistentId, Position = point.Position, Prefab = MaterialFilters.PrefabName(((Object)(object)val != (Object)null) ? ((Component)val).gameObject : ((Component)point).gameObject), Creator = (((Object)(object)val != (Object)null) ? val.GetCreator() : 0) }; } private static SavedRouteEntry GatewayRouteEntry(Door door) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)door?.m_nview == (Object)null || !door.m_nview.IsValid()) { return null; } Piece val = ((Component)door).GetComponent() ?? ((Component)door).GetComponentInParent(); return new SavedRouteEntry { Id = door.m_nview.GetZDO().m_uid, Position = ((Component)door).transform.position, Prefab = MaterialFilters.PrefabName(((Object)(object)val != (Object)null) ? ((Component)val).gameObject : ((Component)door).gameObject), Creator = (((Object)(object)val != (Object)null) ? val.GetCreator() : 0) }; } private static string EncodeRouteIdentity(IEnumerable entries) { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Expected O, but got Unknown //IL_006d: Unknown result type (might be due to invalid IL or missing references) List list = entries?.Where((SavedRouteEntry entry) => entry != null).Take(64).ToList() ?? new List(); ZPackage val = new ZPackage(); val.Write(1); val.Write(list.Count); foreach (SavedRouteEntry item in list) { val.Write(item.Id); val.Write(item.Position.x); val.Write(item.Position.y); val.Write(item.Position.z); val.Write(item.Prefab ?? string.Empty); val.Write(item.Creator); } return val.GetBase64(); } private static List DecodeRouteIdentity(string encoded) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown //IL_0044: 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_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) List list = new List(); if (string.IsNullOrEmpty(encoded)) { return list; } try { ZPackage val = new ZPackage(encoded); if (val.ReadInt() != 1) { return list; } int num = Mathf.Clamp(val.ReadInt(), 0, 64); for (int i = 0; i < num; i++) { list.Add(new SavedRouteEntry { Id = val.ReadZDOID(), Position = new Vector3(val.ReadSingle(), val.ReadSingle(), val.ReadSingle()), Prefab = val.ReadString(), Creator = val.ReadLong() }); } } catch (Exception ex) { Diagnostics.Log("Hearthfolk[routing]: invalid saved identity: " + ex.Message); list.Clear(); } return list; } internal static string EncodePatrolRoute(IEnumerable route) { //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Expected O, but got Unknown //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) List list = route?.Where((ZDOID id) => id != ZDOID.None).Distinct().Take(64) .ToList() ?? new List(); ZPackage val = new ZPackage(); val.Write(list.Count); foreach (ZDOID item in list) { val.Write(item); } return val.GetBase64(); } internal static List DecodePatrolRoute(string encoded) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0035: 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_004c: Unknown result type (might be due to invalid IL or missing references) List list = new List(); if (string.IsNullOrEmpty(encoded)) { return list; } try { ZPackage val = new ZPackage(encoded); int num = Mathf.Clamp(val.ReadInt(), 0, 64); for (int i = 0; i < num; i++) { ZDOID val2 = val.ReadZDOID(); if (val2 != ZDOID.None && !list.Contains(val2)) { list.Add(val2); } } } catch (Exception ex) { Diagnostics.Log("Hearthfolk[patrol]: invalid saved route: " + ex.Message); } return list; } internal static bool AlertAt(Vector3 home, long ownerId) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) ExilesHearth exilesHearth = FindFor(home, ownerId); if ((Object)(object)exilesHearth != (Object)null) { return exilesHearth.AlertActive; } return false; } internal static bool DefenseThreatAt(Vector3 home, long ownerId) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) ExilesHearth exilesHearth = FindFor(home, ownerId); if ((Object)(object)exilesHearth != (Object)null) { return exilesHearth.DefenseThreatActive; } return false; } internal static void ReportSettlerAttack(Vector3 home, long ownerId, Character attacker) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) if (IsActualAttacker(attacker)) { FindFor(home, ownerId)?.SignalDefenseThreat(); } } internal static void ReportBaseDamage(WearNTear target, Character attacker) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)target == (Object)null) && !((Object)(object)target.m_piece == (Object)null) && target.m_piece.GetCreator() != 0L && IsActualAttacker(attacker)) { ExilesHearth exilesHearth = NearestTo(((Component)target).transform.position, 0L); float num = Mathf.Max(18f, (HfConfig.WorkRadius != null) ? HfConfig.WorkRadius.Value : 30f); if ((Object)(object)exilesHearth != (Object)null && Utils.DistanceXZ(((Component)exilesHearth).transform.position, ((Component)target).transform.position) <= num) { exilesHearth.SignalDefenseThreat(); } } } private static bool IsActualAttacker(Character attacker) { if ((Object)(object)attacker != (Object)null && !attacker.IsDead() && !attacker.IsTamed() && !(attacker is Player)) { return (Object)(object)((Component)attacker).GetComponent() == (Object)null; } return false; } private void SignalDefenseThreat() { if (!((Object)(object)_nview == (Object)null) && _nview.IsValid()) { _nview.InvokeRPC("hf_SignalDefenseThreat", Array.Empty()); } } private void RPC_SignalDefenseThreat(long sender) { if (!((Object)(object)_nview == (Object)null) && _nview.IsValid() && _nview.IsOwner()) { _nview.GetZDO().Set("hf_defense_threat_until", DateTime.UtcNow.AddSeconds(12.0).Ticks); Diagnostics.Log("Hearthfolk[defense]: settlement is under attack"); } } internal static bool RaidAt(Vector3 position) { //IL_000d: 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_002c: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)RandEventSystem.instance == (Object)null || position.y > 3000f) { return false; } RandomEvent currentRandomEvent = RandEventSystem.instance.GetCurrentRandomEvent(); if (currentRandomEvent != null) { return Utils.DistanceXZ(position, currentRandomEvent.m_pos) < currentRandomEvent.m_eventRange; } return false; } internal static ExilesHearth FindFor(Vector3 home, long ownerId) { //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) return (from hearth in Instances where (Object)(object)hearth != (Object)null && (Object)(object)hearth._nview != (Object)null && hearth._nview.IsValid() && (ownerId == 0L || hearth.OwnerId == 0L || hearth.OwnerId == ownerId) && Vector3.Distance(((Component)hearth).transform.position, home) <= 6f orderby Vector3.Distance(((Component)hearth).transform.position, home) select hearth).FirstOrDefault(); } internal static ExilesHearth NearestTo(Vector3 point, long ownerId) { //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) return (from hearth in Instances where (Object)(object)hearth != (Object)null && (Object)(object)hearth._nview != (Object)null && hearth._nview.IsValid() && (ownerId == 0L || hearth.OwnerId == 0L || hearth.OwnerId == ownerId) orderby Vector3.Distance(((Component)hearth).transform.position, point) select hearth).FirstOrDefault(); } internal static ExilesHearth IntakeCandidateFor(Container container, long ownerId) { if (!ChestSortRules.CanConfigure(container, ownerId)) { return null; } return IntakeHearthWithinRange(container, ownerId); } private static ExilesHearth IntakeHearthWithinRange(Container container, long ownerId) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)container == (Object)null) { return null; } ExilesHearth exilesHearth = NearestTo(((Component)container).transform.position, ownerId); float num = Mathf.Max(20f, (HfConfig.WorkRadius != null) ? HfConfig.WorkRadius.Value : 30f); if (!((Object)(object)exilesHearth != (Object)null) || !(Vector3.Distance(((Component)exilesHearth).transform.position, ((Component)container).transform.position) <= num)) { return null; } return exilesHearth; } private List FindAvailableGatewayDoors() { float radius = Mathf.Max(20f, (HfConfig.WorkRadius != null) ? (HfConfig.WorkRadius.Value + 10f) : 40f); return (from door in SceneObjectCache.Get(1f).Where(delegate(Door door) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)door == (Object)null || (Object)(object)door.m_nview == (Object)null || !door.m_nview.IsValid() || Vector3.Distance(((Component)this).transform.position, ((Component)door).transform.position) > radius) { return false; } Piece val = ((Component)door).GetComponent() ?? ((Component)door).GetComponentInParent(); long num = (((Object)(object)val != (Object)null) ? val.GetCreator() : 0); return (Object)(object)val != (Object)null && val.IsPlacedByPlayer() && (OwnerId == 0L || num == 0L || num == OwnerId); }) group door by door.m_nview.GetZDO().m_uid into @group select @group.First() into door orderby Vector3.Distance(((Component)this).transform.position, ((Component)door).transform.position) select door).ToList(); } internal void Recruit(Player player) { //IL_0083: 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_0098: 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_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null || (Object)(object)_nview == (Object)null || !_nview.IsValid()) { return; } Inventory inventory = ((Humanoid)player).GetInventory(); int recruitCost = RecruitCost; if (inventory.CountItems("$item_coins", -1, true) < recruitCost) { Message(player, "$hf_need_coins", recruitCost); return; } GameObject prefab = PrefabManager.Instance.GetPrefab("hf_settler"); if ((Object)(object)prefab == (Object)null) { ((Character)player).Message((MessageType)2, "$hf_prefab_missing", 0, (Sprite)null); return; } Vector3 val = ((Component)this).transform.position + ((Component)this).transform.forward * 2.2f + Vector3.up * 0.2f; GameObject val2 = Object.Instantiate(prefab, val, Quaternion.LookRotation(((Component)this).transform.forward)); ZNetView component = val2.GetComponent(); if ((Object)(object)component == (Object)null || !component.IsValid()) { if ((Object)(object)val2 != (Object)null) { Object.Destroy((Object)(object)val2); } ((Character)player).Message((MessageType)2, "$hf_recruit_failed", 0, (Sprite)null); return; } inventory.RemoveItem("$item_coins", recruitCost, -1, true); string text = NextName(); ZDO zDO = component.GetZDO(); zDO.Set("hf_owner", player.GetPlayerID()); zDO.Set("hf_home", ((Component)this).transform.position); zDO.Set("hf_name", text); zDO.Set("hf_role", 3); Message(player, "$hf_recruited", text); } public bool UseItem(Humanoid user, ItemData item) { return false; } private string NextName() { ZDO zDO = _nview.GetZDO(); int num = zDO.GetInt("hf_next_settler", 0) + 1; zDO.Set("hf_next_settler", num); string[] array = (from name in (HfConfig.SettlerNamePool?.Value ?? string.Empty).Split(new char[4] { ',', ';', '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries) select name.Trim() into name where !string.IsNullOrEmpty(name) select name).Distinct(StringComparer.OrdinalIgnoreCase).ToArray(); if (array.Length == 0) { array = SettlerNames; } int num2 = num - 1; string text = array[num2 % array.Length]; int num3 = num2 / array.Length; if (num3 != 0) { return $"{text} {num3 + 1}"; } return text; } private static void Message(Player player, string key, object arg) { string format = Localization.instance.Localize(key); ((Character)player).Message((MessageType)2, string.Format(format, arg), 0, (Sprite)null); } } internal sealed class FarmCrop { internal string PlantPrefabName; internal GameObject PlantPrefab; internal string SeedSharedName; internal string SeedPrefabName; internal string DisplayName; internal float GrowRadius; internal int YieldAmount = 1; internal readonly HashSet MaturePrefabNames = new HashSet(); internal readonly HashSet DropPrefabNames = new HashSet(); internal readonly HashSet DropSharedNames = new HashSet(); } internal static class FarmCropCatalog { internal const string AllPermissionsToken = "*"; internal const string NoPermissionsToken = "-"; private static readonly List Cache = new List(); private static ObjectDB _cachedObjectDb; internal static IReadOnlyList All() { if ((Object)(object)ObjectDB.instance == (Object)null) { return Cache; } if ((Object)(object)_cachedObjectDb == (Object)(object)ObjectDB.instance && Cache.Count > 0) { return Cache; } _cachedObjectDb = ObjectDB.instance; Cache.Clear(); GameObject itemPrefab = ObjectDB.instance.GetItemPrefab("Cultivator"); PieceTable val = ((itemPrefab == null) ? null : itemPrefab.GetComponent()?.m_itemData?.m_shared?.m_buildPieces); if ((Object)(object)val == (Object)null || val.m_pieces == null) { return Cache; } foreach (GameObject piece in val.m_pieces) { Plant val2 = (((Object)(object)piece != (Object)null) ? piece.GetComponent() : null); Piece val3 = (((Object)(object)piece != (Object)null) ? piece.GetComponent() : null); Requirement val4 = val3?.m_resources?.FirstOrDefault((Func)((Requirement resource) => (Object)(object)resource?.m_resItem != (Object)null && resource.m_amount > 0)); if ((Object)(object)val2 == (Object)null || (Object)(object)val3 == (Object)null || val4 == null || val2.m_grownPrefabs == null) { continue; } List list = val2.m_grownPrefabs.Where((GameObject grown) => (Object)(object)grown != (Object)null && (Object)(object)grown.GetComponentInChildren(true) != (Object)null).ToList(); if (list.Count == 0) { continue; } FarmCrop farmCrop = new FarmCrop { PlantPrefabName = ((Object)piece).name, PlantPrefab = piece, SeedSharedName = val4.m_resItem.m_itemData.m_shared.m_name, SeedPrefabName = ((Object)((Component)val4.m_resItem).gameObject).name, GrowRadius = Mathf.Max(0.45f, val2.m_growRadius) }; foreach (GameObject item in list) { farmCrop.MaturePrefabNames.Add(CleanPrefabName(((Object)item).name)); Pickable componentInChildren = item.GetComponentInChildren(true); if ((Object)(object)componentInChildren?.m_itemPrefab != (Object)null) { farmCrop.YieldAmount = Mathf.Max(farmCrop.YieldAmount, Mathf.Max(1, componentInChildren.m_amount)); farmCrop.DropPrefabNames.Add(CleanPrefabName(((Object)componentInChildren.m_itemPrefab).name)); string text = componentInChildren.m_itemPrefab.GetComponent()?.m_itemData?.m_shared?.m_name; if (!string.IsNullOrEmpty(text)) { farmCrop.DropSharedNames.Add(text); } if (string.IsNullOrEmpty(farmCrop.DisplayName)) { farmCrop.DisplayName = FriendlyName(((Object)componentInChildren.m_itemPrefab).name); } } } if (string.IsNullOrEmpty(farmCrop.DisplayName)) { farmCrop.DisplayName = FriendlyName(((Object)piece).name); } Cache.Add(farmCrop); } Cache.Sort((FarmCrop left, FarmCrop right) => string.Compare(left.DisplayName, right.DisplayName, StringComparison.OrdinalIgnoreCase)); return Cache; } internal static FarmCrop Find(string plantPrefabName) { return All().FirstOrDefault((FarmCrop crop) => crop.PlantPrefabName == plantPrefabName); } internal static FarmCrop CyclePartner(FarmCrop crop) { if (crop == null) { return null; } string seedPrefab = CleanPrefabName(crop.SeedPrefabName); return All().FirstOrDefault((FarmCrop candidate) => candidate != null && candidate != crop && crop.DropPrefabNames.Contains(CleanPrefabName(candidate.SeedPrefabName)) && candidate.DropPrefabNames.Contains(seedPrefab) && candidate.PlantPrefabName != crop.PlantPrefabName); } internal static bool IsCycleCrop(FarmCrop configured, FarmCrop candidate) { if (configured != null && candidate != null) { if (!(configured.PlantPrefabName == candidate.PlantPrefabName)) { return CyclePartner(configured)?.PlantPrefabName == candidate.PlantPrefabName; } return true; } return false; } internal static string PermissionKey(FarmCrop crop) { if (crop == null) { return string.Empty; } FarmCrop farmCrop = CyclePartner(crop); if (farmCrop != null && string.CompareOrdinal(crop.PlantPrefabName, farmCrop.PlantPrefabName) > 0) { return farmCrop.PlantPrefabName; } return crop.PlantPrefabName; } internal static List PermissionOptions() { return (from @group in (from crop in All() where crop != null && !string.IsNullOrEmpty(PermissionKey(crop)) select crop).GroupBy(PermissionKey, StringComparer.Ordinal) select @group.OrderBy(delegate(FarmCrop crop) { string displayName = crop.DisplayName; return (displayName != null && displayName.IndexOf("seed", StringComparison.OrdinalIgnoreCase) >= 0) ? 1 : 0; }).ThenBy((FarmCrop crop) => crop.DisplayName?.Length ?? int.MaxValue).ThenBy((FarmCrop crop) => crop.DisplayName, StringComparer.OrdinalIgnoreCase) .First()).OrderBy((FarmCrop crop) => crop.DisplayName, StringComparer.OrdinalIgnoreCase).ToList(); } internal static FarmCrop PermissionRepresentative(FarmCrop crop) { string key = PermissionKey(crop); return PermissionOptions().FirstOrDefault((FarmCrop option) => PermissionKey(option) == key); } internal static bool PermissionEnabled(string serialized, FarmCrop crop) { if (crop == null) { return false; } if (serialized == "*") { return true; } string item = PermissionKey(crop); return ParsePermissions(serialized).Contains(item); } internal static string TogglePermission(string serialized, FarmCrop crop) { string text = PermissionKey(crop); if (string.IsNullOrEmpty(text)) { return NormalizePermissions(serialized); } HashSet hashSet = new HashSet(PermissionOptions().Select(PermissionKey), StringComparer.Ordinal); HashSet hashSet2 = ((serialized == "*") ? new HashSet(hashSet, StringComparer.Ordinal) : ParsePermissions(serialized)); if (!hashSet2.Remove(text)) { hashSet2.Add(text); } return SerializePermissions(hashSet2, hashSet); } internal static string NormalizePermissions(string serialized) { if (serialized == null || serialized == "*") { return "*"; } HashSet hashSet = new HashSet(PermissionOptions().Select(PermissionKey), StringComparer.Ordinal); HashSet hashSet2 = ParsePermissions(serialized); hashSet2.IntersectWith(hashSet); return SerializePermissions(hashSet2, hashSet); } private static HashSet ParsePermissions(string serialized) { return new HashSet(from value in (serialized ?? string.Empty).Split(new char[1] { ';' }, StringSplitOptions.RemoveEmptyEntries) select value.Trim() into value where !string.IsNullOrEmpty(value) select value, StringComparer.Ordinal); } private static string SerializePermissions(HashSet enabled, HashSet known) { if (known.Count > 0 && known.All(enabled.Contains)) { return "*"; } string text = string.Join(";", enabled.Where(known.Contains).OrderBy((string value) => value, StringComparer.Ordinal)); if (!string.IsNullOrEmpty(text)) { return text; } return "-"; } internal static int StockTarget(string serialized, FarmCrop crop) { string text = PermissionKey(crop); if (!string.IsNullOrEmpty(text) && ParseStockTargets(serialized).TryGetValue(text, out var value)) { return value; } return 0; } internal static string SetStockTarget(string serialized, FarmCrop crop, int target) { string text = PermissionKey(crop); HashSet known = new HashSet(PermissionOptions().Select(PermissionKey), StringComparer.Ordinal); Dictionary source = ParseStockTargets(serialized); source = source.Where((KeyValuePair pair) => known.Contains(pair.Key)).ToDictionary, string, int>((KeyValuePair pair) => pair.Key, (KeyValuePair pair) => pair.Value, StringComparer.Ordinal); if (known.Contains(text) && target > 0) { source[text] = Mathf.Clamp(target, 1, 10000); } else { source.Remove(text); } return SerializeStockTargets(source); } internal static string NormalizeStockTargets(string serialized) { HashSet known = new HashSet(PermissionOptions().Select(PermissionKey), StringComparer.Ordinal); return SerializeStockTargets((from pair in ParseStockTargets(serialized) where known.Contains(pair.Key) select pair).ToDictionary, string, int>((KeyValuePair pair) => pair.Key, (KeyValuePair pair) => Mathf.Clamp(pair.Value, 1, 10000), StringComparer.Ordinal)); } private static Dictionary ParseStockTargets(string serialized) { Dictionary dictionary = new Dictionary(StringComparer.Ordinal); string[] array = (serialized ?? string.Empty).Split(new char[1] { ';' }, StringSplitOptions.RemoveEmptyEntries); foreach (string text in array) { int num = text.LastIndexOf('='); if (num > 0 && int.TryParse(text.Substring(num + 1), out var result) && result > 0) { dictionary[text.Substring(0, num)] = Mathf.Clamp(result, 1, 10000); } } return dictionary; } private static string SerializeStockTargets(Dictionary targets) { return string.Join(";", from pair in targets.Where((KeyValuePair pair) => pair.Value > 0).OrderBy, string>((KeyValuePair pair) => pair.Key, StringComparer.Ordinal) select $"{pair.Key}={pair.Value}"); } internal static List AvailableTo(Player player) { return (from crop in All() where (Object)(object)player == (Object)null || player.IsKnownMaterial(crop.SeedSharedName) select crop).ToList(); } internal static string CleanPrefabName(string name) { if (!string.IsNullOrEmpty(name)) { return name.Replace("(Clone)", string.Empty).Trim(); } return string.Empty; } internal static string FriendlyName(string raw) { raw = CleanPrefabName(raw); if (string.IsNullOrEmpty(raw)) { return "Unknown crop"; } string[] array = new string[3] { "piece_", "sapling_", "Pickable_" }; foreach (string text in array) { if (raw.StartsWith(text, StringComparison.OrdinalIgnoreCase)) { raw = raw.Substring(text.Length); break; } } StringBuilder stringBuilder = new StringBuilder(raw.Length + 8); for (int j = 0; j < raw.Length; j++) { char c = raw[j]; if (c == '_' || c == '-') { stringBuilder.Append(' '); continue; } if (j > 0 && char.IsUpper(c) && raw[j - 1] != '_' && !char.IsUpper(raw[j - 1])) { stringBuilder.Append(' '); } stringBuilder.Append(c); } string text2 = stringBuilder.ToString().Trim().ToLowerInvariant(); if (text2.Length != 0) { return char.ToUpperInvariant(text2[0]) + text2.Substring(1); } return "Unknown crop"; } } internal sealed class FarmMarker : MonoBehaviour, Interactable, Hoverable { private sealed class CropSelection { internal FarmCrop Crop; internal bool Combined; internal string DisplayName { get { FarmCrop farmCrop = (Combined ? FarmCropCatalog.CyclePartner(Crop) : null); if (farmCrop == null) { return Crop.DisplayName; } return Crop.DisplayName + " + " + farmCrop.DisplayName; } } } private const int BoundarySegments = 72; private const float BoundaryGroundOffset = 0.14f; private static readonly Color BoundaryColor = new Color(1f, 0.72f, 0.16f, 0.92f); internal static readonly List Instances = new List(); private ZNetView _nview; private Piece _piece; private LineRenderer _boundary; private Material _boundaryMaterial; private float _boundaryVisibleUntil; private float _lastBoundaryRadius = -1f; private bool _boundaryCreationFailed; internal bool IsValid { get { if ((Object)(object)_nview != (Object)null) { return _nview.IsValid(); } return false; } } internal ZDOID PersistentId { get { //IL_0019: 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 (!IsValid) { return ZDOID.None; } return _nview.GetZDO().m_uid; } } internal Vector3 Position => ((Component)this).transform.position; internal float Radius => Mathf.Max(3f, HfConfig.FarmRadius.Value); internal long OwnerId { get { if (!((Object)(object)_piece != (Object)null)) { return 0L; } return _piece.GetCreator(); } } internal bool CombinedCycle { get { if (IsValid && _nview.GetZDO().GetBool("hf_farm_combined", false)) { return FarmCropCatalog.CyclePartner(Crop) != null; } return false; } } internal bool CombinedPartnerNext { get { if (CombinedCycle) { return _nview.GetZDO().GetBool("hf_farm_combined_next", false); } return false; } } internal string SelectionDisplayName { get { FarmCrop crop = Crop; if (crop == null) { return string.Empty; } FarmCrop farmCrop = (CombinedCycle ? FarmCropCatalog.CyclePartner(crop) : null); if (farmCrop == null) { return crop.DisplayName; } return crop.DisplayName + " + " + farmCrop.DisplayName; } } internal FarmCrop Crop { get { IReadOnlyList readOnlyList = FarmCropCatalog.All(); if (readOnlyList.Count == 0) { return null; } FarmCrop farmCrop = FarmCropCatalog.Find(IsValid ? _nview.GetZDO().GetString("hf_farm_crop", string.Empty) : string.Empty); if (farmCrop != null) { return farmCrop; } Player player = Player.GetPlayer(OwnerId); List source = FarmCropCatalog.AvailableTo(player); if (!((Object)(object)player != (Object)null)) { return readOnlyList[0]; } return source.FirstOrDefault(); } } private void Awake() { _nview = ((Component)this).GetComponent(); _piece = ((Component)this).GetComponent(); if ((Object)(object)_nview != (Object)null && _nview.IsValid()) { _nview.Register("hf_SetFarmCrop", (Action)RPC_SetCrop); _nview.Register("hf_SetFarmSelection", (Action)RPC_SetSelection); } if (!Instances.Contains(this)) { Instances.Add(this); } } private void OnDestroy() { Instances.Remove(this); if ((Object)(object)_boundaryMaterial != (Object)null) { Object.Destroy((Object)(object)_boundaryMaterial); } } private void Update() { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_boundary == (Object)null)) { Player localPlayer = Player.m_localPlayer; bool enabled = Time.time <= _boundaryVisibleUntil && (Object)(object)localPlayer != (Object)null && Vector3.Distance(((Component)localPlayer).transform.position, Position) <= Mathf.Max(35f, Radius + 10f); ((Renderer)_boundary).enabled = enabled; } } public string GetHoverName() { return "$piece_hf_farm_marker"; } public string GetHoverText() { ShowBoundary(0.25f); if (Crop == null) { return Localization.instance.Localize("$piece_hf_farm_marker\n$hf_farm_no_crops"); } return Localization.instance.Localize("$piece_hf_farm_marker\n$hf_farm_crop: " + SelectionDisplayName + "\n[$KEY_Use] $hf_farm_next_crop"); } public bool Interact(Humanoid user, bool hold, bool alt) { Player val = (Player)(object)((user is Player) ? user : null); if (hold || (Object)(object)val == (Object)null || !IsValid) { return false; } ShowBoundary(4f); List list = AvailableSelections(val); if (list.Count == 0) { return true; } FarmCrop current = Crop; int num = ((current != null) ? list.FindIndex((CropSelection selection) => selection.Crop.PlantPrefabName == current.PlantPrefabName && selection.Combined == CombinedCycle) : (-1)); CropSelection cropSelection = list[(num + 1 + list.Count) % list.Count]; _nview.InvokeRPC("hf_SetFarmSelection", new object[3] { val.GetPlayerID(), cropSelection.Crop.PlantPrefabName, cropSelection.Combined ? 1 : 0 }); return true; } private void ShowBoundary(float seconds) { _boundaryVisibleUntil = Mathf.Max(_boundaryVisibleUntil, Time.time + Mathf.Max(0.1f, seconds)); bool flag = (Object)(object)_boundary != (Object)null && ((Renderer)_boundary).enabled; if (!((Object)(object)_boundary == (Object)null) || EnsureBoundary()) { ((Renderer)_boundary).enabled = true; if (!flag || !Mathf.Approximately(_lastBoundaryRadius, Radius)) { RefreshBoundary(); } } } private bool EnsureBoundary() { //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Expected O, but got Unknown //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Expected O, but got Unknown //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: Unknown result type (might be due to invalid IL or missing references) //IL_01ef: Unknown result type (might be due to invalid IL or missing references) //IL_01f7: Unknown result type (might be due to invalid IL or missing references) //IL_0209: Expected O, but got Unknown //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_01db: Unknown result type (might be due to invalid IL or missing references) //IL_02a1: Unknown result type (might be due to invalid IL or missing references) //IL_029a: Unknown result type (might be due to invalid IL or missing references) //IL_02bb: Unknown result type (might be due to invalid IL or missing references) //IL_02b4: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_boundary != (Object)null) { return true; } if (_boundaryCreationFailed) { return false; } Shader val = Shader.Find("Sprites/Default") ?? Shader.Find("Particles/Standard Unlit") ?? Shader.Find("Unlit/Color"); bool flag = (Object)(object)val == (Object)null; if (!flag) { _boundaryMaterial = new Material(val); } else { Material val2 = ((Component)this).GetComponentsInChildren(true).SelectMany((Renderer renderer) => renderer.sharedMaterials).FirstOrDefault((Func)((Material material) => (Object)(object)material != (Object)null && (Object)(object)material.shader != (Object)null)); if ((Object)(object)val2 != (Object)null) { _boundaryMaterial = new Material(val2); } } if ((Object)(object)_boundaryMaterial == (Object)null) { _boundaryCreationFailed = true; Logger.LogWarning((object)"Hearthfolk: unable to create the Farm Marker boundary material."); return false; } ((Object)_boundaryMaterial).name = "hf_farm_boundary_material"; ((Object)_boundaryMaterial).hideFlags = (HideFlags)61; Color val3 = (flag ? BoundaryColor : Color.white); if (_boundaryMaterial.HasProperty("_Color")) { _boundaryMaterial.SetColor("_Color", val3); } if (_boundaryMaterial.HasProperty("_BaseColor")) { _boundaryMaterial.SetColor("_BaseColor", val3); } if (_boundaryMaterial.HasProperty("_MainTex")) { _boundaryMaterial.SetTexture("_MainTex", (Texture)(object)Texture2D.whiteTexture); } if (_boundaryMaterial.HasProperty("_BaseMap")) { _boundaryMaterial.SetTexture("_BaseMap", (Texture)(object)Texture2D.whiteTexture); } if (_boundaryMaterial.HasProperty("_EmissionColor")) { _boundaryMaterial.EnableKeyword("_EMISSION"); _boundaryMaterial.SetColor("_EmissionColor", BoundaryColor * 0.55f); } GameObject val4 = new GameObject("hf_farm_boundary") { hideFlags = (HideFlags)52, layer = ((Component)this).gameObject.layer }; val4.transform.SetParent(((Component)this).transform, false); _boundary = val4.AddComponent(); ((Renderer)_boundary).sharedMaterial = _boundaryMaterial; _boundary.useWorldSpace = true; _boundary.loop = true; _boundary.positionCount = 72; _boundary.widthMultiplier = 0.09f; _boundary.numCornerVertices = 2; _boundary.alignment = (LineAlignment)0; _boundary.textureMode = (LineTextureMode)0; _boundary.startColor = (flag ? Color.white : BoundaryColor); _boundary.endColor = (flag ? Color.white : BoundaryColor); ((Renderer)_boundary).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)_boundary).receiveShadows = false; ((Renderer)_boundary).enabled = false; return true; } private void RefreshBoundary() { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: 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_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_boundary == (Object)null) { return; } float radius = Radius; float y = default(float); for (int i = 0; i < 72; i++) { float num = (float)i * (float)Math.PI * 2f / 72f; Vector3 val = Position + new Vector3(Mathf.Cos(num) * radius, 0f, Mathf.Sin(num) * radius); Heightmap val2 = Heightmap.FindHeightmap(val); if ((Object)(object)val2 != (Object)null && val2.GetWorldHeight(val, ref y)) { val.y = y; } else { val.y = Position.y; } val.y += 0.14f; _boundary.SetPosition(i, val); } _lastBoundaryRadius = radius; } public bool UseItem(Humanoid user, ItemData item) { return false; } private void RPC_SetCrop(long sender, long requesterId, string plantPrefabName) { SetCropSelection(requesterId, plantPrefabName, combined: false); } private void RPC_SetSelection(long sender, long requesterId, string plantPrefabName, int combined) { SetCropSelection(requesterId, plantPrefabName, combined != 0); } private void SetCropSelection(long requesterId, string plantPrefabName, bool combined) { FarmCrop farmCrop = FarmCropCatalog.Find(plantPrefabName); FarmCrop farmCrop2 = (combined ? FarmCropCatalog.CyclePartner(farmCrop) : null); if (IsValid && _nview.IsOwner() && (OwnerId == 0L || OwnerId == requesterId) && farmCrop != null && (!combined || farmCrop2 != null)) { Player player = Player.GetPlayer(requesterId); if (!((Object)(object)player != (Object)null) || (player.IsKnownMaterial(farmCrop.SeedSharedName) && (!combined || player.IsKnownMaterial(farmCrop2.SeedSharedName)))) { _nview.GetZDO().Set("hf_farm_crop", plantPrefabName); _nview.GetZDO().Set("hf_farm_combined", combined); _nview.GetZDO().Set("hf_farm_combined_next", false); Diagnostics.Log($"Hearthfolk[farm]: crop -> {plantPrefabName}, combined={combined}"); } } } internal void RecordCombinedPlant(FarmCrop planted) { if (CombinedCycle && planted != null && _nview.IsOwner()) { _nview.GetZDO().Set("hf_farm_combined_next", planted.PlantPrefabName == Crop.PlantPrefabName); } } private static List AvailableSelections(Player player) { List list = FarmCropCatalog.AvailableTo(player).ToList(); HashSet hashSet = new HashSet(list.Select((FarmCrop crop) => crop.PlantPrefabName)); List list2 = new List(); foreach (FarmCrop item in list) { list2.Add(new CropSelection { Crop = item, Combined = false }); FarmCrop farmCrop = FarmCropCatalog.PermissionRepresentative(item); FarmCrop farmCrop2 = FarmCropCatalog.CyclePartner(item); if (farmCrop != null && farmCrop.PlantPrefabName == item.PlantPrefabName && farmCrop2 != null && hashSet.Contains(farmCrop2.PlantPrefabName)) { list2.Add(new CropSelection { Crop = item, Combined = true }); } } return list2; } internal bool BelongsTo(Vector3 home, long ownerId) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0040: 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) if (!IsValid || (ownerId != 0L && OwnerId != 0L && OwnerId != ownerId) || Vector3.Distance(Position, home) > Mathf.Max(20f, HfConfig.FarmMarkerMaxRange.Value)) { return false; } ExilesHearth exilesHearth = ExilesHearth.FindFor(home, ownerId); if ((Object)(object)exilesHearth != (Object)null) { return (Object)(object)ExilesHearth.NearestTo(Position, OwnerId) == (Object)(object)exilesHearth; } return false; } internal static List MarkersFor(Vector3 home, long ownerId) { //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) return (from marker in Instances where (Object)(object)marker != (Object)null && marker.BelongsTo(home, ownerId) && marker.Crop != null orderby Vector3.Distance(marker.Position, home) select marker).ToList(); } } internal static class HearthfolkLocalization { internal static void Register() { CustomLocalization localization = LocalizationManager.Instance.GetLocalization(); Dictionary dictionary = new Dictionary { { "piece_hf_hearth", "Exiles' Hearth" }, { "piece_hf_hearth_desc", "The heart of a small settlement. Recruit and manage settlers." }, { "piece_hf_sawmill", "Sawmill" }, { "piece_hf_sawmill_desc", "A timber production building supporting up to three carpenters." }, { "piece_hf_mine", "Mine" }, { "piece_hf_mine_desc", "A stone and ore production building supporting up to three miners." }, { "piece_hf_barracks", "Barracks" }, { "piece_hf_barracks_desc", "A guard post and rally point during settlement alerts." }, { "piece_hf_patrol_point", "Patrol Point" }, { "piece_hf_patrol_point_desc", "Defines the nearest Exiles' Hearth route. Points are visited in order around the hearth." }, { "piece_hf_farm_marker", "Farm Marker" }, { "piece_hf_farm_marker_desc", "Defines a crop field for Farmers. Use the marker to select its crop." }, { "piece_hf_settler_tent", "Settler Tent" }, { "piece_hf_settler_tent_desc", "A large furnished white-canvas tent reserved for one Hearthfolk resident. Its always-lit torches provide Fire." }, { "hf_settler_shelter_reserved", "Reserved for Hearthfolk residents" }, { "hf_farm_crop", "Crop" }, { "hf_farm_next_crop", "Select next crop" }, { "hf_farm_no_crops", "No plantable crops are available" }, { "hf_building_manage", "Manage building" }, { "hf_building_open_storage", "Open storage" }, { "hf_building_storage_suffix", "- Storage" }, { "hf_legacy_building_storage", "Retired structure storage" }, { "piece_hf_hearth_recruit", "Recruit a settler" }, { "piece_hf_lumber_banner", "Lumberjack Banner" }, { "piece_hf_lumber_banner_desc", "A freestanding field banner that extends the work area of Lumberjacks." }, { "piece_hf_miner_banner", "Miner Banner" }, { "piece_hf_miner_banner_desc", "A freestanding field banner that extends the work area of Miners." }, { "hf_settler", "Settler" }, { "hf_role_idle", "Idle" }, { "hf_role_lumberjack", "Lumberjack" }, { "hf_role_guard", "Guard" }, { "hf_role_caretaker", "Caretaker" }, { "hf_role_miner", "Miner" }, { "hf_role_follower", "Follower" }, { "hf_role_farmer", "Farmer" }, { "hf_status_caretaker_idle", "Checking the settlement" }, { "hf_status_socializing", "Chatting with other residents" }, { "hf_status_caretaker_fetch", "Fetching supplies from the chest" }, { "hf_status_caretaker_fire", "Refuelling fires and lights" }, { "hf_status_caretaker_fuel", "Refuelling a production machine" }, { "hf_status_caretaker_input", "Loading a production machine" }, { "hf_status_caretaker_collect", "Collecting finished products" }, { "hf_status_caretaker_no_supplies", "Required supplies are unavailable" }, { "hf_status_caretaker_repair_base", "Repairing a base structure" }, { "hf_status_caretaker_need_hammer", "Needs a usable hammer" }, { "hf_status_caretaker_sort_fetch", "Fetching materials to sort" }, { "hf_status_caretaker_sort", "Sorting items into chests" }, { "hf_status_caretaker_sort_return", "Returning cargo to the intake chest" }, { "hf_status_farmer_need_cultivator", "Needs a usable Cultivator" }, { "hf_status_farmer_no_field", "Needs a connected Farm Marker" }, { "hf_status_farmer_no_assigned_field", "No Farm Marker is assigned to this Farmer" }, { "hf_status_farmer_no_allowed_field", "No Farm Marker uses an allowed crop" }, { "hf_status_farmer_waiting", "Waiting for crops to grow" }, { "hf_status_farmer_collect", "Collecting the harvest" }, { "hf_status_farmer_move_harvest", "Heading to a ripe crop" }, { "hf_status_farmer_harvest", "Harvesting a ripe crop" }, { "hf_status_farmer_fetch_seed", "Fetching planting resources" }, { "hf_status_farmer_move_plant", "Heading to an empty planting spot" }, { "hf_status_farmer_planting", "Planting a crop" }, { "hf_status_farmer_deposit", "Taking the harvest to storage" }, { "hf_chest_sort_hover", "[Ctrl+$KEY_Use] Configure sorting" }, { "hf_chest_sort_title", "Hearthfolk Sorting" }, { "hf_chest_sort_mode_explicit", "Mode: explicit filters" }, { "hf_chest_sort_mode_auto", "Mode: automatic from contents" }, { "hf_chest_sort_desc", "Select the items the Caretaker may carry into this chest. Changes apply when you save the filters." }, { "hf_chest_sort_search", "Search" }, { "hf_chest_sort_select_present", "Select items already inside" }, { "hf_chest_sort_clear", "Clear selection" }, { "hf_chest_sort_no_items", "No known item matches the search." }, { "hf_chest_sort_selected", "Selected items: {0}" }, { "hf_chest_sort_save", "Save filters" }, { "hf_chest_sort_use_auto", "Use automatic mode" }, { "hf_chest_sort_saved", "Sorting filters saved." }, { "hf_chest_sort_auto_restored", "Automatic sorting restored." }, { "hf_chest_intake_section", "Settlement intake roles" }, { "hf_chest_intake_desc", "Choose which workers use this physical chest. A chest may serve several roles; Caretakers sort every assigned intake chest regardless of these toggles." }, { "hf_chest_intake_no_hearth", "No hearth you own is connected to this chest." }, { "hf_chest_intake_current", "This is an assigned intake chest." }, { "hf_chest_intake_available", "This chest is not currently assigned." }, { "hf_chest_intake_set", "Use as intake chest" }, { "hf_chest_intake_all", "All worker roles" }, { "hf_chest_intake_remove", "Remove intake" }, { "hf_chest_intake_saved", "Settlement intake roles updated." }, { "hf_status_need_pick", "Needs a usable pickaxe" }, { "hf_status_need_better_pick", "Needs a better pickaxe for the rocks in the area" }, { "hf_status_no_rock", "No rock in the work area" }, { "hf_status_move_rock", "Heading to a rock" }, { "hf_status_mining", "Mining the rock" }, { "hf_status_collect_ore", "Collecting the ore" }, { "hf_f_beech", "Beech" }, { "hf_f_fir", "Fir" }, { "hf_f_pine", "Pine" }, { "hf_f_birch", "Birch" }, { "hf_f_oak", "Oak" }, { "hf_f_swamp", "Swamp" }, { "hf_f_ygga", "Yggdrasil" }, { "hf_f_ashtree", "Ashlands" }, { "hf_f_stone", "Stone" }, { "hf_f_copper", "Copper" }, { "hf_f_tin", "Tin" }, { "hf_f_silver", "Silver" }, { "hf_f_obsidian", "Obsidian" }, { "hf_f_iron", "Iron" }, { "hf_f_flametal", "Flametal" }, { "hf_change_role", "Change assignment" }, { "hf_inventory", "Inventory and equipment" }, { "hf_assign_storage", "Assign storage" }, { "hf_need_coins", "You need {0} coins." }, { "hf_recruited", "{0} joined your settlement." }, { "hf_recruit_failed", "Recruitment failed: no resources spent." }, { "hf_prefab_missing", "Hearthfolk: settler prefab unavailable." }, { "hf_not_owner", "You are not the owner of this settler." }, { "hf_storage_set", "Storage assigned." }, { "hf_storage_cleared", "Storage cleared." }, { "hf_status_idle", "Awaiting orders" }, { "hf_status_need_axe", "Needs a usable axe" }, { "hf_status_need_weapon", "Needs a weapon" }, { "hf_status_no_tree", "No tree in the work area" }, { "hf_status_need_better_axe", "Needs a better axe for the trees in the area" }, { "hf_status_move_tree", "Heading to a tree" }, { "hf_status_chopping", "Chopping a tree" }, { "hf_status_guarding", "Guarding the hearth" }, { "hf_status_to_storage", "Hauling resources to storage" }, { "hf_status_deposit", "Depositing resources" }, { "hf_status_inv_full", "Inventory full" }, { "hf_status_no_storage", "No storage assigned" }, { "hf_status_storage_unreachable", "Assigned storage is unreachable" }, { "hf_status_returning", "Returning to the hearth" }, { "hf_status_collect", "Collecting wood" }, { "hf_status_need_bed", "Needs an available Settler Tent near the hearth" }, { "hf_status_rest", "Resting until morning" }, { "hf_status_leaving_tent", "Leaving the tent after waking" }, { "hf_status_respawning", "Returning at the hearth in {0}" }, { "hf_status_respawned", "Returned at the hearth" }, { "hf_status_dead", "Dead" }, { "hf_status_fetch_food", "Fetching food from storage" }, { "hf_status_no_food", "Cannot find food in the chests" }, { "hf_status_find_seat", "Looking for a place to eat" }, { "hf_status_find_rest", "Looking for a free place to rest" }, { "hf_status_resting", "Resting while waiting for work" }, { "hf_status_sawmill_approach", "Going to the sawmill" }, { "hf_status_sawmill_work", "Working at the sawmill" }, { "hf_status_mine_approach", "Going to the mine" }, { "hf_status_mine_work", "Working in the mine" }, { "hf_status_workstation_unavailable", "The assigned building is unavailable" }, { "hf_status_patrolling", "Patrolling the hearth route" }, { "hf_status_follower_available", "Waiting at the hearth for a player" }, { "hf_status_follower_following", "Following the player" }, { "hf_status_follower_catching_up", "Catching up with the player" }, { "hf_status_follower_waiting", "Waiting here" }, { "hf_status_follower_waiting_for_player", "Waiting for the player to load" }, { "hf_status_follower_returning", "Returning to the hearth" }, { "hf_status_follower_defending", "Defending the player" }, { "hf_status_follower_eating_meal", "Eating a meal during the journey" }, { "hf_status_follower_eating_food", "Eating food to recover health" }, { "hf_status_eating_dinner", "Eating dinner before bed" }, { "hf_status_eating_breakfast", "Eating breakfast before work" }, { "hf_status_woke_healthy", "Woke up completely rested" }, { "hf_status_repair", "Repairing tools at the workbench" }, { "hf_no_chest", "No chest near the hearth." }, { "hf_panel_work_radius", "Hearth radius" }, { "hf_panel_banner_radius", "Banner radius" }, { "hf_panel_respawn_minutes", "Settler respawn (minutes)" }, { "hf_panel_meal_minutes", "Meal duration (minutes)" }, { "hf_panel_desertion", "Desertion from unhappiness" }, { "hf_panel_desertion_days", "Miserable days before leaving" }, { "hf_panel_happiness", "Happiness: {0}/100" }, { "hf_enabled", "Enabled" }, { "hf_disabled", "Disabled" }, { "hf_panel_settlers", "Settlers: {0}" }, { "hf_panel_tab_settlers", "Settlers" }, { "hf_panel_tab_settings", "Settings" }, { "hf_panel_alert_enable", "Alert: to arms" }, { "hf_panel_alert_disable", "End alert" }, { "hf_panel_raid_active", "Raid: defending settlement" }, { "hf_panel_attack_active", "Settlement under attack" }, { "hf_panel_residents", "Residents" }, { "hf_panel_select_settler", "Select a settler from the list." }, { "hf_panel_current_activity", "Current activity" }, { "hf_panel_morale_section", "Well-being" }, { "hf_panel_role_section", "Assignment" }, { "hf_panel_appearance_section", "Appearance" }, { "hf_panel_appearance_customize", "Customize appearance" }, { "hf_panel_appearance_hide", "Hide appearance controls" }, { "hf_panel_appearance_desc", "Uses Valheim's native character styles. Changes are saved, synchronized and preserved after respawn." }, { "hf_appearance_preview_unavailable", "Preview unavailable" }, { "hf_appearance_name", "Resident name" }, { "hf_appearance_name_apply", "Rename" }, { "hf_appearance_name_invalid", "Enter a valid name." }, { "hf_appearance_name_in_use", "Another resident already uses that name." }, { "hf_appearance_body", "Body type" }, { "hf_appearance_hair", "Hair" }, { "hf_appearance_beard", "Beard" }, { "hf_appearance_hair_color", "Hair colour" }, { "hf_appearance_skin_tone", "Skin tone" }, { "hf_appearance_randomize", "Randomize appearance" }, { "hf_panel_follower_section", "Follower commands" }, { "hf_panel_follower_desc", "Any player may use Crouch+Use on this settler to make them follow or wait. Multiple followers keep separate formation positions. Followers eat from their own inventory and do not need sleep." }, { "hf_follower_target_none", "Available at the hearth" }, { "hf_follower_target_following", "Following: {0}" }, { "hf_follower_target_waiting", "Waiting for: {0}" }, { "hf_follower_follow_me", "Follow me" }, { "hf_follower_wait_here", "Wait here" }, { "hf_follower_recall", "Recall to hearth" }, { "hf_follower_combat_mode", "Combat stance" }, { "hf_follower_combat_defensive", "Defensive" }, { "hf_follower_combat_aggressive", "Aggressive" }, { "hf_follower_combat_passive", "Passive" }, { "hf_follower_combat_defensive_desc", "Engages enemies threatening the follower or the followed player." }, { "hf_follower_combat_aggressive_desc", "Proactively engages enemies within 30 metres." }, { "hf_follower_combat_passive_desc", "Never enters combat and keeps following or waiting." }, { "hf_panel_storage_section", "Settlement intake" }, { "hf_panel_storage_assign_hint", "Choose the exact chest with Ctrl+Use on the physical chest, then select “Use as intake chest”." }, { "hf_panel_filters_section", "Allowed materials" }, { "hf_panel_farmer_settings_section", "Farmer settings" }, { "hf_panel_farmer_mode_section", "Work mode" }, { "hf_farmer_mode_full", "Full cycle" }, { "hf_farmer_mode_plant", "Plant only" }, { "hf_farmer_mode_harvest", "Harvest only" }, { "hf_panel_farmer_fields_section", "Assigned fields" }, { "hf_farmer_fields_all", "All connected fields" }, { "hf_farmer_fields_custom", "Custom field assignment" }, { "hf_farmer_fields_use_all", "Use all" }, { "hf_farmer_fields_use_none", "Clear all" }, { "hf_farmer_fields_none", "No connected Farm Markers are available." }, { "hf_farmer_field_label", "Field {0}: {1} ({2} m)" }, { "hf_panel_farmer_crops_section", "Allowed crops" }, { "hf_panel_farmer_targets_section", "Stock targets" }, { "hf_panel_farmer_targets_hint", "Optional. At zero the Farmer plants without a stock limit; otherwise growing crops and stored harvest count toward the target." }, { "hf_farmer_target_unlimited", "No limit" }, { "hf_panel_caretaker_tasks_section", "Allowed caretaker tasks" }, { "hf_caretaker_task_repair", "Repair structures" }, { "hf_caretaker_task_sort", "Sort storage" }, { "hf_caretaker_task_fires", "Fuel fires" }, { "hf_caretaker_task_machine_fuel", "Fuel machines" }, { "hf_caretaker_task_machine_input", "Load machines" }, { "hf_caretaker_task_outputs", "Collect outputs" }, { "hf_panel_danger_section", "Resident management" }, { "hf_panel_dismiss_desc", "Dismissal requires an empty inventory and releases the bed and storage." }, { "hf_panel_settings_work", "Work area" }, { "hf_panel_settings_movement", "Movement" }, { "hf_gateway_available", "Detected doors and gates: {0}" }, { "hf_gateway_mode_automatic", "Settlement entrances: automatic detection" }, { "hf_gateway_mode_manual", "Settlement entrances: configured" }, { "hf_gateway_editor_open", "Configure entrances" }, { "hf_gateway_editor_title", "Settlement entrance editor" }, { "hf_gateway_editor_desc", "Select the perimeter doors or gates residents should prefer when entering or leaving the settlement. Interior doors remain available for houses, beds and indoor storage." }, { "hf_gateway_editor_count", "Detected: {0} · Selected: {1}" }, { "hf_gateway_use_automatic", "Use automatic detection" }, { "hf_gateway_save", "Save entrances" }, { "hf_panel_settings_needs", "Routine and happiness" }, { "hf_panel_social_rest", "Idle social conversations" }, { "hf_panel_social_chance", "Socialization chance (%)" }, { "hf_panel_social_duration", "Conversation duration (seconds)" }, { "hf_panel_social_bonus", "Daily social happiness bonus" }, { "hf_panel_settings_lifecycle", "Death and respawn" }, { "hf_panel_settings_production", "Production buildings" }, { "hf_panel_settings_guards", "Guards and patrols" }, { "hf_panel_patrol_radius", "Patrol point radius" }, { "hf_panel_settings_farming", "Farming" }, { "hf_panel_farm_radius", "Farm Marker radius" }, { "hf_panel_farm_max_range", "Maximum marker distance" }, { "hf_panel_farm_seed_reserve", "Planting-resource reserve" }, { "hf_panel_farm_markers", "Connected Farm Markers: {0}" }, { "hf_hearth_patrol_count", "Points in the current route: {0}" }, { "hf_hearth_patrol_available", "Available patrol points: {0}" }, { "hf_patrol_editor_open", "Edit patrol route" }, { "hf_patrol_editor_title", "Patrol route editor" }, { "hf_patrol_editor_open_guard", "Configure this guard's route" }, { "hf_patrol_editor_guard_title", "{0} — patrol route" }, { "hf_patrol_per_guard_hint", "Select a guard in the Residents tab to configure their individual route." }, { "hf_patrol_editor_desc", "Select this guard's patrol points in visit order. Click a selected point to remove it; drag the map to pan and use the mouse wheel to zoom." }, { "hf_patrol_editor_back", "Back" }, { "hf_patrol_editor_count", "Available: {0} · Selected: {1}" }, { "hf_patrol_mode_automatic", "Automatic clockwise order" }, { "hf_patrol_mode_manual", "Manual route" }, { "hf_patrol_zoom", "Zoom" }, { "hf_patrol_undo", "Undo last" }, { "hf_patrol_clear", "Clear selection" }, { "hf_patrol_use_automatic", "Use automatic order" }, { "hf_patrol_save", "Save route" }, { "hf_patrol_saved", "Saved" }, { "hf_guard_schedule", "Guard shift" }, { "hf_guard_schedule_desc", "Off duty, the guard rests seated by day and sleeps at night. A settlement alert always puts them on duty." }, { "hf_panel_production_amount", "Materials per cycle and settler" }, { "hf_panel_production_minutes", "Cycle duration (minutes)" }, { "hf_panel_production_workers", "Maximum settlers per building" }, { "hf_panel_production_unloaded", "Production while zone is unloaded" }, { "hf_panel_production_catchup", "Maximum catch-up (hours)" }, { "hf_panel_production_offline_percent", "Unloaded time counted as work (%)" }, { "hf_building_workers", "Assigned settlers" }, { "hf_building_rate", "Production: {0} materials every {1} minutes per settler" }, { "hf_building_output", "Selected resource: {0}" }, { "hf_building_paused_alert", "Production paused: settlement alert is active." }, { "hf_barracks_summary", "Assigned guards use this barracks as their post. During an alert every settler rallies here." }, { "hf_barracks_patrol_count", "Route points: {0}" }, { "hf_barracks_shift", "Shift" }, { "hf_barracks_on_shift", "On duty" }, { "hf_barracks_off_shift", "Off duty" }, { "hf_building_choose_output", "Resource to produce" }, { "hf_building_unlock_hint", "Only previously discovered resources can be selected." }, { "hf_building_assign_workers", "Worker management" }, { "hf_building_no_settlers", "No settlers belonging to a nearby hearth." }, { "hf_building_assigned_elsewhere", "Assigned to another building" }, { "hf_building_assign_worker", "Assign" }, { "hf_building_remove_worker", "Remove" }, { "hf_panel_recruit", "Recruit a settler ({0} coins)" }, { "hf_panel_empty", "No settlers yet. Recruit one!" }, { "hf_panel_storage_set", "Intake chest: assigned" }, { "hf_panel_storage_unset", "Intake chest: none" }, { "hf_panel_assign_storage_short", "Assign nearby chest" }, { "hf_panel_dismiss", "Dismiss" }, { "hf_panel_dismiss_confirm", "Confirm dismissal" }, { "hf_dismiss_not_empty", "Empty the settler's inventory first." }, { "hf_mood_very_happy", "Very happy" }, { "hf_mood_happy", "Happy" }, { "hf_mood_neutral", "Neutral" }, { "hf_mood_unhappy", "Unhappy" }, { "hf_mood_miserable", "Miserable" }, { "hf_reason_new_home", "Settling into the new home" }, { "hf_reason_socialized", "Enjoyed some company" }, { "hf_reason_rested", "Slept well" }, { "hf_reason_missed_sleep", "Did not sleep enough" }, { "hf_reason_no_bed", "Has no bed" }, { "hf_reason_had_dinner", "Ate dinner" }, { "hf_reason_missed_dinner", "Missed dinner" }, { "hf_reason_had_breakfast", "Ate breakfast" }, { "hf_reason_missed_breakfast", "Missed breakfast" }, { "hf_reason_sat_to_eat", "Ate while seated" }, { "hf_reason_social_meal", "Shared a meal" }, { "hf_reason_threatened", "The settlement was threatened" }, { "hf_reason_safe", "Feels safe" }, { "hf_reason_comfortable", "Has a lit hearth under a roof" }, { "hf_reason_equipped", "Has suitable equipment" }, { "hf_reason_unequipped", "Lacks suitable equipment" }, { "hf_morale_warning", "{0} is unhappy ({1}/100). Check their needs." }, { "hf_morale_critical", "{0} is miserable ({1}/100) and may leave in {2} days." }, { "hf_settler_left", "{0} left the settlement. Their inventory remains at the hearth." }, { "hf_panel_hints", "Use on a settler: inventory · Ctrl+Use on a chest: sorting and settlement intake" }, { "hf_panel_close", "Close" }, { "hf_manage", "Manage the settlement" } }; string text = "English"; localization.AddTranslation(ref text, dictionary); text = "Italian"; localization.AddTranslation(ref text, new Dictionary(dictionary)); } } internal sealed class HearthInteractionProxy : MonoBehaviour, Hoverable, Interactable { private ExilesHearth Hearth => ((Component)this).GetComponentInParent(); public string GetHoverName() { if (!((Object)(object)Hearth != (Object)null)) { return string.Empty; } return Hearth.GetHoverName(); } public string GetHoverText() { if (!((Object)(object)Hearth != (Object)null)) { return string.Empty; } return Hearth.GetHoverText(); } public bool Interact(Humanoid user, bool hold, bool alt) { if ((Object)(object)Hearth != (Object)null) { return Hearth.Interact(user, hold, alt); } return false; } public bool UseItem(Humanoid user, ItemData item) { return false; } } internal sealed class HearthPanel : MonoBehaviour { private const float PreferredWidth = 980f; private const float PreferredHeight = 760f; private const float MinimumWidth = 600f; private const float MinimumHeight = 540f; private const float SettlerListWidth = 300f; private const float MaxUseDistance = 10f; private const float HearthMembershipRadius = 6f; private static HearthPanel _instance; private ExilesHearth _hearth; private Rect _rect; private Vector2 _scroll; private Vector2 _detailScroll; private Vector2 _settingsScroll; private int _activeTab; private ZDOID _selectedSettler = ZDOID.None; private ZDOID _dismissCandidate = ZDOID.None; private float _dismissConfirmUntil; private bool _showAppearance; private ZDOID _renameTarget = ZDOID.None; private string _renameDraft = string.Empty; private Camera _appearancePreviewCamera; private RenderTexture _appearancePreviewTexture; private bool _appearancePreviewFailed; private bool _patrolEditorOpen; private ZDOID _patrolEditorHearth = ZDOID.None; private ZDOID _patrolEditorGuard = ZDOID.None; private readonly List _patrolDraft = new List(); private float _patrolMapZoom = 1f; private Vector2 _patrolMapPan; private bool _patrolMapDragging; private float _patrolSavedUntil; private bool _gatewayEditorOpen; private ZDOID _gatewayEditorHearth = ZDOID.None; private readonly List _gatewayDraft = new List(); private float _gatewaySavedUntil; private static readonly (SettlerFlags flag, string key)[] TreeFilters = new(SettlerFlags, string)[8] { (SettlerFlags.Beech, "$hf_f_beech"), (SettlerFlags.Fir, "$hf_f_fir"), (SettlerFlags.Pine, "$hf_f_pine"), (SettlerFlags.Birch, "$hf_f_birch"), (SettlerFlags.Oak, "$hf_f_oak"), (SettlerFlags.Swamp, "$hf_f_swamp"), (SettlerFlags.Yggdrasil, "$hf_f_ygga"), (SettlerFlags.AshTree, "$hf_f_ashtree") }; private static readonly (SettlerFlags flag, string key)[] RockFilters = new(SettlerFlags, string)[7] { (SettlerFlags.Stone, "$hf_f_stone"), (SettlerFlags.Copper, "$hf_f_copper"), (SettlerFlags.Tin, "$hf_f_tin"), (SettlerFlags.Silver, "$hf_f_silver"), (SettlerFlags.Obsidian, "$hf_f_obsidian"), (SettlerFlags.Iron, "$hf_f_iron"), (SettlerFlags.Flametal, "$hf_f_flametal") }; private static readonly (CaretakerTasks task, string key)[] CaretakerTaskFilters = new(CaretakerTasks, string)[6] { (CaretakerTasks.RepairStructures, "$hf_caretaker_task_repair"), (CaretakerTasks.SortStorage, "$hf_caretaker_task_sort"), (CaretakerTasks.FuelFires, "$hf_caretaker_task_fires"), (CaretakerTasks.FuelMachines, "$hf_caretaker_task_machine_fuel"), (CaretakerTasks.LoadMachines, "$hf_caretaker_task_machine_input"), (CaretakerTasks.CollectOutputs, "$hf_caretaker_task_outputs") }; internal static void Toggle(ExilesHearth hearth) { if ((Object)(object)_instance == (Object)null) { GameObject val = (((Object)(object)HearthfolkPlugin.Instance != (Object)null) ? ((Component)HearthfolkPlugin.Instance).gameObject : null); if ((Object)(object)val == (Object)null) { return; } _instance = val.AddComponent(); } if ((Object)(object)_instance._hearth == (Object)(object)hearth) { _instance.Close(); } else { _instance.Open(hearth); } } private void Open(ExilesHearth hearth) { //IL_0068: 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_0078: 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_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: 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_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) _hearth = hearth; float num = Mathf.Max(600f, Mathf.Min(980f, (float)Screen.width - 40f)); float num2 = Mathf.Max(540f, Mathf.Min(760f, (float)Screen.height - 40f)); _rect = new Rect(((float)Screen.width - num) / 2f, ((float)Screen.height - num2) / 2f, num, num2); _scroll = Vector2.zero; _detailScroll = Vector2.zero; _settingsScroll = Vector2.zero; _activeTab = 0; _selectedSettler = ZDOID.None; _showAppearance = false; _renameTarget = ZDOID.None; _renameDraft = string.Empty; _patrolEditorOpen = false; _patrolEditorHearth = ZDOID.None; _patrolEditorGuard = ZDOID.None; _patrolDraft.Clear(); _gatewayEditorOpen = false; _gatewayEditorHearth = ZDOID.None; _gatewayDraft.Clear(); _patrolMapZoom = 1f; _patrolMapPan = Vector2.zero; GUIManager.BlockInput(true); } private void Close() { _hearth = null; DestroyAppearancePreview(); GUIManager.BlockInput(false); } private void OnDestroy() { DestroyAppearancePreview(); } private void Update() { //IL_0032: 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) if (!((Object)(object)_hearth == (Object)null)) { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || (Object)(object)_hearth == (Object)null || Vector3.Distance(((Component)localPlayer).transform.position, ((Component)_hearth).transform.position) > 10f || Input.GetKeyDown((KeyCode)27)) { Close(); return; } Cursor.lockState = (CursorLockMode)0; Cursor.visible = true; } } private void OnGUI() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Expected O, but got Unknown //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_hearth == (Object)null)) { GUISkin skin = GUI.skin; GUI.skin = HfGuiSkin.Get(); _rect = GUILayout.Window(((Object)this).GetInstanceID(), _rect, new WindowFunction(DrawWindow), Localization.instance.Localize("$piece_hf_hearth"), Array.Empty()); GUI.skin = skin; } } private void DrawWindow(int id) { //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) ExilesHearth hearth = _hearth; if ((Object)(object)hearth == (Object)null) { return; } List list = CollectSettlers(hearth); List list2 = CollectDormantSettlers(hearth, list); EnsureSelection(list, list2); DrawHeader(hearth, list.Count + list2.Count); if (_gatewayEditorOpen) { DrawGatewayEditor(hearth); DrawFooter(); GUI.DragWindow(new Rect(0f, 0f, 10000f, 20f)); return; } if (_patrolEditorOpen) { DrawPatrolRouteEditor(hearth); DrawFooter(); GUI.DragWindow(new Rect(0f, 0f, 10000f, 20f)); return; } DrawTabs(); GUILayout.Space(8f); if (_activeTab == 0) { DrawSettlersView(list, list2); } else { DrawSettingsView(); } DrawFooter(); GUI.DragWindow(new Rect(0f, 0f, 10000f, 20f)); } private void DrawHeader(ExilesHearth hearth, int count) { GUILayout.BeginHorizontal(Array.Empty()); GUILayout.Label(Format("$hf_panel_settlers", count), HfGuiSkin.SectionTitle, Array.Empty()); GUILayout.FlexibleSpace(); bool raidActive = hearth.RaidActive; bool defenseThreatActive = hearth.DefenseThreatActive; bool flag = raidActive || defenseThreatActive; string text = (raidActive ? "$hf_panel_raid_active" : (defenseThreatActive ? "$hf_panel_attack_active" : (hearth.AlertActive ? "$hf_panel_alert_disable" : "$hf_panel_alert_enable"))); bool enabled = GUI.enabled; GUI.enabled = !flag; if (GUILayout.Button(Localization.instance.Localize(text), (flag || hearth.AlertActive) ? HfGuiSkin.DangerButton : GUI.skin.button, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(210f) })) { hearth.RequestToggleAlert(); } GUI.enabled = enabled; GUILayout.Space(8f); if (GUILayout.Button(Format("$hf_panel_recruit", hearth.RecruitCost), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(240f) })) { hearth.Recruit(Player.m_localPlayer); } GUILayout.EndHorizontal(); } private void DrawTabs() { GUILayout.BeginHorizontal(Array.Empty()); DrawTabButton(0, "$hf_panel_tab_settlers"); DrawTabButton(1, "$hf_panel_tab_settings"); GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); } private void DrawTabButton(int tab, string labelKey) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_001e: 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) Color backgroundColor = GUI.backgroundColor; if (_activeTab == tab) { GUI.backgroundColor = new Color(1.8f, 1.45f, 0.65f); } if (GUILayout.Button(Localization.instance.Localize(labelKey), HfGuiSkin.TabButton, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(170f) })) { _activeTab = tab; } GUI.backgroundColor = backgroundColor; } private void DrawSettlersView(List settlers, List dormantSettlers) { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0051: 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_0148: Unknown result type (might be due to invalid IL or missing references) //IL_0152: 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) GUILayout.BeginHorizontal(Array.Empty()); GUILayout.BeginVertical((GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(300f) }); GUILayout.Label(Localization.instance.Localize("$hf_panel_residents"), HfGuiSkin.SectionTitle, Array.Empty()); _scroll = GUILayout.BeginScrollView(_scroll, GUI.skin.box); if (settlers.Count == 0 && dormantSettlers.Count == 0) { GUILayout.Label(Localization.instance.Localize("$hf_panel_empty"), HfGuiSkin.MutedLabel, Array.Empty()); } foreach (DormantSettlerRegistry.Record dormantSettler in dormantSettlers) { DrawDormantSettlerCard(dormantSettler); GUILayout.Space(5f); } foreach (SettlerController settler in settlers) { DrawSettlerCard(settler); GUILayout.Space(5f); } GUILayout.EndScrollView(); GUILayout.EndVertical(); GUILayout.Space(10f); GUILayout.BeginVertical(Array.Empty()); SettlerController settlerController = settlers.Find((SettlerController s) => s.PersistentId == _selectedSettler); DormantSettlerRegistry.Record record = dormantSettlers.Find((DormantSettlerRegistry.Record s) => s.Id == _selectedSettler); _detailScroll = GUILayout.BeginScrollView(_detailScroll, Array.Empty()); if ((Object)(object)settlerController != (Object)null) { DrawSettlerDetails(settlerController); } else if (record != null) { DrawDormantSettlerDetails(record); } else { GUILayout.FlexibleSpace(); GUILayout.Label(Localization.instance.Localize("$hf_panel_select_settler"), HfGuiSkin.MutedLabel, Array.Empty()); GUILayout.FlexibleSpace(); } GUILayout.EndScrollView(); GUILayout.EndVertical(); GUILayout.EndHorizontal(); } private void DrawSettlerCard(SettlerController settler) { //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) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0066: 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_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0206: Unknown result type (might be due to invalid IL or missing references) //IL_01f1: Unknown result type (might be due to invalid IL or missing references) //IL_01f6: Unknown result type (might be due to invalid IL or missing references) //IL_01fc: Unknown result type (might be due to invalid IL or missing references) //IL_0201: Unknown result type (might be due to invalid IL or missing references) bool flag = settler.PersistentId == _selectedSettler; Color backgroundColor = GUI.backgroundColor; if (settler.IsRespawning) { GUI.backgroundColor = (flag ? new Color(1.55f, 0.58f, 0.38f) : new Color(1.15f, 0.42f, 0.32f)); } else if (flag) { GUI.backgroundColor = new Color(1.75f, 1.4f, 0.65f); } if (settler.IsRespawning) { if (GUILayout.Button(settler.PanelName + "\n" + Localization.instance.Localize("$hf_status_dead") + " · " + SettlerController.RoleLabel(settler.CurrentRole) + "\n" + settler.RespawnStatusText, HfGuiSkin.CardButton, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(76f) })) { _selectedSettler = settler.PersistentId; _detailScroll = Vector2.zero; } GUI.backgroundColor = backgroundColor; return; } string arg = ((settler.CurrentRole != SettlerRole.Follower) ? Localization.instance.Localize(settler.HasStorage ? "$hf_panel_storage_set" : "$hf_panel_storage_unset") : (string.IsNullOrEmpty(settler.FollowerTargetName) ? Localization.instance.Localize("$hf_follower_target_none") : string.Format(Localization.instance.Localize((settler.CurrentFollowerMode == FollowerMode.Waiting) ? "$hf_follower_target_waiting" : "$hf_follower_target_following"), settler.FollowerTargetName))); if (GUILayout.Button(settler.PanelName + "\n" + SettlerController.RoleLabel(settler.CurrentRole) + " · " + $"{settler.MoodLabel} ({settler.Happiness}/100)\n{arg}", HfGuiSkin.CardButton, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(76f) })) { _selectedSettler = settler.PersistentId; _detailScroll = Vector2.zero; } GUI.backgroundColor = backgroundColor; } private void DrawDormantSettlerCard(DormantSettlerRegistry.Record settler) { //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) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) bool num = settler.Id == _selectedSettler; Color backgroundColor = GUI.backgroundColor; GUI.backgroundColor = (num ? new Color(1.55f, 0.58f, 0.38f) : new Color(1.15f, 0.42f, 0.32f)); if (GUILayout.Button(settler.Name + "\n" + Localization.instance.Localize("$hf_status_dead") + " · " + SettlerController.RoleLabel(settler.Role) + "\n" + settler.StatusText, HfGuiSkin.CardButton, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(76f) })) { _selectedSettler = settler.Id; _detailScroll = Vector2.zero; } GUI.backgroundColor = backgroundColor; } private void DrawSettlerDetails(SettlerController settler) { GUILayout.BeginHorizontal(Array.Empty()); GUILayout.Label(settler.PanelName, HfGuiSkin.SectionTitle, Array.Empty()); GUILayout.FlexibleSpace(); GUILayout.Label(SettlerController.RoleLabel(settler.CurrentRole), HfGuiSkin.MutedLabel, Array.Empty()); GUILayout.EndHorizontal(); if (settler.IsRespawning) { DrawDeadStatus(settler.RespawnStatusText); return; } GUILayout.BeginVertical(GUI.skin.box, Array.Empty()); GUILayout.Label(Localization.instance.Localize("$hf_panel_current_activity"), HfGuiSkin.CardTitle, Array.Empty()); string currentStatusText = settler.CurrentStatusText; GUILayout.Label(string.IsNullOrEmpty(currentStatusText) ? "—" : currentStatusText, Array.Empty()); GUILayout.EndVertical(); GUILayout.Space(6f); GUILayout.Label(Localization.instance.Localize("$hf_panel_morale_section"), HfGuiSkin.CardTitle, Array.Empty()); DrawHappinessBar(settler); string moraleReasonsText = settler.MoraleReasonsText; if (!string.IsNullOrEmpty(moraleReasonsText)) { GUILayout.Label(moraleReasonsText, HfGuiSkin.MutedLabel, Array.Empty()); } bool enabled = GUI.enabled; GUI.enabled = !settler.IsRespawning; DrawRoleSection(settler); DrawAppearanceSection(settler); if (settler.CurrentRole == SettlerRole.Follower) { DrawFollowerSection(settler); } else { DrawStorageSection(settler); } DrawFlagRow(settler); if (settler.CurrentRole == SettlerRole.Guard) { DrawGuardSchedule(settler); } GUI.enabled = enabled; DrawDismissSection(settler); } private static void DrawDormantSettlerDetails(DormantSettlerRegistry.Record settler) { GUILayout.BeginHorizontal(Array.Empty()); GUILayout.Label(settler.Name, HfGuiSkin.SectionTitle, Array.Empty()); GUILayout.FlexibleSpace(); GUILayout.Label(SettlerController.RoleLabel(settler.Role), HfGuiSkin.MutedLabel, Array.Empty()); GUILayout.EndHorizontal(); DrawDeadStatus(settler.StatusText); } private static void DrawDeadStatus(string countdown) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) GUILayout.Space(8f); Color backgroundColor = GUI.backgroundColor; GUI.backgroundColor = new Color(1.1f, 0.38f, 0.28f); GUILayout.BeginVertical(GUI.skin.box, Array.Empty()); GUI.backgroundColor = backgroundColor; GUILayout.Label(Localization.instance.Localize("$hf_status_dead"), HfGuiSkin.SectionTitle, Array.Empty()); GUILayout.Space(4f); GUILayout.Label(countdown, HfGuiSkin.CardTitle, Array.Empty()); GUILayout.EndVertical(); } private static void DrawHappinessBar(SettlerController settler) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0038: 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_00a0: 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_0109: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) Rect rect = GUILayoutUtility.GetRect(100f, 22f, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) }); Color color = GUI.color; GUI.color = new Color(0.12f, 0.1f, 0.08f, 0.9f); GUI.DrawTexture(rect, (Texture)(object)Texture2D.whiteTexture); float num = Mathf.Clamp01((float)settler.Happiness / 100f); Rect val = new Rect(((Rect)(ref rect)).x + 2f, ((Rect)(ref rect)).y + 2f, Mathf.Max(0f, (((Rect)(ref rect)).width - 4f) * num), ((Rect)(ref rect)).height - 4f); GUI.color = ((num >= 0.7f) ? new Color(0.42f, 0.72f, 0.28f) : ((num >= 0.4f) ? new Color(0.88f, 0.65f, 0.2f) : new Color(0.78f, 0.25f, 0.18f))); GUI.DrawTexture(val, (Texture)(object)Texture2D.whiteTexture); GUI.color = color; GUI.Label(rect, $"{settler.Happiness}/100 — {settler.MoodLabel}", HfGuiSkin.CenteredSmall); } private static void DrawRoleSection(SettlerController settler) { GUILayout.Space(8f); GUILayout.Label(Localization.instance.Localize("$hf_panel_role_section"), HfGuiSkin.CardTitle, Array.Empty()); GUILayout.BeginHorizontal(Array.Empty()); DrawRoleButton(settler, SettlerRole.Idle); DrawRoleButton(settler, SettlerRole.Lumberjack); DrawRoleButton(settler, SettlerRole.Miner); DrawRoleButton(settler, SettlerRole.Guard); DrawRoleButton(settler, SettlerRole.Caretaker); DrawRoleButton(settler, SettlerRole.Follower); DrawRoleButton(settler, SettlerRole.Farmer); GUILayout.EndHorizontal(); } private void DrawAppearanceSection(SettlerController settler) { //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) GUILayout.Space(8f); string text = (_showAppearance ? "$hf_panel_appearance_hide" : "$hf_panel_appearance_customize"); if (GUILayout.Button(Localization.instance.Localize(text), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(32f) })) { _showAppearance = !_showAppearance; if (!_showAppearance) { DestroyAppearancePreview(); } } if (_showAppearance) { GUILayout.BeginVertical(GUI.skin.box, Array.Empty()); GUILayout.Label(Localization.instance.Localize("$hf_panel_appearance_section"), HfGuiSkin.CardTitle, Array.Empty()); GUILayout.Label(Localization.instance.Localize("$hf_panel_appearance_desc"), HfGuiSkin.MutedLabel, Array.Empty()); GUILayout.BeginHorizontal(Array.Empty()); DrawAppearancePreview(settler); GUILayout.Space(10f); GUILayout.BeginVertical(Array.Empty()); if (_renameTarget != settler.PersistentId) { _renameTarget = settler.PersistentId; _renameDraft = settler.PanelName; } GUILayout.Label(Localization.instance.Localize("$hf_appearance_name"), Array.Empty()); GUILayout.BeginHorizontal(Array.Empty()); _renameDraft = GUILayout.TextField(_renameDraft ?? string.Empty, 24, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(190f) }); if (GUILayout.Button(Localization.instance.Localize("$hf_appearance_name_apply"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(90f) })) { settler.RequestRename(_renameDraft); GUI.FocusControl((string)null); } GUILayout.EndHorizontal(); DrawAppearanceRow("$hf_appearance_body", settler.AppearanceBodyLabel, delegate(int direction) { settler.RequestCycleAppearance(SettlerAppearanceField.Body, direction); }); DrawAppearanceRow("$hf_appearance_hair", settler.AppearanceHairLabel, delegate(int direction) { settler.RequestCycleAppearance(SettlerAppearanceField.Hair, direction); }); bool enabled = GUI.enabled; GUI.enabled = enabled && settler.AppearanceSupportsBeard; DrawAppearanceRow("$hf_appearance_beard", settler.AppearanceBeardLabel, delegate(int direction) { settler.RequestCycleAppearance(SettlerAppearanceField.Beard, direction); }); GUI.enabled = enabled; DrawAppearanceRow("$hf_appearance_hair_color", settler.AppearanceHairColorLabel, delegate(int direction) { settler.RequestCycleAppearance(SettlerAppearanceField.HairColor, direction); }); DrawAppearanceRow("$hf_appearance_skin_tone", settler.AppearanceSkinToneLabel, delegate(int direction) { settler.RequestCycleAppearance(SettlerAppearanceField.SkinTone, direction); }); GUILayout.BeginHorizontal(Array.Empty()); GUILayout.FlexibleSpace(); if (GUILayout.Button(Localization.instance.Localize("$hf_appearance_randomize"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(180f) })) { settler.RequestCycleAppearance(SettlerAppearanceField.Randomize, 1); } GUILayout.EndHorizontal(); GUILayout.EndVertical(); GUILayout.EndHorizontal(); GUILayout.EndVertical(); } } private void DrawAppearancePreview(SettlerController settler) { //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_016e: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Invalid comparison between Unknown and I4 //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_006a: 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_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: 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_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) EnsureAppearancePreview(); if ((Object)(object)_appearancePreviewCamera != (Object)null && (Object)(object)_appearancePreviewTexture != (Object)null && !_appearancePreviewFailed && (int)Event.current.type == 7) { try { Transform transform = ((Component)settler).transform; Vector3 val = transform.forward; val.y = 0f; val = ((((Vector3)(ref val)).sqrMagnitude > 0.01f) ? ((Vector3)(ref val)).normalized : Vector3.forward); Vector3 val2 = transform.position + Vector3.up * 1.05f; Vector3 val3 = val2 + val * 3.6f + Vector3.up * 0.12f; ((Component)_appearancePreviewCamera).transform.position = val3; ((Component)_appearancePreviewCamera).transform.rotation = Quaternion.LookRotation(val2 - val3, Vector3.up); _appearancePreviewCamera.cullingMask = (((Object)(object)Camera.main != (Object)null) ? Camera.main.cullingMask : (-1)); _appearancePreviewCamera.Render(); } catch (Exception ex) { _appearancePreviewFailed = true; Diagnostics.Log("Hearthfolk[appearance]: preview disabled: " + ex.Message); } } Rect rect = GUILayoutUtility.GetRect(190f, 250f, (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.Width(190f), GUILayout.Height(250f) }); GUI.Box(rect, GUIContent.none); if ((Object)(object)_appearancePreviewTexture != (Object)null && !_appearancePreviewFailed) { GUI.DrawTexture(new Rect(((Rect)(ref rect)).x + 3f, ((Rect)(ref rect)).y + 3f, ((Rect)(ref rect)).width - 6f, ((Rect)(ref rect)).height - 6f), (Texture)(object)_appearancePreviewTexture, (ScaleMode)1, false); } else { GUI.Label(rect, Localization.instance.Localize("$hf_appearance_preview_unavailable"), HfGuiSkin.CenteredSmall); } } private void EnsureAppearancePreview() { //IL_0038: 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_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Expected O, but got Unknown //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Expected O, but got Unknown //IL_00ca: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_appearancePreviewCamera != (Object)null) || !((Object)(object)_appearancePreviewTexture != (Object)null)) { DestroyAppearancePreview(); _appearancePreviewFailed = false; _appearancePreviewTexture = new RenderTexture(380, 500, 16, (RenderTextureFormat)0) { name = "Hearthfolk appearance preview", hideFlags = (HideFlags)61, antiAliasing = 2 }; _appearancePreviewTexture.Create(); GameObject val = new GameObject("Hearthfolk appearance preview camera") { hideFlags = (HideFlags)61 }; _appearancePreviewCamera = val.AddComponent(); ((Behaviour)_appearancePreviewCamera).enabled = false; _appearancePreviewCamera.targetTexture = _appearancePreviewTexture; _appearancePreviewCamera.clearFlags = (CameraClearFlags)2; _appearancePreviewCamera.backgroundColor = new Color(0.08f, 0.07f, 0.055f, 1f); _appearancePreviewCamera.fieldOfView = 34f; _appearancePreviewCamera.nearClipPlane = 0.05f; _appearancePreviewCamera.farClipPlane = 14f; _appearancePreviewCamera.allowHDR = false; _appearancePreviewCamera.allowMSAA = true; } } private void DestroyAppearancePreview() { if ((Object)(object)_appearancePreviewCamera != (Object)null) { _appearancePreviewCamera.targetTexture = null; Object.Destroy((Object)(object)((Component)_appearancePreviewCamera).gameObject); _appearancePreviewCamera = null; } if ((Object)(object)_appearancePreviewTexture != (Object)null) { _appearancePreviewTexture.Release(); Object.Destroy((Object)(object)_appearancePreviewTexture); _appearancePreviewTexture = null; } } private static void DrawAppearanceRow(string labelKey, string value, Action change) { GUILayout.BeginHorizontal(Array.Empty()); GUILayout.Label(Localization.instance.Localize(labelKey), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(105f) }); if (GUILayout.Button("<", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(34f) })) { change(-1); } GUILayout.Label(value, HfGuiSkin.CenteredSmall, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(105f) }); if (GUILayout.Button(">", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(34f) })) { change(1); } GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); } private static void DrawFollowerSection(SettlerController settler) { GUILayout.Space(8f); GUILayout.Label(Localization.instance.Localize("$hf_panel_follower_section"), HfGuiSkin.CardTitle, Array.Empty()); GUILayout.BeginVertical(GUI.skin.box, Array.Empty()); GUILayout.Label(Localization.instance.Localize("$hf_panel_follower_desc"), HfGuiSkin.MutedLabel, Array.Empty()); string text = ((settler.CurrentFollowerMode == FollowerMode.Following && !string.IsNullOrEmpty(settler.FollowerTargetName)) ? string.Format(Localization.instance.Localize("$hf_follower_target_following"), settler.FollowerTargetName) : ((settler.CurrentFollowerMode != FollowerMode.Waiting || string.IsNullOrEmpty(settler.FollowerTargetName)) ? Localization.instance.Localize("$hf_follower_target_none") : string.Format(Localization.instance.Localize("$hf_follower_target_waiting"), settler.FollowerTargetName))); GUILayout.Label(text, Array.Empty()); DrawFollowerCombatModes(settler, showDescription: true); GUILayout.BeginHorizontal(Array.Empty()); GUILayout.FlexibleSpace(); if (GUILayout.Button(Localization.instance.Localize("$hf_follower_recall"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(190f) })) { settler.RequestFollowerReturnHome(); } GUILayout.EndHorizontal(); GUILayout.EndVertical(); } private static void DrawStorageSection(SettlerController settler) { GUILayout.Space(8f); GUILayout.Label(Localization.instance.Localize("$hf_panel_storage_section"), HfGuiSkin.CardTitle, Array.Empty()); GUILayout.BeginVertical(GUI.skin.box, Array.Empty()); GUILayout.Label(Localization.instance.Localize(settler.HasStorage ? "$hf_panel_storage_set" : "$hf_panel_storage_unset"), Array.Empty()); GUILayout.Label(Localization.instance.Localize("$hf_panel_storage_assign_hint"), HfGuiSkin.MutedLabel, Array.Empty()); GUILayout.EndVertical(); } private void DrawDismissSection(SettlerController settler) { //IL_006a: 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_0105: 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_012b: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) GUILayout.Space(12f); GUILayout.BeginVertical(GUI.skin.box, Array.Empty()); GUILayout.Label(Localization.instance.Localize("$hf_panel_danger_section"), HfGuiSkin.CardTitle, Array.Empty()); GUILayout.Label(Localization.instance.Localize("$hf_panel_dismiss_desc"), HfGuiSkin.MutedLabel, Array.Empty()); GUILayout.BeginHorizontal(Array.Empty()); GUILayout.FlexibleSpace(); bool flag = _dismissCandidate == settler.PersistentId && Time.realtimeSinceStartup <= _dismissConfirmUntil; bool enabled = GUI.enabled; GUI.enabled = !settler.IsRespawning; string text = (flag ? "$hf_panel_dismiss_confirm" : "$hf_panel_dismiss"); if (GUILayout.Button(Localization.instance.Localize(text), HfGuiSkin.DangerButton, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(180f) })) { if (!settler.CanDismiss) { Player localPlayer = Player.m_localPlayer; if (localPlayer != null) { ((Character)localPlayer).Message((MessageType)2, "$hf_dismiss_not_empty", 0, (Sprite)null); } } else if (!flag) { _dismissCandidate = settler.PersistentId; _dismissConfirmUntil = Time.realtimeSinceStartup + 6f; } else if (settler.RequestDismiss()) { _dismissCandidate = ZDOID.None; _dismissConfirmUntil = 0f; _selectedSettler = ZDOID.None; } } GUI.enabled = enabled; GUILayout.EndHorizontal(); GUILayout.EndVertical(); } private void DrawSettingsView() { //IL_0002: 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) //IL_0011: Unknown result type (might be due to invalid IL or missing references) _settingsScroll = GUILayout.BeginScrollView(_settingsScroll, Array.Empty()); GUILayout.BeginHorizontal(Array.Empty()); GUILayout.FlexibleSpace(); GUILayout.BeginVertical((GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(Mathf.Min(720f, ((Rect)(ref _rect)).width - 80f)) }); DrawSettingsBox("$hf_panel_settings_work", delegate { DrawRadiusRow("$hf_panel_work_radius", HfConfig.WorkRadius, 8f, 120f); DrawRadiusRow("$hf_panel_banner_radius", HfConfig.BannerRadius, 5f, 120f); }); DrawSettingsBox("$hf_panel_settings_movement", delegate { GUILayout.Label(Format("$hf_gateway_available", ((Object)(object)_hearth != (Object)null) ? _hearth.AvailableGatewayDoorCount : 0), HfGuiSkin.MutedLabel, Array.Empty()); GUILayout.Label(Localization.instance.Localize(((Object)(object)_hearth != (Object)null && _hearth.GatewayDoorsConfigured) ? "$hf_gateway_mode_manual" : "$hf_gateway_mode_automatic"), HfGuiSkin.MutedLabel, Array.Empty()); if (GUILayout.Button(Localization.instance.Localize("$hf_gateway_editor_open"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(220f) })) { OpenGatewayEditor(); } }); DrawSettingsBox("$hf_panel_settings_needs", delegate { DrawIntConfigRow("$hf_panel_meal_minutes", HfConfig.MealMinutes, 1, 5); DrawBoolConfigRow("$hf_panel_social_rest", HfConfig.EnableSocialRest); if (HfConfig.EnableSocialRest.Value) { DrawIntConfigRow("$hf_panel_social_chance", HfConfig.SocialChancePercent, 0, 100, 5); DrawIntConfigRow("$hf_panel_social_duration", HfConfig.SocialDurationSeconds, 30, 300, 15); DrawIntConfigRow("$hf_panel_social_bonus", HfConfig.SocialHappinessBonus, 0, 20); } DrawBoolConfigRow("$hf_panel_desertion", HfConfig.EnableDesertion); if (HfConfig.EnableDesertion.Value) { DrawIntConfigRow("$hf_panel_desertion_days", HfConfig.DesertionDays, 1, 10); } }); DrawSettingsBox("$hf_panel_settings_lifecycle", delegate { DrawIntConfigRow("$hf_panel_respawn_minutes", HfConfig.RespawnMinutes, 1, 120); }); DrawSettingsBox("$hf_panel_settings_guards", delegate { DrawRadiusRow("$hf_panel_patrol_radius", HfConfig.PatrolPointRadius, 10f, 150f); GUILayout.Label(Format("$hf_hearth_patrol_available", ((Object)(object)_hearth != (Object)null) ? _hearth.AvailablePatrolPointCount : 0), HfGuiSkin.MutedLabel, Array.Empty()); GUILayout.Label(Localization.instance.Localize("$hf_patrol_per_guard_hint"), HfGuiSkin.MutedLabel, Array.Empty()); }); DrawSettingsBox("$hf_panel_settings_farming", delegate { //IL_0066: Unknown result type (might be due to invalid IL or missing references) DrawRadiusRow("$hf_panel_farm_radius", HfConfig.FarmRadius, 3f, 20f); DrawRadiusRow("$hf_panel_farm_max_range", HfConfig.FarmMarkerMaxRange, 20f, 300f); DrawIntConfigRow("$hf_panel_farm_seed_reserve", HfConfig.FarmSeedReserve, 0, 50); GUILayout.Label(Format("$hf_panel_farm_markers", ((Object)(object)_hearth != (Object)null) ? FarmMarker.MarkersFor(((Component)_hearth).transform.position, _hearth.OwnerId).Count : 0), HfGuiSkin.MutedLabel, Array.Empty()); }); GUILayout.EndVertical(); GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); GUILayout.EndScrollView(); } private static void DrawSettingsBox(string titleKey, Action content) { GUILayout.BeginVertical(GUI.skin.box, Array.Empty()); GUILayout.Label(Localization.instance.Localize(titleKey), HfGuiSkin.SectionTitle, Array.Empty()); GUILayout.Space(4f); content(); GUILayout.EndVertical(); GUILayout.Space(10f); } private void OpenPatrolRouteEditor(SettlerController guard) { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: 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_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_hearth == (Object)null) && !((Object)(object)guard == (Object)null) && guard.CurrentRole == SettlerRole.Guard) { _gatewayEditorOpen = false; _patrolEditorOpen = true; _patrolEditorHearth = _hearth.PersistentId; _patrolEditorGuard = guard.PersistentId; _patrolDraft.Clear(); if (guard.GuardPatrolConfigured) { _patrolDraft.AddRange(guard.GuardPatrolRouteIds); } _patrolMapZoom = 1f; _patrolMapPan = Vector2.zero; _patrolMapDragging = false; _patrolSavedUntil = 0f; } } private void OpenGatewayEditor() { //IL_0024: 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_0068: 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) if (!((Object)(object)_hearth == (Object)null)) { _patrolEditorOpen = false; _gatewayEditorOpen = true; _gatewayEditorHearth = _hearth.PersistentId; _gatewayDraft.Clear(); if (_hearth.GatewayDoorsConfigured) { _gatewayDraft.AddRange(_hearth.SavedGatewayDoorIds); } _patrolMapZoom = 1f; _patrolMapPan = Vector2.zero; _patrolMapDragging = false; _gatewaySavedUntil = 0f; } } private void DrawPatrolRouteEditor(ExilesHearth hearth) { //IL_002b: 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_02e7: 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_0335: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)hearth == (Object)null) { _patrolEditorOpen = false; return; } if (_patrolEditorHearth != hearth.PersistentId) { _patrolEditorOpen = false; return; } SettlerController settlerController = SettlerController.Instances.FirstOrDefault((SettlerController settler) => (Object)(object)settler != (Object)null && settler.PersistentId == _patrolEditorGuard && settler.CurrentRole == SettlerRole.Guard && Vector3.Distance(settler.HomePosition, ((Component)hearth).transform.position) <= 6f); if ((Object)(object)settlerController == (Object)null) { _patrolEditorOpen = false; return; } List availablePatrolPoints = hearth.AvailablePatrolPoints; HashSet validIds = new HashSet(availablePatrolPoints.Select((PatrolPoint point) => point.PersistentId)); _patrolDraft.RemoveAll((ZDOID id) => !validIds.Contains(id)); GUILayout.Space(8f); GUILayout.BeginHorizontal(Array.Empty()); if (GUILayout.Button(Localization.instance.Localize("$hf_patrol_editor_back"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(110f) })) { _patrolEditorOpen = false; _patrolMapDragging = false; return; } GUILayout.Label(string.Format(Localization.instance.Localize("$hf_patrol_editor_guard_title"), settlerController.PanelName), HfGuiSkin.SectionTitle, Array.Empty()); GUILayout.FlexibleSpace(); GUILayout.Label(Localization.instance.Localize(settlerController.GuardPatrolConfigured ? "$hf_patrol_mode_manual" : "$hf_patrol_mode_automatic"), HfGuiSkin.MutedLabel, Array.Empty()); GUILayout.EndHorizontal(); GUILayout.Label(Localization.instance.Localize("$hf_patrol_editor_desc"), HfGuiSkin.MutedLabel, Array.Empty()); GUILayout.BeginHorizontal(Array.Empty()); GUILayout.Label(string.Format(Localization.instance.Localize("$hf_patrol_editor_count"), availablePatrolPoints.Count, _patrolDraft.Count), Array.Empty()); GUILayout.FlexibleSpace(); GUILayout.Label(Localization.instance.Localize("$hf_patrol_zoom") + ": " + $"{_patrolMapZoom:0.0}x", HfGuiSkin.MutedLabel, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(90f) }); if (GUILayout.Button("-", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(34f) })) { _patrolMapZoom = Mathf.Clamp(_patrolMapZoom / 1.25f, 0.6f, 3f); } if (GUILayout.Button("+", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(34f) })) { _patrolMapZoom = Mathf.Clamp(_patrolMapZoom * 1.25f, 0.6f, 3f); } GUILayout.EndHorizontal(); float num = Mathf.Clamp(((Rect)(ref _rect)).height - 255f, 330f, 520f); Rect rect = GUILayoutUtility.GetRect(300f, num, (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.ExpandWidth(true), GUILayout.Height(num) }); float num2 = Mathf.Min(((Rect)(ref rect)).width, ((Rect)(ref rect)).height); Rect mapRect = default(Rect); ((Rect)(ref mapRect))..ctor(((Rect)(ref rect)).x + (((Rect)(ref rect)).width - num2) * 0.5f, ((Rect)(ref rect)).y, num2, num2); DrawPatrolMap(hearth, availablePatrolPoints, mapRect); GUILayout.BeginHorizontal(Array.Empty()); bool enabled = GUI.enabled; GUI.enabled = _patrolDraft.Count > 0; if (GUILayout.Button(Localization.instance.Localize("$hf_patrol_undo"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(120f) })) { _patrolDraft.RemoveAt(_patrolDraft.Count - 1); } if (GUILayout.Button(Localization.instance.Localize("$hf_patrol_clear"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(120f) })) { _patrolDraft.Clear(); } GUI.enabled = enabled; if (GUILayout.Button(Localization.instance.Localize("$hf_patrol_use_automatic"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(190f) })) { settlerController.RequestAutomaticGuardPatrolRoute(); _patrolDraft.Clear(); _patrolSavedUntil = Time.realtimeSinceStartup + 2.5f; } GUILayout.FlexibleSpace(); if (Time.realtimeSinceStartup < _patrolSavedUntil) { GUILayout.Label(Localization.instance.Localize("$hf_patrol_saved"), HfGuiSkin.MutedLabel, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(75f) }); } if (GUILayout.Button(Localization.instance.Localize("$hf_patrol_save"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(130f) })) { settlerController.RequestSetGuardPatrolRoute(_patrolDraft); _patrolSavedUntil = Time.realtimeSinceStartup + 2.5f; } GUILayout.EndHorizontal(); } private void DrawGatewayEditor(ExilesHearth hearth) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_02b9: Unknown result type (might be due to invalid IL or missing references) //IL_02be: Unknown result type (might be due to invalid IL or missing references) //IL_0301: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)hearth == (Object)null) { _gatewayEditorOpen = false; return; } if (_gatewayEditorHearth != hearth.PersistentId) { OpenGatewayEditor(); } List availableGatewayDoors = hearth.AvailableGatewayDoors; HashSet validIds = new HashSet(from door in availableGatewayDoors where (Object)(object)door?.m_nview != (Object)null && door.m_nview.IsValid() select door.m_nview.GetZDO().m_uid); _gatewayDraft.RemoveAll((ZDOID id) => !validIds.Contains(id)); GUILayout.Space(8f); GUILayout.BeginHorizontal(Array.Empty()); if (GUILayout.Button(Localization.instance.Localize("$hf_patrol_editor_back"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(110f) })) { _gatewayEditorOpen = false; _patrolMapDragging = false; return; } GUILayout.Label(Localization.instance.Localize("$hf_gateway_editor_title"), HfGuiSkin.SectionTitle, Array.Empty()); GUILayout.FlexibleSpace(); GUILayout.Label(Localization.instance.Localize(hearth.GatewayDoorsConfigured ? "$hf_gateway_mode_manual" : "$hf_gateway_mode_automatic"), HfGuiSkin.MutedLabel, Array.Empty()); GUILayout.EndHorizontal(); GUILayout.Label(Localization.instance.Localize("$hf_gateway_editor_desc"), HfGuiSkin.MutedLabel, Array.Empty()); GUILayout.BeginHorizontal(Array.Empty()); GUILayout.Label(string.Format(Localization.instance.Localize("$hf_gateway_editor_count"), availableGatewayDoors.Count, _gatewayDraft.Count), Array.Empty()); GUILayout.FlexibleSpace(); GUILayout.Label(Localization.instance.Localize("$hf_patrol_zoom") + ": " + $"{_patrolMapZoom:0.0}x", HfGuiSkin.MutedLabel, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(90f) }); if (GUILayout.Button("-", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(34f) })) { _patrolMapZoom = Mathf.Clamp(_patrolMapZoom / 1.25f, 0.6f, 3f); } if (GUILayout.Button("+", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(34f) })) { _patrolMapZoom = Mathf.Clamp(_patrolMapZoom * 1.25f, 0.6f, 3f); } GUILayout.EndHorizontal(); float num = Mathf.Clamp(((Rect)(ref _rect)).height - 255f, 330f, 520f); Rect rect = GUILayoutUtility.GetRect(300f, num, (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.ExpandWidth(true), GUILayout.Height(num) }); float num2 = Mathf.Min(((Rect)(ref rect)).width, ((Rect)(ref rect)).height); Rect mapRect = default(Rect); ((Rect)(ref mapRect))..ctor(((Rect)(ref rect)).x + (((Rect)(ref rect)).width - num2) * 0.5f, ((Rect)(ref rect)).y, num2, num2); DrawGatewayMap(hearth, availableGatewayDoors, mapRect); GUILayout.BeginHorizontal(Array.Empty()); bool enabled = GUI.enabled; GUI.enabled = _gatewayDraft.Count > 0; if (GUILayout.Button(Localization.instance.Localize("$hf_patrol_clear"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(120f) })) { _gatewayDraft.Clear(); } GUI.enabled = enabled; if (GUILayout.Button(Localization.instance.Localize("$hf_gateway_use_automatic"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(190f) })) { hearth.RequestAutomaticGatewayDoors(); _gatewayDraft.Clear(); _gatewaySavedUntil = Time.realtimeSinceStartup + 2.5f; } GUILayout.FlexibleSpace(); if (Time.realtimeSinceStartup < _gatewaySavedUntil) { GUILayout.Label(Localization.instance.Localize("$hf_patrol_saved"), HfGuiSkin.MutedLabel, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(75f) }); } enabled = GUI.enabled; GUI.enabled = _gatewayDraft.Count > 0; if (GUILayout.Button(Localization.instance.Localize("$hf_gateway_save"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(150f) })) { hearth.RequestSetGatewayDoors(_gatewayDraft); _gatewaySavedUntil = Time.realtimeSinceStartup + 2.5f; } GUI.enabled = enabled; GUILayout.EndHorizontal(); } private void DrawGatewayMap(ExilesHearth hearth, List doors, Rect mapRect) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_003e: 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_0092: 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_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: 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_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_010e: 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_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_02ab: Unknown result type (might be due to invalid IL or missing references) //IL_02dc: Unknown result type (might be due to invalid IL or missing references) //IL_02ef: Unknown result type (might be due to invalid IL or missing references) //IL_02f4: Unknown result type (might be due to invalid IL or missing references) //IL_030e: Unknown result type (might be due to invalid IL or missing references) //IL_0321: Unknown result type (might be due to invalid IL or missing references) //IL_0326: Unknown result type (might be due to invalid IL or missing references) //IL_0340: Unknown result type (might be due to invalid IL or missing references) //IL_0353: 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) //IL_0372: Unknown result type (might be due to invalid IL or missing references) //IL_0385: Unknown result type (might be due to invalid IL or missing references) //IL_038a: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_01b5: Unknown result type (might be due to invalid IL or missing references) //IL_01ba: Unknown result type (might be due to invalid IL or missing references) //IL_01be: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: Unknown result type (might be due to invalid IL or missing references) //IL_01db: Unknown result type (might be due to invalid IL or missing references) //IL_01e3: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Unknown result type (might be due to invalid IL or missing references) //IL_01f9: Unknown result type (might be due to invalid IL or missing references) //IL_0210: Unknown result type (might be due to invalid IL or missing references) //IL_0215: Unknown result type (might be due to invalid IL or missing references) //IL_021a: Unknown result type (might be due to invalid IL or missing references) //IL_0245: Unknown result type (might be due to invalid IL or missing references) //IL_022f: Unknown result type (might be due to invalid IL or missing references) //IL_0287: Unknown result type (might be due to invalid IL or missing references) //IL_0280: Unknown result type (might be due to invalid IL or missing references) //IL_0270: Unknown result type (might be due to invalid IL or missing references) GUI.BeginGroup(mapRect); ((Rect)(ref mapRect))..ctor(0f, 0f, ((Rect)(ref mapRect)).width, ((Rect)(ref mapRect)).height); Color color = GUI.color; GUI.color = new Color(0.12f, 0.1f, 0.075f, 1f); GUI.DrawTexture(mapRect, (Texture)(object)Texture2D.whiteTexture); GUI.color = color; float num = Mathf.Max(20f, HfConfig.WorkRadius.Value + 10f); float num2 = num * 1.15f / Mathf.Max(0.1f, _patrolMapZoom); Vector3 center = ((Component)hearth).transform.position + new Vector3(_patrolMapPan.x, 0f, _patrolMapPan.y); DrawPatrolMapTexture(mapRect, center, num2); Vector2 val = PatrolWorldToMap(((Component)hearth).transform.position, mapRect, center, num2); DrawCircle(val, num / (num2 * 2f) * ((Rect)(ref mapRect)).width, new Color(0.38f, 0.82f, 1f, 0.75f), 2f); Rect val2 = new Rect(val.x - 14f, val.y - 14f, 28f, 28f); Color backgroundColor = GUI.backgroundColor; GUI.backgroundColor = new Color(2.3f, 1.65f, 0.55f); GUI.Box(val2, "H"); GUI.backgroundColor = backgroundColor; foreach (Door door in doors) { if ((Object)(object)door?.m_nview == (Object)null || !door.m_nview.IsValid()) { continue; } Vector2 val3 = PatrolWorldToMap(((Component)door).transform.position, mapRect, center, num2); if (!((Rect)(ref mapRect)).Contains(val3)) { continue; } ZDOID uid = door.m_nview.GetZDO().m_uid; bool flag = _gatewayDraft.Contains(uid); Rect val4 = new Rect(val3.x - 15f, val3.y - 15f, 30f, 30f); backgroundColor = GUI.backgroundColor; GUI.backgroundColor = (flag ? new Color(0.55f, 2.1f, 1.2f) : new Color(0.55f, 0.9f, 1.25f)); if (GUI.Button(val4, flag ? "✓" : "+")) { if (flag) { _gatewayDraft.Remove(uid); } else { _gatewayDraft.Add(uid); } } GUI.backgroundColor = backgroundColor; } HandlePatrolMapInput(mapRect, num, num2); Color color2 = default(Color); ((Color)(ref color2))..ctor(0.38f, 0.82f, 1f, 0.9f); DrawLine(new Vector2(((Rect)(ref mapRect)).x, ((Rect)(ref mapRect)).y), new Vector2(((Rect)(ref mapRect)).xMax, ((Rect)(ref mapRect)).y), color2, 2f); DrawLine(new Vector2(((Rect)(ref mapRect)).xMax, ((Rect)(ref mapRect)).y), new Vector2(((Rect)(ref mapRect)).xMax, ((Rect)(ref mapRect)).yMax), color2, 2f); DrawLine(new Vector2(((Rect)(ref mapRect)).xMax, ((Rect)(ref mapRect)).yMax), new Vector2(((Rect)(ref mapRect)).x, ((Rect)(ref mapRect)).yMax), color2, 2f); DrawLine(new Vector2(((Rect)(ref mapRect)).x, ((Rect)(ref mapRect)).yMax), new Vector2(((Rect)(ref mapRect)).x, ((Rect)(ref mapRect)).y), color2, 2f); GUI.EndGroup(); } private void DrawPatrolMap(ExilesHearth hearth, List points, Rect mapRect) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: 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_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Unknown result type (might be due to invalid IL or missing references) //IL_01f9: Unknown result type (might be due to invalid IL or missing references) //IL_0210: Unknown result type (might be due to invalid IL or missing references) //IL_0215: Unknown result type (might be due to invalid IL or missing references) //IL_021a: Unknown result type (might be due to invalid IL or missing references) //IL_022b: Unknown result type (might be due to invalid IL or missing references) //IL_023f: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: 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_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_025e: Unknown result type (might be due to invalid IL or missing references) //IL_0263: Unknown result type (might be due to invalid IL or missing references) //IL_0264: Unknown result type (might be due to invalid IL or missing references) //IL_0266: Unknown result type (might be due to invalid IL or missing references) //IL_026b: Unknown result type (might be due to invalid IL or missing references) //IL_026f: Unknown result type (might be due to invalid IL or missing references) //IL_0283: Unknown result type (might be due to invalid IL or missing references) //IL_028f: Unknown result type (might be due to invalid IL or missing references) //IL_029c: Unknown result type (might be due to invalid IL or missing references) //IL_02b3: Unknown result type (might be due to invalid IL or missing references) //IL_02b8: Unknown result type (might be due to invalid IL or missing references) //IL_02bd: Unknown result type (might be due to invalid IL or missing references) //IL_035d: Unknown result type (might be due to invalid IL or missing references) //IL_038e: Unknown result type (might be due to invalid IL or missing references) //IL_03a1: Unknown result type (might be due to invalid IL or missing references) //IL_03a6: Unknown result type (might be due to invalid IL or missing references) //IL_03c0: Unknown result type (might be due to invalid IL or missing references) //IL_03d3: Unknown result type (might be due to invalid IL or missing references) //IL_03d8: Unknown result type (might be due to invalid IL or missing references) //IL_03f2: 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_040a: Unknown result type (might be due to invalid IL or missing references) //IL_0424: Unknown result type (might be due to invalid IL or missing references) //IL_0437: Unknown result type (might be due to invalid IL or missing references) //IL_043c: Unknown result type (might be due to invalid IL or missing references) //IL_02e9: Unknown result type (might be due to invalid IL or missing references) //IL_02d3: Unknown result type (might be due to invalid IL or missing references) //IL_0339: Unknown result type (might be due to invalid IL or missing references) //IL_032f: Unknown result type (might be due to invalid IL or missing references) GUI.BeginGroup(mapRect); ((Rect)(ref mapRect))..ctor(0f, 0f, ((Rect)(ref mapRect)).width, ((Rect)(ref mapRect)).height); Color color = GUI.color; GUI.color = new Color(0.12f, 0.1f, 0.075f, 1f); GUI.DrawTexture(mapRect, (Texture)(object)Texture2D.whiteTexture); GUI.color = color; float num = Mathf.Max(10f, HfConfig.PatrolPointRadius.Value); float num2 = num * 1.15f / Mathf.Max(0.1f, _patrolMapZoom); Vector3 center = ((Component)hearth).transform.position + new Vector3(_patrolMapPan.x, 0f, _patrolMapPan.y); DrawPatrolMapTexture(mapRect, center, num2); Vector2 val = PatrolWorldToMap(((Component)hearth).transform.position, mapRect, center, num2); DrawCircle(val, num / (num2 * 2f) * ((Rect)(ref mapRect)).width, new Color(1f, 0.78f, 0.28f, 0.75f), 2f); Dictionary pointById = points.ToDictionary((PatrolPoint point) => point.PersistentId); List list = (from id in _patrolDraft.Where(pointById.ContainsKey) select pointById[id]).ToList(); if (list.Count > 1) { for (int num3 = 0; num3 < list.Count; num3++) { int index = (num3 + 1) % list.Count; Vector2 val2 = PatrolWorldToMap(list[num3].Position, mapRect, center, num2); Vector2 to = PatrolWorldToMap(list[index].Position, mapRect, center, num2); DrawArrow(val2, to, new Color(1f, 0.74f, 0.2f, 0.95f)); } } Rect val3 = new Rect(val.x - 14f, val.y - 14f, 28f, 28f); Color backgroundColor = GUI.backgroundColor; GUI.backgroundColor = new Color(2.3f, 1.65f, 0.55f); GUI.Box(val3, "H"); GUI.backgroundColor = backgroundColor; foreach (PatrolPoint point in points) { Vector2 val4 = PatrolWorldToMap(point.Position, mapRect, center, num2); if (!((Rect)(ref mapRect)).Contains(val4)) { continue; } int num4 = _patrolDraft.IndexOf(point.PersistentId); Rect val5 = new Rect(val4.x - 15f, val4.y - 15f, 30f, 30f); backgroundColor = GUI.backgroundColor; GUI.backgroundColor = ((num4 >= 0) ? new Color(2.3f, 1.75f, 0.62f) : new Color(0.82f, 0.68f, 0.48f)); if (GUI.Button(val5, (num4 >= 0) ? (num4 + 1).ToString() : "+")) { if (num4 >= 0) { _patrolDraft.RemoveAt(num4); } else { _patrolDraft.Add(point.PersistentId); } } GUI.backgroundColor = backgroundColor; } HandlePatrolMapInput(mapRect, num, num2); Color color2 = default(Color); ((Color)(ref color2))..ctor(0.85f, 0.68f, 0.38f, 0.9f); DrawLine(new Vector2(((Rect)(ref mapRect)).x, ((Rect)(ref mapRect)).y), new Vector2(((Rect)(ref mapRect)).xMax, ((Rect)(ref mapRect)).y), color2, 2f); DrawLine(new Vector2(((Rect)(ref mapRect)).xMax, ((Rect)(ref mapRect)).y), new Vector2(((Rect)(ref mapRect)).xMax, ((Rect)(ref mapRect)).yMax), color2, 2f); DrawLine(new Vector2(((Rect)(ref mapRect)).xMax, ((Rect)(ref mapRect)).yMax), new Vector2(((Rect)(ref mapRect)).x, ((Rect)(ref mapRect)).yMax), color2, 2f); DrawLine(new Vector2(((Rect)(ref mapRect)).x, ((Rect)(ref mapRect)).yMax), new Vector2(((Rect)(ref mapRect)).x, ((Rect)(ref mapRect)).y), color2, 2f); GUI.EndGroup(); } private static void DrawPatrolMapTexture(Rect rect, Vector3 center, float halfSpan) { //IL_0033: 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_0059: 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_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_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) Minimap instance = Minimap.instance; if ((Object)(object)instance == (Object)null || (Object)(object)instance.m_mapTexture == (Object)null || instance.m_textureSize <= 0 || instance.m_pixelSize <= 0f) { DrawMapGrid(rect); return; } float num = (float)instance.m_textureSize * instance.m_pixelSize; Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor(center.x / num + 0.5f, center.z / num + 0.5f); float num2 = halfSpan * 2f / num; Rect val2 = default(Rect); ((Rect)(ref val2))..ctor(val.x - num2 * 0.5f, val.y - num2 * 0.5f, num2, num2); GUI.DrawTextureWithTexCoords(rect, (Texture)(object)instance.m_mapTexture, val2, false); DrawMapGrid(rect); } private static void DrawMapGrid(Rect rect) { //IL_005c: 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_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) Color color = default(Color); ((Color)(ref color))..ctor(0.88f, 0.78f, 0.58f, 0.16f); for (int i = 1; i < 4; i++) { float num = ((Rect)(ref rect)).x + ((Rect)(ref rect)).width * (float)i / 4f; float num2 = ((Rect)(ref rect)).y + ((Rect)(ref rect)).height * (float)i / 4f; DrawLine(new Vector2(num, ((Rect)(ref rect)).y), new Vector2(num, ((Rect)(ref rect)).yMax), color, 1f); DrawLine(new Vector2(((Rect)(ref rect)).x, num2), new Vector2(((Rect)(ref rect)).xMax, num2), color, 1f); } } private void HandlePatrolMapInput(Rect rect, float radius, float halfSpan) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Invalid comparison between Unknown and I4 //IL_0019: 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_002d: Invalid comparison between Unknown and I4 //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Invalid comparison between Unknown and I4 //IL_00c6: 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_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) Event current = Event.current; if ((int)current.rawType == 1) { _patrolMapDragging = false; } if (((Rect)(ref rect)).Contains(current.mousePosition)) { if ((int)current.type == 6) { _patrolMapZoom = Mathf.Clamp(_patrolMapZoom * ((current.delta.y > 0f) ? 0.85f : 1.18f), 0.6f, 3f); current.Use(); } else if ((int)current.type == 0 && (current.button == 0 || current.button == 2)) { _patrolMapDragging = true; current.Use(); } else if ((int)current.type == 3 && _patrolMapDragging) { float num = halfSpan * 2f / ((Rect)(ref rect)).width; _patrolMapPan.x -= current.delta.x * num; _patrolMapPan.y += current.delta.y * num; _patrolMapPan = Vector2.ClampMagnitude(_patrolMapPan, radius); current.Use(); } } } private static Vector2 PatrolWorldToMap(Vector3 point, Rect rect, Vector3 center, float halfSpan) { //IL_0002: 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) //IL_0012: 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) //IL_0036: 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) //IL_0054: Unknown result type (might be due to invalid IL or missing references) return new Vector2(((Rect)(ref rect)).center.x + (point.x - center.x) / (halfSpan * 2f) * ((Rect)(ref rect)).width, ((Rect)(ref rect)).center.y - (point.z - center.z) / (halfSpan * 2f) * ((Rect)(ref rect)).height); } private static void DrawArrow(Vector2 from, Vector2 to, Color color) { //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_0002: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_002b: 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) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0040: 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_004c: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0068: 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_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) DrawLine(from, to, color, 3f); Vector2 val = to - from; if (!(((Vector2)(ref val)).sqrMagnitude < 4f)) { ((Vector2)(ref val)).Normalize(); Vector2 val2 = Vector2.Lerp(from, to, 0.58f); Vector2 val3 = default(Vector2); ((Vector2)(ref val3))..ctor(0f - val.y, val.x); DrawLine(val2, val2 - val * 11f + val3 * 5f, color, 2f); DrawLine(val2, val2 - val * 11f - val3 * 5f, color, 2f); } } private static void DrawCircle(Vector2 center, float radius, Color color, float thickness) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //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_0043: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) Vector2 val = center + new Vector2(radius, 0f); for (int i = 1; i <= 48; i++) { float num = (float)Math.PI * 2f * (float)i / 48f; Vector2 val2 = center + new Vector2(Mathf.Cos(num) * radius, Mathf.Sin(num) * radius); DrawLine(val, val2, color, thickness); val = val2; } } private static void DrawLine(Vector2 from, Vector2 to, Color color, float thickness) { //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_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_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_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) Vector2 val = to - from; if (!(((Vector2)(ref val)).sqrMagnitude < 0.01f)) { Matrix4x4 matrix = GUI.matrix; Color color2 = GUI.color; GUI.color = color; GUIUtility.RotateAroundPivot(Mathf.Atan2(val.y, val.x) * 57.29578f, from); GUI.DrawTexture(new Rect(from.x, from.y - thickness * 0.5f, ((Vector2)(ref val)).magnitude, thickness), (Texture)(object)Texture2D.whiteTexture); GUI.matrix = matrix; GUI.color = color2; } } private void DrawFooter() { GUILayout.Space(8f); GUILayout.BeginHorizontal(Array.Empty()); GUILayout.Label(Localization.instance.Localize("$hf_panel_hints"), HfGuiSkin.MutedLabel, Array.Empty()); GUILayout.FlexibleSpace(); if (GUILayout.Button(Localization.instance.Localize("$hf_panel_close"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(130f) })) { Close(); } GUILayout.EndHorizontal(); } private void EnsureSelection(List settlers, List dormantSettlers) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) if (settlers.Count == 0 && dormantSettlers.Count == 0) { _selectedSettler = ZDOID.None; } else if (!settlers.Exists((SettlerController s) => s.PersistentId == _selectedSettler) && !dormantSettlers.Exists((DormantSettlerRegistry.Record s) => s.Id == _selectedSettler)) { _selectedSettler = ((dormantSettlers.Count > 0) ? dormantSettlers[0].Id : settlers[0].PersistentId); } } private void DrawLegacyWindow(int id) { //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_01f7: Unknown result type (might be due to invalid IL or missing references) ExilesHearth hearth = _hearth; if ((Object)(object)hearth == (Object)null) { return; } List list = CollectSettlers(hearth); GUILayout.Space(4f); GUILayout.BeginHorizontal(Array.Empty()); GUILayout.Label(Format("$hf_panel_settlers", list.Count), Array.Empty()); GUILayout.FlexibleSpace(); if (GUILayout.Button(Format("$hf_panel_recruit", hearth.RecruitCost), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(220f) })) { hearth.Recruit(Player.m_localPlayer); } GUILayout.EndHorizontal(); GUILayout.Space(6f); _scroll = GUILayout.BeginScrollView(_scroll, Array.Empty()); if (list.Count == 0) { GUILayout.Label(Localization.instance.Localize("$hf_panel_empty"), Array.Empty()); } foreach (SettlerController item in list) { DrawSettlerRow(item); GUILayout.Space(6f); } GUILayout.EndScrollView(); GUILayout.Space(6f); DrawRadiusRow("$hf_panel_work_radius", HfConfig.WorkRadius, 8f, 120f); DrawRadiusRow("$hf_panel_banner_radius", HfConfig.BannerRadius, 5f, 120f); DrawIntConfigRow("$hf_panel_respawn_minutes", HfConfig.RespawnMinutes, 1, 120); DrawIntConfigRow("$hf_panel_meal_minutes", HfConfig.MealMinutes, 1, 5); DrawBoolConfigRow("$hf_panel_desertion", HfConfig.EnableDesertion); if (HfConfig.EnableDesertion.Value) { DrawIntConfigRow("$hf_panel_desertion_days", HfConfig.DesertionDays, 1, 10); } GUILayout.Space(6f); GUILayout.Label(Localization.instance.Localize("$hf_panel_hints"), Array.Empty()); if (GUILayout.Button(Localization.instance.Localize("$hf_panel_close"), Array.Empty())) { Close(); } GUI.DragWindow(new Rect(0f, 0f, 10000f, 20f)); } private void DrawSettlerRow(SettlerController settler) { GUILayout.BeginVertical(GUI.skin.box, Array.Empty()); GUILayout.BeginHorizontal(Array.Empty()); GUILayout.Label(settler.PanelName + " — " + SettlerController.RoleLabel(settler.CurrentRole), Array.Empty()); GUILayout.FlexibleSpace(); if (settler.CurrentRole == SettlerRole.Follower) { GUILayout.Label(string.IsNullOrEmpty(settler.FollowerTargetName) ? Localization.instance.Localize("$hf_follower_target_none") : settler.FollowerTargetName, Array.Empty()); } else { GUILayout.Label(Localization.instance.Localize(settler.HasStorage ? "$hf_panel_storage_set" : "$hf_panel_storage_unset"), Array.Empty()); } GUILayout.EndHorizontal(); string currentStatusText = settler.CurrentStatusText; if (!string.IsNullOrEmpty(currentStatusText)) { GUILayout.Label(" " + currentStatusText, Array.Empty()); } GUILayout.Label(Format("$hf_panel_happiness", settler.Happiness) + " — " + settler.MoodLabel, Array.Empty()); string moraleReasonsText = settler.MoraleReasonsText; if (!string.IsNullOrEmpty(moraleReasonsText)) { GUILayout.Label(" " + moraleReasonsText, Array.Empty()); } GUILayout.BeginHorizontal(Array.Empty()); bool enabled = GUI.enabled; GUI.enabled = !settler.IsRespawning; DrawRoleButton(settler, SettlerRole.Idle); DrawRoleButton(settler, SettlerRole.Lumberjack); DrawRoleButton(settler, SettlerRole.Miner); DrawRoleButton(settler, SettlerRole.Guard); DrawRoleButton(settler, SettlerRole.Caretaker); DrawRoleButton(settler, SettlerRole.Follower); DrawRoleButton(settler, SettlerRole.Farmer); GUILayout.Space(12f); if (settler.CurrentRole == SettlerRole.Follower && GUILayout.Button(Localization.instance.Localize("$hf_follower_recall"), Array.Empty())) { settler.RequestFollowerReturnHome(); } GUI.enabled = enabled; GUILayout.EndHorizontal(); if (settler.CurrentRole == SettlerRole.Follower) { DrawFollowerCombatModes(settler, showDescription: false); } DrawFlagRow(settler); DrawDismissRow(settler); GUILayout.EndVertical(); } private static void DrawFlagRow(SettlerController settler) { switch (settler.CurrentRole) { case SettlerRole.Lumberjack: GUILayout.Space(8f); GUILayout.Label(Localization.instance.Localize("$hf_panel_filters_section"), HfGuiSkin.CardTitle, Array.Empty()); GUILayout.BeginVertical(GUI.skin.box, Array.Empty()); DrawFlagGrid(settler, TreeFilters); GUILayout.EndVertical(); break; case SettlerRole.Miner: GUILayout.Space(8f); GUILayout.Label(Localization.instance.Localize("$hf_panel_filters_section"), HfGuiSkin.CardTitle, Array.Empty()); GUILayout.BeginVertical(GUI.skin.box, Array.Empty()); DrawFlagGrid(settler, RockFilters); GUILayout.EndVertical(); break; case SettlerRole.Farmer: GUILayout.Space(8f); GUILayout.Label(Localization.instance.Localize("$hf_panel_farmer_settings_section"), HfGuiSkin.CardTitle, Array.Empty()); GUILayout.BeginVertical(GUI.skin.box, Array.Empty()); GUILayout.Label(Localization.instance.Localize("$hf_panel_farmer_mode_section"), HfGuiSkin.CardTitle, Array.Empty()); DrawFarmerMode(settler); GUILayout.Space(6f); GUILayout.Label(Localization.instance.Localize("$hf_panel_farmer_fields_section"), HfGuiSkin.CardTitle, Array.Empty()); DrawFarmerMarkerGrid(settler); GUILayout.Space(6f); GUILayout.Label(Localization.instance.Localize("$hf_panel_farmer_crops_section"), HfGuiSkin.CardTitle, Array.Empty()); DrawFarmerCropGrid(settler); GUILayout.Space(6f); GUILayout.Label(Localization.instance.Localize("$hf_panel_farmer_targets_section"), HfGuiSkin.CardTitle, Array.Empty()); GUILayout.Label(Localization.instance.Localize("$hf_panel_farmer_targets_hint"), HfGuiSkin.MutedLabel, Array.Empty()); DrawFarmerStockTargets(settler); GUILayout.EndVertical(); break; case SettlerRole.Caretaker: { GUILayout.Space(8f); GUILayout.Label(Localization.instance.Localize("$hf_panel_caretaker_tasks_section"), HfGuiSkin.CardTitle, Array.Empty()); GUILayout.BeginVertical(GUI.skin.box, Array.Empty()); for (int i = 0; i < CaretakerTaskFilters.Length; i += 3) { GUILayout.BeginHorizontal(Array.Empty()); for (int j = i; j < CaretakerTaskFilters.Length && j < i + 3; j++) { DrawCaretakerTaskToggle(settler, CaretakerTaskFilters[j].task, CaretakerTaskFilters[j].key); } GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); } GUILayout.EndVertical(); break; } } } private static void DrawFarmerMode(SettlerController settler) { GUILayout.BeginHorizontal(Array.Empty()); DrawFarmerModeButton(settler, FarmerWorkMode.FullCycle, "$hf_farmer_mode_full"); DrawFarmerModeButton(settler, FarmerWorkMode.Plant, "$hf_farmer_mode_plant"); DrawFarmerModeButton(settler, FarmerWorkMode.Harvest, "$hf_farmer_mode_harvest"); GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); } private static void DrawFarmerModeButton(SettlerController settler, FarmerWorkMode mode, string labelKey) { bool flag = settler.FarmerMode == mode; if (GUILayout.Button((flag ? "✓ " : string.Empty) + Localization.instance.Localize(labelKey), flag ? HfGuiSkin.SelectedButton : GUI.skin.button, Array.Empty())) { settler.RequestFarmerMode(mode); } } private static void DrawFarmerMarkerGrid(SettlerController settler) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0144: 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_0174: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: 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_0215: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_0202: Unknown result type (might be due to invalid IL or missing references) List list = FarmMarker.MarkersFor(settler.Home, settler.SettlementOwnerId); GUILayout.BeginHorizontal(Array.Empty()); GUILayout.Label(Localization.instance.Localize(settler.FarmerMarkersConfigured ? "$hf_farmer_fields_custom" : "$hf_farmer_fields_all"), HfGuiSkin.MutedLabel, Array.Empty()); GUILayout.FlexibleSpace(); if (GUILayout.Button(Localization.instance.Localize("$hf_farmer_fields_use_all"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(110f) })) { settler.RequestSetFarmerMarkers(null, configured: false); } if (GUILayout.Button(Localization.instance.Localize("$hf_farmer_fields_use_none"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(110f) })) { settler.RequestSetFarmerMarkers(Array.Empty(), configured: true); } GUILayout.EndHorizontal(); if (list.Count == 0) { GUILayout.Label(Localization.instance.Localize("$hf_farmer_fields_none"), HfGuiSkin.MutedLabel, Array.Empty()); return; } HashSet hashSet = (settler.FarmerMarkersConfigured ? new HashSet(settler.FarmerMarkerIds) : new HashSet(list.Select((FarmMarker marker) => marker.PersistentId))); for (int num = 0; num < list.Count; num += 2) { GUILayout.BeginHorizontal(Array.Empty()); for (int num2 = num; num2 < list.Count && num2 < num + 2; num2++) { FarmMarker farmMarker = list[num2]; bool num3 = hashSet.Contains(farmMarker.PersistentId); string arg = farmMarker.Crop?.DisplayName ?? "—"; float num4 = Vector3.Distance(settler.Home, farmMarker.Position); string text = string.Format(Localization.instance.Localize("$hf_farmer_field_label"), num2 + 1, arg, num4.ToString("0")); Color contentColor = GUI.contentColor; if (!num3) { GUI.contentColor = new Color(0.55f, 0.5f, 0.42f); } if (GUILayout.Button((num3 ? "✓ " : "— ") + text, Array.Empty())) { if (!hashSet.Remove(farmMarker.PersistentId)) { hashSet.Add(farmMarker.PersistentId); } settler.RequestSetFarmerMarkers(hashSet, configured: true); } GUI.contentColor = contentColor; } GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); } } private static List VisibleFarmerCropOptions() { List list = FarmCropCatalog.PermissionOptions(); Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { return list; } HashSet known = new HashSet(FarmCropCatalog.AvailableTo(localPlayer).Select(FarmCropCatalog.PermissionKey), StringComparer.Ordinal); return list.Where((FarmCrop crop) => known.Contains(FarmCropCatalog.PermissionKey(crop))).ToList(); } private static void DrawFarmerCropGrid(SettlerController settler) { //IL_0068: 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_0080: 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) List list = VisibleFarmerCropOptions(); if (list.Count == 0) { GUILayout.Label(Localization.instance.Localize("$hf_farm_no_crops"), Array.Empty()); return; } for (int i = 0; i < list.Count; i += 4) { GUILayout.BeginHorizontal(Array.Empty()); for (int j = i; j < list.Count && j < i + 4; j++) { FarmCrop farmCrop = list[j]; bool num = settler.FarmerCropEnabled(farmCrop); string text = (num ? "✓ " : "— ") + farmCrop.DisplayName; Color contentColor = GUI.contentColor; if (!num) { GUI.contentColor = new Color(0.55f, 0.5f, 0.42f); } if (GUILayout.Button(text, Array.Empty())) { settler.RequestToggleFarmerCrop(farmCrop); } GUI.contentColor = contentColor; } GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); } } private static void DrawFarmerStockTargets(SettlerController settler) { List list = VisibleFarmerCropOptions(); if (list.Count == 0) { GUILayout.Label(Localization.instance.Localize("$hf_farm_no_crops"), Array.Empty()); return; } foreach (FarmCrop item in list) { int num = settler.FarmerStockTarget(item); GUILayout.BeginHorizontal(Array.Empty()); GUILayout.Label(item.DisplayName + ": " + ((num <= 0) ? Localization.instance.Localize("$hf_farmer_target_unlimited") : num.ToString()), Array.Empty()); GUILayout.FlexibleSpace(); if (GUILayout.Button("-10", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(48f) })) { settler.RequestFarmerStockTarget(item, Mathf.Max(0, num - 10)); } if (GUILayout.Button("+10", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(48f) })) { settler.RequestFarmerStockTarget(item, Mathf.Min(10000, num + 10)); } GUILayout.EndHorizontal(); } } private static void DrawFlagGrid(SettlerController settler, (SettlerFlags flag, string key)[] filters) { for (int i = 0; i < filters.Length; i += 4) { GUILayout.BeginHorizontal(Array.Empty()); for (int j = i; j < filters.Length && j < i + 4; j++) { DrawFlagToggle(settler, filters[j].flag, filters[j].key); } GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); } } private static void DrawFlagToggle(SettlerController settler, SettlerFlags flag, string labelKey) { //IL_0027: 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) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) bool num = settler.FlagEnabled(flag); string text = (num ? "✓ " : "— ") + Localization.instance.Localize(labelKey); Color contentColor = GUI.contentColor; if (!num) { GUI.contentColor = new Color(0.55f, 0.5f, 0.42f); } if (GUILayout.Button(text, Array.Empty())) { settler.RequestToggleFlag(flag); } GUI.contentColor = contentColor; } private static void DrawCaretakerTaskToggle(SettlerController settler, CaretakerTasks task, string labelKey) { //IL_0027: 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) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) bool num = settler.CaretakerTaskEnabled(task); string text = (num ? "✓ " : "— ") + Localization.instance.Localize(labelKey); Color contentColor = GUI.contentColor; if (!num) { GUI.contentColor = new Color(0.55f, 0.5f, 0.42f); } if (GUILayout.Button(text, Array.Empty())) { settler.RequestToggleCaretakerTask(task); } GUI.contentColor = contentColor; } private static void DrawRadiusRow(string labelKey, ConfigEntry entry, float min, float max) { GUILayout.BeginHorizontal(Array.Empty()); GUILayout.Label($"{Localization.instance.Localize(labelKey)}: {entry.Value:0} m", Array.Empty()); GUILayout.FlexibleSpace(); if (GUILayout.Button("-", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(36f) })) { entry.Value = Mathf.Clamp(entry.Value - 5f, min, max); } if (GUILayout.Button("+", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(36f) })) { entry.Value = Mathf.Clamp(entry.Value + 5f, min, max); } GUILayout.EndHorizontal(); } private static void DrawIntConfigRow(string labelKey, ConfigEntry entry, int min, int max, int step = 1) { GUILayout.BeginHorizontal(Array.Empty()); GUILayout.Label($"{Localization.instance.Localize(labelKey)}: {entry.Value}", Array.Empty()); GUILayout.FlexibleSpace(); if (GUILayout.Button("-", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(36f) })) { entry.Value = Mathf.Clamp(entry.Value - step, min, max); } if (GUILayout.Button("+", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(36f) })) { entry.Value = Mathf.Clamp(entry.Value + step, min, max); } GUILayout.EndHorizontal(); } private static void DrawBoolConfigRow(string labelKey, ConfigEntry entry) { GUILayout.BeginHorizontal(Array.Empty()); GUILayout.Label(Localization.instance.Localize(labelKey), Array.Empty()); GUILayout.FlexibleSpace(); if (GUILayout.Button(Localization.instance.Localize(entry.Value ? "$hf_enabled" : "$hf_disabled"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(90f) })) { entry.Value = !entry.Value; } GUILayout.EndHorizontal(); } private void DrawDismissRow(SettlerController settler) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) GUILayout.BeginHorizontal(Array.Empty()); GUILayout.FlexibleSpace(); bool flag = _dismissCandidate == settler.PersistentId && Time.realtimeSinceStartup <= _dismissConfirmUntil; bool enabled = GUI.enabled; GUI.enabled = !settler.IsRespawning; string text = (flag ? "$hf_panel_dismiss_confirm" : "$hf_panel_dismiss"); if (GUILayout.Button(Localization.instance.Localize(text), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(160f) })) { if (!settler.CanDismiss) { Player localPlayer = Player.m_localPlayer; if (localPlayer != null) { ((Character)localPlayer).Message((MessageType)2, "$hf_dismiss_not_empty", 0, (Sprite)null); } } else if (!flag) { _dismissCandidate = settler.PersistentId; _dismissConfirmUntil = Time.realtimeSinceStartup + 6f; } else if (settler.RequestDismiss()) { _dismissCandidate = ZDOID.None; _dismissConfirmUntil = 0f; } } GUI.enabled = enabled; GUILayout.EndHorizontal(); } private static void DrawRoleButton(SettlerController settler, SettlerRole role) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0027: 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_0066: Unknown result type (might be due to invalid IL or missing references) bool flag = settler.CurrentRole == role; Color backgroundColor = GUI.backgroundColor; Color contentColor = GUI.contentColor; if (flag) { GUI.backgroundColor = new Color(2.4f, 2f, 1.1f); GUI.contentColor = new Color(1f, 0.85f, 0.45f); } if (GUILayout.Button(SettlerController.RoleLabel(role), Array.Empty()) && !flag) { settler.RequestRole(role); } GUI.backgroundColor = backgroundColor; GUI.contentColor = contentColor; } private static void DrawFollowerCombatModes(SettlerController settler, bool showDescription) { GUILayout.Space(4f); GUILayout.Label(Localization.instance.Localize("$hf_follower_combat_mode"), HfGuiSkin.CardTitle, Array.Empty()); if (showDescription) { FollowerCombatMode currentFollowerCombatMode = settler.CurrentFollowerCombatMode; GUILayout.Label(Localization.instance.Localize(currentFollowerCombatMode switch { FollowerCombatMode.Aggressive => "$hf_follower_combat_aggressive_desc", FollowerCombatMode.Passive => "$hf_follower_combat_passive_desc", _ => "$hf_follower_combat_defensive_desc", }), HfGuiSkin.MutedLabel, Array.Empty()); } GUILayout.BeginHorizontal(Array.Empty()); DrawFollowerCombatButton(settler, FollowerCombatMode.Defensive, "$hf_follower_combat_defensive"); DrawFollowerCombatButton(settler, FollowerCombatMode.Aggressive, "$hf_follower_combat_aggressive"); DrawFollowerCombatButton(settler, FollowerCombatMode.Passive, "$hf_follower_combat_passive"); GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); } private static void DrawFollowerCombatButton(SettlerController settler, FollowerCombatMode mode, string labelKey) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0041: 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) bool flag = settler.CurrentFollowerCombatMode == mode; Color backgroundColor = GUI.backgroundColor; Color contentColor = GUI.contentColor; if (flag) { GUI.backgroundColor = new Color(2.4f, 2f, 1.1f); GUI.contentColor = new Color(1f, 0.85f, 0.45f); } if (GUILayout.Button(Localization.instance.Localize(labelKey), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(120f) }) && !flag) { settler.RequestFollowerCombatMode(mode); } GUI.backgroundColor = backgroundColor; GUI.contentColor = contentColor; } private void DrawGuardSchedule(SettlerController settler) { GUILayout.Space(8f); GUILayout.BeginVertical(GUI.skin.box, Array.Empty()); GUILayout.Label(Localization.instance.Localize("$hf_guard_schedule"), HfGuiSkin.CardTitle, Array.Empty()); GUILayout.Label(Localization.instance.Localize("$hf_guard_schedule_desc"), HfGuiSkin.MutedLabel, Array.Empty()); GUILayout.Space(4f); int guardShiftStart = settler.GuardShiftStart; int guardShiftEnd = settler.GuardShiftEnd; GUILayout.BeginHorizontal(Array.Empty()); GUILayout.Label(Localization.instance.Localize("$hf_barracks_shift"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(70f) }); if (GUILayout.Button("-", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(32f) })) { settler.RequestSetGuardSchedule(guardShiftStart - 1, guardShiftEnd); } GUILayout.Label($"{guardShiftStart:00}:00", HfGuiSkin.CenteredSmall, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(58f) }); if (GUILayout.Button("+", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(32f) })) { settler.RequestSetGuardSchedule(guardShiftStart + 1, guardShiftEnd); } GUILayout.Label("→", HfGuiSkin.CenteredSmall, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(26f) }); if (GUILayout.Button("-", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(32f) })) { settler.RequestSetGuardSchedule(guardShiftStart, guardShiftEnd - 1); } GUILayout.Label($"{guardShiftEnd:00}:00", HfGuiSkin.CenteredSmall, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(58f) }); if (GUILayout.Button("+", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(32f) })) { settler.RequestSetGuardSchedule(guardShiftStart, guardShiftEnd + 1); } GUILayout.FlexibleSpace(); GUILayout.Label(Localization.instance.Localize(settler.IsGuardOnShift ? "$hf_barracks_on_shift" : "$hf_barracks_off_shift"), HfGuiSkin.MutedLabel, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(100f) }); GUILayout.EndHorizontal(); GUILayout.Space(6f); GUILayout.BeginHorizontal(Array.Empty()); GUILayout.Label(Localization.instance.Localize(settler.GuardPatrolConfigured ? "$hf_patrol_mode_manual" : "$hf_patrol_mode_automatic"), HfGuiSkin.MutedLabel, Array.Empty()); GUILayout.FlexibleSpace(); if (GUILayout.Button(Localization.instance.Localize("$hf_patrol_editor_open_guard"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(220f) })) { OpenPatrolRouteEditor(settler); } GUILayout.EndHorizontal(); GUILayout.EndVertical(); } private static List CollectSettlers(ExilesHearth hearth) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) List list = new List(); Vector3 position = ((Component)hearth).transform.position; foreach (SettlerController instance in SettlerController.Instances) { if ((Object)(object)instance != (Object)null && instance.IsValidSettler && instance.LocalPlayerCanManage && Vector3.Distance(instance.HomePosition, position) <= 6f) { list.Add(instance); } } list.Sort((SettlerController left, SettlerController right) => string.Compare(left.PanelName, right.PanelName, StringComparison.CurrentCultureIgnoreCase)); return list; } private static List CollectDormantSettlers(ExilesHearth hearth, IEnumerable instantiated) { return DormantSettlerRegistry.ForHearth(hearth, instantiated.Select((SettlerController settler) => settler.PersistentId)); } private static string Format(string key, object arg) { return string.Format(Localization.instance.Localize(key), arg); } } internal static class HfConfig { internal static ConfigEntry RecruitCoins; internal static ConfigEntry SettlerNamePool; internal static ConfigEntry WorkRadius; internal static ConfigEntry BannerRadius; internal static ConfigEntry BannerMaxRange; internal static ConfigEntry DepositThreshold; internal static ConfigEntry RequireBed; internal static ConfigEntry NightRest; internal static ConfigEntry ChopDamage; internal static ConfigEntry PickDamage; internal static ConfigEntry SettlerHealth; internal static ConfigEntry RespawnMinutes; internal static ConfigEntry MealMinutes; internal static ConfigEntry DesertionDays; internal static ConfigEntry EnableDesertion; internal static ConfigEntry EnableSocialRest; internal static ConfigEntry SocialChancePercent; internal static ConfigEntry SocialDurationSeconds; internal static ConfigEntry SocialHappinessBonus; internal static ConfigEntry PatrolPointRadius; internal static ConfigEntry FarmRadius; internal static ConfigEntry FarmMarkerMaxRange; internal static ConfigEntry FarmSeedReserve; internal static ConfigEntry DebugLog; internal static void Bind(ConfigFile config) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Expected O, but got Unknown //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Expected O, but got Unknown //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Expected O, but got Unknown //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Expected O, but got Unknown //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Expected O, but got Unknown //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Expected O, but got Unknown //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Expected O, but got Unknown //IL_01c7: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Expected O, but got Unknown //IL_0208: Unknown result type (might be due to invalid IL or missing references) //IL_0212: Expected O, but got Unknown //IL_0249: Unknown result type (might be due to invalid IL or missing references) //IL_0253: Expected O, but got Unknown //IL_028a: Unknown result type (might be due to invalid IL or missing references) //IL_0294: Expected O, but got Unknown //IL_02c0: Unknown result type (might be due to invalid IL or missing references) //IL_02ca: Expected O, but got Unknown //IL_02f5: Unknown result type (might be due to invalid IL or missing references) //IL_02ff: Expected O, but got Unknown //IL_0324: Unknown result type (might be due to invalid IL or missing references) //IL_032e: Expected O, but got Unknown //IL_035a: Unknown result type (might be due to invalid IL or missing references) //IL_0364: Expected O, but got Unknown //IL_0389: Unknown result type (might be due to invalid IL or missing references) //IL_0393: Expected O, but got Unknown //IL_03c0: Unknown result type (might be due to invalid IL or missing references) //IL_03ca: Expected O, but got Unknown //IL_03fb: Unknown result type (might be due to invalid IL or missing references) //IL_0405: Expected O, but got Unknown //IL_0431: Unknown result type (might be due to invalid IL or missing references) //IL_043b: Expected O, but got Unknown //IL_0472: Unknown result type (might be due to invalid IL or missing references) //IL_047c: Expected O, but got Unknown //IL_04b3: Unknown result type (might be due to invalid IL or missing references) //IL_04bd: Expected O, but got Unknown //IL_04f4: Unknown result type (might be due to invalid IL or missing references) //IL_04fe: Expected O, but got Unknown //IL_052a: Unknown result type (might be due to invalid IL or missing references) //IL_0534: Expected O, but got Unknown DebugLog = config.Bind("Debug", "VerboseLog", false, "Log settler work decisions (tree search, chopping) to the BepInEx console. Local only."); RecruitCoins = config.Bind("Recruitment", "Coins", 10, new ConfigDescription("Coins consumed to recruit one settler.", (AcceptableValueBase)null, new object[1] { AdminOnly() })); SettlerNamePool = config.Bind("Recruitment", "NamePool", "Astrid, Birger, Eira, Freydis, Gorm, Hakon, Ingrid, Kari, Leif, Runa, Sigrid, Torsten", new ConfigDescription("Comma- or semicolon-separated names used for newly recruited settlers. When the list is exhausted a numeric suffix keeps every generated name unique.", (AcceptableValueBase)null, new object[1] { AdminOnly() })); WorkRadius = config.Bind("Work", "WorkRadius", 30f, new ConfigDescription("Work radius around the Exiles' Hearth itself.", (AcceptableValueBase)(object)new AcceptableValueRange(8f, 120f), new object[1] { AdminOnly() })); BannerRadius = config.Bind("Work", "BannerRadius", 40f, new ConfigDescription("Work radius around each placed work banner.", (AcceptableValueBase)(object)new AcceptableValueRange(5f, 120f), new object[1] { AdminOnly() })); BannerMaxRange = config.Bind("Work", "BannerMaxRange", 200f, new ConfigDescription("A work banner only counts if it is within this distance of the settler's hearth.", (AcceptableValueBase)(object)new AcceptableValueRange(20f, 400f), new object[1] { AdminOnly() })); DepositThreshold = config.Bind("Work", "DepositThreshold", 20, new ConfigDescription("A settler hauls its load to the assigned chest once it carries at least this many resources.", (AcceptableValueBase)(object)new AcceptableValueRange(1, 100), new object[1] { AdminOnly() })); RequireBed = config.Bind("Settler", "RequireBed", true, new ConfigDescription("Settlers refuse to work until they claim a free, roofed bed near the hearth.", (AcceptableValueBase)null, new object[1] { AdminOnly() })); NightRest = config.Bind("Settler", "NightRest", true, new ConfigDescription("Workers stop at night and rest at their bed until morning (guards keep watch).", (AcceptableValueBase)null, new object[1] { AdminOnly() })); ChopDamage = config.Bind("Work", "LumberjackChopDamage", 20f, new ConfigDescription("Fallback chop damage applied to a tree only when the real swing does not connect.", (AcceptableValueBase)(object)new AcceptableValueRange(1f, 200f), new object[1] { AdminOnly() })); PickDamage = config.Bind("Work", "MinerPickDamage", 20f, new ConfigDescription("Fallback pickaxe damage applied to a rock only when the real swing does not connect.", (AcceptableValueBase)(object)new AcceptableValueRange(1f, 200f), new object[1] { AdminOnly() })); SettlerHealth = config.Bind("Settler", "Health", 100f, new ConfigDescription("Base max health of a settler.", (AcceptableValueBase)(object)new AcceptableValueRange(10f, 1000f), new object[1] { AdminOnly() })); RespawnMinutes = config.Bind("Settler", "RespawnMinutes", 5, new ConfigDescription("Minutes before a dead settler respawns at its Exiles' Hearth. Equipment is retained; gathered cargo is lost.", (AcceptableValueBase)(object)new AcceptableValueRange(1, 120), new object[1] { AdminOnly() })); MealMinutes = config.Bind("Needs", "MealMinutes", 2, new ConfigDescription("Minutes spent eating dinner or breakfast after food has been collected.", (AcceptableValueBase)(object)new AcceptableValueRange(1, 5), new object[1] { AdminOnly() })); EnableDesertion = config.Bind("Needs", "EnableDesertion", true, new ConfigDescription("Miserable settlers eventually leave and leave their inventory at the hearth.", (AcceptableValueBase)null, new object[1] { AdminOnly() })); DesertionDays = config.Bind("Needs", "DesertionDays", 3, new ConfigDescription("Consecutive simulated miserable days before a settler leaves.", (AcceptableValueBase)(object)new AcceptableValueRange(1, 10), new object[1] { AdminOnly() })); EnableSocialRest = config.Bind("Needs", "EnableSocialRest", true, new ConfigDescription("Idle residents may form seated or standing conversation groups.", (AcceptableValueBase)null, new object[1] { AdminOnly() })); SocialChancePercent = config.Bind("Needs", "SocialChancePercent", 65, new ConfigDescription("Chance that an available resident joins a social rest group.", (AcceptableValueBase)(object)new AcceptableValueRange(0, 100), new object[1] { AdminOnly() })); SocialDurationSeconds = config.Bind("Needs", "SocialDurationSeconds", 90, new ConfigDescription("Approximate duration of an idle conversation.", (AcceptableValueBase)(object)new AcceptableValueRange(30, 300), new object[1] { AdminOnly() })); SocialHappinessBonus = config.Bind("Needs", "SocialHappinessBonus", 4, new ConfigDescription("Daily happiness gained after completing a conversation.", (AcceptableValueBase)(object)new AcceptableValueRange(0, 20), new object[1] { AdminOnly() })); PatrolPointRadius = config.Bind("Guards", "PatrolPointRadius", 60f, new ConfigDescription("Maximum distance between an Exiles' Hearth and one of its patrol points.", (AcceptableValueBase)(object)new AcceptableValueRange(10f, 150f), new object[1] { AdminOnly() })); FarmRadius = config.Bind("Farming", "FarmRadius", 8f, new ConfigDescription("Planting and harvesting radius around each Farm Marker.", (AcceptableValueBase)(object)new AcceptableValueRange(3f, 20f), new object[1] { AdminOnly() })); FarmMarkerMaxRange = config.Bind("Farming", "FarmMarkerMaxRange", 120f, new ConfigDescription("Maximum distance between a Farm Marker and its Exiles' Hearth.", (AcceptableValueBase)(object)new AcceptableValueRange(20f, 300f), new object[1] { AdminOnly() })); FarmSeedReserve = config.Bind("Farming", "SeedReserve", 3, new ConfigDescription("Planting resources kept in storage during normal planting. A farmer may consume one harvested product when needed to restart reciprocal seed production.", (AcceptableValueBase)(object)new AcceptableValueRange(0, 50), new object[1] { AdminOnly() })); } private static ConfigurationManagerAttributes AdminOnly() { return new ConfigurationManagerAttributes { IsAdminOnly = true }; } } internal sealed class ConfigurationManagerAttributes { public bool? IsAdminOnly; } internal static class HfConstants { internal const string PluginGuid = "gianl.hearthfolk"; internal const string PluginName = "Hearthfolk"; internal const string PluginVersion = "1.0.0"; internal const string HearthPrefabName = "piece_hf_exiles_hearth"; internal const string LumberBannerPrefabName = "piece_hf_lumber_banner"; internal const string MinerBannerPrefabName = "piece_hf_miner_banner"; internal const string LegacySawmillPrefabName = "piece_hf_sawmill"; internal const string LegacyMinePrefabName = "piece_hf_mine"; internal const string LegacyBarracksPrefabName = "piece_hf_barracks"; internal const string PatrolPointPrefabName = "piece_hf_patrol_point"; internal const string FarmMarkerPrefabName = "piece_hf_farm_marker"; internal const string SettlerShelterPrefabName = "piece_hf_settler_shelter"; internal const string SettlerPrefabName = "hf_settler"; internal const string SettlerBasePrefab = "Player"; internal const string ZdoOwner = "hf_owner"; internal const string ZdoHome = "hf_home"; internal const string ZdoName = "hf_name"; internal const string ZdoIdentity = "hf_identity"; internal const string ZdoRole = "hf_role"; internal const string ZdoStatus = "hf_status"; internal const string ZdoStorage = "hf_storage"; internal const string ZdoStoragePosition = "hf_storage_pos"; internal const string ZdoStoragePrefab = "hf_storage_prefab"; internal const string ZdoStorageCreator = "hf_storage_creator"; internal const string ZdoChestSortConfigured = "hf_sort_configured"; internal const string ZdoChestSortItems = "hf_sort_items"; internal const string ZdoIntakeHearth = "hf_intake_hearth"; internal const string ZdoIntakeRoles = "hf_intake_roles"; internal const string SortCargoTag = "hf_sort_cargo"; internal const string ZdoBed = "hf_bed"; internal const string ZdoCaretakerTasks = "hf_caretaker_tasks"; internal const string ZdoFarmerCrops = "hf_farmer_crops"; internal const string ZdoFarmerMode = "hf_farmer_mode"; internal const string ZdoFarmerMarkersConfigured = "hf_farmer_markers_configured"; internal const string ZdoFarmerMarkers = "hf_farmer_markers"; internal const string ZdoFarmerStockTargets = "hf_farmer_stock_targets"; internal const string ZdoWorkRadius = "hf_radius"; internal const string ZdoRespawning = "hf_respawning"; internal const string ZdoRespawnAt = "hf_respawn_at"; internal const string ZdoNeedsInitialized = "hf_needs_init"; internal const string ZdoHappiness = "hf_happiness"; internal const string ZdoMoraleReasons = "hf_morale_reasons"; internal const string ZdoNeedsEvaluatedDay = "hf_needs_eval_day"; internal const string ZdoUnhappyDays = "hf_unhappy_days"; internal const string ZdoDinnerDay = "hf_dinner_day"; internal const string ZdoDinnerMissedDay = "hf_dinner_missed_day"; internal const string ZdoBreakfastDay = "hf_breakfast_day"; internal const string ZdoBreakfastMissedDay = "hf_breakfast_missed_day"; internal const string ZdoSleepStartedDay = "hf_sleep_started_day"; internal const string ZdoSleepStartedAt = "hf_sleep_started_at"; internal const string ZdoSleptDay = "hf_slept_day"; internal const string ZdoHealedDay = "hf_healed_day"; internal const string ZdoSleepMissedDay = "hf_sleep_missed_day"; internal const string ZdoSeatedMealDay = "hf_seated_meal_day"; internal const string ZdoSocialMealDay = "hf_social_meal_day"; internal const string ZdoThreatDay = "hf_threat_day"; internal const string ZdoMealKind = "hf_meal_kind"; internal const string ZdoMealEnd = "hf_meal_end"; internal const string ZdoMealSearchUntil = "hf_meal_search_until"; internal const string ZdoLastFood = "hf_last_food"; internal const string ZdoWorkstation = "hf_workstation"; internal const string ZdoWorkstationPreviousRole = "hf_workstation_prev_role"; internal const string ZdoGuardShiftStart = "hf_guard_shift_start"; internal const string ZdoGuardShiftEnd = "hf_guard_shift_end"; internal const string ZdoGuardScheduleInitialized = "hf_guard_shift_initialized"; internal const string ZdoGuardPatrolConfigured = "hf_guard_patrol_configured"; internal const string ZdoGuardPatrolRoute = "hf_guard_patrol_route"; internal const string ZdoFollowerTarget = "hf_follower_target"; internal const string ZdoFollowerTargetName = "hf_follower_target_name"; internal const string ZdoFollowerMode = "hf_follower_mode"; internal const string ZdoFollowerWaitPosition = "hf_follower_wait_position"; internal const string ZdoFollowerCombatMode = "hf_follower_combat_mode"; internal const string ZdoAppearanceInitialized = "hf_appearance_initialized"; internal const string ZdoAppearanceBody = "hf_appearance_body"; internal const string ZdoAppearanceHair = "hf_appearance_hair"; internal const string ZdoAppearanceBeard = "hf_appearance_beard"; internal const string ZdoAppearanceHairColor = "hf_appearance_hair_color"; internal const string ZdoAppearanceSkinTone = "hf_appearance_skin_tone"; internal const string ZdoSocializedDay = "hf_socialized_day"; internal const string ZdoSocialLine = "hf_social_line"; internal const string ZdoSocialLineSequence = "hf_social_line_sequence"; internal const string ZdoSocialLineTime = "hf_social_line_time"; internal const string ZdoBedClaim = "hf_claim"; internal const string ZdoBedClaimIdentity = "hf_claim_identity"; internal const string ZdoTentPalette = "hf_tent_palette"; internal const string ZdoNextSerial = "hf_next_settler"; internal const string ZdoSettlementAlert = "hf_settlement_alert"; internal const string ZdoDefenseThreatUntil = "hf_defense_threat_until"; internal const string ZdoPatrolRouteConfigured = "hf_patrol_route_configured"; internal const string ZdoPatrolRoute = "hf_patrol_route"; internal const string ZdoPatrolRouteIdentity = "hf_patrol_route_identity"; internal const string ZdoGatewayDoorsConfigured = "hf_gateway_doors_configured"; internal const string ZdoGatewayDoors = "hf_gateway_doors"; internal const string ZdoGatewayDoorsIdentity = "hf_gateway_doors_identity"; internal const string ZdoGatewayMarkerEnabled = "hf_gateway_marker"; internal const string ZdoGatewayMarkerHearth = "hf_gateway_hearth"; internal const string ZdoGatewayMarkerCreator = "hf_gateway_creator"; internal const string ZdoFarmCrop = "hf_farm_crop"; internal const string ZdoFarmCombined = "hf_farm_combined"; internal const string ZdoFarmCombinedNext = "hf_farm_combined_next"; internal const string ZdoFlags = "hf_flags"; internal const string FarmCargoTag = "hf_farm_cargo"; internal const string RpcSetRole = "hf_SetRole"; internal const string RpcSetStorage = "hf_SetStorage"; internal const string RpcSetFlags = "hf_SetFlags"; internal const string RpcSetCaretakerTasks = "hf_SetCaretakerTasks"; internal const string RpcSetFarmerCrops = "hf_SetFarmerCrops"; internal const string RpcSetFarmerMode = "hf_SetFarmerMode"; internal const string RpcSetFarmerMarkers = "hf_SetFarmerMarkers"; internal const string RpcSetFarmerStockTarget = "hf_SetFarmerStockTarget"; internal const string RpcDismiss = "hf_Dismiss"; internal const string RpcSetChestSort = "hf_SetChestSort"; internal const string RpcSetGuardSchedule = "hf_SetGuardSchedule"; internal const string RpcSetGuardPatrolRoute = "hf_SetGuardPatrolRoute"; internal const string RpcFollowerCommand = "hf_FollowerCommand"; internal const string RpcSetFollowerCombatMode = "hf_SetFollowerCombatMode"; internal const string RpcCycleAppearance = "hf_CycleAppearance"; internal const string RpcRenameSettler = "hf_RenameSettler"; internal const string RpcSetPatrolRoute = "hf_SetPatrolRoute"; internal const string RpcToggleSettlementAlert = "hf_ToggleSettlementAlert"; internal const string RpcSignalDefenseThreat = "hf_SignalDefenseThreat"; internal const string RpcSetFarmCrop = "hf_SetFarmCrop"; internal const string RpcSetFarmSelection = "hf_SetFarmSelection"; internal const string RpcSetIntakeStorage = "hf_SetIntakeStorage"; internal const string RpcSetIntakeStorageRoles = "hf_SetIntakeStorageRoles"; internal const string RpcSetGatewayDoors = "hf_SetGatewayDoors"; } internal enum SettlerRole { Idle, Lumberjack, Guard, Caretaker, Miner, Follower, Farmer } [Flags] internal enum FarmerWorkMode { None = 0, Plant = 1, Harvest = 2, FullCycle = 3 } [Flags] internal enum IntakeRoles { None = 0, Lumberjack = 1, Miner = 2, Farmer = 4, All = 7 } internal enum FollowerMode { Returning, Following, Waiting } internal enum FollowerCommand { FollowMe = 1, WaitHere, ReturnHome } internal enum FollowerCombatMode { Defensive, Aggressive, Passive } internal enum SettlerAppearanceField { Body, Hair, Beard, HairColor, SkinTone, Randomize } [Flags] internal enum CaretakerTasks { None = 0, RepairStructures = 1, SortStorage = 2, FuelFires = 4, FuelMachines = 8, LoadMachines = 0x10, CollectOutputs = 0x20, All = 0x3F } [Flags] internal enum SettlerFlags { None = 0, Beech = 1, Fir = 2, Pine = 4, Birch = 8, Oak = 0x10, Swamp = 0x20, Yggdrasil = 0x40, AshTree = 0x80, Stone = 0x100, Copper = 0x200, Tin = 0x400, Silver = 0x800, Obsidian = 0x1000, Iron = 0x2000, Flametal = 0x4000, All = -1 } internal static class HfGuiSkin { private static GUISkin _skin; private static GUIStyle _sectionTitle; private static GUIStyle _cardTitle; private static GUIStyle _mutedLabel; private static GUIStyle _cardButton; private static GUIStyle _tabButton; private static GUIStyle _selectedButton; private static GUIStyle _dangerButton; private static GUIStyle _centeredSmall; private static readonly Color Parchment = new Color(0.85f, 0.77f, 0.6f); private static readonly Color Gold = new Color(1f, 0.85f, 0.45f); private static readonly Color PanelBg = new Color(0.11f, 0.085f, 0.06f, 0.96f); private static readonly Color RowBg = new Color(0.19f, 0.15f, 0.1f, 0.92f); private static readonly Color ButtonBg = new Color(0.28f, 0.21f, 0.13f); private static readonly Color ButtonHover = new Color(0.38f, 0.29f, 0.17f); private static readonly Color ButtonActive = new Color(0.48f, 0.37f, 0.2f); internal static GUIStyle SectionTitle { get { Get(); return _sectionTitle; } } internal static GUIStyle CardTitle { get { Get(); return _cardTitle; } } internal static GUIStyle MutedLabel { get { Get(); return _mutedLabel; } } internal static GUIStyle CardButton { get { Get(); return _cardButton; } } internal static GUIStyle TabButton { get { Get(); return _tabButton; } } internal static GUIStyle SelectedButton { get { Get(); return _selectedButton; } } internal static GUIStyle DangerButton { get { Get(); return _dangerButton; } } internal static GUIStyle CenteredSmall { get { Get(); return _centeredSmall; } } internal static GUISkin Get() { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_009c: 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_00e3: Expected O, but got Unknown //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0161: 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_019d: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01cf: Unknown result type (might be due to invalid IL or missing references) //IL_01fa: Unknown result type (might be due to invalid IL or missing references) //IL_0204: Expected O, but got Unknown //IL_0212: Unknown result type (might be due to invalid IL or missing references) //IL_021c: Expected O, but got Unknown //IL_022b: Unknown result type (might be due to invalid IL or missing references) //IL_0249: Unknown result type (might be due to invalid IL or missing references) //IL_0263: Unknown result type (might be due to invalid IL or missing references) //IL_026d: Expected O, but got Unknown //IL_028b: 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) //IL_0298: 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) //IL_02a4: Unknown result type (might be due to invalid IL or missing references) //IL_02ae: Expected O, but got Unknown //IL_02b3: Expected O, but got Unknown //IL_02bd: Unknown result type (might be due to invalid IL or missing references) //IL_02d1: Unknown result type (might be due to invalid IL or missing references) //IL_02d6: Unknown result type (might be due to invalid IL or missing references) //IL_02de: Unknown result type (might be due to invalid IL or missing references) //IL_02e5: Unknown result type (might be due to invalid IL or missing references) //IL_02f1: Expected O, but got Unknown //IL_02fb: Unknown result type (might be due to invalid IL or missing references) //IL_030f: Unknown result type (might be due to invalid IL or missing references) //IL_0314: Unknown result type (might be due to invalid IL or missing references) //IL_031c: Unknown result type (might be due to invalid IL or missing references) //IL_0328: Expected O, but got Unknown //IL_0341: Unknown result type (might be due to invalid IL or missing references) //IL_0355: Unknown result type (might be due to invalid IL or missing references) //IL_035a: Unknown result type (might be due to invalid IL or missing references) //IL_0361: Unknown result type (might be due to invalid IL or missing references) //IL_0369: Unknown result type (might be due to invalid IL or missing references) //IL_0370: Unknown result type (might be due to invalid IL or missing references) //IL_0379: Unknown result type (might be due to invalid IL or missing references) //IL_0383: Expected O, but got Unknown //IL_0383: Unknown result type (might be due to invalid IL or missing references) //IL_0388: Unknown result type (might be due to invalid IL or missing references) //IL_0392: Expected O, but got Unknown //IL_0397: Expected O, but got Unknown //IL_03a1: Unknown result type (might be due to invalid IL or missing references) //IL_03a6: Unknown result type (might be due to invalid IL or missing references) //IL_03ae: Unknown result type (might be due to invalid IL or missing references) //IL_03b5: Unknown result type (might be due to invalid IL or missing references) //IL_03c5: Expected O, but got Unknown //IL_03cf: Unknown result type (might be due to invalid IL or missing references) //IL_03d4: Unknown result type (might be due to invalid IL or missing references) //IL_03e0: Expected O, but got Unknown //IL_03ef: Unknown result type (might be due to invalid IL or missing references) //IL_0433: Unknown result type (might be due to invalid IL or missing references) //IL_045b: Unknown result type (might be due to invalid IL or missing references) //IL_0474: Unknown result type (might be due to invalid IL or missing references) //IL_0488: Unknown result type (might be due to invalid IL or missing references) //IL_049c: Unknown result type (might be due to invalid IL or missing references) //IL_04b0: Unknown result type (might be due to invalid IL or missing references) //IL_04c4: Unknown result type (might be due to invalid IL or missing references) //IL_04ce: Expected O, but got Unknown //IL_04dd: Unknown result type (might be due to invalid IL or missing references) //IL_0521: Unknown result type (might be due to invalid IL or missing references) //IL_0549: Unknown result type (might be due to invalid IL or missing references) //IL_0562: Unknown result type (might be due to invalid IL or missing references) //IL_0567: Unknown result type (might be due to invalid IL or missing references) //IL_056e: Unknown result type (might be due to invalid IL or missing references) //IL_0576: Unknown result type (might be due to invalid IL or missing references) //IL_0582: Expected O, but got Unknown if ((Object)(object)_skin != (Object)null) { return _skin; } _skin = Object.Instantiate(GUI.skin); ((Object)_skin).hideFlags = (HideFlags)61; _skin.window.normal.background = Tex(PanelBg); _skin.window.onNormal.background = _skin.window.normal.background; _skin.window.normal.textColor = Gold; _skin.window.onNormal.textColor = Gold; _skin.window.fontSize = 16; _skin.window.fontStyle = (FontStyle)1; _skin.window.padding = new RectOffset(14, 14, 26, 12); _skin.label.normal.textColor = Parchment; _skin.label.fontSize = 14; _skin.label.wordWrap = true; Texture2D background = Tex(ButtonBg); _skin.button.normal.background = background; _skin.button.onNormal.background = background; _skin.button.hover.background = Tex(ButtonHover); _skin.button.active.background = Tex(ButtonActive); _skin.button.normal.textColor = Parchment; _skin.button.hover.textColor = Gold; _skin.button.active.textColor = Gold; _skin.button.fontSize = 13; _skin.button.padding = new RectOffset(10, 10, 6, 6); _skin.button.margin = new RectOffset(3, 3, 3, 3); _skin.box.normal.background = Tex(RowBg); _skin.box.normal.textColor = Parchment; _skin.box.padding = new RectOffset(10, 10, 8, 8); _skin.verticalScrollbar.fixedWidth = 12f; _sectionTitle = new GUIStyle(_skin.label) { fontSize = 16, fontStyle = (FontStyle)1, margin = new RectOffset(2, 2, 8, 5) }; _sectionTitle.normal.textColor = Gold; _cardTitle = new GUIStyle(_skin.label) { fontSize = 16, fontStyle = (FontStyle)1, wordWrap = false }; _cardTitle.normal.textColor = Gold; _mutedLabel = new GUIStyle(_skin.label) { fontSize = 12, wordWrap = true }; _mutedLabel.normal.textColor = new Color(0.66f, 0.58f, 0.44f); _cardButton = new GUIStyle(_skin.button) { alignment = (TextAnchor)0, fontSize = 13, wordWrap = true, padding = new RectOffset(12, 12, 9, 9), margin = new RectOffset(2, 2, 3, 3) }; _tabButton = new GUIStyle(_skin.button) { fontSize = 14, fontStyle = (FontStyle)1, fixedHeight = 34f }; _selectedButton = new GUIStyle(_skin.button) { fontStyle = (FontStyle)1 }; Texture2D background2 = Tex(new Color(0.52f, 0.38f, 0.16f)); _selectedButton.normal.background = background2; _selectedButton.onNormal.background = background2; _selectedButton.hover.background = Tex(new Color(0.62f, 0.46f, 0.19f)); _selectedButton.active.background = Tex(new Color(0.7f, 0.52f, 0.22f)); _selectedButton.normal.textColor = Gold; _selectedButton.onNormal.textColor = Gold; _selectedButton.hover.textColor = Gold; _selectedButton.active.textColor = Gold; _dangerButton = new GUIStyle(_skin.button); Texture2D background3 = Tex(new Color(0.34f, 0.12f, 0.09f)); _dangerButton.normal.background = background3; _dangerButton.onNormal.background = background3; _dangerButton.hover.background = Tex(new Color(0.48f, 0.16f, 0.1f)); _dangerButton.active.background = Tex(new Color(0.58f, 0.2f, 0.11f)); _centeredSmall = new GUIStyle(_skin.label) { alignment = (TextAnchor)4, fontSize = 12, fontStyle = (FontStyle)1 }; return _skin; } private static Texture2D Tex(Color color) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown Texture2D val = new Texture2D(1, 1, (TextureFormat)4, false) { hideFlags = (HideFlags)61 }; val.SetPixel(0, 0, color); val.Apply(); return val; } } internal static class ItemDrawerBridge { internal sealed class Target { private readonly object _drawer; private readonly GameObject _physicalObject; internal ZNetView View { get; } internal GameObject GameObject => _physicalObject; internal Vector3 Position { get { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_physicalObject != (Object)null)) { return Vector3.zero; } return _physicalObject.transform.position; } } internal string Prefab { get { if (!IsValid) { return string.Empty; } return View.GetZDO().GetString("Prefab", string.Empty); } } internal int Amount { get { if (!IsValid) { return 0; } return View.GetZDO().GetInt("Amount", 0); } } internal int Quality { get { if (!IsValid) { return 1; } return View.GetZDO().GetInt("Quality", 1); } } internal bool IsValid { get { if (_drawer != null && (Object)(object)View != (Object)null && View.IsValid() && (Object)(object)GameObject != (Object)null) { return GameObject.activeInHierarchy; } return false; } } internal Target(object drawer, ZNetView view) { _drawer = drawer; View = view; Piece val = (((Object)(object)view != (Object)null) ? (((Component)view).GetComponent() ?? ((Component)view).GetComponentInParent()) : null); _physicalObject = (((Object)(object)val != (Object)null) ? ((Component)val).gameObject : (((Object)(object)view != (Object)null) ? ((Component)view).gameObject : null)); } internal bool Matches(string prefab, int quality) { if (IsValid && !string.IsNullOrEmpty(prefab) && Prefab == prefab) { return Quality == Mathf.Max(1, quality); } return false; } internal bool Add(int amount, int quality) { if (!IsValid || amount <= 0 || _add == null) { return false; } try { _add.Invoke(_drawer, new object[2] { amount, Mathf.Max(1, quality) }); return true; } catch (Exception exception) { Logger.LogWarning((object)("Hearthfolk: ItemDrawers deposit RPC failed: " + Unwrap(exception).Message)); return false; } } } private const string ApiTypeName = "API.ItemDrawers_API, kg_ItemDrawers"; private const float RetryInterval = 10f; private static Type _apiType; private static Type _drawerType; private static Type _drawerComponentType; private static MethodInfo _allInRange; private static MethodInfo _add; private static FieldInfo _view; private static FieldInfo _prefab; private static FieldInfo _amount; private static FieldInfo _quality; private static float _retryAt; private static bool _loggedAvailable; internal static List FindTargets(SettlerController settler) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) List list = new List(); if ((Object)(object)settler == (Object)null || !EnsureApi()) { return list; } try { if (!(_allInRange.Invoke(null, new object[2] { settler.Home, settler.WorkRadius }) is IEnumerable enumerable)) { return list; } foreach (object item in enumerable) { ZNetView view = (ZNetView)((item != null) ? /*isinst with value type is only supported in some contexts*/: null); Target target = new Target(item, view); if (IsManaged(settler, target)) { list.Add(target); } } } catch (Exception exception) { Logger.LogWarning((object)("Hearthfolk: ItemDrawers discovery failed: " + Unwrap(exception).Message)); ResetForRetry(); } return list; } internal static bool CanStore(ItemData item, Target target) { if (item == null || target == null || (Object)(object)item.m_dropPrefab == (Object)null || item.m_stack <= 0 || item.m_equipped || (item.m_customData != null && item.m_customData.Count > 0)) { return false; } return target.Matches(((Object)item.m_dropPrefab).name, item.m_quality); } internal static bool CanReach(SettlerController settler, Target target, float reach) { //IL_0024: 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_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: 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_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: 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_00b0: 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_012b: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)settler == (Object)null || target == null || !target.IsValid || _drawerComponentType == null) { return false; } Vector3 val = settler.Position + Vector3.up * 1.05f; Vector3 val2 = target.Position + Vector3.up * 0.75f; float num = Vector3.Distance(val, val2); Collider[] componentsInChildren = target.GameObject.GetComponentsInChildren(true); foreach (Collider val3 in componentsInChildren) { if (!((Object)(object)val3 == (Object)null) && !val3.isTrigger && val3.enabled) { Vector3 val4 = val3.ClosestPoint(val); float num2 = Vector3.Distance(val, val4); if (num2 < num) { val2 = val4; num = num2; } } } if (num > reach) { return false; } Vector3 val5 = val2 - val; float magnitude = ((Vector3)(ref val5)).magnitude; if (magnitude <= 0.05f) { return true; } foreach (RaycastHit item in from hit in Physics.RaycastAll(val, val5 / magnitude, magnitude, -5, (QueryTriggerInteraction)1) orderby ((RaycastHit)(ref hit)).distance select hit) { RaycastHit current = item; Transform val6 = (((Object)(object)((RaycastHit)(ref current)).collider != (Object)null) ? ((Component)((RaycastHit)(ref current)).collider).transform : null); if (!((Object)(object)val6 == (Object)null) && !((Object)(object)((Component)val6).GetComponentInParent() != (Object)null) && !val6.IsChildOf(target.GameObject.transform) && !target.GameObject.transform.IsChildOf(val6) && !((Object)(object)((Component)val6).GetComponentInParent(_drawerComponentType) != (Object)null)) { return false; } } return true; } internal static int Deposit(Inventory inventory, Target target, string sharedName, string prefabName, int quality, int requested) { if (inventory == null || target == null || requested <= 0 || string.IsNullOrEmpty(sharedName) || string.IsNullOrEmpty(prefabName) || !target.Matches(prefabName, quality)) { return 0; } ItemData val = ((IEnumerable)inventory.GetAllItems()).FirstOrDefault((Func)((ItemData candidate) => candidate != null && !candidate.m_equipped && candidate.m_stack > 0 && candidate.m_shared.m_name == sharedName && (Object)(object)candidate.m_dropPrefab != (Object)null && ((Object)candidate.m_dropPrefab).name == prefabName && candidate.m_quality == quality && candidate.m_customData != null && candidate.m_customData.Count == 1 && candidate.m_customData.ContainsKey("hf_sort_cargo"))); if (val == null) { return 0; } int num = Mathf.Min(requested, val.m_stack); ItemData val2 = val.Clone(); val2.m_stack = num; if (!inventory.RemoveItem(val, num)) { return 0; } if (!target.Add(num, quality)) { inventory.AddItem(val2); inventory.Changed(); return 0; } inventory.Changed(); Diagnostics.Log($"Hearthfolk[itemdrawers]: deposited {num} x {prefabName} quality={quality}"); return num; } private static bool IsManaged(SettlerController settler, Target target) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) if (target == null || !target.IsValid || Vector3.Distance(target.Position, settler.Home) > settler.WorkRadius || !PrivateArea.CheckAccess(target.Position, 0f, false, false)) { return false; } Piece val = ((Component)target.View).GetComponent() ?? ((Component)target.View).GetComponentInParent(); if ((Object)(object)val != (Object)null) { return val.IsPlacedByPlayer(); } return false; } private static bool EnsureApi() { if (_apiType != null && _drawerType != null && _drawerComponentType != null && _allInRange != null && _add != null && _view != null) { return true; } if (Time.realtimeSinceStartup < _retryAt) { return false; } _retryAt = Time.realtimeSinceStartup + 10f; try { _apiType = Type.GetType("API.ItemDrawers_API, kg_ItemDrawers", throwOnError: false); _drawerType = _apiType?.GetNestedType("Drawer", BindingFlags.Public | BindingFlags.NonPublic); _drawerComponentType = Type.GetType("kg_ItemDrawers.DrawerComponent, kg_ItemDrawers", throwOnError: false); _allInRange = _apiType?.GetMethod("AllDrawersInRange", BindingFlags.Static | BindingFlags.Public); _add = _drawerType?.GetMethod("Add", BindingFlags.Instance | BindingFlags.Public); _view = _drawerType?.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault((FieldInfo field) => typeof(ZNetView).IsAssignableFrom(field.FieldType)); _prefab = _drawerType?.GetField("Prefab", BindingFlags.Instance | BindingFlags.Public); _amount = _drawerType?.GetField("Amount", BindingFlags.Instance | BindingFlags.Public); _quality = _drawerType?.GetField("Quality", BindingFlags.Instance | BindingFlags.Public); if (_apiType == null || _drawerType == null || _drawerComponentType == null || _allInRange == null || _add == null || _view == null || _prefab == null || _amount == null || _quality == null) { ResetForRetry(); return false; } if (!_loggedAvailable) { _loggedAvailable = true; Logger.LogInfo((object)"Hearthfolk: compatible ItemDrawers API detected; caretaker sorting enabled."); } return true; } catch (Exception exception) { Logger.LogWarning((object)("Hearthfolk: ItemDrawers API initialization failed: " + Unwrap(exception).Message)); ResetForRetry(); return false; } } private static void ResetForRetry() { _apiType = null; _drawerType = null; _drawerComponentType = null; _allInRange = null; _add = null; _view = null; _prefab = null; _amount = null; _quality = null; _retryAt = Time.realtimeSinceStartup + 10f; } private static Exception Unwrap(Exception exception) { if (!(exception is TargetInvocationException { InnerException: not null } ex)) { return exception; } return ex.InnerException; } } internal sealed class LegacyBuildingCleanup : MonoBehaviour { private static readonly string[] WorkerKeys = new string[3] { "hf_building_worker_0", "hf_building_worker_1", "hf_building_worker_2" }; private ZNetView _nview; private Container _container; private int _attempts; private void Awake() { _nview = ((Component)this).GetComponent(); _container = ((Component)this).GetComponent(); } private void Start() { TryRemove(); } private void TryRemove() { //IL_0052: 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_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005b: 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_0091: 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) if ((Object)(object)_nview == (Object)null || !_nview.IsValid() || !_nview.IsOwner() || (Object)(object)ZNetScene.instance == (Object)null) { return; } ZDO zDO = _nview.GetZDO(); string[] workerKeys = WorkerKeys; foreach (string text in workerKeys) { ZDOID zDOID = zDO.GetZDOID(text); if (!(zDOID == ZDOID.None) && ZDOMan.instance != null) { ZDO zDO2 = ZDOMan.instance.GetZDO(zDOID); if (_attempts < 15 && zDO2 != null && zDO2.GetZDOID("hf_workstation") == zDO.m_uid) { _attempts++; ((MonoBehaviour)this).Invoke("TryRemove", 2f); return; } } } if ((Object)(object)_container != (Object)null && _container.GetInventory().NrOfItems() > 0) { _container.OnDestroyed(); } Logger.LogInfo((object)("Hearthfolk: removing retired structure " + ((Object)((Component)this).gameObject).name + ".")); ZNetScene.instance.Destroy(((Component)this).gameObject); } } internal sealed class MapPins : MonoBehaviour { private const float UpdateInterval = 1f; private readonly Dictionary _pins = new Dictionary(); private readonly List _stale = new List(); private float _next; private void Update() { //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) if (Time.time < _next || (Object)(object)Minimap.instance == (Object)null) { return; } _next = Time.time + 1f; foreach (WorkBanner instance in WorkBanner.Instances) { if ((Object)(object)instance != (Object)null && instance.IsValid) { Sync((Component)(object)instance, instance.Position, (PinType)2, instance.LocalizedName); } } foreach (SettlerController instance2 in SettlerController.Instances) { if ((Object)(object)instance2 != (Object)null && instance2.IsValidSettler) { Sync((Component)(object)instance2, ((Component)instance2).transform.position, (PinType)10, instance2.PanelName); } } PruneStale(); } private void Sync(Component owner, Vector3 position, PinType type, string name) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0036: 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) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) if (_pins.TryGetValue(owner, out var value)) { value.m_pos = position; value.m_name = name; } else { _pins[owner] = Minimap.instance.AddPin(position, type, name, false, false, 0L, default(PlatformUserID)); } } private void PruneStale() { _stale.Clear(); foreach (KeyValuePair pin in _pins) { if ((Object)(object)pin.Key == (Object)null) { _stale.Add(pin.Key); } } foreach (Component item in _stale) { if ((Object)(object)Minimap.instance != (Object)null && _pins[item] != null) { Minimap.instance.RemovePin(_pins[item]); } _pins.Remove(item); } } private void OnDestroy() { if ((Object)(object)Minimap.instance == (Object)null) { return; } foreach (PinData value in _pins.Values) { if (value != null) { Minimap.instance.RemovePin(value); } } _pins.Clear(); } } internal static class MaterialFilters { internal static bool Allowed(SettlerFlags enabled, SettlerFlags material) { if (material != SettlerFlags.None) { return (enabled & material) != 0; } return true; } internal static SettlerFlags TreeFlag(GameObject go) { string text = PrefabName(go).ToLowerInvariant(); if (text.Contains("beech")) { return SettlerFlags.Beech; } if (text.Contains("fir")) { return SettlerFlags.Fir; } if (text.Contains("pine")) { return SettlerFlags.Pine; } if (text.Contains("birch")) { return SettlerFlags.Birch; } if (text.Contains("oak")) { return SettlerFlags.Oak; } if (text.Contains("swamp")) { return SettlerFlags.Swamp; } if (text.Contains("ygga") || text.Contains("yggdrasil")) { return SettlerFlags.Yggdrasil; } if (text.Contains("ashland") || text.Contains("ashtree")) { return SettlerFlags.AshTree; } return SettlerFlags.None; } internal static SettlerFlags RockFlag(GameObject go) { string text = PrefabName(go).ToLowerInvariant(); if (text.Contains("copper")) { return SettlerFlags.Copper; } if (text.Contains("tin")) { return SettlerFlags.Tin; } if (text.Contains("silvervein")) { return SettlerFlags.Silver; } if (text.Contains("obsidian")) { return SettlerFlags.Obsidian; } if (text.Contains("mud") || text.Contains("giant")) { return SettlerFlags.Iron; } if (text.Contains("flametal")) { return SettlerFlags.Flametal; } return SettlerFlags.Stone; } internal static string PrefabName(GameObject go) { if ((Object)(object)go == (Object)null) { return string.Empty; } ZNetView componentInParent = go.GetComponentInParent(); if ((Object)(object)componentInParent != (Object)null && componentInParent.IsValid() && (Object)(object)ZNetScene.instance != (Object)null) { GameObject prefab = ZNetScene.instance.GetPrefab(componentInParent.GetZDO().GetPrefab()); if ((Object)(object)prefab != (Object)null) { return ((Object)prefab).name; } } return Utils.GetPrefabName(go); } internal static SettlerFlags ItemFlag(string sharedName) { return sharedName switch { "$item_finewood" => SettlerFlags.Birch | SettlerFlags.Oak, "$item_roundlog" => SettlerFlags.Pine, "$item_ancientbark" => SettlerFlags.Swamp, "$item_yggdrasilwood" => SettlerFlags.Yggdrasil, "$item_ashwood" => SettlerFlags.AshTree, "$item_stone" => SettlerFlags.Stone, "$item_copperore" => SettlerFlags.Copper, "$item_tinore" => SettlerFlags.Tin, "$item_silverore" => SettlerFlags.Silver, "$item_obsidian" => SettlerFlags.Obsidian, "$item_ironscrap" => SettlerFlags.Iron, "$item_flametalore" => SettlerFlags.Flametal, _ => SettlerFlags.None, }; } } internal sealed class MineTarget { private readonly MineRock5 _vein; private readonly Destructible _boulder; private Collider _selectedCollider; internal bool IsVein => (Object)(object)_vein != (Object)null; internal GameObject GameObject { get { if (!((Object)(object)_vein != (Object)null)) { if (!((Object)(object)_boulder != (Object)null)) { return null; } return ((Component)_boulder).gameObject; } return ((Component)_vein).gameObject; } } internal int InstanceId { get { if (!((Object)(object)GameObject != (Object)null)) { return 0; } return ((Object)GameObject).GetInstanceID(); } } internal Vector3 Center => GameObject.transform.position; internal int MinToolTier { get { if (!((Object)(object)_vein != (Object)null)) { if (!((Object)(object)_boulder != (Object)null)) { return 0; } return _boulder.m_minToolTier; } return _vein.m_minToolTier; } } internal MineTarget(MineRock5 vein) { _vein = vein; } internal MineTarget(Destructible boulder) { _boulder = boulder; } internal bool IsValid() { GameObject gameObject = GameObject; if ((Object)(object)gameObject == (Object)null || !gameObject.activeInHierarchy) { return false; } if ((Object)(object)_vein != (Object)null) { return HasExposedVeinArea(); } if ((Object)(object)_boulder == (Object)null) { return false; } ZNetView nview = _boulder.m_nview; if ((((Object)(object)nview != (Object)null && nview.IsValid()) ? nview.GetZDO().GetFloat(ZDOVars.s_health, _boulder.m_health) : _boulder.m_health) > 0f) { return HasExposedCollider(gameObject); } return false; } internal static bool IsMineableRock(Destructible destructible) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_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) //IL_000e: Invalid comparison between Unknown and I4 //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Invalid comparison between Unknown and I4 //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Invalid comparison between Unknown and I4 //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Invalid comparison between Unknown and I4 DamageModifiers damages = destructible.m_damages; if ((int)damages.m_pickaxe != 3 && (int)damages.m_pickaxe != 4 && (int)damages.m_slash == 3) { return (int)damages.m_chop == 3; } return false; } internal Vector3 ClosestPoint(Vector3 from) { //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0068: 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_0118: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) _selectedCollider = null; if ((Object)(object)_vein != (Object)null && _vein.m_hitAreas != null) { Vector3 result = from; float num = float.MaxValue; foreach (HitArea hitArea in _vein.m_hitAreas) { if (IsLiveExposedArea(hitArea)) { Vector3 val = SurfacePoint(hitArea.m_collider, from); float num2 = Vector3.Distance(val, from); if (num2 < num) { _selectedCollider = hitArea.m_collider; result = val; num = num2; } } } if (!((Object)(object)_selectedCollider != (Object)null)) { return from; } return result; } GameObject gameObject = GameObject; if ((Object)(object)gameObject == (Object)null) { return from; } Vector3 result2 = from; float num3 = float.MaxValue; Collider[] componentsInChildren = gameObject.GetComponentsInChildren(); foreach (Collider val2 in componentsInChildren) { if (IsUsableCollider(val2) && IsExposed(val2)) { Vector3 val3 = SurfacePoint(val2, from); float num4 = Vector3.Distance(val3, from); if (num4 < num3) { _selectedCollider = val2; result2 = val3; num3 = num4; } } } if (!((Object)(object)_selectedCollider != (Object)null)) { return gameObject.transform.position; } return result2; } internal float ReadHealth() { if ((Object)(object)_boulder != (Object)null) { ZNetView nview = _boulder.m_nview; if (!((Object)(object)nview != (Object)null) || !nview.IsValid()) { return _boulder.m_health; } return nview.GetZDO().GetFloat(ZDOVars.s_health, _boulder.m_health); } if ((Object)(object)_vein != (Object)null && _vein.m_hitAreas != null) { float num = 0f; { foreach (HitArea hitArea in _vein.m_hitAreas) { if (hitArea.m_health > 0f) { num += hitArea.m_health; } } return num; } } return 0f; } internal void Damage(HitData hit) { if ((Object)(object)_vein != (Object)null) { if (IsSelectedColliderLive()) { hit.m_hitCollider = _selectedCollider; hit.m_radius = 0f; _vein.Damage(hit); } } else if ((Object)(object)_boulder != (Object)null) { hit.m_hitCollider = _selectedCollider; _boulder.Damage(hit); } } private bool HasExposedVeinArea() { if (_vein.m_hitAreas == null) { return false; } foreach (HitArea hitArea in _vein.m_hitAreas) { if (IsLiveExposedArea(hitArea)) { return true; } } return false; } private bool IsSelectedColliderLive() { if ((Object)(object)_selectedCollider == (Object)null || _vein.m_hitAreas == null) { return false; } foreach (HitArea hitArea in _vein.m_hitAreas) { if ((Object)(object)hitArea.m_collider == (Object)(object)_selectedCollider) { return IsLiveExposedArea(hitArea); } } return false; } private static bool IsLiveExposedArea(HitArea area) { if (area != null && area.m_health > 0f && IsUsableCollider(area.m_collider)) { return IsExposed(area.m_collider); } return false; } private static bool HasExposedCollider(GameObject go) { Collider[] componentsInChildren = go.GetComponentsInChildren(); foreach (Collider collider in componentsInChildren) { if (IsUsableCollider(collider) && IsExposed(collider)) { return true; } } return false; } private static bool IsUsableCollider(Collider collider) { if ((Object)(object)collider != (Object)null && collider.enabled && !collider.isTrigger) { return ((Component)collider).gameObject.activeInHierarchy; } return false; } private static bool IsExposed(Collider collider) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001d: 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_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)ZoneSystem.instance == (Object)null) { return true; } ZoneSystem instance = ZoneSystem.instance; Bounds bounds = collider.bounds; float groundHeight = instance.GetGroundHeight(((Bounds)(ref bounds)).center); bounds = collider.bounds; return ((Bounds)(ref bounds)).max.y > groundHeight + 0.05f; } private static Vector3 SurfacePoint(Collider collider, Vector3 from) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_003a: 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_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_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) Bounds bounds = collider.bounds; Vector3 val = ((Bounds)(ref bounds)).center - from; if (((Vector3)(ref val)).sqrMagnitude > 0.001f) { Ray val2 = default(Ray); ((Ray)(ref val2))..ctor(from, ((Vector3)(ref val)).normalized); float magnitude = ((Vector3)(ref val)).magnitude; bounds = collider.bounds; Vector3 extents = ((Bounds)(ref bounds)).extents; float num = magnitude + ((Vector3)(ref extents)).magnitude + 0.5f; RaycastHit val3 = default(RaycastHit); if (collider.Raycast(val2, ref val3, num)) { return ((RaycastHit)(ref val3)).point; } } MeshCollider val4 = (MeshCollider)(object)((collider is MeshCollider) ? collider : null); if (!((Object)(object)val4 != (Object)null) || val4.convex) { return collider.ClosestPoint(from); } bounds = collider.bounds; return ((Bounds)(ref bounds)).ClosestPoint(from); } } internal sealed class PatrolPoint : MonoBehaviour { internal static readonly List Instances = new List(); private ZNetView _nview; private Piece _piece; internal bool IsValid { get { if ((Object)(object)_nview != (Object)null) { return _nview.IsValid(); } return false; } } private long OwnerId { get { if (!((Object)(object)_piece != (Object)null)) { return 0L; } return _piece.GetCreator(); } } internal ZDOID PersistentId { get { //IL_0019: 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 (!IsValid) { return ZDOID.None; } return _nview.GetZDO().m_uid; } } internal Vector3 Position => ((Component)this).transform.position; private void Awake() { _nview = ((Component)this).GetComponent(); _piece = ((Component)this).GetComponent(); if (!Instances.Contains(this)) { Instances.Add(this); } } private void OnDestroy() { Instances.Remove(this); } internal bool BelongsTo(ExilesHearth hearth) { //IL_004c: 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_006a: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)hearth == (Object)null) { return false; } float num = Mathf.Max(10f, HfConfig.PatrolPointRadius.Value); if (IsValid && (hearth.OwnerId == 0L || OwnerId == 0L || OwnerId == hearth.OwnerId) && Vector3.Distance(((Component)this).transform.position, ((Component)hearth).transform.position) <= num) { return (Object)(object)ExilesHearth.NearestTo(((Component)this).transform.position, OwnerId) == (Object)(object)hearth; } return false; } internal static List PointsFor(ExilesHearth hearth) { return (from point in Instances where (Object)(object)point != (Object)null && point.BelongsTo(hearth) orderby Mathf.Atan2(((Component)point).transform.position.z - ((Component)hearth).transform.position.z, ((Component)point).transform.position.x - ((Component)hearth).transform.position.x) select point).ToList(); } internal static List RouteIdsFor(ExilesHearth hearth) { //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0086: 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_0095: 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_00a9: Unknown result type (might be due to invalid IL or missing references) List source = PointsFor(hearth); if ((Object)(object)hearth == (Object)null || !hearth.PatrolRouteConfigured) { return source.Select((PatrolPoint point) => point.PersistentId).ToList(); } Dictionary dictionary = source.ToDictionary((PatrolPoint point) => point.PersistentId); List list = new List(); foreach (ZDOID item in hearth.SavedPatrolRoute) { if (item != ZDOID.None && dictionary.ContainsKey(item) && !list.Contains(item)) { list.Add(item); } } return list; } internal static List RouteFor(ExilesHearth hearth) { Dictionary points = PointsFor(hearth).ToDictionary((PatrolPoint point) => point.PersistentId); return (from id in RouteIdsFor(hearth).Where(points.ContainsKey) select points[id].Position).ToList(); } } [BepInPlugin("gianl.hearthfolk", "Hearthfolk", "1.0.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] internal sealed class HearthfolkPlugin : BaseUnityPlugin { private Harmony _harmony; internal static HearthfolkPlugin Instance { get; private set; } private void Awake() { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Expected O, but got Unknown Instance = this; HfConfig.Bind(((BaseUnityPlugin)this).Config); HearthfolkLocalization.Register(); PrefabRegistry.Register(); ((Component)this).gameObject.AddComponent(); _harmony = new Harmony("gianl.hearthfolk"); _harmony.PatchAll(); Logger.LogInfo((object)"Hearthfolk 1.0.0 loaded. Build the Exiles' Hearth to found a settlement."); } private void OnDestroy() { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } } internal static class PrefabRegistry { private const float SettlerTentHalfWidth = 1.85f; private const float SettlerTentHalfLength = 2.35f; private const float SettlerTentRidgeHeight = 3.05f; private static Material _tentFlameParticleMaterial; private static Material _tentFlameCoreMaterial; private static Material _tentSurfaceTemplate; internal static void Register() { PrefabManager.OnVanillaPrefabsAvailable += CreatePrefabs; } private static void CreatePrefabs() { try { CreateSettler(); CreateHearth(); CreateWorkBanner(); CreatePatrolPoint(); CreateFarmMarker(); CreateSettlerShelter(); RegisterLegacyBuildingCleanup("piece_hf_sawmill", "piece_workbench"); RegisterLegacyBuildingCleanup("piece_hf_mine", "piece_stonecutter"); RegisterLegacyBuildingCleanup("piece_hf_barracks", "piece_banner03"); } catch (Exception arg) { Logger.LogError((object)$"Hearthfolk: prefab registration failed: {arg}"); } finally { PrefabManager.OnVanillaPrefabsAvailable -= CreatePrefabs; } } private static void CreateSettler() { GameObject val = PrefabManager.Instance.CreateClonedPrefab("hf_settler", "Player"); if ((Object)(object)val == (Object)null) { Logger.LogError((object)"Hearthfolk: could not clone the settler base prefab; settlers are disabled."); return; } if ((Object)(object)SettlerConversion.Convert(val) == (Object)null) { Object.DestroyImmediate((Object)(object)val); return; } val.AddComponent(); val.AddComponent(); PrefabManager.Instance.AddPrefab(val); Logger.LogInfo((object)"Hearthfolk: settler prefab registered."); } private static void CreateHearth() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Expected O, but got Unknown //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Expected O, but got Unknown //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Expected O, but got Unknown //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Expected O, but got Unknown //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: Unknown result type (might be due to invalid IL or missing references) //IL_01db: Unknown result type (might be due to invalid IL or missing references) //IL_01e2: Unknown result type (might be due to invalid IL or missing references) //IL_01e7: Unknown result type (might be due to invalid IL or missing references) PieceConfig val = new PieceConfig(); val.Name = "$piece_hf_hearth"; val.Description = "$piece_hf_hearth_desc"; val.PieceTable = PieceTables.Hammer; val.Category = PieceCategories.Misc; val.Icon = LoadHearthIcon(); val.Requirements = (RequirementConfig[])(object)new RequirementConfig[2] { new RequirementConfig("Wood", 20, 0, true), new RequirementConfig("Stone", 10, 0, true) }; PieceConfig val2 = val; string text = ResolveHearthBasePrefab(); if (string.IsNullOrEmpty(text)) { Logger.LogError((object)"Hearthfolk: no compatible vanilla hearth base prefab was found."); return; } CustomPiece val3 = new CustomPiece("piece_hf_exiles_hearth", text, val2); GameObject piecePrefab = val3.PiecePrefab; if ((Object)(object)piecePrefab == (Object)null) { Logger.LogError((object)"Hearthfolk: could not build the hearth piece."); return; } GameObject val4 = new GameObject("hf_hearth_visual_root"); val4.layer = piecePrefab.layer; val4.transform.SetParent(piecePrefab.transform, false); val4.transform.localPosition = new Vector3(0f, 0.1f, 0f); Fireplace[] componentsInChildren = piecePrefab.GetComponentsInChildren(true); foreach (Fireplace val5 in componentsInChildren) { if ((Object)(object)val5.m_enabledObject != (Object)null) { val5.m_enabledObject.SetActive(true); } if ((Object)(object)val5.m_enabledObjectHigh != (Object)null) { val5.m_enabledObjectHigh.SetActive(true); } if ((Object)(object)val5.m_enabledObjectLow != (Object)null) { val5.m_enabledObjectLow.SetActive(false); } float num = ((text == "piece_brazierfloor01") ? 0.32f : 0f); GameObject[] array = (GameObject[])(object)new GameObject[3] { val5.m_enabledObject, val5.m_enabledObjectHigh, val5.m_enabledObjectLow }; foreach (GameObject val6 in array) { if ((Object)(object)val6 != (Object)null && num > 0f) { Transform transform = val6.transform; transform.position += Vector3.up * num; } } Object.DestroyImmediate((Object)(object)val5); } Aoe[] componentsInChildren2 = piecePrefab.GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren2.Length; i++) { Object.DestroyImmediate((Object)(object)componentsInChildren2[i]); } Piece component = piecePrefab.GetComponent(); if ((Object)(object)component != (Object)null) { component.m_clipEverything = true; component.m_groundOnly = true; } piecePrefab.AddComponent(); AddHearthModel(val4); AddHearthInteractionVolume(piecePrefab); TameHearthLights(piecePrefab); PieceManager.Instance.AddPiece(val3); } private static string ResolveHearthBasePrefab() { string[] array = new string[3] { "fire_pit", "piece_brazierfloor01", "piece_workbench" }; foreach (string text in array) { if ((Object)(object)PrefabManager.Instance.GetPrefab(text) != (Object)null) { Logger.LogInfo((object)("Hearthfolk: using " + text + " as hearth base prefab.")); return text; } } return null; } private static void CreateWorkBanner() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got Unknown //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Expected O, but got Unknown //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Expected O, but got Unknown //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Expected O, but got Unknown CreateRoleWorkBanner(SettlerRole.Lumberjack, "piece_hf_lumber_banner", "piece_banner01", "$piece_hf_lumber_banner", "$piece_hf_lumber_banner_desc", (RequirementConfig[])(object)new RequirementConfig[2] { new RequirementConfig("Wood", 10, 0, true), new RequirementConfig("Coal", 2, 0, true) }); string bannerVisualPrefab = ResolveAvailablePrefab("piece_banner05", "piece_banner04", "piece_banner02", "piece_banner01"); CreateRoleWorkBanner(SettlerRole.Miner, "piece_hf_miner_banner", bannerVisualPrefab, "$piece_hf_miner_banner", "$piece_hf_miner_banner_desc", (RequirementConfig[])(object)new RequirementConfig[2] { new RequirementConfig("Wood", 10, 0, true), new RequirementConfig("Stone", 4, 0, true) }); } private static void CreateRoleWorkBanner(SettlerRole role, string prefabName, string bannerVisualPrefab, string name, string description, RequirementConfig[] requirements) { //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006c: 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_0093: Expected O, but got Unknown //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Expected O, but got Unknown if (string.IsNullOrEmpty(bannerVisualPrefab)) { Logger.LogError((object)$"Hearthfolk: no vanilla banner is available for {role}."); return; } string text = ResolveAvailablePrefab("wood_pole2", "wood_pole", "piece_workbench"); if (string.IsNullOrEmpty(text)) { Logger.LogError((object)$"Hearthfolk: no ground placement base is available for {role}."); return; } PieceConfig val = new PieceConfig { Name = name, Description = description, PieceTable = PieceTables.Hammer, Category = PieceCategories.Misc, Requirements = requirements }; CustomPiece val2 = new CustomPiece(prefabName, text, val); GameObject piecePrefab = val2.PiecePrefab; if ((Object)(object)piecePrefab == (Object)null) { Logger.LogError((object)$"Hearthfolk: could not build the {role} work banner."); return; } PrepareGroundWorkBanner(piecePrefab, role, bannerVisualPrefab); piecePrefab.AddComponent().Configure(role); PieceManager.Instance.AddPiece(val2); } private static string ResolveAvailablePrefab(params string[] candidates) { return candidates.FirstOrDefault((string candidate) => (Object)(object)PrefabManager.Instance.GetPrefab(candidate) != (Object)null); } private static void PrepareGroundWorkBanner(GameObject prefab, SettlerRole role, string bannerVisualPrefab) { //IL_01c7: 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) //IL_01d8: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: Unknown result type (might be due to invalid IL or missing references) //IL_0200: Unknown result type (might be due to invalid IL or missing references) //IL_0219: Unknown result type (might be due to invalid IL or missing references) //IL_0223: Unknown result type (might be due to invalid IL or missing references) //IL_0238: Unknown result type (might be due to invalid IL or missing references) //IL_024c: Unknown result type (might be due to invalid IL or missing references) //IL_025c: Expected O, but got Unknown //IL_025c: Unknown result type (might be due to invalid IL or missing references) //IL_0271: Unknown result type (might be due to invalid IL or missing references) //IL_0285: Unknown result type (might be due to invalid IL or missing references) //IL_0295: Expected O, but got Unknown //IL_0295: Unknown result type (might be due to invalid IL or missing references) //IL_02ab: Unknown result type (might be due to invalid IL or missing references) //IL_02bf: Unknown result type (might be due to invalid IL or missing references) //IL_02d3: Unknown result type (might be due to invalid IL or missing references) //IL_02df: Expected O, but got Unknown //IL_02fb: Unknown result type (might be due to invalid IL or missing references) //IL_0300: Unknown result type (might be due to invalid IL or missing references) //IL_0316: Unknown result type (might be due to invalid IL or missing references) //IL_031b: Unknown result type (might be due to invalid IL or missing references) //IL_0331: Unknown result type (might be due to invalid IL or missing references) //IL_0336: Unknown result type (might be due to invalid IL or missing references) //IL_034c: Unknown result type (might be due to invalid IL or missing references) //IL_0351: Unknown result type (might be due to invalid IL or missing references) //IL_0367: Unknown result type (might be due to invalid IL or missing references) //IL_036c: Unknown result type (might be due to invalid IL or missing references) //IL_0373: Unknown result type (might be due to invalid IL or missing references) //IL_037d: Expected O, but got Unknown Renderer[] componentsInChildren = prefab.GetComponentsInChildren(true); GameObject prefab2 = PrefabManager.Instance.GetPrefab(bannerVisualPrefab); Material material = ((prefab2 != null) ? prefab2.GetComponentsInChildren(true).SelectMany((Renderer renderer) => renderer.sharedMaterials).FirstOrDefault((Func)((Material val2) => (Object)(object)val2 != (Object)null && (Object)(object)val2.shader != (Object)null)) : null); Material material2 = FindVanillaMaterial("wood_pole2", "wood_pole", "wood_beam", "piece_workbench"); Renderer[] array = componentsInChildren; for (int num = 0; num < array.Length; num++) { array[num].enabled = false; } Collider[] componentsInChildren2 = prefab.GetComponentsInChildren(true); for (int num = 0; num < componentsInChildren2.Length; num++) { componentsInChildren2[num].enabled = false; } Piece component = prefab.GetComponent(); if ((Object)(object)component != (Object)null) { component.m_craftingStation = null; component.m_groundOnly = true; component.m_groundPiece = true; component.m_noInWater = true; component.m_allowAltGroundPlacement = false; component.m_clipGround = true; component.m_noClipping = true; component.m_clipEverything = true; Logger.LogInfo((object)($"Hearthfolk: {role} banner placement configured " + "(base=" + ((Object)prefab).name + ", station=none, groundOnly=" + $"{component.m_groundOnly}, groundPiece={component.m_groundPiece}, " + $"clipGround={component.m_clipGround}, clipEverything=" + $"{component.m_clipEverything}).")); } GameObject val = new GameObject((role == SettlerRole.Miner) ? "hf_miner_banner_ground_frame" : "hf_lumber_banner_ground_frame") { layer = prefab.layer }; val.transform.SetParent(prefab.transform, false); BoxCollider obj = val.AddComponent(); obj.center = new Vector3(0f, 1.58f, 0f); obj.size = new Vector3(1.82f, 2.76f, 0.24f); AddBeamBetween(val, "hf_banner_ground_post", new Vector3(0f, -0.12f, 0.08f), new Vector3(0f, 3.03f, 0.08f), 0.115f, material2); AddBeamBetween(val, "hf_banner_crossbar_top", new Vector3(-0.94f, 2.91f, -0.02f), new Vector3(0.94f, 2.91f, -0.02f), 0.09f, material2); AddPrimitiveVisual(val, "hf_banner_post_cap", (PrimitiveType)3, new Vector3(0f, 3.09f, 0.08f), Quaternion.Euler(0f, 45f, 0f), new Vector3(0.14f, 0.14f, 0.14f), material2, keepCollider: false); AddTentPanel(val, "hf_banner_pointed_canvas", (Vector3[])(object)new Vector3[5] { new Vector3(-0.78f, 2.77f, -0.075f), new Vector3(0.78f, 2.77f, -0.075f), new Vector3(0.78f, 0.82f, -0.075f), new Vector3(0f, 0.4f, -0.075f), new Vector3(-0.78f, 0.82f, -0.075f) }, material, collision: false, Vector2.one); } private static void CreatePatrolPoint() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Expected O, but got Unknown //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Expected O, but got Unknown //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Expected O, but got Unknown //IL_0095: 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) PieceConfig val = new PieceConfig(); val.Name = "$piece_hf_patrol_point"; val.Description = "$piece_hf_patrol_point_desc"; val.PieceTable = PieceTables.Hammer; val.Category = PieceCategories.Misc; val.Requirements = (RequirementConfig[])(object)new RequirementConfig[2] { new RequirementConfig("Wood", 2, 0, true), new RequirementConfig("Resin", 1, 0, true) }; PieceConfig val2 = val; CustomPiece val3 = new CustomPiece("piece_hf_patrol_point", "piece_banner02", val2); if ((Object)(object)val3.PiecePrefab == (Object)null) { Logger.LogError((object)"Hearthfolk: could not build the patrol point."); return; } val3.PiecePrefab.transform.localScale = Vector3.one * 0.6f; val3.PiecePrefab.AddComponent(); PieceManager.Instance.AddPiece(val3); } private static void CreateFarmMarker() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Expected O, but got Unknown //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Expected O, but got Unknown //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Expected O, but got Unknown //IL_0095: 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) PieceConfig val = new PieceConfig(); val.Name = "$piece_hf_farm_marker"; val.Description = "$piece_hf_farm_marker_desc"; val.PieceTable = PieceTables.Hammer; val.Category = PieceCategories.Misc; val.Requirements = (RequirementConfig[])(object)new RequirementConfig[2] { new RequirementConfig("Wood", 4, 0, true), new RequirementConfig("Resin", 1, 0, true) }; PieceConfig val2 = val; CustomPiece val3 = new CustomPiece("piece_hf_farm_marker", "piece_banner03", val2); if ((Object)(object)val3.PiecePrefab == (Object)null) { Logger.LogError((object)"Hearthfolk: could not build the farm marker."); return; } val3.PiecePrefab.transform.localScale = Vector3.one * 0.55f; val3.PiecePrefab.AddComponent(); PieceManager.Instance.AddPiece(val3); } private static void CreateSettlerShelter() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Expected O, but got Unknown //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Expected O, but got Unknown //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Expected O, but got Unknown //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Expected O, but got Unknown //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: 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_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: Unknown result type (might be due to invalid IL or missing references) //IL_0201: 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_0214: Unknown result type (might be due to invalid IL or missing references) //IL_0219: Unknown result type (might be due to invalid IL or missing references) //IL_0220: Unknown result type (might be due to invalid IL or missing references) //IL_0225: Unknown result type (might be due to invalid IL or missing references) //IL_0234: Unknown result type (might be due to invalid IL or missing references) //IL_0239: Unknown result type (might be due to invalid IL or missing references) //IL_0250: Unknown result type (might be due to invalid IL or missing references) //IL_025c: Unknown result type (might be due to invalid IL or missing references) //IL_0268: Unknown result type (might be due to invalid IL or missing references) //IL_026f: Unknown result type (might be due to invalid IL or missing references) //IL_0274: Unknown result type (might be due to invalid IL or missing references) //IL_027b: Unknown result type (might be due to invalid IL or missing references) //IL_0280: Unknown result type (might be due to invalid IL or missing references) //IL_028b: Unknown result type (might be due to invalid IL or missing references) //IL_028d: Unknown result type (might be due to invalid IL or missing references) PieceConfig val = new PieceConfig(); val.Name = "$piece_hf_settler_tent"; val.Description = "$piece_hf_settler_tent_desc"; val.PieceTable = PieceTables.Hammer; val.Category = PieceCategories.Furniture; val.Requirements = (RequirementConfig[])(object)new RequirementConfig[3] { new RequirementConfig("Wood", 22, 0, true), new RequirementConfig("DeerHide", 8, 0, true), new RequirementConfig("Resin", 6, 0, true) }; PieceConfig val2 = val; CustomPiece val3 = new CustomPiece("piece_hf_settler_shelter", "bed", val2); GameObject piecePrefab = val3.PiecePrefab; Bed val4 = (((Object)(object)piecePrefab != (Object)null) ? (piecePrefab.GetComponent() ?? piecePrefab.GetComponentInChildren(true)) : null); if ((Object)(object)piecePrefab == (Object)null || (Object)(object)val4 == (Object)null || (Object)(object)val4.m_spawnPoint == (Object)null) { Logger.LogError((object)"Hearthfolk: could not build the decorated Settler Tent."); return; } Vector3 val5 = piecePrefab.transform.InverseTransformPoint(val4.m_spawnPoint.position); Vector3 val6 = piecePrefab.transform.InverseTransformDirection(val4.m_spawnPoint.forward); val6.y = 0f; if (((Vector3)(ref val6)).sqrMagnitude < 0.01f) { val6 = Vector3.forward; } ((Vector3)(ref val6)).Normalize(); Vector3 val7 = BedVisualCenter(piecePrefab, val5); HideBaseBedGeometry(piecePrefab); RemoveBaseBedSnapPoints(piecePrefab); Piece component = piecePrefab.GetComponent(); if ((Object)(object)component != (Object)null) { component.m_groundOnly = true; component.m_groundPiece = true; component.m_noInWater = true; component.m_allowAltGroundPlacement = false; component.m_clipGround = false; component.m_noClipping = false; component.m_clipEverything = false; } GameObject val8 = new GameObject("hf_shelter_access"); val8.transform.SetParent(piecePrefab.transform, false); val8.transform.localPosition = new Vector3(val7.x, 0.05f, val7.z) - val6 * 3.1299999f; GameObject val9 = new GameObject("hf_shelter_exit_inside"); val9.transform.SetParent(piecePrefab.transform, false); val9.transform.localPosition = new Vector3(val7.x, 0.05f, val7.z) - val6 * 1.7299999f; GameObject val10 = new GameObject("hf_shelter_interaction"); val10.transform.SetParent(piecePrefab.transform, false); val10.transform.localPosition = new Vector3(val7.x, Mathf.Max(0.45f, val5.y), val7.z) - val6 * 0.95f; AddSettlerTentModel(piecePrefab, val7, val6); piecePrefab.AddComponent(); PieceManager.Instance.AddPiece(val3); Logger.LogInfo((object)"Hearthfolk: decorated Settler Tent prefab registered."); } private static void HideBaseBedGeometry(GameObject prefab) { Renderer[] componentsInChildren = prefab.GetComponentsInChildren(true); Renderer[] array = componentsInChildren; foreach (Renderer val in array) { if ((Object)(object)val != (Object)null) { val.enabled = false; } } Collider[] componentsInChildren2 = prefab.GetComponentsInChildren(true); Collider[] array2 = componentsInChildren2; foreach (Collider val2 in array2) { if ((Object)(object)val2 != (Object)null) { val2.enabled = false; } } Logger.LogInfo((object)($"Hearthfolk: hidden {componentsInChildren.Length} vanilla bed renderers " + $"and {componentsInChildren2.Length} obsolete bed colliders.")); } private static void RemoveBaseBedSnapPoints(GameObject prefab) { List list = (from candidate in prefab.GetComponentsInChildren(true) where (Object)(object)candidate != (Object)null && (Object)(object)candidate != (Object)(object)prefab.transform && ((Object)candidate).name.IndexOf("snappoint", StringComparison.OrdinalIgnoreCase) >= 0 select candidate).ToList(); foreach (Transform item in list) { Object.DestroyImmediate((Object)(object)((Component)item).gameObject); } if (list.Count > 0) { Logger.LogInfo((object)$"Hearthfolk: removed {list.Count} inherited bed snap point(s) from the Settler Tent."); } } private static Vector3 BedVisualCenter(GameObject prefab, Vector3 fallback) { //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) List list = (from renderer in prefab.GetComponentsInChildren(true) where (Object)(object)renderer != (Object)null && renderer.enabled select renderer).ToList(); if (list.Count == 0) { return new Vector3(fallback.x, 0f, fallback.z); } Bounds bounds = list[0].bounds; for (int num = 1; num < list.Count; num++) { ((Bounds)(ref bounds)).Encapsulate(list[num].bounds); } Vector3 result = prefab.transform.InverseTransformPoint(((Bounds)(ref bounds)).center); result.y = 0f; return result; } private static void RegisterLegacyBuildingCleanup(string prefabName, string basePrefab) { //IL_0065: Unknown result type (might be due to invalid IL or missing references) GameObject val = PrefabManager.Instance.CreateClonedPrefab(prefabName, basePrefab); if ((Object)(object)val == (Object)null) { Logger.LogWarning((object)("Hearthfolk: could not register cleanup for " + prefabName + ".")); return; } Piece component = val.GetComponent(); if ((Object)(object)component != (Object)null) { ((Behaviour)component).enabled = false; } Container val2 = val.AddComponent(); val2.m_name = "$hf_legacy_building_storage"; val2.m_width = 6; val2.m_height = 4; val2.m_privacy = (PrivacySetting)0; val2.m_checkGuardStone = false; GameObject prefab = PrefabManager.Instance.GetPrefab("piece_chest_wood"); Container val3 = ((prefab != null) ? prefab.GetComponent() : null); if ((Object)(object)val3 != (Object)null) { val2.m_bkg = val3.m_bkg; val2.m_destroyedLootPrefab = val3.m_destroyedLootPrefab; val2.m_openEffects = val3.m_openEffects; val2.m_closeEffects = val3.m_closeEffects; } val.AddComponent(); PrefabManager.Instance.AddPrefab(val); } private static void AddHearthModel(GameObject prefab) { //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0160: 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) Material material = FindVanillaMaterial("wood_pole2", "wood_pole", "wood_beam", "Wood", "piece_workbench"); AddPrimitiveVisual(prefab, "hf_hearth_post_left", (PrimitiveType)2, new Vector3(-1.38f, 1.15f, 0.12f), Quaternion.Euler(0f, 0f, -2f), new Vector3(0.16f, 1.15f, 0.16f), material, keepCollider: true); AddPrimitiveVisual(prefab, "hf_hearth_post_right", (PrimitiveType)2, new Vector3(1.38f, 1.15f, 0.12f), Quaternion.Euler(0f, 0f, 2f), new Vector3(0.16f, 1.15f, 0.16f), material, keepCollider: true); AddPrimitiveVisual(prefab, "hf_hearth_crossbeam", (PrimitiveType)2, new Vector3(0f, 2.28f, 0.12f), Quaternion.Euler(0f, 0f, 90f), new Vector3(0.18f, 1.58f, 0.18f), material, keepCollider: true); AddBeamBetween(prefab, "hf_hearth_brace_left", new Vector3(-1.3f, 1.88f, 0.12f), new Vector3(-0.88f, 2.25f, 0.12f), 0.085f, material); AddBeamBetween(prefab, "hf_hearth_brace_right", new Vector3(1.3f, 1.88f, 0.12f), new Vector3(0.88f, 2.25f, 0.12f), 0.085f, material); } private static void AddSettlerTentModel(GameObject prefab, Vector3 tentCenter, Vector3 bedForward) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0051: 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_00fb: 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_0119: Unknown result type (might be due to invalid IL or missing references) //IL_013c: 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_0188: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Unknown result type (might be due to invalid IL or missing references) //IL_01d7: 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_01f2: Unknown result type (might be due to invalid IL or missing references) //IL_01f7: 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_0212: Unknown result type (might be due to invalid IL or missing references) //IL_0224: Unknown result type (might be due to invalid IL or missing references) //IL_024b: 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_0266: Unknown result type (might be due to invalid IL or missing references) //IL_026b: Unknown result type (might be due to invalid IL or missing references) //IL_0281: 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_029c: Unknown result type (might be due to invalid IL or missing references) //IL_02a1: Unknown result type (might be due to invalid IL or missing references) //IL_02b3: Unknown result type (might be due to invalid IL or missing references) //IL_02da: Unknown result type (might be due to invalid IL or missing references) //IL_02df: Unknown result type (might be due to invalid IL or missing references) //IL_02f5: Unknown result type (might be due to invalid IL or missing references) //IL_02fa: Unknown result type (might be due to invalid IL or missing references) //IL_0310: Unknown result type (might be due to invalid IL or missing references) //IL_0315: Unknown result type (might be due to invalid IL or missing references) //IL_0327: Unknown result type (might be due to invalid IL or missing references) //IL_034e: Unknown result type (might be due to invalid IL or missing references) //IL_0353: Unknown result type (might be due to invalid IL or missing references) //IL_0369: Unknown result type (might be due to invalid IL or missing references) //IL_036e: Unknown result type (might be due to invalid IL or missing references) //IL_0384: Unknown result type (might be due to invalid IL or missing references) //IL_0389: Unknown result type (might be due to invalid IL or missing references) //IL_039b: Unknown result type (might be due to invalid IL or missing references) //IL_03c2: Unknown result type (might be due to invalid IL or missing references) //IL_03c7: Unknown result type (might be due to invalid IL or missing references) //IL_03dd: Unknown result type (might be due to invalid IL or missing references) //IL_03e2: 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_03fd: Unknown result type (might be due to invalid IL or missing references) //IL_040f: Unknown result type (might be due to invalid IL or missing references) //IL_0436: Unknown result type (might be due to invalid IL or missing references) //IL_043b: Unknown result type (might be due to invalid IL or missing references) //IL_0451: Unknown result type (might be due to invalid IL or missing references) //IL_0456: Unknown result type (might be due to invalid IL or missing references) //IL_046c: Unknown result type (might be due to invalid IL or missing references) //IL_0471: Unknown result type (might be due to invalid IL or missing references) //IL_0487: Unknown result type (might be due to invalid IL or missing references) //IL_048c: Unknown result type (might be due to invalid IL or missing references) //IL_049e: Unknown result type (might be due to invalid IL or missing references) //IL_04c5: Unknown result type (might be due to invalid IL or missing references) //IL_04ca: Unknown result type (might be due to invalid IL or missing references) //IL_04e0: Unknown result type (might be due to invalid IL or missing references) //IL_04e5: Unknown result type (might be due to invalid IL or missing references) //IL_04fb: Unknown result type (might be due to invalid IL or missing references) //IL_0500: Unknown result type (might be due to invalid IL or missing references) //IL_0508: Unknown result type (might be due to invalid IL or missing references) //IL_0517: Unknown result type (might be due to invalid IL or missing references) //IL_051c: Unknown result type (might be due to invalid IL or missing references) //IL_0528: Unknown result type (might be due to invalid IL or missing references) //IL_053a: Unknown result type (might be due to invalid IL or missing references) //IL_054f: Unknown result type (might be due to invalid IL or missing references) //IL_056d: Unknown result type (might be due to invalid IL or missing references) //IL_058c: Unknown result type (might be due to invalid IL or missing references) //IL_05a0: Unknown result type (might be due to invalid IL or missing references) //IL_05c5: Unknown result type (might be due to invalid IL or missing references) //IL_05d9: Unknown result type (might be due to invalid IL or missing references) //IL_05fe: Unknown result type (might be due to invalid IL or missing references) //IL_0612: Unknown result type (might be due to invalid IL or missing references) //IL_0637: Unknown result type (might be due to invalid IL or missing references) //IL_064b: Unknown result type (might be due to invalid IL or missing references) //IL_0670: Unknown result type (might be due to invalid IL or missing references) //IL_0684: Unknown result type (might be due to invalid IL or missing references) //IL_06a9: Unknown result type (might be due to invalid IL or missing references) //IL_06bd: 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_06f7: Unknown result type (might be due to invalid IL or missing references) //IL_0749: Unknown result type (might be due to invalid IL or missing references) //IL_074e: Unknown result type (might be due to invalid IL or missing references) //IL_0771: Unknown result type (might be due to invalid IL or missing references) //IL_0776: Unknown result type (might be due to invalid IL or missing references) //IL_078b: Unknown result type (might be due to invalid IL or missing references) //IL_078d: Unknown result type (might be due to invalid IL or missing references) //IL_0797: Unknown result type (might be due to invalid IL or missing references) //IL_079c: Unknown result type (might be due to invalid IL or missing references) //IL_07b0: Unknown result type (might be due to invalid IL or missing references) //IL_07c4: Unknown result type (might be due to invalid IL or missing references) //IL_07d7: Unknown result type (might be due to invalid IL or missing references) //IL_07d9: Unknown result type (might be due to invalid IL or missing references) //IL_07e3: Unknown result type (might be due to invalid IL or missing references) //IL_07e8: Unknown result type (might be due to invalid IL or missing references) //IL_07fc: Unknown result type (might be due to invalid IL or missing references) //IL_0810: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("hf_tent_visual_root"); val.layer = prefab.layer; val.transform.SetParent(prefab.transform, false); val.transform.localPosition = new Vector3(tentCenter.x, 0f, tentCenter.z); val.transform.localRotation = Quaternion.LookRotation(bedForward, Vector3.up); Material val2 = FindVanillaMaterial("wood_pole2", "wood_pole", "wood_beam", "piece_workbench"); _tentSurfaceTemplate = val2 ?? FindVanillaMaterial("piece_table", "piece_workbench", "bed"); Texture2D texture = CreateWovenTexture("hf_tent_canvas_texture", 9173, coarse: false); Texture2D texture2 = CreateWovenTexture("hf_tent_hide_texture", 5417, coarse: true); Color tint = default(Color); ((Color)(ref tint))..ctor(0.92f, 0.92f, 0.88f, 1f); Material val3 = CreateTentMaterial("hf_tent_canvas", tint, texture); Material val4 = CreateTentMaterial("hf_tent_flap", tint, texture); Material val5 = CreateTentMaterial("hf_tent_trim", tint, texture); Material val6 = CreateTentMaterial("hf_tent_hide", new Color(0.76f, 0.64f, 0.44f, 1f), texture2); Material darkHide = CreateTentMaterial("hf_tent_dark_hide", new Color(0.31f, 0.2f, 0.12f, 1f), texture2); Material paleFur = CreateTentMaterial("hf_tent_pale_fur", new Color(0.88f, 0.82f, 0.68f, 1f), texture2); Logger.LogInfo((object)"Hearthfolk: procedural woven canvas and hide materials ready."); AddTentPanel(val, "hf_tent_canvas_left", (Vector3[])(object)new Vector3[4] { new Vector3(-1.85f, 0.1f, -2.35f), new Vector3(-1.85f, 0.1f, 2.35f), new Vector3(0f, 3.05f, 2.35f), new Vector3(0f, 3.05f, -2.35f) }, val3, collision: true, new Vector2(3.5f, 2.7f)); AddTentPanel(val, "hf_tent_canvas_right", (Vector3[])(object)new Vector3[4] { new Vector3(0f, 3.05f, -2.35f), new Vector3(0f, 3.05f, 2.35f), new Vector3(1.85f, 0.1f, 2.35f), new Vector3(1.85f, 0.1f, -2.35f) }, val3, collision: true, new Vector2(3.5f, 2.7f)); AddTentPanel(val, "hf_tent_canvas_back", (Vector3[])(object)new Vector3[3] { new Vector3(-1.85f, 0.1f, 2.35f), new Vector3(1.85f, 0.1f, 2.35f), new Vector3(0f, 3.05f, 2.35f) }, val3, collision: true, new Vector2(2.8f, 2.2f)); AddTentPanel(val, "hf_tent_flap_left", (Vector3[])(object)new Vector3[3] { new Vector3(-1.85f, 0.1f, -2.35f), new Vector3(0f, 3.05f, -2.35f), new Vector3(-0.68f, 0.58f, -2.4299998f) }, val4, collision: false, new Vector2(1.8f, 2.2f)); AddTentPanel(val, "hf_tent_flap_right", (Vector3[])(object)new Vector3[3] { new Vector3(0f, 3.05f, -2.35f), new Vector3(1.85f, 0.1f, -2.35f), new Vector3(0.68f, 0.58f, -2.4299998f) }, val4, collision: false, new Vector2(1.8f, 2.2f)); AddTentPanel(val, "hf_tent_floor_hide", (Vector3[])(object)new Vector3[4] { new Vector3(-1.48f, 0.035f, -1.86f), new Vector3(-1.48f, 0.035f, 1.94f), new Vector3(1.48f, 0.035f, 1.94f), new Vector3(1.48f, 0.035f, -1.86f) }, val6, collision: false, new Vector2(2.1f, 2.9f)); AddTentPanel(val, "hf_tent_pennant", (Vector3[])(object)new Vector3[3] { new Vector3(-0.34f, 2.87f, -2.385f), new Vector3(0.34f, 2.87f, -2.385f), new Vector3(0f, 2.21f, -2.405f) }, val5, collision: false, Vector2.one); GameObject val7 = new GameObject("hf_tent_cover") { layer = val.layer }; val7.transform.SetParent(val.transform, false); val7.transform.localPosition = new Vector3(0f, 2.81f, 0f); val7.AddComponent().size = new Vector3(1f, 0.08f, 4.371f); AddBeamBetween(val, "hf_tent_ridge", new Vector3(0f, 3.05f, -2.55f), new Vector3(0f, 3.05f, 2.55f), 0.065f, val2); AddBeamBetween(val, "hf_tent_front_left", new Vector3(-1.85f, 0f, -2.3799999f), new Vector3(0f, 3.1299999f, -2.3799999f), 0.065f, val2); AddBeamBetween(val, "hf_tent_front_right", new Vector3(1.85f, 0f, -2.3799999f), new Vector3(0f, 3.1299999f, -2.3799999f), 0.065f, val2); AddBeamBetween(val, "hf_tent_back_left", new Vector3(-1.85f, 0f, 2.3799999f), new Vector3(0f, 3.1299999f, 2.3799999f), 0.065f, val2); AddBeamBetween(val, "hf_tent_back_right", new Vector3(1.85f, 0f, 2.3799999f), new Vector3(0f, 3.1299999f, 2.3799999f), 0.065f, val2); AddBeamBetween(val, "hf_tent_flap_tie_left", new Vector3(0f, 3.02f, -2.4399998f), new Vector3(-0.68f, 0.58f, -2.4499998f), 0.018f, val5); AddBeamBetween(val, "hf_tent_flap_tie_right", new Vector3(0f, 3.02f, -2.4399998f), new Vector3(0.68f, 0.58f, -2.4499998f), 0.018f, val5); Vector3 val8 = default(Vector3); ((Vector3)(ref val8))..ctor(0f, 0.04f, -4.3999996f); Vector3 val9 = default(Vector3); ((Vector3)(ref val9))..ctor(0f, 0.04f, 4.3999996f); AddBeamBetween(val, "hf_tent_guy_front", new Vector3(0f, 3.05f, -2.55f), val8, 0.012f, val5); AddBeamBetween(val, "hf_tent_guy_back", new Vector3(0f, 3.05f, 2.55f), val9, 0.012f, val5); AddPrimitiveVisual(val, "hf_tent_stake_front", (PrimitiveType)2, val8 + Vector3.up * 0.17f, Quaternion.Euler(12f, 0f, 0f), new Vector3(0.035f, 0.2f, 0.035f), val2, keepCollider: false); AddPrimitiveVisual(val, "hf_tent_stake_back", (PrimitiveType)2, val9 + Vector3.up * 0.17f, Quaternion.Euler(-12f, 0f, 0f), new Vector3(0.035f, 0.2f, 0.035f), val2, keepCollider: false); AddTentSideAwning(val, val2, val3, val5); AddTentCampDetails(val, val2, val3, val4, val5, val6, darkHide, paleFur); } private static void AddTentSideAwning(GameObject tentRoot, Material wood, Material canvas, Material trim) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0038: 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_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_006e: 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_0084: 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_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_017a: 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_0197: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_01c4: Unknown result type (might be due to invalid IL or missing references) AddTentPanel(tentRoot, "hf_tent_side_awning", (Vector3[])(object)new Vector3[4] { new Vector3(1.04f, 1.36f, -1.18f), new Vector3(1.04f, 1.36f, 1.58f), new Vector3(3.45f, 1.83f, 1.42f), new Vector3(3.45f, 1.83f, -1.02f) }, canvas, collision: false, new Vector2(2.6f, 2f)); AddBeamBetween(tentRoot, "hf_tent_awning_outer_front", new Vector3(3.45f, 0f, -1.02f), new Vector3(3.45f, 1.87f, -1.02f), 0.045f, wood); AddBeamBetween(tentRoot, "hf_tent_awning_outer_back", new Vector3(3.45f, 0f, 1.42f), new Vector3(3.45f, 1.87f, 1.42f), 0.045f, wood); AddBeamBetween(tentRoot, "hf_tent_awning_edge", new Vector3(3.45f, 1.83f, -1.07f), new Vector3(3.45f, 1.83f, 1.47f), 0.035f, wood); for (int i = 0; i < 4; i++) { float num = -0.79f + (float)i * 0.63f; AddTentPanel(tentRoot, "hf_tent_awning_pennant_" + i, (Vector3[])(object)new Vector3[3] { new Vector3(3.47f, 1.79f, num - 0.16f), new Vector3(3.47f, 1.79f, num + 0.16f), new Vector3(3.48f, 1.42f, num) }, trim, collision: false, new Vector2(0.5f, 0.7f)); } } private static void AddTentCampDetails(GameObject tentRoot, Material wood, Material canvas, Material flap, Material trim, Material hide, Material darkHide, Material paleFur) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0038: 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_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_006e: 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_0089: 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_00a4: 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_00bb: 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_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_0169: 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_0180: 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_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: Unknown result type (might be due to invalid IL or missing references) //IL_01dd: Unknown result type (might be due to invalid IL or missing references) //IL_01e2: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Unknown result type (might be due to invalid IL or missing references) //IL_01fd: Unknown result type (might be due to invalid IL or missing references) //IL_0213: Unknown result type (might be due to invalid IL or missing references) //IL_0218: Unknown result type (might be due to invalid IL or missing references) //IL_022e: Unknown result type (might be due to invalid IL or missing references) //IL_0233: Unknown result type (might be due to invalid IL or missing references) //IL_0245: Unknown result type (might be due to invalid IL or missing references) //IL_0265: Unknown result type (might be due to invalid IL or missing references) //IL_0279: Unknown result type (might be due to invalid IL or missing references) //IL_028d: 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) //IL_02d8: Unknown result type (might be due to invalid IL or missing references) //IL_02f9: Unknown result type (might be due to invalid IL or missing references) //IL_030d: Unknown result type (might be due to invalid IL or missing references) //IL_0333: 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_0375: Unknown result type (might be due to invalid IL or missing references) //IL_037a: 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_0395: Unknown result type (might be due to invalid IL or missing references) //IL_03ab: Unknown result type (might be due to invalid IL or missing references) //IL_03b0: Unknown result type (might be due to invalid IL or missing references) //IL_03c6: Unknown result type (might be due to invalid IL or missing references) //IL_03cb: Unknown result type (might be due to invalid IL or missing references) //IL_03dd: Unknown result type (might be due to invalid IL or missing references) //IL_03fc: Unknown result type (might be due to invalid IL or missing references) //IL_0410: Unknown result type (might be due to invalid IL or missing references) //IL_0432: Unknown result type (might be due to invalid IL or missing references) //IL_0446: Unknown result type (might be due to invalid IL or missing references) //IL_046d: Unknown result type (might be due to invalid IL or missing references) //IL_0481: Unknown result type (might be due to invalid IL or missing references) //IL_0495: Unknown result type (might be due to invalid IL or missing references) //IL_04b5: 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_04e9: Unknown result type (might be due to invalid IL or missing references) //IL_04fd: Unknown result type (might be due to invalid IL or missing references) //IL_051e: Unknown result type (might be due to invalid IL or missing references) //IL_0532: Unknown result type (might be due to invalid IL or missing references) //IL_0546: Unknown result type (might be due to invalid IL or missing references) //IL_0569: Unknown result type (might be due to invalid IL or missing references) //IL_056e: Unknown result type (might be due to invalid IL or missing references) //IL_0582: Unknown result type (might be due to invalid IL or missing references) //IL_05a4: Unknown result type (might be due to invalid IL or missing references) //IL_05b8: Unknown result type (might be due to invalid IL or missing references) //IL_05cc: Unknown result type (might be due to invalid IL or missing references) //IL_05ed: Unknown result type (might be due to invalid IL or missing references) //IL_0601: Unknown result type (might be due to invalid IL or missing references) //IL_0628: 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_0650: Unknown result type (might be due to invalid IL or missing references) //IL_0672: Unknown result type (might be due to invalid IL or missing references) //IL_0677: Unknown result type (might be due to invalid IL or missing references) //IL_068b: Unknown result type (might be due to invalid IL or missing references) //IL_06ad: Unknown result type (might be due to invalid IL or missing references) //IL_06c1: Unknown result type (might be due to invalid IL or missing references) AddTentPanel(tentRoot, "hf_tent_bedroll_base", (Vector3[])(object)new Vector3[6] { new Vector3(-0.91f, 0.075f, -1.12f), new Vector3(-0.98f, 0.075f, 0.96f), new Vector3(-0.72f, 0.075f, 1.22f), new Vector3(0.84f, 0.075f, 1.16f), new Vector3(0.97f, 0.075f, -0.93f), new Vector3(0.69f, 0.075f, -1.18f) }, darkHide, collision: false, new Vector2(1.4f, 2.2f)); AddTentPanel(tentRoot, "hf_tent_fur_bedroll", (Vector3[])(object)new Vector3[6] { new Vector3(-0.82f, 0.087f, -1.04f), new Vector3(-0.91f, 0.087f, 0.78f), new Vector3(-0.62f, 0.087f, 1.1f), new Vector3(0.72f, 0.087f, 1.04f), new Vector3(0.88f, 0.087f, -0.82f), new Vector3(0.57f, 0.087f, -1.1f) }, hide, collision: false, new Vector2(1.5f, 2.5f)); AddTentPanel(tentRoot, "hf_tent_fur_bedroll_top", (Vector3[])(object)new Vector3[6] { new Vector3(-0.67f, 0.099f, -0.8f), new Vector3(-0.72f, 0.099f, 0.66f), new Vector3(-0.48f, 0.099f, 0.94f), new Vector3(0.58f, 0.099f, 0.9f), new Vector3(0.69f, 0.099f, -0.64f), new Vector3(0.43f, 0.099f, -0.88f) }, paleFur, collision: false, new Vector2(1.4f, 2.2f)); AddPrimitiveVisual(tentRoot, "hf_tent_hide_pillow", (PrimitiveType)0, new Vector3(0f, 0.22f, 1.02f), Quaternion.Euler(0f, 7f, 0f), new Vector3(0.48f, 0.13f, 0.28f), hide, keepCollider: false); AddPrimitiveVisual(tentRoot, "hf_tent_rolled_blanket", (PrimitiveType)2, new Vector3(0f, 0.22f, -0.91f), Quaternion.Euler(0f, 0f, 90f), new Vector3(0.17f, 0.7f, 0.17f), flap, keepCollider: false); AddBeamBetween(tentRoot, "hf_tent_blanket_tie_left", new Vector3(-0.34f, 0.18f, -1.07f), new Vector3(-0.34f, 0.18f, -0.75f), 0.015f, trim); AddBeamBetween(tentRoot, "hf_tent_blanket_tie_right", new Vector3(0.34f, 0.18f, -1.07f), new Vector3(0.34f, 0.18f, -0.75f), 0.015f, trim); AddTentPanel(tentRoot, "hf_tent_entrance_runner", (Vector3[])(object)new Vector3[4] { new Vector3(-0.58f, 0.045f, -2.9f), new Vector3(-0.64f, 0.045f, -1.72f), new Vector3(0.59f, 0.045f, -1.7f), new Vector3(0.66f, 0.045f, -2.91f) }, darkHide, collision: false, new Vector2(1.2f, 1.8f)); AddDecorativeTorch(tentRoot, "hf_tent_torch_left", new Vector3(-2.2f, 0f, -2.42f), Quaternion.Euler(0f, 18f, 0f), wood, trim); AddDecorativeTorch(tentRoot, "hf_tent_torch_right", new Vector3(2.2f, 0f, -2.42f), Quaternion.Euler(0f, -18f, 0f), wood, trim); AddVanillaDecoration(tentRoot, "hf_tent_camp_table", "piece_table_round", new Vector3(2.42f, 0f, 0.26f), Quaternion.Euler(0f, -12f, 0f), new Vector3(0.72f, 0.72f, 0.72f)); AddRusticChair(tentRoot, "hf_tent_camp_chair_front", new Vector3(2.34f, 0f, -0.82f), Quaternion.Euler(0f, 8f, 0f), wood); AddRusticChair(tentRoot, "hf_tent_camp_chair_back", new Vector3(2.62f, 0f, 1.25f), Quaternion.Euler(0f, 190f, 0f), wood); AddPrimitiveVisual(tentRoot, "hf_tent_table_bowl", (PrimitiveType)2, new Vector3(2.4f, 0.67f, 0.26f), Quaternion.Euler(0f, -12f, 0f), new Vector3(0.16f, 0.035f, 0.16f), darkHide, keepCollider: false); AddPrimitiveVisual(tentRoot, "hf_tent_table_cup", (PrimitiveType)2, new Vector3(2.16f, 0.72f, 0.12f), Quaternion.identity, new Vector3(0.055f, 0.09f, 0.055f), wood, keepCollider: false); AddPrimitiveVisual(tentRoot, "hf_tent_table_map", (PrimitiveType)2, new Vector3(2.64f, 0.72f, 0.33f), Quaternion.Euler(0f, 0f, 90f), new Vector3(0.045f, 0.19f, 0.045f), canvas, keepCollider: false); AddBeamBetween(tentRoot, "hf_tent_table_map_tie", new Vector3(2.64f, 0.675f, 0.29f), new Vector3(2.64f, 0.765f, 0.29f), 0.012f, trim); AddPrimitiveVisual(tentRoot, "hf_tent_travel_shield", (PrimitiveType)2, new Vector3(-1.84f, 0.6f, 0.54f), Quaternion.Euler(0f, 0f, 78f), new Vector3(0.46f, 0.065f, 0.46f), wood, keepCollider: false); AddPrimitiveVisual(tentRoot, "hf_tent_shield_boss", (PrimitiveType)0, new Vector3(-1.9f, 0.6f, 0.54f), Quaternion.identity, new Vector3(0.13f, 0.13f, 0.13f), darkHide, keepCollider: false); AddBeamBetween(tentRoot, "hf_tent_shield_trim", new Vector3(-1.88f, 0.24f, 0.54f), new Vector3(-1.88f, 0.96f, 0.54f), 0.025f, trim); } private static void AddRusticChair(GameObject parent, string name, Vector3 position, Quaternion rotation, Material wood) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0037: 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_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_018b: 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_01cb: Unknown result type (might be due to invalid IL or missing references) //IL_01df: Unknown result type (might be due to invalid IL or missing references) //IL_020b: Unknown result type (might be due to invalid IL or missing references) //IL_021f: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name); val.layer = parent.layer; val.transform.SetParent(parent.transform, false); val.transform.localPosition = position; val.transform.localRotation = rotation; AddPrimitiveVisual(val, name + "_seat", (PrimitiveType)3, new Vector3(0f, 0.47f, 0f), Quaternion.identity, new Vector3(0.43f, 0.065f, 0.4f), wood, keepCollider: false); float[] array = new float[2] { -0.31f, 0.31f }; foreach (float num in array) { float[] array2 = new float[2] { -0.28f, 0.28f }; foreach (float num2 in array2) { AddBeamBetween(val, name + $"_leg_{num:0.00}_{num2:0.00}", new Vector3(num, 0.02f, num2), new Vector3(num * 0.93f, 0.46f, num2 * 0.93f), 0.038f, wood); } } AddBeamBetween(val, name + "_back_left", new Vector3(-0.32f, 0.43f, -0.29f), new Vector3(-0.35f, 1.18f, -0.34f), 0.043f, wood); AddBeamBetween(val, name + "_back_right", new Vector3(0.32f, 0.43f, -0.29f), new Vector3(0.35f, 1.18f, -0.34f), 0.043f, wood); AddBeamBetween(val, name + "_back_top", new Vector3(-0.35f, 1.1f, -0.34f), new Vector3(0.35f, 1.1f, -0.34f), 0.045f, wood); AddBeamBetween(val, name + "_back_middle", new Vector3(-0.34f, 0.83f, -0.32f), new Vector3(0.34f, 0.83f, -0.32f), 0.035f, wood); } private static GameObject AddVanillaDecoration(GameObject parent, string name, string prefabName, Vector3 position, Quaternion rotation, Vector3 scale) { //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_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_009e: 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_00a5: Unknown result type (might be due to invalid IL or missing references) GameObject prefab = PrefabManager.Instance.GetPrefab(prefabName); if ((Object)(object)prefab == (Object)null) { Logger.LogWarning((object)("Hearthfolk: decorative prefab " + prefabName + " not found.")); return null; } WearNTear component = prefab.GetComponent(); GameObject val = (((Object)(object)component != (Object)null && (Object)(object)component.m_new != (Object)null) ? component.m_new : prefab); GameObject val2 = Object.Instantiate(val, parent.transform, false); ((Object)val2).name = name; val2.transform.localPosition = position; val2.transform.localRotation = rotation * val.transform.localRotation; val2.transform.localScale = Vector3.Scale(val.transform.localScale, scale); val2.SetActive(true); Transform[] componentsInChildren = val2.GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren.Length; i++) { ((Component)componentsInChildren[i]).gameObject.layer = parent.layer; } MonoBehaviour[] componentsInChildren2 = val2.GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren2.Length; i++) { Object.DestroyImmediate((Object)(object)componentsInChildren2[i]); } Collider[] componentsInChildren3 = val2.GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren3.Length; i++) { Object.DestroyImmediate((Object)(object)componentsInChildren3[i]); } Rigidbody[] componentsInChildren4 = val2.GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren4.Length; i++) { Object.DestroyImmediate((Object)(object)componentsInChildren4[i]); } return val2; } private static void AddDecorativeTorch(GameObject parent, string name, Vector3 position, Quaternion rotation, Material wood, Material basketMaterial) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0037: 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_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: 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_015a: 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_019a: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: Unknown result type (might be due to invalid IL or missing references) //IL_01db: Unknown result type (might be due to invalid IL or missing references) //IL_01e0: 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_0220: Unknown result type (might be due to invalid IL or missing references) //IL_0225: Unknown result type (might be due to invalid IL or missing references) //IL_0231: Unknown result type (might be due to invalid IL or missing references) //IL_0243: Unknown result type (might be due to invalid IL or missing references) //IL_0258: Unknown result type (might be due to invalid IL or missing references) //IL_0285: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name); val.layer = parent.layer; val.transform.SetParent(parent.transform, false); val.transform.localPosition = position; val.transform.localRotation = rotation; AddBeamBetween(val, name + "_pole", new Vector3(0f, 0.02f, 0f), new Vector3(0f, 1.29f, 0f), 0.04f, wood); AddPrimitiveVisual(val, name + "_basket", (PrimitiveType)2, new Vector3(0f, 1.29f, 0f), Quaternion.identity, new Vector3(0.12f, 0.07f, 0.12f), basketMaterial, keepCollider: false); AddBeamBetween(val, name + "_basket_left", new Vector3(-0.12f, 1.2f, 0f), new Vector3(-0.07f, 1.43f, 0f), 0.018f, basketMaterial); AddBeamBetween(val, name + "_basket_right", new Vector3(0.12f, 1.2f, 0f), new Vector3(0.07f, 1.43f, 0f), 0.018f, basketMaterial); AddBeamBetween(val, name + "_basket_front", new Vector3(0f, 1.2f, -0.12f), new Vector3(0f, 1.43f, -0.07f), 0.018f, basketMaterial); AddBeamBetween(val, name + "_basket_back", new Vector3(0f, 1.2f, 0.12f), new Vector3(0f, 1.43f, 0.07f), 0.018f, basketMaterial); AddPrimitiveVisual(val, name + "_flame_core", (PrimitiveType)0, new Vector3(0f, 1.45f, 0f), Quaternion.identity, new Vector3(0.075f, 0.16f, 0.075f), TentFlameCoreMaterial(), keepCollider: false); AddTorchFlameParticles(val, name + "_flame_particles"); GameObject val2 = new GameObject(name + "_light") { layer = parent.layer }; val2.transform.SetParent(val.transform, false); val2.transform.localPosition = new Vector3(0f, 1.46f, 0f); Light obj = val2.AddComponent(); ((Behaviour)obj).enabled = true; obj.type = (LightType)2; obj.color = new Color(1f, 0.46f, 0.14f); obj.range = 5.2f; obj.intensity = 1.18f; obj.shadows = (LightShadows)0; val.AddComponent(); AddTentFireArea(val, name + "_heat"); } private static void AddTorchFlameParticles(GameObject torch, string name) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0070: 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_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Expected O, but got Unknown //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_01c9: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_01d8: Unknown result type (might be due to invalid IL or missing references) //IL_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_0205: Unknown result type (might be due to invalid IL or missing references) //IL_020a: Unknown result type (might be due to invalid IL or missing references) //IL_021b: Unknown result type (might be due to invalid IL or missing references) //IL_0220: Unknown result type (might be due to invalid IL or missing references) //IL_022e: Unknown result type (might be due to invalid IL or missing references) //IL_0239: Unknown result type (might be due to invalid IL or missing references) //IL_023e: Unknown result type (might be due to invalid IL or missing references) //IL_0261: Unknown result type (might be due to invalid IL or missing references) //IL_0266: Unknown result type (might be due to invalid IL or missing references) //IL_0277: Unknown result type (might be due to invalid IL or missing references) //IL_027c: Unknown result type (might be due to invalid IL or missing references) //IL_028d: Unknown result type (might be due to invalid IL or missing references) //IL_0292: Unknown result type (might be due to invalid IL or missing references) //IL_0297: Unknown result type (might be due to invalid IL or missing references) //IL_02a1: Expected O, but got Unknown //IL_029c: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name) { layer = torch.layer }; val.transform.SetParent(torch.transform, false); val.transform.localPosition = new Vector3(0f, 1.42f, 0f); ParticleSystem val2 = val.AddComponent(); MainModule main = val2.main; ((MainModule)(ref main)).loop = true; ((MainModule)(ref main)).duration = 1f; ((MainModule)(ref main)).startLifetime = new MinMaxCurve(0.34f, 0.62f); ((MainModule)(ref main)).startSpeed = new MinMaxCurve(0.12f, 0.28f); ((MainModule)(ref main)).startSize = new MinMaxCurve(0.16f, 0.29f); ((MainModule)(ref main)).startColor = new MinMaxGradient(new Color(1f, 0.82f, 0.18f, 0.95f), new Color(1f, 0.22f, 0.025f, 0.85f)); ((MainModule)(ref main)).simulationSpace = (ParticleSystemSimulationSpace)0; ((MainModule)(ref main)).maxParticles = 48; EmissionModule emission = val2.emission; ((EmissionModule)(ref emission)).rateOverTime = MinMaxCurve.op_Implicit(22f); ShapeModule shape = val2.shape; ((ShapeModule)(ref shape)).shapeType = (ParticleSystemShapeType)4; ((ShapeModule)(ref shape)).angle = 10f; ((ShapeModule)(ref shape)).radius = 0.045f; ((ShapeModule)(ref shape)).rotation = new Vector3(-90f, 0f, 0f); ColorOverLifetimeModule colorOverLifetime = val2.colorOverLifetime; ((ColorOverLifetimeModule)(ref colorOverLifetime)).enabled = true; Gradient val3 = new Gradient(); val3.SetKeys((GradientColorKey[])(object)new GradientColorKey[3] { new GradientColorKey(new Color(1f, 0.92f, 0.3f), 0f), new GradientColorKey(new Color(1f, 0.34f, 0.04f), 0.55f), new GradientColorKey(new Color(0.42f, 0.04f, 0.01f), 1f) }, (GradientAlphaKey[])(object)new GradientAlphaKey[3] { new GradientAlphaKey(0.9f, 0f), new GradientAlphaKey(0.75f, 0.55f), new GradientAlphaKey(0f, 1f) }); ((ColorOverLifetimeModule)(ref colorOverLifetime)).color = new MinMaxGradient(val3); SizeOverLifetimeModule sizeOverLifetime = val2.sizeOverLifetime; ((SizeOverLifetimeModule)(ref sizeOverLifetime)).enabled = true; ((SizeOverLifetimeModule)(ref sizeOverLifetime)).size = new MinMaxCurve(1f, new AnimationCurve((Keyframe[])(object)new Keyframe[3] { new Keyframe(0f, 0.55f), new Keyframe(0.3f, 1f), new Keyframe(1f, 0.05f) })); ParticleSystemRenderer component = ((Component)val2).GetComponent(); component.renderMode = (ParticleSystemRenderMode)0; ((Renderer)component).sharedMaterial = TentFlameParticleMaterial(); component.sortingFudge = 1f; val2.Play(true); } private static void AddTentFireArea(GameObject torch, string name) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name) { layer = torch.layer }; val.transform.SetParent(torch.transform, false); val.transform.localPosition = new Vector3(0f, 0.85f, 0f); val.AddComponent(); } private static Material TentFlameCoreMaterial() { //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Expected O, but got Unknown //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_tentFlameCoreMaterial != (Object)null) { return _tentFlameCoreMaterial; } Material val = _tentSurfaceTemplate ?? FindVanillaMaterial("wood_pole2", "piece_workbench", "bed"); if ((Object)(object)val == (Object)null) { Logger.LogError((object)"Hearthfolk: no loaded Valheim material is available for the tent flame core."); return null; } _tentFlameCoreMaterial = new Material(val) { name = "hf_tent_flame_core" }; ClearInheritedSurfaceMaps(_tentFlameCoreMaterial); SetMaterialColor(_tentFlameCoreMaterial, new Color(1f, 0.34f, 0.035f, 1f)); SetMaterialEmission(_tentFlameCoreMaterial, new Color(2.6f, 0.58f, 0.06f, 1f)); if (_tentFlameCoreMaterial.HasProperty("_Glossiness")) { _tentFlameCoreMaterial.SetFloat("_Glossiness", 0f); } return _tentFlameCoreMaterial; } private static Material TentFlameParticleMaterial() { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Expected O, but got Unknown //IL_00a7: 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_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Expected O, but got Unknown //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_tentFlameParticleMaterial != (Object)null) { return _tentFlameParticleMaterial; } Material val = FindVanillaParticleMaterial("piece_groundtorchwood", "piece_groundtorch", "piece_brazierfloor01", "fire_pit"); if ((Object)(object)val != (Object)null) { _tentFlameParticleMaterial = new Material(val) { name = "hf_tent_flame_particles" }; return _tentFlameParticleMaterial; } val = _tentSurfaceTemplate ?? FindVanillaMaterial("wood_pole2", "piece_workbench", "bed"); if ((Object)(object)val == (Object)null) { Logger.LogError((object)"Hearthfolk: no loaded Valheim material is available for tent flame particles."); return null; } _tentFlameParticleMaterial = new Material(val) { name = "hf_tent_flame_particles", mainTexture = (Texture)(object)CreateFlameTexture() }; ClearInheritedSurfaceMaps(_tentFlameParticleMaterial); SetMaterialColor(_tentFlameParticleMaterial, Color.white); SetMaterialEmission(_tentFlameParticleMaterial, new Color(2.6f, 0.58f, 0.06f, 1f)); if (_tentFlameParticleMaterial.HasProperty("_MainTex")) { _tentFlameParticleMaterial.SetTexture("_MainTex", _tentFlameParticleMaterial.mainTexture); } return _tentFlameParticleMaterial; } private static Material FindVanillaParticleMaterial(params string[] prefabNames) { foreach (string text in prefabNames) { GameObject prefab = PrefabManager.Instance.GetPrefab(text); if ((Object)(object)prefab == (Object)null) { continue; } ParticleSystemRenderer[] componentsInChildren = prefab.GetComponentsInChildren(true); for (int j = 0; j < componentsInChildren.Length; j++) { Material sharedMaterial = ((Renderer)componentsInChildren[j]).sharedMaterial; if ((Object)(object)sharedMaterial != (Object)null && (Object)(object)sharedMaterial.shader != (Object)null) { return sharedMaterial; } } } return null; } private static Texture2D CreateFlameTexture() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Expected O, but got Unknown //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(32, 32, (TextureFormat)4, true) { name = "hf_tent_flame_texture", wrapMode = (TextureWrapMode)1, filterMode = (FilterMode)1 }; Color[] array = (Color[])(object)new Color[1024]; for (int i = 0; i < 32; i++) { float num = ((float)i + 0.5f) / 32f; float num2 = Mathf.Lerp(0.42f, 0.14f, num); for (int j = 0; j < 32; j++) { float num3 = Mathf.Abs(((float)j + 0.5f) / 32f - 0.5f); float num4 = Mathf.Clamp01(1f - num3 / num2); float num5 = Mathf.Sin(num * (float)Math.PI); float num6 = Mathf.Pow(num4 * num5, 0.7f); array[i * 32 + j] = new Color(1f, 0.86f, 0.24f, num6); } } val.SetPixels(array); val.Apply(true, true); return val; } private static void AddTentPanel(GameObject parent, string name, Vector3[] points, Material material, bool collision, Vector2 uvScale) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: 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_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_0127: 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_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_018d: 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_019f: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: 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_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_01c9: Unknown result type (might be due to invalid IL or missing references) //IL_01db: Unknown result type (might be due to invalid IL or missing references) //IL_01e6: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Unknown result type (might be due to invalid IL or missing references) //IL_0208: Unknown result type (might be due to invalid IL or missing references) //IL_020a: Unknown result type (might be due to invalid IL or missing references) //IL_0214: 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_0298: Unknown result type (might be due to invalid IL or missing references) //IL_029d: Unknown result type (might be due to invalid IL or missing references) //IL_02ae: Unknown result type (might be due to invalid IL or missing references) //IL_02b5: Unknown result type (might be due to invalid IL or missing references) //IL_02bc: Unknown result type (might be due to invalid IL or missing references) //IL_02c3: Unknown result type (might be due to invalid IL or missing references) //IL_02cd: Expected O, but got Unknown //IL_02dc: Unknown result type (might be due to invalid IL or missing references) //IL_02e3: Expected O, but got Unknown if (points != null && points.Length >= 3) { int num = points.Length; Vector3[] array = (Vector3[])(object)new Vector3[num * 2]; Vector3[] array2 = (Vector3[])(object)new Vector3[num * 2]; Vector2[] array3 = (Vector2[])(object)new Vector2[num * 2]; Vector3 val = Vector3.Cross(points[1] - points[0], points[2] - points[0]); Vector3 normalized = ((Vector3)(ref val)).normalized; Vector3 val2 = points[0]; Vector3 val3 = points[0]; for (int i = 1; i < num; i++) { val2 = Vector3.Min(val2, points[i]); val3 = Vector3.Max(val3, points[i]); } Vector3 val4 = val3 - val2; int axis; int axis2; if (val4.x >= val4.y && val4.x >= val4.z) { axis = 0; axis2 = ((!(val4.z >= val4.y)) ? 1 : 2); } else if (val4.y >= val4.x && val4.y >= val4.z) { axis = 1; axis2 = ((val4.z >= val4.x) ? 2 : 0); } else { axis = 2; axis2 = ((!(val4.x >= val4.y)) ? 1 : 0); } float num2 = AxisValue(val2, axis); float num3 = AxisValue(val2, axis2); float num4 = Mathf.Max(0.001f, AxisValue(val3, axis) - num2); float num5 = Mathf.Max(0.001f, AxisValue(val3, axis2) - num3); Vector2 val5 = default(Vector2); for (int j = 0; j < num; j++) { array[j] = points[j]; array[j + num] = points[j]; array2[j] = normalized; array2[j + num] = -normalized; ((Vector2)(ref val5))..ctor((AxisValue(points[j], axis) - num2) / num4 * uvScale.x, (AxisValue(points[j], axis2) - num3) / num5 * uvScale.y); array3[j] = val5; array3[j + num] = val5; } int[] array4 = new int[(num - 2) * 6]; int num6 = 0; for (int k = 1; k < num - 1; k++) { array4[num6++] = 0; array4[num6++] = k; array4[num6++] = k + 1; array4[num6++] = num; array4[num6++] = num + k + 1; array4[num6++] = num + k; } Mesh val6 = new Mesh { name = name + "_mesh", vertices = array, normals = array2, uv = array3, triangles = array4 }; val6.RecalculateBounds(); val6.RecalculateTangents(); GameObject val7 = new GameObject(name); val7.layer = parent.layer; val7.transform.SetParent(parent.transform, false); val7.AddComponent().sharedMesh = val6; ((Renderer)val7.AddComponent()).sharedMaterial = material; if (collision) { val7.AddComponent().sharedMesh = val6; } } } private static float AxisValue(Vector3 value, int axis) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) return axis switch { 1 => value.y, 0 => value.x, _ => value.z, }; } private static Material CreateTentMaterial(string name, Color tint, Texture2D texture) { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Expected O, but got Unknown //IL_0057: Unknown result type (might be due to invalid IL or missing references) Material val = _tentSurfaceTemplate ?? FindVanillaMaterial("wood_pole2", "piece_workbench", "bed"); if ((Object)(object)val == (Object)null) { Logger.LogError((object)"Hearthfolk: no loaded Valheim material is available for the tent canvas."); return null; } Material val2 = new Material(val); ((Object)val2).name = name; ClearInheritedSurfaceMaps(val2); SetMaterialColor(val2, tint); if (val2.HasProperty("_MainTex")) { val2.SetTexture("_MainTex", (Texture)(object)texture); } if (val2.HasProperty("_BaseMap")) { val2.SetTexture("_BaseMap", (Texture)(object)texture); } if (val2.HasProperty("_Metallic")) { val2.SetFloat("_Metallic", 0f); } if (val2.HasProperty("_Glossiness")) { val2.SetFloat("_Glossiness", 0.12f); } if (val2.HasProperty("_Mode")) { val2.SetFloat("_Mode", 0f); } if (val2.HasProperty("_Cutoff")) { val2.SetFloat("_Cutoff", 0f); } if (val2.HasProperty("_Cull")) { val2.SetInt("_Cull", 0); } val2.enableInstancing = true; return val2; } private static void ClearInheritedSurfaceMaps(Material material) { if ((Object)(object)material == (Object)null) { return; } string[] array = new string[6] { "_BumpMap", "_MetallicGlossMap", "_OcclusionMap", "_EmissionMap", "_DetailAlbedoMap", "_DetailNormalMap" }; foreach (string text in array) { if (material.HasProperty(text)) { material.SetTexture(text, (Texture)null); } } } private static void SetMaterialColor(Material material, Color color) { //IL_0013: 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) if (material.HasProperty("_Color")) { material.SetColor("_Color", color); } if (material.HasProperty("_BaseColor")) { material.SetColor("_BaseColor", color); } } private static void SetMaterialEmission(Material material, Color color) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) if (material.HasProperty("_EmissionColor")) { material.EnableKeyword("_EMISSION"); material.SetColor("_EmissionColor", color); } } private static Texture2D CreateWovenTexture(string name, int seed, bool coarse) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Expected O, but got Unknown //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(128, 128, (TextureFormat)4, true) { name = name, wrapMode = (TextureWrapMode)0, filterMode = (FilterMode)1, anisoLevel = 4 }; Color[] array = (Color[])(object)new Color[16384]; for (int i = 0; i < 128; i++) { for (int j = 0; j < 128; j++) { float num = TextureNoise(j, i, seed); float num2 = TextureNoise(j / 7, i / 7, seed + 131); float num4; if (coarse) { float num3 = (((j + i / 3) % 9 == 0) ? 0.09f : 0f) + (((i + j / 4) % 13 == 0) ? 0.06f : 0f); num4 = 0.72f + num2 * 0.2f + (num - 0.5f) * 0.16f + num3; } else { float num5 = ((j % 4 == 0) ? (-0.075f) : 0.025f); float num6 = ((i % 4 == 0) ? (-0.065f) : 0.02f); float num7 = (((j + i) % 17 == 0) ? 0.055f : 0f); num4 = 0.82f + (num2 - 0.5f) * 0.12f + (num - 0.5f) * 0.08f + num5 + num6 + num7; } num4 = Mathf.Clamp(num4, 0.52f, 1f); array[i * 128 + j] = new Color(num4, num4, num4, 1f); } } val.SetPixels(array); val.Apply(true, true); return val; } private static float TextureNoise(int x, int y, int seed) { int num = x * 374761393 + y * 668265263 + seed * -2048144777; int num2 = (num ^ (num >>> 13)) * 1274126177; return (float)(uint)((num2 ^ (num2 >>> 16)) & 0xFFFFFF) / 16777215f; } private static Material FindVanillaMaterial(params string[] prefabNames) { foreach (string text in prefabNames) { GameObject prefab = PrefabManager.Instance.GetPrefab(text); if (!((Object)(object)prefab == (Object)null)) { WearNTear component = prefab.GetComponent(); Material val = (((Object)(object)component != (Object)null && (Object)(object)component.m_new != (Object)null) ? component.m_new : prefab).GetComponentsInChildren(true).SelectMany((Renderer candidate) => candidate.sharedMaterials).FirstOrDefault((Func)((Material candidate) => (Object)(object)candidate != (Object)null && (Object)(object)candidate.shader != (Object)null)); if ((Object)(object)val != (Object)null) { return val; } } } Logger.LogWarning((object)("Hearthfolk: no usable vanilla material found among: " + string.Join(", ", prefabNames) + ". Keeping Unity's primitive material.")); return null; } private static void AddPrimitiveVisual(GameObject parent, string name, PrimitiveType type, Vector3 position, Quaternion rotation, Vector3 scale, Material material, bool keepCollider) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_003e: 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) GameObject val = GameObject.CreatePrimitive(type); ((Object)val).name = name; val.layer = parent.layer; val.transform.SetParent(parent.transform, false); val.transform.localPosition = position; val.transform.localRotation = rotation; val.transform.localScale = scale; Renderer component = val.GetComponent(); if ((Object)(object)component != (Object)null && (Object)(object)material != (Object)null) { component.sharedMaterial = material; } if (!keepCollider) { Collider component2 = val.GetComponent(); if ((Object)(object)component2 != (Object)null) { Object.DestroyImmediate((Object)(object)component2); } } } private static void AddBeamBetween(GameObject parent, string name, Vector3 start, Vector3 end, float radius, Material material) { //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_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000b: 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) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) Vector3 val = end - start; AddPrimitiveVisual(parent, name, (PrimitiveType)2, (start + end) * 0.5f, Quaternion.FromToRotation(Vector3.up, ((Vector3)(ref val)).normalized), new Vector3(radius, ((Vector3)(ref val)).magnitude * 0.5f, radius), material, keepCollider: false); } private static void AddHearthInteractionVolume(GameObject prefab) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0028: 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_0047: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("hf_hearth_interaction") { layer = prefab.layer }; val.transform.SetParent(prefab.transform, false); val.transform.localPosition = new Vector3(0f, 1.15f, 0f); BoxCollider obj = val.AddComponent(); obj.size = new Vector3(3.2f, 2.5f, 1.6f); ((Collider)obj).isTrigger = true; val.AddComponent(); } private static Sprite LoadHearthIcon() { //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: 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_00b0: Expected O, but got Unknown //IL_00d8: 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) using Stream stream = typeof(PrefabRegistry).Assembly.GetManifestResourceStream("Hearthfolk.ExilesHearthIcon.rgba"); if (stream == null) { Logger.LogWarning((object)"Hearthfolk: embedded icon Hearthfolk.ExilesHearthIcon.rgba not found."); return null; } byte[] array = new byte[stream.Length]; int num; for (int i = 0; i < array.Length; i += num) { num = stream.Read(array, i, array.Length - i); if (num <= 0) { break; } } if (array.Length != 262144) { Logger.LogWarning((object)$"Hearthfolk: embedded hearth icon has an invalid size ({array.Length})."); return null; } Texture2D val = new Texture2D(256, 256, (TextureFormat)4, false) { name = "hf_exiles_hearth_icon", wrapMode = (TextureWrapMode)1, filterMode = (FilterMode)1 }; val.LoadRawTextureData(array); val.Apply(false, true); return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 100f); } private static void TameHearthLights(GameObject prefab) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0028: 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_0063: Unknown result type (might be due to invalid IL or missing references) Light[] componentsInChildren = prefab.GetComponentsInChildren(true); if (componentsInChildren.Length == 0) { GameObject val = new GameObject("hf_hearth_light"); val.transform.SetParent(prefab.transform, false); val.transform.localPosition = new Vector3(0f, 0.65f, 0f); Light obj = val.AddComponent(); obj.type = (LightType)2; obj.color = new Color(1f, 0.52f, 0.22f); obj.intensity = 0.42f; obj.range = 4f; obj.shadows = (LightShadows)0; } else { Light[] array = componentsInChildren; foreach (Light obj2 in array) { obj2.intensity = Mathf.Min(obj2.intensity, 0.42f); obj2.range = Mathf.Min(obj2.range, 4f); obj2.shadows = (LightShadows)0; } } } } internal static class SceneObjectCache { private static class Entry where T : Object { internal static T[] Items = Array.Empty(); internal static float ExpiresAt; internal static bool Initialized; } internal static T[] Get(float maxAge = 1f) where T : Object { float unscaledTime = Time.unscaledTime; if (!Entry.Initialized || unscaledTime >= Entry.ExpiresAt) { Entry.Items = Object.FindObjectsByType((FindObjectsSortMode)0); Entry.ExpiresAt = unscaledTime + Mathf.Max(0.1f, maxAge); Entry.Initialized = true; } return Entry.Items; } } internal sealed class SettlerAI : MonsterAI { private sealed class OpenedDoor { internal Door Door; internal float OpenedAt; internal float StartingSide; } private sealed class DoorRoute { internal Door Door; internal Vector3 Entry; internal Vector3 Exit; internal Vector3 Normal; internal float EntrySide; internal List Approach; internal int ApproachIndex; internal bool Crossing; internal float ExpiresAt; } private sealed class PortalCandidate { internal Vector3 Entry; internal Vector3 Exit; internal float Estimate; } private sealed class WaypointRoute { internal List Points; internal int Index; internal float ExpiresAt; } private SettlerController _controller; private Vector3? _requestedTarget; private float _requestedStopDistance; private bool _requestedRun; private Vector3? _moveTarget; private float _stopDistance; private bool _run; private bool _holdPosition; private bool _pathFailing; private float _nextPathRetry; private float _nextDoorTry; private float _progressDistance; private float _progressTime; private float _nextTargetScan; private float _yieldUntil; private float _yieldCooldownUntil; private Vector3 _yieldPoint; private DoorRoute _doorRoute; private WaypointRoute _recoveryRoute; private float _nextDoorRouteSearch; private float _nextRecoveryRouteSearch; private readonly List _openedDoors = new List(); private readonly Dictionary _doorRetryAfter = new Dictionary(); private const float DefensiveAcquireRadius = 12f; private const float DefensivePlayerRadius = 15f; private const float DefensiveRetainRadius = 26f; private const float AggressiveAcquireRadius = 30f; private const float AggressiveRetainRadius = 45f; private const float FollowerTargetScanInterval = 0.45f; private const float SettlementAcquireRadius = 55f; private const float SettlementSelfAcquireRadius = 30f; private const float SettlementRetainRadius = 75f; internal bool PathBlocked { get { if (_moveTarget.HasValue && _doorRoute == null && _recoveryRoute == null) { return Time.time - _progressTime > 4.5f; } return false; } } private string NavigationActor { get { if (!((Object)(object)_controller != (Object)null)) { return ((Object)((Component)this).gameObject).name; } return _controller.PanelName; } } internal bool TryFindNavigationPoint(Vector3 desired, float radius, out Vector3 point) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) return CivilPathPlanner.TryProjectWalkPoint(desired, ((Component)this).transform, out point); } internal void MoveTo(Vector3 point, float stopDistance, bool run) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0062: 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_00e7: Unknown result type (might be due to invalid IL or missing references) bool flag = _doorRoute != null || _recoveryRoute != null; float num = (_requestedTarget.HasValue ? Vector3.Distance(_requestedTarget.Value, point) : float.MaxValue); bool flag2 = _requestedTarget.HasValue && num <= (flag ? 4f : 1.25f); _requestedTarget = point; _requestedStopDistance = stopDistance; _requestedRun = run; if (flag && flag2) { _holdPosition = false; return; } if (flag) { Diagnostics.Navigation("Hearthfolk[ai]: " + NavigationActor + " cancelled physical " + $"route because target shifted {num:0.0}m"); } _doorRoute = null; _recoveryRoute = null; if (!_moveTarget.HasValue || !flag2) { _pathFailing = false; ResetProgress(point); } _moveTarget = point; _stopDistance = stopDistance; _run = run; _holdPosition = false; } internal void ClearMove() { _requestedTarget = null; _moveTarget = null; _doorRoute = null; _recoveryRoute = null; _pathFailing = false; _holdPosition = true; ResetProgress(); } internal bool HasHostileTarget() { if ((Object)(object)base.m_targetCreature != (Object)null) { return !base.m_targetCreature.IsDead(); } return false; } internal void StaggerTargetScan(float phase) { _nextTargetScan = Time.time + Mathf.Clamp01(phase) * 0.45f; } internal void ClearHostileTarget() { base.m_targetCreature = null; base.m_targetStatic = null; ((BaseAI)this).SetAlerted(false); } internal void EngageAttacker(Character attacker) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)attacker == (Object)null) && !attacker.IsDead() && BaseAI.IsEnemy(((BaseAI)this).m_character, attacker)) { base.m_targetCreature = attacker; base.m_targetStatic = null; base.m_lastKnownTargetPos = ((Component)attacker).transform.position; base.m_timeSinceSensedTargetCreature = 0f; ((BaseAI)this).SetAlerted(true); ClearMove(); } } public override bool UpdateAI(float dt) { //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0109: 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_011f: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_0223: Unknown result type (might be due to invalid IL or missing references) //IL_01ef: Unknown result type (might be due to invalid IL or missing references) //IL_01f0: Unknown result type (might be due to invalid IL or missing references) //IL_01f5: Unknown result type (might be due to invalid IL or missing references) //IL_01f7: Unknown result type (might be due to invalid IL or missing references) //IL_020c: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)((BaseAI)this).m_nview == (Object)null || !((BaseAI)this).m_nview.IsValid() || !((BaseAI)this).m_nview.IsOwner()) { return ((MonsterAI)this).UpdateAI(dt); } _controller = (((Object)(object)_controller != (Object)null) ? _controller : ((Component)this).GetComponent()); MaintainOpenedDoors(); if ((Object)(object)_controller != (Object)null && (_controller.SettlementAlertActive || (_controller.CurrentRole == SettlerRole.Guard && _controller.IsGuardOnShift))) { ApplySettlementDefensePolicy(); } else { ApplyFollowerCombatPolicy(); } bool flag = HasHostileTarget(); ((BaseAI)this).m_character.SetWalk((Object)(object)_controller != (Object)null && _controller.ShouldForceWalk && !flag); if (_moveTarget.HasValue && !flag) { MaintainDoorRoute(); MaintainRecoveryRoute(); Vector3 value = _moveTarget.Value; float num = Utils.DistanceXZ(((Component)this).transform.position, value); TrackProgress(value); TryOpenDoorAhead(); if (TryYieldToSettler(dt, value)) { return true; } if (_doorRoute != null || _recoveryRoute != null) { _pathFailing = false; if (num <= Mathf.Max(_stopDistance, 0.4f)) { ((BaseAI)this).StopMoving(); } else { ((BaseAI)this).MoveAndAvoid(dt, value, _stopDistance, _run); } return true; } if (_doorRoute == null && _recoveryRoute == null && Time.time - _progressTime > 2.25f && (TryBeginDoorRoute() || TryBeginRecoveryRoute())) { return true; } if (_pathFailing && Time.time >= _nextPathRetry) { _pathFailing = false; } if (_pathFailing) { if (num <= Mathf.Max(_stopDistance, 1f)) { ((BaseAI)this).StopMoving(); } else { Vector3 target = _requestedTarget ?? value; if (HasStructuralObstructionTowards(target)) { ((BaseAI)this).StopMoving(); } else { ((BaseAI)this).MoveAndAvoid(dt, value, _stopDistance, _run); } } } else if (((BaseAI)this).MoveTo(dt, value, _stopDistance, _run) && num > _stopDistance + 2f) { _pathFailing = true; _nextPathRetry = Time.time + 3f; if (TryBeginDoorRoute() || TryBeginRecoveryRoute()) { return true; } Diagnostics.Navigation("Hearthfolk[ai]: " + NavigationActor + " no path " + $"(dist={num:0.0}); physical recovery unavailable"); } return true; } if (_holdPosition && !flag) { ((BaseAI)this).StopMoving(); return true; } if ((Object)(object)_controller != (Object)null && _controller.CurrentRole == SettlerRole.Follower && !flag) { ((BaseAI)this).StopMoving(); return true; } return ((MonsterAI)this).UpdateAI(dt); } private bool TryBeginDoorRoute() { //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_0246: Unknown result type (might be due to invalid IL or missing references) //IL_024b: Unknown result type (might be due to invalid IL or missing references) //IL_0253: Unknown result type (might be due to invalid IL or missing references) //IL_0258: Unknown result type (might be due to invalid IL or missing references) //IL_058d: Unknown result type (might be due to invalid IL or missing references) //IL_058e: Unknown result type (might be due to invalid IL or missing references) //IL_0594: Unknown result type (might be due to invalid IL or missing references) //IL_0596: 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_059e: Unknown result type (might be due to invalid IL or missing references) //IL_05c1: Unknown result type (might be due to invalid IL or missing references) //IL_026a: Unknown result type (might be due to invalid IL or missing references) //IL_0277: Unknown result type (might be due to invalid IL or missing references) //IL_0600: Unknown result type (might be due to invalid IL or missing references) //IL_063a: Unknown result type (might be due to invalid IL or missing references) //IL_0606: Unknown result type (might be due to invalid IL or missing references) //IL_02ab: Unknown result type (might be due to invalid IL or missing references) //IL_02cf: Unknown result type (might be due to invalid IL or missing references) //IL_02d4: Unknown result type (might be due to invalid IL or missing references) //IL_02e1: Unknown result type (might be due to invalid IL or missing references) //IL_02e4: Unknown result type (might be due to invalid IL or missing references) //IL_02f1: Unknown result type (might be due to invalid IL or missing references) //IL_02f9: Unknown result type (might be due to invalid IL or missing references) //IL_02fe: Unknown result type (might be due to invalid IL or missing references) //IL_0300: Unknown result type (might be due to invalid IL or missing references) //IL_0337: Unknown result type (might be due to invalid IL or missing references) //IL_0339: Unknown result type (might be due to invalid IL or missing references) //IL_033b: Unknown result type (might be due to invalid IL or missing references) //IL_034b: Unknown result type (might be due to invalid IL or missing references) //IL_0355: Unknown result type (might be due to invalid IL or missing references) //IL_0357: Unknown result type (might be due to invalid IL or missing references) //IL_0359: Unknown result type (might be due to invalid IL or missing references) //IL_0369: Unknown result type (might be due to invalid IL or missing references) //IL_038b: Unknown result type (might be due to invalid IL or missing references) //IL_039b: Unknown result type (might be due to invalid IL or missing references) //IL_03a5: Unknown result type (might be due to invalid IL or missing references) //IL_03b2: Unknown result type (might be due to invalid IL or missing references) //IL_0403: 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_040a: Unknown result type (might be due to invalid IL or missing references) //IL_0429: Unknown result type (might be due to invalid IL or missing references) //IL_0433: Unknown result type (might be due to invalid IL or missing references) //IL_046f: Unknown result type (might be due to invalid IL or missing references) //IL_0472: Unknown result type (might be due to invalid IL or missing references) //IL_0496: 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_0499: Unknown result type (might be due to invalid IL or missing references) //IL_049b: Unknown result type (might be due to invalid IL or missing references) //IL_049d: Unknown result type (might be due to invalid IL or missing references) //IL_049f: Unknown result type (might be due to invalid IL or missing references) if (_doorRoute != null || !_requestedTarget.HasValue || Time.time < _nextDoorRouteSearch) { return false; } _nextDoorRouteSearch = Time.time + 0.9f; PruneDoorRetries(); Vector3 finalTarget = _requestedTarget.Value; float num = Utils.DistanceXZ(((Component)this).transform.position, finalTarget); if (num < 4f || !HasStructuralObstructionTowards(finalTarget)) { return false; } Door val = null; Vector3 val2 = default(Vector3); Vector3 exit = default(Vector3); Vector3 normal = default(Vector3); List list = null; float entrySide = 0f; float num2 = float.MaxValue; bool flag = false; float searchRadius = Mathf.Clamp(num + 18f, 20f, 60f); ExilesHearth hearth = (((Object)(object)_controller != (Object)null) ? ExilesHearth.FindFor(_controller.HomePosition, _controller.SettlementOwnerId) : null); HashSet configuredIds = (((Object)(object)hearth != (Object)null && hearth.GatewayDoorsConfigured) ? new HashSet(hearth.SavedGatewayDoorIds) : new HashSet()); IEnumerable source; if (!((Object)(object)hearth != (Object)null)) { IEnumerable enumerable = SceneObjectCache.Get(1f); source = enumerable; } else { IEnumerable enumerable = hearth.AvailableGatewayDoors; source = enumerable; } List list2 = (from door in source.Where(UsableGateway).Where(delegate(Door door) { int instanceID2 = ((Object)((Component)door).gameObject).GetInstanceID(); float value2; return !_doorRetryAfter.TryGetValue(instanceID2, out value2) || Time.time >= value2; }) where Utils.DistanceXZ(((Component)this).transform.position, ((Component)door).transform.position) <= searchRadius && Mathf.Abs(((Component)door).transform.position.y - ((Component)this).transform.position.y) <= 5f select door).ToList(); List list3 = list2.Where(delegate(Door door) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) ZDO zDO2 = door.m_nview.GetZDO(); return zDO2 != null && configuredIds.Contains(zDO2.m_uid) && CrossesSettlementBoundary(hearth, ((Component)door).transform.position, finalTarget); }).ToList(); foreach (Door item in ((list3.Count > 0) ? list3 : list2).OrderBy(delegate(Door door) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0039: 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_004f: Unknown result type (might be due to invalid IL or missing references) //IL_006f: 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) ZDO zDO2 = door.m_nview.GetZDO(); bool num7 = zDO2 != null && configuredIds.Contains(zDO2.m_uid); float num8 = Utils.DistanceXZ(((Component)this).transform.position, ((Component)door).transform.position) + Utils.DistanceXZ(((Component)door).transform.position, finalTarget); if (num7 && CrossesSettlementBoundary(hearth, ((Component)door).transform.position, finalTarget)) { num8 -= 14f; } return num8; }).Take(6)) { if (!UsableGateway(item)) { continue; } int instanceID = ((Object)((Component)item).gameObject).GetInstanceID(); if (_doorRetryAfter.TryGetValue(instanceID, out var value) && Time.time < value) { continue; } Vector3 position = ((Component)item).transform.position; if (Utils.DistanceXZ(((Component)this).transform.position, position) > searchRadius || Mathf.Abs(position.y - ((Component)this).transform.position.y) > 5f) { continue; } ZDO zDO = item.m_nview.GetZDO(); bool flag2 = zDO != null && configuredIds.Contains(zDO.m_uid); foreach (Vector3 item2 in DoorPortalNormals(item)) { bool num3 = flag2 && CrossesSettlementBoundary(hearth, position, finalTarget); float num4 = Mathf.Sign(Vector3.Dot(item2, ((Component)this).transform.position - position)); if (num4 == 0f) { num4 = 1f; } IEnumerable enumerable2; if (num3 && (Object)(object)hearth != (Object)null) { float num5 = ((Utils.DistanceXZ(position + item2, ((Component)hearth).transform.position) < Utils.DistanceXZ(position - item2, ((Component)hearth).transform.position)) ? 1f : (-1f)); bool flag3 = Utils.DistanceXZ(((Component)this).transform.position, ((Component)hearth).transform.position) < Utils.DistanceXZ(position, ((Component)hearth).transform.position); enumerable2 = new float[1] { flag3 ? num5 : (0f - num5) }; } else { enumerable2 = new float[2] { num4, 0f - num4 }; } foreach (float item3 in enumerable2) { if (TryBuildDoorPortal(position, item2, item3, finalTarget, out var bestEntry, out var bestExit, out var bestApproach, out var bestScore)) { float num6 = bestScore + Mathf.Abs(((Component)this).transform.position.y - position.y) * 3f; if (zDO.GetInt(ZDOVars.s_state, 0) != 0) { num6 += 1.5f; } if (flag2) { num6 -= (CrossesSettlementBoundary(hearth, position, finalTarget) ? 14f : 2f); } if (!(num6 >= num2)) { val = item; val2 = bestEntry; exit = bestExit; normal = item2; entrySide = item3; list = bestApproach; num2 = num6; flag = flag2; break; } } } if ((Object)(object)val == (Object)(object)item) { break; } } if ((Object)(object)val == (Object)(object)item) { break; } } if ((Object)(object)val == (Object)null) { Diagnostics.Navigation("Hearthfolk[ai]: " + NavigationActor + " found no usable " + $"door route (loaded={list2.Count}, " + $"configured-boundary={list3.Count})"); return false; } _doorRoute = new DoorRoute { Door = val, Entry = val2, Exit = exit, Normal = normal, EntrySide = entrySide, Approach = list, ExpiresAt = Time.time + Mathf.Clamp(CivilPathPlanner.PathLength(list, ((Component)this).transform.position) * 1.5f + 10f, 14f, 35f) }; _moveTarget = ((list != null && list.Count > 0) ? list[0] : val2); _stopDistance = 0.55f; _run = _requestedRun; _pathFailing = false; ResetProgress(_moveTarget.Value); Diagnostics.Navigation("Hearthfolk[ai]: " + NavigationActor + " routing via door " + ((Object)((Component)val).gameObject).name + " " + $"(detour={num2 - num:0.0}m, " + $"configured={flag})"); return true; } private bool TryBuildDoorPortal(Vector3 doorPosition, Vector3 normal, float orientation, Vector3 finalTarget, out Vector3 bestEntry, out Vector3 bestExit, out List bestApproach, out float bestScore) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: 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_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0096: 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_00a0: 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_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: 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_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: 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) //IL_00f3: 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_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0194: Unknown result type (might be due to invalid IL or missing references) //IL_019b: 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_01be: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Unknown result type (might be due to invalid IL or missing references) //IL_01e0: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Unknown result type (might be due to invalid IL or missing references) //IL_01f1: Unknown result type (might be due to invalid IL or missing references) bestEntry = default(Vector3); bestExit = default(Vector3); bestApproach = null; bestScore = float.MaxValue; Vector3 val = Vector3.Cross(Vector3.up, normal); Vector3 normalized = ((Vector3)(ref val)).normalized; float[] array = new float[4] { 1.35f, 1.85f, 2.4f, 3f }; float[] array2 = new float[5] { 0f, 0.65f, -0.65f, 1.15f, -1.15f }; List list = new List(); float[] array3 = array; foreach (float num in array3) { float[] array4 = array2; foreach (float num2 in array4) { Vector3 desired = doorPosition + normal * orientation * num + normalized * num2; Vector3 desired2 = doorPosition - normal * orientation * num + normalized * num2; if (TryFindPortalPoint(desired, doorPosition, normal, orientation, out var point) && TryFindPortalPoint(desired2, doorPosition, normal, 0f - orientation, out var point2)) { list.Add(new PortalCandidate { Entry = point, Exit = point2, Estimate = Utils.DistanceXZ(((Component)this).transform.position, point) + Utils.DistanceXZ(point2, finalTarget) + Mathf.Abs(num2) * 0.35f }); } } } foreach (PortalCandidate item in list.OrderBy((PortalCandidate item) => item.Estimate).Take(2)) { if (CivilPathPlanner.TryBuildPath(((Component)this).transform.position, item.Entry, ((Component)this).transform, NavigationActor, out var waypoints)) { bestEntry = item.Entry; bestExit = item.Exit; bestApproach = waypoints; bestScore = CivilPathPlanner.PathLength(waypoints, ((Component)this).transform.position) + Utils.DistanceXZ(item.Exit, finalTarget); break; } } return bestScore < float.MaxValue; } private bool TryFindPortalPoint(Vector3 desired, Vector3 doorPosition, Vector3 normal, float expectedSide, out Vector3 point) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: 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) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0022: 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_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) point = desired; if (!CivilPathPlanner.TryProjectWalkPoint(desired, ((Component)this).transform, out point)) { return false; } Vector3 val = point - doorPosition; val.y = 0f; if (Mathf.Sign(Vector3.Dot(normal, val)) == expectedSide && Mathf.Abs(Vector3.Dot(normal, val)) >= 0.45f) { return Mathf.Abs(point.y - doorPosition.y) <= 2.5f; } return false; } private static IEnumerable DoorPortalNormals(Door door) { //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_0100: 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_010f: 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) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_0135: 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_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0071: 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_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_009c: 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_00ad: 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_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) List list = new List(); BoxCollider val = null; float num = 0f; BoxCollider[] componentsInChildren = ((Component)door).GetComponentsInChildren(true); Vector3 val3; foreach (BoxCollider val2 in componentsInChildren) { if (!((Object)(object)val2 == (Object)null) && !((Collider)val2).isTrigger) { val3 = ((Component)val2).transform.TransformVector(Vector3.right * val2.size.x); float magnitude = ((Vector3)(ref val3)).magnitude; val3 = ((Component)val2).transform.TransformVector(Vector3.up * val2.size.y); float magnitude2 = ((Vector3)(ref val3)).magnitude; val3 = ((Component)val2).transform.TransformVector(Vector3.forward * val2.size.z); float magnitude3 = ((Vector3)(ref val3)).magnitude; float num2 = magnitude * magnitude3; if (magnitude2 >= 0.75f && num2 > num) { val = val2; num = num2; } } } if ((Object)(object)val != (Object)null) { val3 = ((Component)val).transform.TransformVector(Vector3.right * val.size.x); float magnitude4 = ((Vector3)(ref val3)).magnitude; val3 = ((Component)val).transform.TransformVector(Vector3.forward * val.size.z); float magnitude5 = ((Vector3)(ref val3)).magnitude; AddPortalNormal(list, (magnitude4 <= magnitude5) ? ((Component)val).transform.right : ((Component)val).transform.forward); return list; } AddPortalNormal(list, ((Component)door).transform.forward); AddPortalNormal(list, ((Component)door).transform.right); return list; } private static void AddPortalNormal(ICollection normals, Vector3 candidate) { //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) //IL_0052: Unknown result type (might be due to invalid IL or missing references) candidate.y = 0f; if (!(((Vector3)(ref candidate)).sqrMagnitude < 0.1f)) { ((Vector3)(ref candidate)).Normalize(); if (!normals.Any((Vector3 existing) => Mathf.Abs(Vector3.Dot(existing, candidate)) > 0.94f)) { normals.Add(candidate); } } } private bool CrossesSettlementBoundary(ExilesHearth hearth, Vector3 doorPosition, Vector3 finalTarget) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)hearth == (Object)null) { return false; } Vector3 position = ((Component)hearth).transform.position; float num = Utils.DistanceXZ(position, doorPosition); float num2 = Utils.DistanceXZ(position, ((Component)this).transform.position); float num3 = Utils.DistanceXZ(position, finalTarget); if (!(num2 < num - 1.25f) || !(num3 > num + 1.25f)) { if (num2 > num + 1.25f) { return num3 < num - 1.25f; } return false; } return true; } private bool TryBeginRecoveryRoute() { //IL_0043: 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_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_015e: 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_0096: 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_009c: 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_00be: 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_00d6: 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_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) if (_doorRoute != null || _recoveryRoute != null || !_requestedTarget.HasValue || Time.time < _nextRecoveryRouteSearch) { return false; } _nextRecoveryRouteSearch = Time.time + 2f; Vector3 value = _requestedTarget.Value; if (Utils.DistanceXZ(((Component)this).transform.position, value) < 3f || !HasStructuralObstructionTowards(value)) { return false; } if (!CivilPathPlanner.TryBuildPath(((Component)this).transform.position, value, ((Component)this).transform, NavigationActor, out var waypoints)) { Vector3 val = ((Component)this).transform.position - value; val.y = 0f; if (((Vector3)(ref val)).sqrMagnitude < 0.1f) { return false; } Vector3 goal = value + ((Vector3)(ref val)).normalized * Mathf.Max(0.9f, _requestedStopDistance); goal.y = value.y; if (!CivilPathPlanner.TryBuildPath(((Component)this).transform.position, goal, ((Component)this).transform, NavigationActor, out waypoints)) { return false; } } _recoveryRoute = new WaypointRoute { Points = waypoints, ExpiresAt = Time.time + Mathf.Clamp(CivilPathPlanner.PathLength(waypoints, ((Component)this).transform.position) * 1.5f + 8f, 12f, 45f) }; _moveTarget = waypoints[0]; _stopDistance = 0.45f; _run = _requestedRun; _pathFailing = false; ResetProgress(_moveTarget.Value); Diagnostics.Navigation("Hearthfolk[ai]: " + NavigationActor + " following physical recovery route " + $"({waypoints.Count} waypoint(s))"); return true; } private void MaintainRecoveryRoute() { //IL_0064: 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_015a: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) WaypointRoute recoveryRoute = _recoveryRoute; if (recoveryRoute == null) { return; } if (Time.time > recoveryRoute.ExpiresAt || recoveryRoute.Points == null || recoveryRoute.Points.Count == 0) { FailRecoveryRoute(); return; } int index = recoveryRoute.Index; while (recoveryRoute.Index < recoveryRoute.Points.Count && Utils.DistanceXZ(((Component)this).transform.position, recoveryRoute.Points[recoveryRoute.Index]) <= 0.72f) { recoveryRoute.Index++; } if (recoveryRoute.Index != index) { Diagnostics.Navigation("Hearthfolk[ai]: " + NavigationActor + " reached recovery " + $"waypoint {recoveryRoute.Index}/{recoveryRoute.Points.Count}"); } if (recoveryRoute.Index >= recoveryRoute.Points.Count) { _recoveryRoute = null; _moveTarget = _requestedTarget; _stopDistance = _requestedStopDistance; _run = _requestedRun; _pathFailing = false; _nextRecoveryRouteSearch = Time.time + 3f; ResetProgress(); Diagnostics.Navigation("Hearthfolk[ai]: " + NavigationActor + " completed physical recovery route"); } else { Vector3 val = recoveryRoute.Points[recoveryRoute.Index]; if (!_moveTarget.HasValue || Utils.DistanceXZ(_moveTarget.Value, val) > 0.1f) { _moveTarget = val; _stopDistance = 0.45f; _pathFailing = false; ResetProgress(val); } } } private void FailRecoveryRoute() { _recoveryRoute = null; _moveTarget = _requestedTarget; _stopDistance = _requestedStopDistance; _run = _requestedRun; _pathFailing = true; _nextPathRetry = Time.time + 2f; _nextRecoveryRouteSearch = Time.time + 8f; ResetProgress(); } private bool HasStructuralObstructionTowards(Vector3 target) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: 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_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003b: 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_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) Vector3 val = ((Component)this).transform.position + Vector3.up * 0.95f; Vector3 val2 = target - val; float magnitude = ((Vector3)(ref val2)).magnitude; if (magnitude <= 0.1f) { return false; } RaycastHit[] array = Physics.RaycastAll(val, val2 / magnitude, magnitude, -5, (QueryTriggerInteraction)1); for (int i = 0; i < array.Length; i++) { RaycastHit val3 = array[i]; Transform val4 = (((Object)(object)((RaycastHit)(ref val3)).collider != (Object)null) ? ((Component)((RaycastHit)(ref val3)).collider).transform : null); if (!((Object)(object)val4 == (Object)null) && !val4.IsChildOf(((Component)this).transform) && !((Object)(object)((Component)val4).GetComponentInParent() != (Object)null) && ((Object)(object)((Component)val4).GetComponentInParent() != (Object)null || (Object)(object)((Component)val4).GetComponentInParent() != (Object)null || (Object)(object)((Component)val4).GetComponentInParent() != (Object)null)) { return true; } } return false; } private void MaintainDoorRoute() { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_029a: Unknown result type (might be due to invalid IL or missing references) //IL_02a5: Unknown result type (might be due to invalid IL or missing references) //IL_02aa: Unknown result type (might be due to invalid IL or missing references) //IL_02af: Unknown result type (might be due to invalid IL or missing references) //IL_02be: Unknown result type (might be due to invalid IL or missing references) //IL_02c3: Unknown result type (might be due to invalid IL or missing references) //IL_021f: Unknown result type (might be due to invalid IL or missing references) //IL_0225: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_02f7: Unknown result type (might be due to invalid IL or missing references) //IL_02fd: Unknown result type (might be due to invalid IL or missing references) //IL_0261: Unknown result type (might be due to invalid IL or missing references) //IL_0284: Unknown result type (might be due to invalid IL or missing references) //IL_01e7: Unknown result type (might be due to invalid IL or missing references) //IL_020a: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_01d5: 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_0114: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) DoorRoute doorRoute = _doorRoute; if (doorRoute == null) { return; } Door door = doorRoute.Door; if (!LiveDoor(door) || Time.time > doorRoute.ExpiresAt) { FailDoorRoute(door, (!LiveDoor(door)) ? "door unavailable" : "route timeout"); return; } float num = Utils.DistanceXZ(((Component)this).transform.position, ((Component)door).transform.position); int num2 = door.m_nview.GetZDO().GetInt(ZDOVars.s_state, 0); if (!doorRoute.Crossing) { if (doorRoute.Approach != null && doorRoute.ApproachIndex < doorRoute.Approach.Count) { Vector3 val = doorRoute.Approach[doorRoute.ApproachIndex]; if (Utils.DistanceXZ(((Component)this).transform.position, val) > 0.72f) { if (!_moveTarget.HasValue || Utils.DistanceXZ(_moveTarget.Value, val) > 0.1f) { _moveTarget = val; _stopDistance = 0.45f; _pathFailing = false; ResetProgress(val); } return; } doorRoute.ApproachIndex++; Diagnostics.Navigation("Hearthfolk[ai]: " + NavigationActor + " reached door " + $"waypoint {doorRoute.ApproachIndex}/" + $"{doorRoute.Approach.Count}"); if (doorRoute.ApproachIndex < doorRoute.Approach.Count) { _moveTarget = doorRoute.Approach[doorRoute.ApproachIndex]; _stopDistance = 0.45f; _pathFailing = false; ResetProgress(_moveTarget.Value); return; } _moveTarget = doorRoute.Entry; _stopDistance = 0.45f; _pathFailing = false; ResetProgress(doorRoute.Entry); } if (!(Utils.DistanceXZ(((Component)this).transform.position, doorRoute.Entry) > 0.9f) || !(num > 2.15f)) { if (num2 == 0 && !TryOpenDoor(door)) { FailDoorRoute(door, "open failed"); return; } doorRoute.Crossing = true; _moveTarget = doorRoute.Exit; _stopDistance = 0.45f; _pathFailing = false; ResetProgress(doorRoute.Exit); } return; } Vector3 val2 = ((Component)this).transform.position - ((Component)door).transform.position; val2.y = 0f; float num3 = Mathf.Sign(Vector3.Dot(doorRoute.Normal, val2)); if ((num3 == 0f || num3 == doorRoute.EntrySide || !(num > 1.15f)) && Utils.DistanceXZ(((Component)this).transform.position, doorRoute.Exit) > 0.65f) { if (num2 == 0 && num < 2.35f && !TryOpenDoor(door)) { FailDoorRoute(door, "reopen failed while crossing"); } return; } _doorRetryAfter[((Object)((Component)door).gameObject).GetInstanceID()] = Time.time + 8f; _doorRoute = null; _moveTarget = _requestedTarget; _stopDistance = _requestedStopDistance; _run = _requestedRun; _pathFailing = false; ResetProgress(); Diagnostics.Navigation("Hearthfolk[ai]: " + NavigationActor + " crossed " + ((Object)((Component)door).gameObject).name + "; resuming destination"); } private void FailDoorRoute(Door door, string reason) { Diagnostics.Navigation("Hearthfolk[ai]: " + NavigationActor + " abandoned door route (" + reason + ")"); if ((Object)(object)door != (Object)null) { _doorRetryAfter[((Object)((Component)door).gameObject).GetInstanceID()] = Time.time + 15f; } _doorRoute = null; _moveTarget = _requestedTarget; _stopDistance = _requestedStopDistance; _run = _requestedRun; _pathFailing = true; _nextPathRetry = Time.time + 2f; _nextDoorRouteSearch = Time.time + 0.5f; ResetProgress(); } private static bool UsableGateway(Door door) { if (!LiveDoor(door)) { return false; } ZDO zDO = door.m_nview.GetZDO(); if (zDO != null) { if (zDO.GetInt(ZDOVars.s_state, 0) == 0) { return door.CanInteract(); } return true; } return false; } private static bool LiveDoor(Door door) { if ((Object)(object)door != (Object)null && ((Behaviour)door).isActiveAndEnabled && (Object)(object)door.m_nview != (Object)null && door.m_nview.IsValid()) { return door.m_nview.GetZDO() != null; } return false; } private void PruneDoorRetries() { List list = new List(); foreach (KeyValuePair item in _doorRetryAfter) { if (Time.time >= item.Value) { list.Add(item.Key); } } foreach (int item2 in list) { _doorRetryAfter.Remove(item2); } } private bool TryYieldToSettler(float dt, Vector3 finalTarget) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_01d8: Unknown result type (might be due to invalid IL or missing references) //IL_01da: Unknown result type (might be due to invalid IL or missing references) //IL_01df: Unknown result type (might be due to invalid IL or missing references) //IL_01e1: Unknown result type (might be due to invalid IL or missing references) //IL_01e6: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_01fd: Unknown result type (might be due to invalid IL or missing references) //IL_0202: Unknown result type (might be due to invalid IL or missing references) //IL_0209: Unknown result type (might be due to invalid IL or missing references) //IL_020e: Unknown result type (might be due to invalid IL or missing references) //IL_0213: Unknown result type (might be due to invalid IL or missing references) //IL_021a: Unknown result type (might be due to invalid IL or missing references) //IL_021f: Unknown result type (might be due to invalid IL or missing references) //IL_0224: Unknown result type (might be due to invalid IL or missing references) //IL_024e: Unknown result type (might be due to invalid IL or missing references) //IL_01ed: Unknown result type (might be due to invalid IL or missing references) //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) if (Time.time < _yieldUntil) { ((BaseAI)this).MoveAndAvoid(dt, _yieldPoint, 0.25f, false); return true; } if (Time.time < _yieldCooldownUntil || Time.time - _progressTime < 1.1f) { return false; } SettlerController settlerController = null; float num = float.MaxValue; foreach (SettlerController instance in SettlerController.Instances) { if ((Object)(object)instance == (Object)null || (Object)(object)instance == (Object)(object)_controller || !instance.IsValidSettler || instance.IsRespawning) { continue; } Vector3 val = instance.Position - ((Component)this).transform.position; float magnitude = ((Vector3)(ref val)).magnitude; if (!(magnitude > 1.45f) && !(magnitude >= num)) { Vector3 val2 = finalTarget - ((Component)this).transform.position; val2.y = 0f; val.y = 0f; if (!(((Vector3)(ref val2)).sqrMagnitude > 0.1f) || !(Vector3.Dot(((Vector3)(ref val2)).normalized, ((Vector3)(ref val)).normalized) < 0.15f)) { settlerController = instance; num = magnitude; } } } if ((Object)(object)settlerController == (Object)null) { return false; } int hashCode = ((object)_controller.PersistentId/*cast due to .constrained prefix*/).GetHashCode(); int hashCode2 = ((object)settlerController.PersistentId/*cast due to .constrained prefix*/).GetHashCode(); if (hashCode < hashCode2 || (hashCode == hashCode2 && ((Object)this).GetInstanceID() < ((Object)settlerController).GetInstanceID())) { return false; } Vector3 val3 = finalTarget - ((Component)this).transform.position; val3.y = 0f; val3 = ((((Vector3)(ref val3)).sqrMagnitude > 0.01f) ? ((Vector3)(ref val3)).normalized : ((Component)this).transform.forward); Vector3 val4 = Vector3.Cross(Vector3.up, val3); if ((hashCode & 1) == 0) { val4 = -val4; } _yieldPoint = ((Component)this).transform.position + val4 * 1.65f - val3 * 0.25f; _yieldUntil = Time.time + 0.75f; _yieldCooldownUntil = Time.time + 1.8f; ((BaseAI)this).MoveAndAvoid(dt, _yieldPoint, 0.25f, false); return true; } private void ApplyFollowerCombatPolicy() { //IL_01d7: 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_0115: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_controller == (Object)null || _controller.CurrentRole != SettlerRole.Follower) { return; } FollowerCombatMode currentFollowerCombatMode = _controller.CurrentFollowerCombatMode; if (currentFollowerCombatMode == FollowerCombatMode.Passive) { ClearHostileTarget(); return; } if ((Object)(object)base.m_targetCreature != (Object)null && (base.m_targetCreature.IsDead() || !BaseAI.IsEnemy(((BaseAI)this).m_character, base.m_targetCreature) || !FollowerMayRetainTarget(base.m_targetCreature, currentFollowerCombatMode))) { ClearHostileTarget(); } if ((Object)(object)base.m_targetCreature != (Object)null || Time.time < _nextTargetScan) { return; } _nextTargetScan = Time.time + 0.45f; Character val = null; float num = float.MaxValue; Player followedPlayer = _controller.FollowedPlayer; foreach (Character allCharacter in Character.GetAllCharacters()) { if ((Object)(object)allCharacter == (Object)null || (Object)(object)allCharacter == (Object)(object)((BaseAI)this).m_character || allCharacter.IsDead() || !BaseAI.IsEnemy(((BaseAI)this).m_character, allCharacter)) { continue; } float num2 = Vector3.Distance(((Component)this).transform.position, ((Component)allCharacter).transform.position); float num3 = (((Object)(object)followedPlayer != (Object)null) ? Vector3.Distance(((Component)followedPlayer).transform.position, ((Component)allCharacter).transform.position) : float.MaxValue); bool num4; if (currentFollowerCombatMode != FollowerCombatMode.Aggressive) { if (num2 <= 12f) { goto IL_0187; } num4 = num3 <= 15f; } else { num4 = num2 <= 30f; } if (!num4) { continue; } goto IL_0187; IL_0187: float num5 = Mathf.Min(num2, num3); if (num5 < num) { val = allCharacter; num = num5; } } if ((Object)(object)val != (Object)null) { base.m_targetCreature = val; base.m_targetStatic = null; base.m_lastKnownTargetPos = ((Component)val).transform.position; base.m_timeSinceSensedTargetCreature = 0f; ((BaseAI)this).SetAlerted(true); } } private void ApplySettlementDefensePolicy() { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_019a: 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_0105: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)base.m_targetCreature != (Object)null && (base.m_targetCreature.IsDead() || !BaseAI.IsEnemy(((BaseAI)this).m_character, base.m_targetCreature) || (Utils.DistanceXZ(_controller.HomePosition, ((Component)base.m_targetCreature).transform.position) > 75f && Utils.DistanceXZ(((Component)this).transform.position, ((Component)base.m_targetCreature).transform.position) > 75f))) { ClearHostileTarget(); } if ((Object)(object)base.m_targetCreature != (Object)null || Time.time < _nextTargetScan) { return; } _nextTargetScan = Time.time + 0.25f; Character val = null; float num = float.MaxValue; foreach (Character allCharacter in Character.GetAllCharacters()) { if ((Object)(object)allCharacter == (Object)null || (Object)(object)allCharacter == (Object)(object)((BaseAI)this).m_character || allCharacter.IsDead() || !BaseAI.IsEnemy(((BaseAI)this).m_character, allCharacter)) { continue; } float num2 = Utils.DistanceXZ(_controller.HomePosition, ((Component)allCharacter).transform.position); float num3 = Utils.DistanceXZ(((Component)this).transform.position, ((Component)allCharacter).transform.position); if (!(num2 > 55f) || !(num3 > 30f)) { float num4 = Mathf.Min(num2, num3); if (num4 < num) { val = allCharacter; num = num4; } } } if ((Object)(object)val != (Object)null) { base.m_targetCreature = val; base.m_targetStatic = null; base.m_lastKnownTargetPos = ((Component)val).transform.position; base.m_timeSinceSensedTargetCreature = 0f; ((BaseAI)this).SetAlerted(true); } } private bool FollowerMayRetainTarget(Character target, FollowerCombatMode stance) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_004e: 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) float num = Vector3.Distance(((Component)this).transform.position, ((Component)target).transform.position); if (stance == FollowerCombatMode.Aggressive) { return num <= 45f; } Player followedPlayer = _controller.FollowedPlayer; float num2 = (((Object)(object)followedPlayer != (Object)null) ? Vector3.Distance(((Component)followedPlayer).transform.position, ((Component)target).transform.position) : float.MaxValue); if (!(num <= 26f)) { return num2 <= 26f; } return true; } private void TrackProgress(Vector3 target) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) float num = Utils.DistanceXZ(((Component)this).transform.position, target); if (_progressDistance - num > 0.35f) { ResetProgress(target); } } private void ResetProgress(Vector3? target = null) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) Vector3? val = target ?? _moveTarget; _progressDistance = (val.HasValue ? Utils.DistanceXZ(((Component)this).transform.position, val.Value) : float.MaxValue); _progressTime = Time.time; } private void TryOpenDoorAhead() { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: 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) if (Time.time < _nextDoorTry) { return; } Vector3 val = ((Component)this).transform.position + ((Component)this).transform.forward * 1.35f + Vector3.up; int mask = LayerMask.GetMask(new string[3] { "piece", "piece_nonsolid", "Default" }); Door val2 = null; float num = float.MaxValue; Collider[] array = Physics.OverlapSphere(val, 1.55f, mask); for (int i = 0; i < array.Length; i++) { Door componentInParent = ((Component)array[i]).GetComponentInParent(); if (!((Object)(object)componentInParent == (Object)null) && !((Object)(object)componentInParent.m_nview == (Object)null) && componentInParent.m_nview.IsValid() && componentInParent.m_nview.GetZDO().GetInt(ZDOVars.s_state, 0) == 0) { float num2 = Utils.DistanceXZ(((Component)this).transform.position, ((Component)componentInParent).transform.position); if (num2 < num) { val2 = componentInParent; num = num2; } } } if (!((Object)(object)val2 == (Object)null)) { TryOpenDoor(val2); } } private bool TryOpenDoor(Door door) { //IL_0087: 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_009c: 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_00ad: 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) if (!LiveDoor(door)) { return false; } if (door.m_nview.GetZDO().GetInt(ZDOVars.s_state, 0) != 0) { return true; } if (!door.CanInteract()) { return false; } if (Time.time < _nextDoorTry) { return true; } Character character = ((BaseAI)this).m_character; Humanoid val = (Humanoid)(object)((character is Humanoid) ? character : null); if ((Object)(object)val == (Object)null) { return false; } _nextDoorTry = Time.time + 0.35f; Vector3 val2 = ((Component)this).transform.position - ((Component)door).transform.position; float startingSide = Mathf.Sign(Vector3.Dot(((Component)door).transform.forward, val2)); Diagnostics.Navigation("Hearthfolk[ai]: " + NavigationActor + " opening a door"); if (!door.Interact(val, false, false)) { return false; } if (!_openedDoors.Exists((OpenedDoor entry) => (Object)(object)entry.Door == (Object)(object)door)) { _openedDoors.Add(new OpenedDoor { Door = door, OpenedAt = Time.time, StartingSide = startingSide }); } return true; } private void MaintainOpenedDoors() { //IL_00d2: 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) //IL_00e2: 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_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) if (_openedDoors.Count == 0) { return; } Character character = ((BaseAI)this).m_character; Humanoid val = (Humanoid)(object)((character is Humanoid) ? character : null); for (int num = _openedDoors.Count - 1; num >= 0; num--) { OpenedDoor openedDoor = _openedDoors[num]; Door door = openedDoor.Door; if ((Object)(object)door == (Object)null || (Object)(object)door.m_nview == (Object)null || !door.m_nview.IsValid()) { _openedDoors.RemoveAt(num); } else if (door.m_nview.GetZDO().GetInt(ZDOVars.s_state, 0) == 0) { _openedDoors.RemoveAt(num); } else if (!((Object)(object)val == (Object)null) && !door.m_canNotBeClosed && !(Time.time - openedDoor.OpenedAt < 0.8f)) { Vector3 val2 = ((Component)this).transform.position - ((Component)door).transform.position; float num2 = Utils.DistanceXZ(((Component)this).transform.position, ((Component)door).transform.position); float num3 = Mathf.Sign(Vector3.Dot(((Component)door).transform.forward, val2)); bool num4 = openedDoor.StartingSide != 0f && num3 != 0f && num3 != openedDoor.StartingSide && num2 > 1.35f; bool flag = Time.time - openedDoor.OpenedAt > 6f && num2 > 1.35f; if ((num4 || flag) && !CharacterNearDoor(door, 1.45f) && door.CanInteract()) { Diagnostics.Navigation("Hearthfolk[ai]: " + NavigationActor + " closing a door"); door.Interact(val, false, false); if (door.m_nview.GetZDO().GetInt(ZDOVars.s_state, 0) == 0) { _openedDoors.RemoveAt(num); } } } } } private bool CharacterNearDoor(Door door, float radius) { //IL_003a: 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) foreach (Character allCharacter in Character.GetAllCharacters()) { if (!((Object)(object)allCharacter == (Object)null) && !((Object)(object)allCharacter == (Object)(object)((BaseAI)this).m_character) && !allCharacter.IsDead() && Utils.DistanceXZ(((Component)allCharacter).transform.position, ((Component)door).transform.position) < radius) { return true; } } return false; } } internal sealed class SettlerController : MonoBehaviour, Interactable, Hoverable { private sealed class AppearanceColor { internal readonly string Name; internal readonly Vector3 Value; internal AppearanceColor(string name, float r, float g, float b) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) Name = name; Value = new Vector3(r, g, b); } } private sealed class GuardPatrolEntry { internal Vector3 Position; internal string Prefab; internal long Creator; } private enum MealKind { None, Dinner, Breakfast } private sealed class SocialGroup { internal int Id; internal readonly List Members = new List(); internal float StartedAt; internal float EndsAt; internal float NextLineAt; internal int Turn; } private static readonly AppearanceColor[] HairColors = new AppearanceColor[8] { new AppearanceColor("Black", 0.1f, 0.07f, 0.05f), new AppearanceColor("Dark brown", 0.24f, 0.12f, 0.06f), new AppearanceColor("Brown", 0.43f, 0.24f, 0.1f), new AppearanceColor("Auburn", 0.52f, 0.17f, 0.07f), new AppearanceColor("Red", 0.72f, 0.24f, 0.07f), new AppearanceColor("Blond", 0.74f, 0.57f, 0.29f), new AppearanceColor("Grey", 0.48f, 0.48f, 0.45f), new AppearanceColor("White", 0.82f, 0.8f, 0.72f) }; private static readonly AppearanceColor[] SkinTones = new AppearanceColor[6] { new AppearanceColor("Pale", 1f, 0.84f, 0.73f), new AppearanceColor("Fair", 0.88f, 0.67f, 0.53f), new AppearanceColor("Warm", 0.72f, 0.48f, 0.32f), new AppearanceColor("Tan", 0.54f, 0.32f, 0.19f), new AppearanceColor("Deep", 0.32f, 0.17f, 0.09f), new AppearanceColor("Dark", 0.18f, 0.09f, 0.05f) }; private static List _appearanceHair; private static List _appearanceBeards; private VisEquipment _appearanceEquipment; private int _lastAppearanceSignature = int.MinValue; internal static readonly List Instances = new List(); internal const float ChopReach = 3.5f; internal const float PlantDistance = 2.3f; internal const float StorageReach = 2.8f; internal const float GuardLeash = 12f; internal const float ThinkStep = 0.3f; private const float ThinkInterval = 0.3f; private const float EquipInterval = 2f; private const float SwingInterval = 1.6f; private const float CollectRadius = 4f; private const float TreeScanCooldown = 1f; private static readonly HashSet WoodNames = new HashSet { "$item_wood", "$item_finewood", "$item_roundlog", "$item_ancientbark", "$item_yggdrasilwood", "$item_ashwood", "$item_elderbark" }; internal static readonly HashSet OreNames = new HashSet { "$item_stone", "$item_copperore", "$item_tinore", "$item_silverore", "$item_obsidian", "$item_ironscrap", "$item_flametalore" }; private static readonly string[] LegacyBuildingWorkerKeys = new string[3] { "hf_building_worker_0", "hf_building_worker_1", "hf_building_worker_2" }; private static readonly string[] LegacyGuardStartKeys = new string[3] { "hf_guard_start_0", "hf_guard_start_1", "hf_guard_start_2" }; private static readonly string[] LegacyGuardEndKeys = new string[3] { "hf_guard_end_0", "hf_guard_end_1", "hf_guard_end_2" }; private ZNetView _nview; private Humanoid _body; private SettlerAI _ai; private SettlerInventory _container; private Inventory _inv; private readonly Dictionary _jobs = new Dictionary(); private ISettlerJob _current; private float _nextThink; private float _nextEquip; private float _nextSwing; private float _nextReclaimLog; private float _lastTreeScan; private float _storageUnreachableUntil; private GameObject _approachTarget; private Vector3 _approachPoint; private Vector3 _approachTargetPosition; private List _anchors; private float _anchorsTime; private bool _equipmentNormalized; private bool _rpcsRegistered; private bool _wasNetworkOwner; private bool _respawnHidden; private Dictionary _respawnRendererStates; private Dictionary _respawnColliderStates; private bool _respawnAiWasEnabled; private bool _respawnBodyWasEnabled; private bool _respawnBodyWasKinematic; private bool _deathHandled; private readonly Dictionary _treeBlacklist = new Dictionary(); private float _nextDiag; private const float BedSearchRadius = 30f; internal const long BedOwnerMarker = 424242L; private Bed _bed; private float _nextBedCheck; private float _nextBedFailureLog; private bool _sleeping; private Transform _sleepPoint; private Bed _bedAccessBed; private Vector3 _bedAccessPoint; private Vector3 _bedAccessBedPosition; private float _nextBedAccessSearch; private float _nextBedAccessFailureLog; private bool _leavingTentAfterSleep; private int _wakeExitStage; private float _wakeExitStartedAt; private float _wakeExitProgressAt; private float _wakeExitLastDistance; private const float StationSearchRadius = 40f; private bool _restMovement; private float _lastMineScan; private float _lastDropScan; private const float MealStorageReach = 2.8f; private const float DiningRadius = 15f; private const int MealSearchSeconds = 30; private const int MinimumSleepSeconds = 60; private const float DefaultHappiness = 70f; private static readonly Dictionary SeatReservations = new Dictionary(); private Container _mealStorage; private string _mealFoodName; private Chair _mealChair; private bool _mealSitting; private bool _waitingSitting; private float _nextEatAnimation; private float _nextFollowerHealingFood; private float _followerHealingPauseUntil; private bool _leavingSettlement; private static readonly string[] SocialLines = new string[24] { "Quiet shift today. I could get used to this.", "The hearth feels warmer when everyone is home.", "Have you seen the new patrol route?", "I hope the stores last through the next storm.", "Someone should really organize that chest.", "The roof held up better than I expected.", "I heard something moving beyond the trees.", "A hot meal makes any day better.", "Do you think the bees are happy?", "The night watch looked peaceful for once.", "I could use a new pair of boots.", "This place is starting to feel like home.", "The forest was unusually quiet this morning.", "I would not mind another chair by the fire.", "We should reinforce the outer wall.", "At least nobody asked me to mine today.", "There is always more wood to cut.", "I wonder what lies beyond the next hill.", "The cook deserves some praise.", "A calm day is never wasted.", "Did you hear that, or was it just the wind?", "Tomorrow will be busy.", "The guards have been doing good work.", "I am glad we are not out in the rain." }; private static int _nextSocialGroupId; private SocialGroup _socialGroup; private float _socialAvailableUntil; private float _nextSocialDecision; private float _nextSocialLook; private int _lastSocialLineSequence; internal string AppearanceBodyLabel { get { if (AppearanceBody != 1) { return "Masculine"; } return "Feminine"; } } internal string AppearanceHairLabel => StyleLabel(HairStyles(), AppearanceHair); internal string AppearanceBeardLabel { get { if (AppearanceBody != 1) { return StyleLabel(BeardStyles(), AppearanceBeard); } return "None"; } } internal string AppearanceHairColorLabel => HairColors[Wrap(AppearanceHairColor, HairColors.Length)].Name; internal string AppearanceSkinToneLabel => SkinTones[Wrap(AppearanceSkinTone, SkinTones.Length)].Name; internal bool AppearanceSupportsBeard => AppearanceBody == 0; private int AppearanceBody { get { if (!Valid) { return 0; } return Mathf.Clamp(_nview.GetZDO().GetInt("hf_appearance_body", 0), 0, 1); } } private string AppearanceHair { get { if (!Valid) { return string.Empty; } return _nview.GetZDO().GetString("hf_appearance_hair", string.Empty); } } private string AppearanceBeard { get { if (!Valid) { return string.Empty; } return _nview.GetZDO().GetString("hf_appearance_beard", string.Empty); } } private int AppearanceHairColor { get { if (!Valid) { return 0; } return _nview.GetZDO().GetInt("hf_appearance_hair_color", 0); } } private int AppearanceSkinTone { get { if (!Valid) { return 1; } return _nview.GetZDO().GetInt("hf_appearance_skin_tone", 1); } } internal SettlerFlags Flags { get { if (!Valid) { return SettlerFlags.All; } return (SettlerFlags)_nview.GetZDO().GetInt("hf_flags", -1); } } internal CaretakerTasks EnabledCaretakerTasks { get { if (!Valid) { return CaretakerTasks.All; } return (CaretakerTasks)_nview.GetZDO().GetInt("hf_caretaker_tasks", 63); } } internal string FarmerCropPermissions { get { if (!Valid) { return "*"; } return _nview.GetZDO().GetString("hf_farmer_crops", "*"); } } internal FarmerWorkMode FarmerMode { get { if (!Valid) { return FarmerWorkMode.FullCycle; } FarmerWorkMode farmerWorkMode = (FarmerWorkMode)_nview.GetZDO().GetInt("hf_farmer_mode", 3); if (farmerWorkMode != FarmerWorkMode.Plant && farmerWorkMode != FarmerWorkMode.Harvest && farmerWorkMode != FarmerWorkMode.FullCycle) { return FarmerWorkMode.FullCycle; } return farmerWorkMode; } } internal bool FarmerCanPlant => (FarmerMode & FarmerWorkMode.Plant) != 0; internal bool FarmerCanHarvest => (FarmerMode & FarmerWorkMode.Harvest) != 0; internal bool FarmerMarkersConfigured { get { if (Valid) { return _nview.GetZDO().GetBool("hf_farmer_markers_configured", false); } return false; } } internal List FarmerMarkerIds { get { if (Valid && FarmerMarkersConfigured) { return ExilesHearth.DecodePatrolRoute(_nview.GetZDO().GetString("hf_farmer_markers", string.Empty)); } return new List(); } } internal string FarmerStockTargets { get { if (!Valid) { return string.Empty; } return _nview.GetZDO().GetString("hf_farmer_stock_targets", string.Empty); } } internal Humanoid Char => _body; internal SettlerAI Ai => _ai; internal Inventory Inv => _inv; internal Vector3 Position => ((Component)this).transform.position; internal Vector3 Home { get { //IL_002a: 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_000e: Unknown result type (might be due to invalid IL or missing references) if (!Valid) { return ((Component)this).transform.position; } return _nview.GetZDO().GetVec3("hf_home", ((Component)this).transform.position); } } internal float WorkRadius => Mathf.Max(8f, HfConfig.WorkRadius.Value); private bool Valid { get { if ((Object)(object)_nview != (Object)null) { return _nview.IsValid(); } return false; } } private long OwnerId { get { if (!Valid) { return 0L; } return _nview.GetZDO().GetLong("hf_owner", 0L); } } internal bool IsRespawning { get { if (Valid) { return _nview.GetZDO().GetBool("hf_respawning", false); } return false; } } internal long SettlementOwnerId => OwnerId; private SettlerRole Role { get { if (!Valid) { return SettlerRole.Idle; } return (SettlerRole)_nview.GetZDO().GetInt("hf_role", 0); } } private ZDOID MyZdoid { get { //IL_0019: 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 (!Valid) { return ZDOID.None; } return _nview.GetZDO().m_uid; } } private string StableIdentity { get { if (!Valid) { return string.Empty; } return _nview.GetZDO().GetString("hf_identity", string.Empty); } } internal bool HasBed => (Object)(object)_bed != (Object)null; internal string PanelName => DisplayName; internal SettlerRole CurrentRole => Role; internal bool HasStorage { get { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) if (!Valid) { return false; } ExilesHearth exilesHearth = ExilesHearth.FindFor(Home, OwnerId); if (!((Object)(object)exilesHearth != (Object)null) || !exilesHearth.HasIntakeStorageFor(CurrentRole)) { return StorageLink.GetId(_nview.GetZDO()) != ZDOID.None; } return true; } } internal bool IsValidSettler => Valid; internal Vector3 HomePosition => Home; internal ZDOID PersistentId => MyZdoid; internal long FollowerTargetId { get { if (!Valid) { return 0L; } return _nview.GetZDO().GetLong("hf_follower_target", 0L); } } internal string FollowerTargetName { get { if (!Valid) { return string.Empty; } return _nview.GetZDO().GetString("hf_follower_target_name", string.Empty); } } internal FollowerMode CurrentFollowerMode { get { if (!Valid) { return FollowerMode.Returning; } return (FollowerMode)Mathf.Clamp(_nview.GetZDO().GetInt("hf_follower_mode", 0), 0, 2); } } internal FollowerCombatMode CurrentFollowerCombatMode { get { if (!Valid) { return FollowerCombatMode.Defensive; } return (FollowerCombatMode)Mathf.Clamp(_nview.GetZDO().GetInt("hf_follower_combat_mode", 0), 0, 2); } } internal Vector3 FollowerWaitPosition { get { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) if (!Valid) { return Position; } return _nview.GetZDO().GetVec3("hf_follower_wait_position", Position); } } internal Player FollowedPlayer { get { if (FollowerTargetId == 0L) { return null; } return Player.GetPlayer(FollowerTargetId); } } private bool ThreatMovement { get { if (!SettlementAlertActive) { if ((Object)(object)_ai != (Object)null) { return _ai.HasHostileTarget(); } return false; } return true; } } private bool FieldWorkerRunning { get { if (!_restMovement) { if (EffectiveRole != SettlerRole.Lumberjack) { return EffectiveRole == SettlerRole.Miner; } return true; } return false; } } internal bool ShouldForceWalk { get { if (!ThreatMovement) { return !FieldWorkerRunning; } return false; } } internal bool SettlementAlertActive { get { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) if (!ExilesHearth.AlertAt(Home, OwnerId) && !ExilesHearth.RaidAt(Home)) { return ExilesHearth.DefenseThreatAt(Home, OwnerId); } return true; } } private SettlerRole EffectiveRole { get { if (SettlementAlertActive) { return SettlerRole.Guard; } if (Role == SettlerRole.Guard && !IsGuardOnShift) { return SettlerRole.Idle; } return Role; } } internal Vector3 GuardPosition => Home; internal bool GuardPatrolConfigured { get { if (Valid) { return _nview.GetZDO().GetBool("hf_guard_patrol_configured", false); } return false; } } internal List GuardPatrolRouteIds => (from point in ResolveGuardPatrolPoints() select point.PersistentId).ToList(); internal List GuardPatrolRoute { get { //IL_0001: Unknown result type (might be due to invalid IL or missing references) ExilesHearth exilesHearth = ExilesHearth.FindFor(Home, OwnerId); if ((Object)(object)exilesHearth == (Object)null) { return new List(); } if (!GuardPatrolConfigured) { return (from point in PatrolPoint.PointsFor(exilesHearth) select point.Position).ToList(); } return (from point in ResolveGuardPatrolPoints() select point.Position).ToList(); } } internal int GuardShiftStart { get { if (!Valid) { return 6; } return _nview.GetZDO().GetInt("hf_guard_shift_start", 6); } } internal int GuardShiftEnd { get { if (!Valid) { return 22; } return _nview.GetZDO().GetInt("hf_guard_shift_end", 22); } } internal bool IsGuardOnShift { get { if (SettlementAlertActive || (Object)(object)EnvMan.instance == (Object)null) { return true; } int guardShiftStart = GuardShiftStart; int guardShiftEnd = GuardShiftEnd; if (guardShiftStart == guardShiftEnd) { return true; } float num = EnvMan.instance.GetDayFraction() * 24f; if (guardShiftStart >= guardShiftEnd) { if (!(num >= (float)guardShiftStart)) { return num < (float)guardShiftEnd; } return true; } if (num >= (float)guardShiftStart) { return num < (float)guardShiftEnd; } return false; } } internal bool CanDismiss { get { if (!IsRespawning && _inv != null) { return _inv.NrOfItems() == 0; } return false; } } internal string RespawnStatusText { get { if (!IsRespawning) { return string.Empty; } return FormatRespawnStatus(_nview.GetZDO().GetLong("hf_respawn_at", 0L)); } } internal bool LocalPlayerCanManage { get { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer != (Object)null) { if (OwnerId != 0L) { return OwnerId == localPlayer.GetPlayerID(); } return true; } return false; } } private bool IsLocalPeerResponsible { get { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer != (Object)null && (OwnerId == 0L || OwnerId == localPlayer.GetPlayerID())) { return true; } if ((Object)(object)localPlayer != (Object)null && Role == SettlerRole.Follower && FollowerTargetId == localPlayer.GetPlayerID()) { return true; } if ((Object)(object)ZNet.instance != (Object)null) { return ZNet.instance.IsServer(); } return false; } } internal string CurrentStatusText { get { if (IsRespawning) { return RespawnStatusText; } string text = (Valid ? _nview.GetZDO().GetString("hf_status", string.Empty) : string.Empty); if (!string.IsNullOrEmpty(text)) { return Localization.instance.Localize(text); } return string.Empty; } } private string DisplayName { get { if (!Valid) { return Localization.instance.Localize("$hf_settler"); } string text = _nview.GetZDO().GetString("hf_name", string.Empty); if (!string.IsNullOrEmpty(text)) { return text; } return Localization.instance.Localize("$hf_settler"); } } internal float EquippedArmor { get { if (_inv != null) { return (from item in _inv.GetAllItems() where item?.m_equipped ?? false select item).Sum((ItemData item) => item.GetArmor()); } return 0f; } } internal bool LastMineTierBlocked { get; private set; } internal bool LastSearchTierBlocked { get; private set; } private static long WorldTimeMilliseconds { get { if (!((Object)(object)ZNet.instance != (Object)null)) { return (long)(Time.realtimeSinceStartup * 1000f); } return (long)(ZNet.instance.GetTimeSeconds() * 1000.0); } } internal int Happiness { get { if (!Valid) { return Mathf.RoundToInt(70f); } return Mathf.RoundToInt(_nview.GetZDO().GetFloat("hf_happiness", 70f)); } } internal string MoodLabel { get { string text = ((Happiness >= 80) ? "$hf_mood_very_happy" : ((Happiness >= 60) ? "$hf_mood_happy" : ((Happiness >= 40) ? "$hf_mood_neutral" : ((Happiness >= 20) ? "$hf_mood_unhappy" : "$hf_mood_miserable")))); return Localization.instance.Localize(text); } } internal string MoraleReasonsText { get { if (!Valid) { return string.Empty; } string text = _nview.GetZDO().GetString("hf_morale_reasons", string.Empty); return string.Join(" · ", from key in text.Split(new char[1] { '|' }, StringSplitOptions.RemoveEmptyEntries) select Localization.instance.Localize(key)); } } private bool SocialRestEnabled { get { if (HfConfig.EnableSocialRest != null) { return HfConfig.EnableSocialRest.Value; } return false; } } internal void RequestCycleAppearance(SettlerAppearanceField field, int direction) { Player localPlayer = Player.m_localPlayer; if (Valid && !((Object)(object)localPlayer == (Object)null) && !IsRespawning) { _nview.InvokeRPC("hf_CycleAppearance", new object[3] { localPlayer.GetPlayerID(), (int)field, direction }); } } internal void RequestRename(string requestedName) { Player localPlayer = Player.m_localPlayer; if (Valid && !((Object)(object)localPlayer == (Object)null) && !IsRespawning) { _nview.InvokeRPC("hf_RenameSettler", new object[2] { localPlayer.GetPlayerID(), requestedName ?? string.Empty }); } } private void RPC_RenameSettler(long sender, long requesterId, string requestedName) { if (!_nview.IsOwner() || IsRespawning || (OwnerId != 0L && OwnerId != requesterId)) { return; } string name = SanitizeName(requestedName); Player player = Player.GetPlayer(requesterId); if (string.IsNullOrEmpty(name)) { if (player != null) { ((Character)player).Message((MessageType)2, "$hf_appearance_name_invalid", 0, (Sprite)null); } return; } if (Instances.Any((SettlerController other) => (Object)(object)other != (Object)null && (Object)(object)other != (Object)(object)this && other.IsValidSettler && Vector3.Distance(other.HomePosition, HomePosition) <= 6f && string.Equals(other.PanelName, name, StringComparison.OrdinalIgnoreCase))) { if (player != null) { ((Character)player).Message((MessageType)2, "$hf_appearance_name_in_use", 0, (Sprite)null); } return; } _nview.GetZDO().Set("hf_name", name); if ((Object)(object)_body != (Object)null) { ((Character)_body).m_name = name; } UpdateClaimedBedName(); } private void UpdateClaimedBedName() { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) Bed val = _bed; if ((Object)(object)val == (Object)null) { val = ResolveBed(_nview.GetZDO().GetZDOID("hf_bed")); } if ((Object)(object)val == (Object)null || (Object)(object)val.m_nview == (Object)null || !val.m_nview.IsValid()) { return; } ZDO zDO = val.m_nview.GetZDO(); string text = zDO.GetString("hf_claim_identity", string.Empty); if ((string.IsNullOrEmpty(text) || !(text != StableIdentity)) && (!string.IsNullOrEmpty(text) || !(zDO.GetZDOID("hf_claim") != MyZdoid))) { if (!val.m_nview.IsOwner()) { val.m_nview.ClaimOwnership(); } zDO.Set(ZDOVars.s_owner, 424242L); zDO.Set(ZDOVars.s_ownerName, DisplayName); } } private static string SanitizeName(string value) { if (string.IsNullOrWhiteSpace(value)) { return string.Empty; } StringBuilder stringBuilder = new StringBuilder(24); bool flag = false; string text = value.Trim(); foreach (char c in text) { if (stringBuilder.Length >= 24) { break; } if (char.IsLetterOrDigit(c) || c == '\'' || c == '-') { stringBuilder.Append(c); flag = false; } else if (char.IsWhiteSpace(c) && !flag && stringBuilder.Length > 0) { stringBuilder.Append(' '); flag = true; } } return stringBuilder.ToString().Trim(); } private void RPC_CycleAppearance(long sender, long requesterId, int requestedField, int direction) { if (!_nview.IsOwner() || IsRespawning || (OwnerId != 0L && OwnerId != requesterId) || !EnsureAppearanceInitialized()) { return; } SettlerAppearanceField settlerAppearanceField = (SettlerAppearanceField)Mathf.Clamp(requestedField, 0, 5); if (settlerAppearanceField == SettlerAppearanceField.Randomize) { RandomizeAppearance(); ApplyAppearance(force: true); return; } int num = ((direction >= 0) ? 1 : (-1)); ZDO zDO = _nview.GetZDO(); switch (settlerAppearanceField) { case SettlerAppearanceField.Body: { int num2 = Wrap(AppearanceBody + num, 2); zDO.Set("hf_appearance_body", num2); if (num2 == 1) { zDO.Set("hf_appearance_beard", NoBeardStyle()); } break; } case SettlerAppearanceField.Hair: zDO.Set("hf_appearance_hair", CycleStyle(HairStyles(), AppearanceHair, num)); break; case SettlerAppearanceField.Beard: if (AppearanceBody == 0) { zDO.Set("hf_appearance_beard", CycleStyle(BeardStyles(), AppearanceBeard, num)); } break; case SettlerAppearanceField.HairColor: zDO.Set("hf_appearance_hair_color", Wrap(AppearanceHairColor + num, HairColors.Length)); break; case SettlerAppearanceField.SkinTone: zDO.Set("hf_appearance_skin_tone", Wrap(AppearanceSkinTone + num, SkinTones.Length)); break; } ApplyAppearance(force: true); } private void MaintainAppearance() { if (Valid && !((Object)(object)ObjectDB.instance == (Object)null) && (!_nview.IsOwner() || EnsureAppearanceInitialized()) && _nview.GetZDO().GetBool("hf_appearance_initialized", false)) { ApplyAppearance(force: false); } } private bool EnsureAppearanceInitialized() { if (!Valid || !_nview.IsOwner() || HairStyles().Count == 0 || BeardStyles().Count == 0) { return false; } ZDO zDO = _nview.GetZDO(); if (zDO.GetBool("hf_appearance_initialized", false)) { return true; } int num = Random.Range(0, 2); List list = HairStyles(); List list2 = BeardStyles(); zDO.Set("hf_appearance_body", num); zDO.Set("hf_appearance_hair", ((Object)((Component)list[Random.Range(0, list.Count)]).gameObject).name); zDO.Set("hf_appearance_beard", (num == 1) ? NoBeardStyle() : ((Object)((Component)list2[Random.Range(0, list2.Count)]).gameObject).name); zDO.Set("hf_appearance_hair_color", Random.Range(0, HairColors.Length)); zDO.Set("hf_appearance_skin_tone", Random.Range(0, SkinTones.Length)); zDO.Set("hf_appearance_initialized", true); _lastAppearanceSignature = int.MinValue; return true; } private void RandomizeAppearance() { List list = HairStyles(); List list2 = BeardStyles(); if (list.Count != 0 && list2.Count != 0) { int num = Random.Range(0, 2); ZDO zDO = _nview.GetZDO(); zDO.Set("hf_appearance_body", num); zDO.Set("hf_appearance_hair", ((Object)((Component)list[Random.Range(0, list.Count)]).gameObject).name); zDO.Set("hf_appearance_beard", (num == 1) ? NoBeardStyle() : ((Object)((Component)list2[Random.Range(0, list2.Count)]).gameObject).name); zDO.Set("hf_appearance_hair_color", Random.Range(0, HairColors.Length)); zDO.Set("hf_appearance_skin_tone", Random.Range(0, SkinTones.Length)); zDO.Set("hf_appearance_initialized", true); } } private void ApplyAppearance(bool force) { //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) _appearanceEquipment = (((Object)(object)_appearanceEquipment != (Object)null) ? _appearanceEquipment : ((Component)this).GetComponent()); if (!((Object)(object)_appearanceEquipment == (Object)null)) { int appearanceBody = AppearanceBody; string appearanceHair = AppearanceHair; string text = ((appearanceBody == 1) ? NoBeardStyle() : AppearanceBeard); int num = Wrap(AppearanceHairColor, HairColors.Length); int num2 = Wrap(AppearanceSkinTone, SkinTones.Length); int num3 = appearanceBody; num3 = (num3 * 397) ^ StringExtensionMethods.GetStableHashCode(appearanceHair ?? string.Empty); num3 = (num3 * 397) ^ StringExtensionMethods.GetStableHashCode(text ?? string.Empty); num3 = (num3 * 397) ^ num; num3 = (num3 * 397) ^ num2; if (force || num3 != _lastAppearanceSignature) { _lastAppearanceSignature = num3; _appearanceEquipment.SetModel(appearanceBody); _appearanceEquipment.SetHairItem(appearanceHair ?? string.Empty); _appearanceEquipment.SetBeardItem(text ?? string.Empty); _appearanceEquipment.SetHairColor(HairColors[num].Value); _appearanceEquipment.SetSkinColor(SkinTones[num2].Value); } } } private static List HairStyles() { if (_appearanceHair == null && (Object)(object)ObjectDB.instance != (Object)null) { _appearanceHair = LoadStyles("Hair"); } return _appearanceHair ?? new List(); } private static List BeardStyles() { if (_appearanceBeards == null && (Object)(object)ObjectDB.instance != (Object)null) { _appearanceBeards = LoadStyles("Beard"); } return _appearanceBeards ?? new List(); } private static List LoadStyles(string category) { List list = (from val in ObjectDB.instance.GetAllItems((ItemType)10, category) where (Object)(object)val != (Object)null && !((Object)((Component)val).gameObject).name.Contains("_") orderby ((Object)((Component)val).gameObject).name select val).ToList(); int num = list.FindIndex((ItemDrop val) => ((Object)((Component)val).gameObject).name.IndexOf("none", StringComparison.OrdinalIgnoreCase) >= 0); if (num > 0) { ItemDrop item = list[num]; list.RemoveAt(num); list.Insert(0, item); } return list; } private static string CycleStyle(List styles, string current, int direction) { if (styles.Count == 0) { return current ?? string.Empty; } int num = styles.FindIndex((ItemDrop item) => ((Object)((Component)item).gameObject).name == current); num = ((num >= 0) ? num : 0); return ((Object)((Component)styles[Wrap(num + direction, styles.Count)]).gameObject).name; } private static string StyleLabel(List styles, string current) { if (styles.Count == 0) { return "Unavailable"; } int num = styles.FindIndex((ItemDrop item) => ((Object)((Component)item).gameObject).name == current); if (num < 0) { num = 0; } if (num != 0 || ((Object)((Component)styles[num]).gameObject).name.IndexOf("none", StringComparison.OrdinalIgnoreCase) < 0) { return $"Style {num + 1}"; } return "None"; } private static string NoBeardStyle() { List list = BeardStyles(); if (list.Count <= 0) { return string.Empty; } return ((Object)((Component)list[0]).gameObject).name; } private static int Wrap(int value, int count) { if (count > 0) { return (value % count + count) % count; } return 0; } private static void CopyAppearanceState(ZDO source, ZDO destination) { if (source != null && destination != null && source.GetBool("hf_appearance_initialized", false)) { destination.Set("hf_appearance_initialized", true); destination.Set("hf_appearance_body", source.GetInt("hf_appearance_body", 0)); destination.Set("hf_appearance_hair", source.GetString("hf_appearance_hair", string.Empty)); destination.Set("hf_appearance_beard", source.GetString("hf_appearance_beard", string.Empty)); destination.Set("hf_appearance_hair_color", source.GetInt("hf_appearance_hair_color", 0)); destination.Set("hf_appearance_skin_tone", source.GetInt("hf_appearance_skin_tone", 1)); } } internal bool FlagEnabled(SettlerFlags flag) { return (Flags & flag) != 0; } internal bool CaretakerTaskEnabled(CaretakerTasks task) { return (EnabledCaretakerTasks & task) != 0; } internal bool FarmerCropEnabled(FarmCrop crop) { return FarmCropCatalog.PermissionEnabled(FarmerCropPermissions, crop); } internal bool FarmerMarkerEnabled(FarmMarker marker) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)marker != (Object)null) { if (FarmerMarkersConfigured) { return FarmerMarkerIds.Contains(marker.PersistentId); } return true; } return false; } internal int FarmerStockTarget(FarmCrop crop) { return FarmCropCatalog.StockTarget(FarmerStockTargets, crop); } internal void RequestToggleFlag(SettlerFlags flag) { Player localPlayer = Player.m_localPlayer; if (Valid && !((Object)(object)localPlayer == (Object)null)) { _nview.InvokeRPC("hf_SetFlags", new object[2] { localPlayer.GetPlayerID(), (int)(Flags ^ flag) }); } } internal void RequestToggleCaretakerTask(CaretakerTasks task) { Player localPlayer = Player.m_localPlayer; if (Valid && !((Object)(object)localPlayer == (Object)null)) { _nview.InvokeRPC("hf_SetCaretakerTasks", new object[2] { localPlayer.GetPlayerID(), (int)(EnabledCaretakerTasks ^ task) }); } } internal void RequestToggleFarmerCrop(FarmCrop crop) { Player localPlayer = Player.m_localPlayer; if (Valid && !((Object)(object)localPlayer == (Object)null) && crop != null) { string text = FarmCropCatalog.TogglePermission(FarmerCropPermissions, crop); _nview.InvokeRPC("hf_SetFarmerCrops", new object[2] { localPlayer.GetPlayerID(), text }); } } internal void RequestFarmerMode(FarmerWorkMode mode) { Player localPlayer = Player.m_localPlayer; if (Valid && !((Object)(object)localPlayer == (Object)null) && Role == SettlerRole.Farmer) { _nview.InvokeRPC("hf_SetFarmerMode", new object[2] { localPlayer.GetPlayerID(), (int)mode }); } } internal void RequestSetFarmerMarkers(IEnumerable markerIds, bool configured) { Player localPlayer = Player.m_localPlayer; if (Valid && !((Object)(object)localPlayer == (Object)null) && Role == SettlerRole.Farmer) { string text = (configured ? ExilesHearth.EncodePatrolRoute(markerIds) : string.Empty); _nview.InvokeRPC("hf_SetFarmerMarkers", new object[3] { localPlayer.GetPlayerID(), configured ? 1 : 0, text }); } } internal void RequestFarmerStockTarget(FarmCrop crop, int target) { Player localPlayer = Player.m_localPlayer; if (Valid && !((Object)(object)localPlayer == (Object)null) && crop != null && Role == SettlerRole.Farmer) { _nview.InvokeRPC("hf_SetFarmerStockTarget", new object[3] { localPlayer.GetPlayerID(), FarmCropCatalog.PermissionKey(crop), Mathf.Clamp(target, 0, 10000) }); } } private List Anchors() { //IL_001d: Unknown result type (might be due to invalid IL or missing references) if (_anchors == null || Time.time - _anchorsTime > 1f) { _anchors = WorkArea.Anchors(Home, OwnerId, Role); _anchorsTime = Time.time; } return _anchors; } internal bool IsInWorkArea(Vector3 point) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) return WorkArea.Contains(point, Anchors()); } private void Awake() { Instances.Add(this); _nview = ((Component)this).GetComponent(); _body = ((Component)this).GetComponent(); _ai = ((Component)this).GetComponent(); _container = ((Component)this).GetComponent(); _inv = (((Object)(object)_body != (Object)null) ? _body.GetInventory() : null); _wasNetworkOwner = Valid && _nview.IsOwner(); StaggerRecurringWork(); _jobs[SettlerRole.Idle] = new IdleJob(); _jobs[SettlerRole.Lumberjack] = new LumberjackJob(); _jobs[SettlerRole.Guard] = new GuardJob(); _jobs[SettlerRole.Caretaker] = new CaretakerJob(); _jobs[SettlerRole.Miner] = new MinerJob(); _jobs[SettlerRole.Follower] = new FollowerJob(); _jobs[SettlerRole.Farmer] = new FarmerJob(); if ((Object)(object)_body != (Object)null) { Humanoid body = _body; ((Character)body).m_onDeath = (Action)Delegate.Combine(((Character)body).m_onDeath, new Action(OnSettlerDeath)); Humanoid body2 = _body; ((Character)body2).m_onDamaged = (Action)Delegate.Combine(((Character)body2).m_onDamaged, new Action(OnSettlerDamaged)); } RegisterRpcs(); } private void StaggerRecurringWork() { float num = (float)((uint)(Valid ? ((object)Unsafe.As(ref _nview.GetZDO().m_uid)/*cast due to .constrained prefix*/).GetHashCode() : ((Object)this).GetInstanceID()) % 997u) / 997f; _nextThink = Time.time + num * 0.3f; _nextEquip = Time.time + num * 2f; _ai?.StaggerTargetScan(num); } private void OnDestroy() { _current?.Exit(this); StopSocialRest(); ReleaseMealSeat(); if ((Object)(object)_body != (Object)null) { Humanoid body = _body; ((Character)body).m_onDamaged = (Action)Delegate.Remove(((Character)body).m_onDamaged, new Action(OnSettlerDamaged)); } Instances.Remove(this); } private void RegisterRpcs() { if (!_rpcsRegistered && Valid) { _nview.Register("hf_SetRole", (Action)RPC_SetRole); _nview.Register("hf_SetStorage", (Action)RPC_SetStorage); _nview.Register("hf_SetFlags", (Action)RPC_SetFlags); _nview.Register("hf_SetCaretakerTasks", (Action)RPC_SetCaretakerTasks); _nview.Register("hf_SetFarmerCrops", (Action)RPC_SetFarmerCrops); _nview.Register("hf_SetFarmerMode", (Action)RPC_SetFarmerMode); _nview.Register("hf_SetFarmerMarkers", (Action)RPC_SetFarmerMarkers); _nview.Register("hf_SetFarmerStockTarget", (Action)RPC_SetFarmerStockTarget); _nview.Register("hf_Dismiss", (Action)RPC_Dismiss); _nview.Register("hf_SetGuardSchedule", (Action)RPC_SetGuardSchedule); _nview.Register("hf_SetGuardPatrolRoute", (Action)RPC_SetGuardPatrolRoute); _nview.Register("hf_FollowerCommand", (Action)RPC_FollowerCommand); _nview.Register("hf_SetFollowerCombatMode", (Action)RPC_SetFollowerCombatMode); _nview.Register("hf_CycleAppearance", (Action)RPC_CycleAppearance); _nview.Register("hf_RenameSettler", (Action)RPC_RenameSettler); _rpcsRegistered = true; } } private void Update() { if (!Valid) { return; } RegisterRpcs(); RepairFriendlyState(); MaintainAppearance(); MaintainSocialPresentation(); if (!_nview.IsOwner()) { if (!_nview.GetZDO().HasOwner() && IsLocalPeerResponsible) { _nview.ClaimOwnership(); if (Time.time >= _nextReclaimLog) { _nextReclaimLog = Time.time + 30f; Diagnostics.Log("Hearthfolk[net]: reclaimed ownership of " + PanelName + " (far from players)"); } } if (!_nview.IsOwner()) { _wasNetworkOwner = false; return; } } if (!_wasNetworkOwner) { _wasNetworkOwner = true; StaggerRecurringWork(); } EnsureStableIdentity(); if (IsRespawning) { MaintainRespawn(); return; } MigrateLegacyWorkstation(); if (!((Object)(object)_container != (Object)null) || _container.Bound) { if (_sleeping) { MaintainSleep(); } if (_mealSitting) { MaintainMealPose(); } if (!_equipmentNormalized) { NormalizeEquipment(); _equipmentNormalized = true; } if (Time.time >= _nextEquip) { _nextEquip = Time.time + 2f; SyncEquipment(); } if (Time.time >= _nextThink) { _nextThink = Time.time + 0.3f; RunJob(); } } } private void RunJob() { //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) _restMovement = false; SettlerRole effectiveRole = EffectiveRole; if (_current == null || _current.Role != effectiveRole) { _current?.Exit(this); _current = _jobs[effectiveRole]; ((BaseAI)_ai).SetPatrolPoint(Home); _current.Enter(this); Diagnostics.Log($"Hearthfolk[job]: role -> {effectiveRole}"); } if (RunWakeExitRoutine()) { return; } if (Diagnostics.Enabled && Time.time >= _nextDiag) { _nextDiag = Time.time + 2f; Diagnostics.Log($"Hearthfolk[job]: role={effectiveRole} owner={_nview.IsOwner()} bound={_container?.Bound} " + $"axe={FindAxe() != null} distHome={DistanceTo(Home):0.0} hostile={_ai.HasHostileTarget()} " + $"vel={((Vector3)(ref ((Character)_body).m_currentVel)).magnitude:0.00} moveDir={((Vector3)(ref ((Character)_body).m_moveDir)).magnitude:0.00} " + $"canMove={((Character)_body).CanMove()} swim={((Character)_body).IsSwimming()} onground={((Character)_body).IsOnGround()}"); } bool flag = Role != SettlerRole.Follower; bool flag2 = !flag || !HfConfig.RequireBed.Value || EnsureBed(); if (!RunNeedsRoutine(effectiveRole, flag2, flag)) { if (flag && !flag2) { _ai.ClearMove(); ReturnHomeIfIdle(); SetStatus("$hf_status_need_bed"); } else { _current.Tick(this); } } } private void EnsureStableIdentity() { if (Valid && _nview.IsOwner() && string.IsNullOrEmpty(_nview.GetZDO().GetString("hf_identity", string.Empty))) { _nview.GetZDO().Set("hf_identity", Guid.NewGuid().ToString("N")); } } private bool EnsureBed() { //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: 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_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_bed != (Object)null && (Object)(object)_bed.m_nview != (Object)null && _bed.m_nview.IsValid()) { if (!_sleeping && !SettlerShelter.IsDedicated(_bed) && Time.time >= _nextBedCheck) { _nextBedCheck = Time.time + 5f; TryMigrateToSettlerShelter(); } return true; } _bed = null; if (Time.time < _nextBedCheck) { return false; } _nextBedCheck = Time.time + 5f; ZDOID zDOID = _nview.GetZDO().GetZDOID("hf_bed"); if (zDOID != ZDOID.None && (Object)(object)ZNetScene.instance != (Object)null) { Bed bed = ResolveBed(zDOID); if (TryRestoreBed(bed, requirePersistedName: false)) { return true; } } Bed[] array = SceneObjectCache.Get(1.5f); foreach (Bed bed2 in array) { if (TryRestoreBed(bed2, requirePersistedName: true)) { return true; } } float bestDistance; Bed val = FindAvailableSettlerShelter(out bestDistance); if ((Object)(object)val == (Object)null) { if (Time.time >= _nextBedFailureLog) { _nextBedFailureLog = Time.time + 30f; Diagnostics.Log("Hearthfolk[bed]: " + PanelName + " could not restore a " + $"bed or find a free Settler Tent; saved={zDOID}"); } return false; } ClaimBed(val, bestDistance, "claimed Settler Tent"); return true; } private Bed FindAvailableSettlerShelter(out float bestDistance) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0150: 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_015f: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) Vector3 home = Home; Bed result = null; bestDistance = float.MaxValue; Bed[] array = SceneObjectCache.Get(1.5f); foreach (Bed val in array) { if (!SettlerShelter.IsDedicated(val) || (Object)(object)val.m_nview == (Object)null || !val.m_nview.IsValid()) { continue; } float num = Vector3.Distance(((Component)val).transform.position, home); if (num > 30f || num >= bestDistance) { continue; } ZDO zDO = val.m_nview.GetZDO(); if (zDO == null) { continue; } SettlerShelter settlerShelter = SettlerShelter.For(val); if (!CivilPathPlanner.TryProjectWalkPoint(settlerShelter.AccessPosition, ((Component)this).transform, out var point) || Utils.DistanceXZ(point, settlerShelter.AccessPosition) > 0.5f || !CanInteractWithPointFrom(point, settlerShelter.InteractionPosition, ((Component)val).gameObject, 2.4f)) { continue; } long num2 = zDO.GetLong(ZDOVars.s_owner, 0L); if (num2 == 0L || num2 == 424242) { ZDOID zDOID = zDO.GetZDOID("hf_claim"); string text = zDO.GetString("hf_claim_identity", string.Empty); if ((string.IsNullOrEmpty(text) || !(text != StableIdentity)) && (!string.IsNullOrEmpty(text) || !(zDOID != ZDOID.None) || !(zDOID != MyZdoid) || !HasLiveBedClaimant(zDOID))) { result = val; bestDistance = num; } } } return result; } private void TryMigrateToSettlerShelter() { float bestDistance; Bed val = FindAvailableSettlerShelter(out bestDistance); if (!((Object)(object)val == (Object)null)) { Bed bed = _bed; ReleaseBed(); ClaimBed(val, bestDistance, "migrated to Settler Tent"); Diagnostics.Navigation("Hearthfolk[bed]: " + PanelName + " released legacy bed " + ((bed != null) ? ((Object)((Component)bed).gameObject).name : null) + " after dedicated-bed migration"); } } private void ClaimBed(Bed bed, float distance, string action) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) if (!bed.m_nview.IsOwner()) { bed.m_nview.ClaimOwnership(); } ZDO zDO = bed.m_nview.GetZDO(); zDO.Set("hf_claim", MyZdoid); zDO.Set("hf_claim_identity", StableIdentity); zDO.Set(ZDOVars.s_owner, 424242L); zDO.Set(ZDOVars.s_ownerName, DisplayName); _nview.GetZDO().Set("hf_bed", zDO.m_uid); _bed = bed; _bedAccessBed = null; Diagnostics.Navigation($"Hearthfolk[bed]: {PanelName} {action} at {distance:0.0}m"); } private static Bed ResolveBed(ZDOID id) { //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_0021: Unknown result type (might be due to invalid IL or missing references) if (id == ZDOID.None || (Object)(object)ZNetScene.instance == (Object)null) { return null; } GameObject val = ZNetScene.instance.FindInstance(id); object obj; if (!((Object)(object)val == (Object)null)) { obj = val.GetComponent(); if (obj == null) { return val.GetComponentInChildren(true); } } else { obj = null; } return (Bed)obj; } private bool TryRestoreBed(Bed bed, bool requirePersistedName) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: 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_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: Unknown result type (might be due to invalid IL or missing references) //IL_01d4: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0122: 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_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)bed == (Object)null || (Object)(object)bed.m_nview == (Object)null || !bed.m_nview.IsValid() || Vector3.Distance(((Component)bed).transform.position, Home) > 30f) { return false; } ZDO zDO = bed.m_nview.GetZDO(); long num = zDO.GetLong(ZDOVars.s_owner, 0L); string a = zDO.GetString(ZDOVars.s_ownerName, string.Empty); bool flag = num == 424242 && string.Equals(a, DisplayName, StringComparison.Ordinal); if (requirePersistedName && !flag) { return false; } if (num != 0L && num != 424242) { return false; } ZDOID zDOID = zDO.GetZDOID("hf_claim"); string text = zDO.GetString("hf_claim_identity", string.Empty); if (!string.IsNullOrEmpty(text) && text != StableIdentity) { return false; } if (!requirePersistedName && string.IsNullOrEmpty(text) && zDOID != MyZdoid && !flag && (num != 0L || zDOID != ZDOID.None)) { return false; } if (string.IsNullOrEmpty(text) && zDOID != ZDOID.None && zDOID != MyZdoid && HasLiveBedClaimant(zDOID)) { return false; } if (!bed.m_nview.IsOwner()) { bed.m_nview.ClaimOwnership(); } zDO.Set("hf_claim", MyZdoid); zDO.Set("hf_claim_identity", StableIdentity); zDO.Set(ZDOVars.s_owner, 424242L); zDO.Set(ZDOVars.s_ownerName, DisplayName); _nview.GetZDO().Set("hf_bed", zDO.m_uid); _bed = bed; _bedAccessBed = null; Diagnostics.Log($"Hearthfolk[bed]: {PanelName} restored bed link {zDO.m_uid} (claim was {zDOID})"); return true; } private static bool HasLiveBedClaimant(ZDOID claimant) { //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_0021: Unknown result type (might be due to invalid IL or missing references) if (claimant == ZDOID.None || (Object)(object)ZNetScene.instance == (Object)null) { return false; } GameObject val = ZNetScene.instance.FindInstance(claimant); if ((Object)(object)val == (Object)null) { return false; } SettlerController settlerController = val.GetComponent() ?? val.GetComponentInChildren(true); if ((Object)(object)settlerController != (Object)null && settlerController.IsValidSettler) { return !settlerController.IsRespawning; } return false; } private bool TryGetBedAccessPoint(out Vector3 accessPoint) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0141: 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_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: 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_0106: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_018f: 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_0266: Unknown result type (might be due to invalid IL or missing references) //IL_026d: Unknown result type (might be due to invalid IL or missing references) //IL_026e: Unknown result type (might be due to invalid IL or missing references) //IL_01e8: 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_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: Unknown result type (might be due to invalid IL or missing references) //IL_01c4: Unknown result type (might be due to invalid IL or missing references) //IL_0204: Unknown result type (might be due to invalid IL or missing references) //IL_0206: Unknown result type (might be due to invalid IL or missing references) accessPoint = default(Vector3); if ((Object)(object)_bed == (Object)null) { return false; } if ((Object)(object)_bedAccessBed == (Object)(object)_bed && Vector3.Distance(_bedAccessBedPosition, ((Component)_bed).transform.position) <= 0.2f && CanInteractWithBedFrom(_bedAccessPoint) && CivilPathPlanner.TryProjectWalkPoint(_bedAccessPoint, ((Component)this).transform, out var point) && Utils.DistanceXZ(point, _bedAccessPoint) <= 0.35f) { accessPoint = _bedAccessPoint; return true; } _bedAccessBed = null; if (Time.time < _nextBedAccessSearch) { return false; } _nextBedAccessSearch = Time.time + 0.9f; SettlerShelter settlerShelter = SettlerShelter.For(_bed); if ((Object)(object)settlerShelter != (Object)null && CivilPathPlanner.TryProjectWalkPoint(settlerShelter.AccessPosition, ((Component)this).transform, out var point2) && Utils.DistanceXZ(point2, settlerShelter.AccessPosition) <= 0.5f && CanInteractWithBedFrom(point2)) { CacheBedAccessPoint(point2); accessPoint = point2; Diagnostics.Navigation("Hearthfolk[bed]: " + PanelName + " selected the marked Settler Tent entrance"); return true; } List obj = (((Object)(object)settlerShelter != (Object)null) ? ShelterAccessCandidates(settlerShelter) : VanillaBedAccessCandidates()); Vector3 val = default(Vector3); float num = float.MaxValue; int num2 = 0; foreach (Vector3 item in obj) { if (CivilPathPlanner.TryProjectWalkPoint(item, ((Component)this).transform, out var point3) && CanInteractWithBedFrom(point3)) { num2++; float num3 = Utils.DistanceXZ(((Component)this).transform.position, point3) + (((Object)(object)settlerShelter != (Object)null) ? (Utils.DistanceXZ(point3, settlerShelter.AccessPosition) * 0.3f) : (Vector3.Distance(point3, ((Object)(object)_bed.m_spawnPoint != (Object)null) ? _bed.m_spawnPoint.position : ((Component)_bed).transform.position) * 0.15f)); if (!(num3 >= num)) { val = point3; num = num3; } } } if (num2 == 0) { if (Time.time >= _nextBedAccessFailureLog) { _nextBedAccessFailureLog = Time.time + 15f; Diagnostics.Navigation("Hearthfolk[bed]: " + PanelName + " found no safe standing point beside the assigned bed"); } return false; } CacheBedAccessPoint(val); accessPoint = val; Diagnostics.Navigation("Hearthfolk[bed]: " + PanelName + " selected a safe bed access " + $"point ({num2} candidate(s), " + $"{num:0.0} score)"); return true; } private List ShelterAccessCandidates(SettlerShelter shelter) { //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) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0040: 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_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_0069: Unknown result type (might be due to invalid IL or missing references) List list = new List(); Vector3 interactionPosition = shelter.InteractionPosition; Vector3 val = default(Vector3); for (int i = 0; i < 16; i++) { float num = (float)i * 22.5f * ((float)Math.PI / 180f); ((Vector3)(ref val))..ctor(Mathf.Sin(num), 0f, Mathf.Cos(num)); Vector3 item = interactionPosition + val * 1.15f; item.y = ((Component)_bed).transform.position.y; list.Add(item); } return list; } private List VanillaBedAccessCandidates() { //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: 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_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0147: 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_0156: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_016f: 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) List list = (from collider in ((Component)_bed).GetComponentsInChildren(true) where (Object)(object)collider != (Object)null && collider.enabled && !collider.isTrigger select collider).ToList(); Bounds val = (Bounds)((list.Count > 0) ? list[0].bounds : new Bounds(((Component)_bed).transform.position, new Vector3(1.8f, 0.8f, 2.2f))); for (int num = 1; num < list.Count; num++) { ((Bounds)(ref val)).Encapsulate(list[num].bounds); } List list2 = new List(); Vector3 val2 = default(Vector3); for (int num2 = 0; num2 < 16; num2++) { float num3 = (float)num2 * 22.5f * ((float)Math.PI / 180f); ((Vector3)(ref val2))..ctor(Mathf.Sin(num3), 0f, Mathf.Cos(num3)); float num4 = ((Mathf.Abs(val2.x) > 0.001f) ? (((Bounds)(ref val)).extents.x / Mathf.Abs(val2.x)) : float.MaxValue); float num5 = ((Mathf.Abs(val2.z) > 0.001f) ? (((Bounds)(ref val)).extents.z / Mathf.Abs(val2.z)) : float.MaxValue); float num6 = Mathf.Min(num4, num5); Vector3 item = ((Bounds)(ref val)).center + val2 * (num6 + 0.72f); item.y = ((Component)_bed).transform.position.y; list2.Add(item); } return list2; } private void CacheBedAccessPoint(Vector3 point) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) _bedAccessBed = _bed; _bedAccessBedPosition = ((Component)_bed).transform.position; _bedAccessPoint = point; } private void RestTick() { //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) UseRestMovement(); if (_sleeping) { SetStatus("$hf_status_rest"); return; } Transform val = (((Object)(object)_bed != (Object)null && (Object)(object)_bed.m_spawnPoint != (Object)null) ? _bed.m_spawnPoint : null); Vector3 accessPoint; if ((Object)(object)val == (Object)null) { ReturnHomeIfIdle(); SetStatus("$hf_status_rest"); } else if ((Object)(object)_bed != (Object)null && CanInteractWithBedFrom(((Component)this).transform.position)) { StartSleep(val); SetStatus("$hf_status_rest"); } else if (!TryGetBedAccessPoint(out accessPoint)) { Hold(); SetStatus("$hf_status_rest"); } else if (DistanceTo(accessPoint) > 0.72f) { GoTo(accessPoint, 0.5f, run: false); SetStatus("$hf_status_rest"); } else { _bedAccessBed = null; Hold(); SetStatus("$hf_status_rest"); } } private void StartSleep(Transform point) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) _leavingTentAfterSleep = false; MarkSleepStarted(); _sleeping = true; _sleepPoint = point; Hold(); ((Component)this).transform.position = point.position; ((Component)this).transform.rotation = point.rotation; if (!((Character)_body).m_body.isKinematic) { ((Character)_body).m_body.linearVelocity = Vector3.zero; } ((Character)_body).m_zanim.SetBool("attach_bed", true); Diagnostics.Navigation("Hearthfolk[bed]: " + PanelName + " reached the bed and went to sleep"); } private void StopSleep() { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_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_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) if (!_sleeping) { return; } _sleeping = false; _sleepPoint = null; ((Character)_body).m_zanim.SetBool("attach_bed", false); Vector3 position = ((Component)this).transform.position + Vector3.up * 0.3f; ((Component)this).transform.position = position; if ((Object)(object)((Character)_body).m_body != (Object)null) { ((Character)_body).m_body.position = position; if (!((Character)_body).m_body.isKinematic) { ((Character)_body).m_body.linearVelocity = Vector3.zero; } } if ((Object)(object)SettlerShelter.For(_bed) != (Object)null) { _leavingTentAfterSleep = true; _wakeExitStage = 0; _wakeExitStartedAt = Time.time; _wakeExitProgressAt = Time.time; _wakeExitLastDistance = float.MaxValue; } Diagnostics.Log("Hearthfolk[bed]: " + PanelName + " woke up"); } private bool RunWakeExitRoutine() { //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0062: 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_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: 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_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_014a: 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_0156: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0160: 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_0146: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_020c: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_01e1: Unknown result type (might be due to invalid IL or missing references) if (!_leavingTentAfterSleep) { return false; } if (SettlementAlertActive || _ai.HasHostileTarget()) { _leavingTentAfterSleep = false; return false; } UseRestMovement(); SettlerShelter settlerShelter = SettlerShelter.For(_bed); if ((Object)(object)settlerShelter == (Object)null) { _leavingTentAfterSleep = false; return false; } Vector3 point = ((_wakeExitStage == 0) ? settlerShelter.InteriorExitPosition : settlerShelter.AccessPosition); float num = DistanceTo(point); float num2 = ((_wakeExitStage == 0) ? 0.48f : 0.65f); if (num <= num2) { if (_wakeExitStage != 0) { _leavingTentAfterSleep = false; Hold(); Diagnostics.Navigation("Hearthfolk[bed]: " + PanelName + " walked out of the tent"); return false; } _wakeExitStage = 1; _wakeExitProgressAt = Time.time; _wakeExitLastDistance = float.MaxValue; point = settlerShelter.AccessPosition; num = DistanceTo(point); } if (num + 0.12f < _wakeExitLastDistance) { _wakeExitLastDistance = num; _wakeExitProgressAt = Time.time; } if (Time.time - _wakeExitStartedAt > 10f || Time.time - _wakeExitProgressAt > 4.5f) { Vector3 val = settlerShelter.AccessPosition; if (CivilPathPlanner.TryProjectWalkPoint(val, ((Component)this).transform, out var point2)) { val = point2; } val += Vector3.up * 0.18f; Hold(); ((Component)this).transform.position = val; if ((Object)(object)((Character)_body).m_body != (Object)null) { ((Character)_body).m_body.position = val; if (!((Character)_body).m_body.isKinematic) { ((Character)_body).m_body.linearVelocity = Vector3.zero; } } if (Valid && _nview.IsOwner()) { _nview.GetZDO().SetPosition(val); } _leavingTentAfterSleep = false; Diagnostics.Navigation("Hearthfolk[bed]: " + PanelName + " recovered outside the tent after the doorway was blocked"); return false; } GoTo(point, num2, run: false); SetStatus("$hf_status_leaving_tent"); return true; } private void MaintainSleep() { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_sleepPoint == (Object)null) { StopSleep(); return; } ((Component)this).transform.position = _sleepPoint.position; ((Component)this).transform.rotation = _sleepPoint.rotation; if (!((Character)_body).m_body.isKinematic) { ((Character)_body).m_body.linearVelocity = Vector3.zero; } } internal bool HasBrokenTool() { if (_inv != null) { return _inv.GetAllItems().Any((ItemData item) => item != null && item.m_shared.m_useDurability && item.m_durability <= 0f); } return false; } internal CraftingStation FindNearestCraftingStation() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) Vector3 home = Home; CraftingStation result = null; float num = float.MaxValue; foreach (CraftingStation allStation in CraftingStation.m_allStations) { if (!((Object)(object)allStation == (Object)null) && !(Vector3.Distance(((Component)allStation).transform.position, home) > 40f)) { float num2 = DistanceTo(((Component)allStation).transform.position); if (num2 < num) { result = allStation; num = num2; } } } return result; } internal void RepairAllTools() { if (_inv == null) { return; } int num = 0; foreach (ItemData allItem in _inv.GetAllItems()) { if (allItem != null && allItem.m_shared.m_useDurability && allItem.m_durability <= 0f) { allItem.m_durability = allItem.GetMaxDurability(); num++; } } if (num > 0) { _inv.Changed(); Diagnostics.Log($"Hearthfolk[repair]: {PanelName} repaired {num} item(s)"); } } public string GetHoverName() { return DisplayName; } internal string HoverName() { return GetHoverName(); } internal string HoverText() { return GetHoverText(); } public string GetHoverText() { string text = (Valid ? _nview.GetZDO().GetString("hf_status", string.Empty) : string.Empty); string text2 = (string.IsNullOrEmpty(text) ? string.Empty : ("\n" + Localization.instance.Localize(text) + "")); string text3 = string.Empty; if (Role == SettlerRole.Follower) { Player localPlayer = Player.m_localPlayer; text3 = (((Object)(object)localPlayer != (Object)null && FollowerTargetId == localPlayer.GetPlayerID() && CurrentFollowerMode == FollowerMode.Following) ? "\n[$KEY_Crouch+$KEY_Use] $hf_follower_wait_here" : "\n[$KEY_Crouch+$KEY_Use] $hf_follower_follow_me"); } return Localization.instance.Localize(DisplayName + " — " + LocalizeRole(Role) + text2 + "\n[$KEY_Use] $hf_inventory" + ((Role == SettlerRole.Follower) ? text3 : string.Empty)); } public bool Interact(Humanoid user, bool hold, bool alt) { if (!hold) { Player val = (Player)(object)((user is Player) ? user : null); if (val != null && !((Object)(object)val != (Object)(object)Player.m_localPlayer) && Valid) { if (Role == SettlerRole.Follower && ((Character)val).IsCrouching()) { FollowerCommand command = ((FollowerTargetId != val.GetPlayerID() || CurrentFollowerMode != FollowerMode.Following) ? FollowerCommand.FollowMe : FollowerCommand.WaitHere); RequestFollowerCommand(val, command); return true; } if (OwnerId != 0L && OwnerId != val.GetPlayerID()) { ((Character)val).Message((MessageType)2, "$hf_not_owner", 0, (Sprite)null); return true; } if ((Object)(object)_container != (Object)null) { return ((Container)_container).Interact(user, false, false); } return false; } } return false; } public bool UseItem(Humanoid user, ItemData item) { return false; } internal Vector3 FollowerFormationPosition(Player target) { //IL_0010: 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_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0115: 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_011c: 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_0127: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)target == (Object)null) { return Position; } long targetId = target.GetPlayerID(); List list = (from s in Instances where (Object)(object)s != (Object)null && s.IsValidSettler && !s.IsRespawning && s.CurrentRole == SettlerRole.Follower && s.CurrentFollowerMode == FollowerMode.Following && s.FollowerTargetId == targetId orderby ((object)s.PersistentId/*cast due to .constrained prefix*/).GetHashCode(), s.PanelName select s).ToList(); int num = list.IndexOf(this); if (num < 0) { num = 0; } Vector2 val = FollowerFormationOffset(num, list.Count); Vector3 val2 = ((Component)target).transform.forward; Vector3 val3 = ((Component)target).transform.right; val2.y = 0f; val3.y = 0f; val2 = ((((Vector3)(ref val2)).sqrMagnitude > 0.01f) ? ((Vector3)(ref val2)).normalized : Vector3.forward); val3 = ((((Vector3)(ref val3)).sqrMagnitude > 0.01f) ? ((Vector3)(ref val3)).normalized : Vector3.right); return ((Component)target).transform.position + val3 * val.x + val2 * val.y; } private static Vector2 FollowerFormationOffset(int slot, int count) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_009c: 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_00d8: 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) if (count <= 1) { return new Vector2(0f, -3.2f); } if (count == 2) { return new Vector2((slot == 0) ? (-1.6f) : 1.6f, -3.4f); } switch (slot) { case 0: return new Vector2(0f, -3.2f); case 1: return new Vector2(-2.2f, -3.8f); case 2: return new Vector2(2.2f, -3.8f); case 3: return new Vector2(-3.4f, -5.4f); case 4: return new Vector2(0f, -5.4f); case 5: return new Vector2(3.4f, -5.4f); default: { int num = slot - 6; int num2 = num / 4; int num3 = num % 4; return new Vector2(-4.5f + (float)num3 * 3f, -7f - (float)num2 * 2.2f); } } } private void UseRestMovement() { _restMovement = true; } internal static bool IsPlayerConnected(long playerId) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) if (playerId == 0L) { return false; } if ((Object)(object)Player.GetPlayer(playerId) != (Object)null) { return true; } if ((Object)(object)ZNet.instance == (Object)null || ZDOMan.instance == null) { return false; } foreach (PlayerInfo player in ZNet.instance.GetPlayerList()) { ZDO zDO = ZDOMan.instance.GetZDO(player.m_characterID); if (zDO != null && zDO.GetLong(ZDOVars.s_playerID, 0L) == playerId) { return true; } } return false; } private void OnSettlerDamaged(float damage, Character attacker) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) if (damage > 0f && Valid && !IsRespawning) { StopSleep(); StopWaitingSit(); _ai?.EngageAttacker(attacker); _nextEquip = 0f; SyncEquipment(); ExilesHearth.ReportSettlerAttack(Home, OwnerId, attacker); } } internal static string FormatRespawnStatus(long deadline) { int num = (int)Math.Ceiling((double)Math.Max(0L, deadline - DateTime.UtcNow.Ticks) / 10000000.0); int num2 = num / 60; int num3 = num % 60; return string.Format(Localization.instance.Localize("$hf_status_respawning"), $"{num2:00}:{num3:00}"); } internal static string RoleLabel(SettlerRole role) { return LocalizeRole(role); } internal void RequestRole(SettlerRole role) { Player localPlayer = Player.m_localPlayer; if (Valid && !((Object)(object)localPlayer == (Object)null)) { _nview.InvokeRPC("hf_SetRole", new object[2] { localPlayer.GetPlayerID(), (int)role }); } } internal void RequestFollowerReturnHome() { Player localPlayer = Player.m_localPlayer; if (Valid && (Object)(object)localPlayer != (Object)null && Role == SettlerRole.Follower) { RequestFollowerCommand(localPlayer, FollowerCommand.ReturnHome); } } internal void RequestFollowerCombatMode(FollowerCombatMode mode) { Player localPlayer = Player.m_localPlayer; if (Valid && !((Object)(object)localPlayer == (Object)null) && Role == SettlerRole.Follower) { _nview.InvokeRPC("hf_SetFollowerCombatMode", new object[2] { localPlayer.GetPlayerID(), (int)mode }); } } private void RequestFollowerCommand(Player player, FollowerCommand command) { if (Valid && (Object)(object)player != (Object)null && Role == SettlerRole.Follower) { _nview.InvokeRPC("hf_FollowerCommand", new object[2] { player.GetPlayerID(), (int)command }); } } private void MigrateLegacyWorkstation() { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_002e: 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_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_006a: 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_0086: Unknown result type (might be due to invalid IL or missing references) if (!Valid || !_nview.IsOwner()) { return; } ZDO zDO = _nview.GetZDO(); ZDOID zDOID = zDO.GetZDOID("hf_workstation"); if (!(zDOID != ZDOID.None)) { return; } if (Role == SettlerRole.Guard && !zDO.GetBool("hf_guard_shift_initialized", false) && ZDOMan.instance != null) { ZDO zDO2 = ZDOMan.instance.GetZDO(zDOID); if (zDO2 != null) { for (int i = 0; i < LegacyBuildingWorkerKeys.Length; i++) { if (!(zDO2.GetZDOID(LegacyBuildingWorkerKeys[i]) != MyZdoid)) { zDO.Set("hf_guard_shift_start", zDO2.GetInt(LegacyGuardStartKeys[i], WrapHour(6 + i * 8))); zDO.Set("hf_guard_shift_end", zDO2.GetInt(LegacyGuardEndKeys[i], WrapHour(14 + i * 8))); zDO.Set("hf_guard_shift_initialized", true); break; } } } } zDO.Set("hf_workstation", ZDOID.None); zDO.Set("hf_workstation_prev_role", (int)Role); SetStatus(string.Empty); } internal void RequestSetGuardSchedule(int startHour, int endHour) { Player localPlayer = Player.m_localPlayer; if (Valid && (Object)(object)localPlayer != (Object)null && Role == SettlerRole.Guard) { _nview.InvokeRPC("hf_SetGuardSchedule", new object[3] { localPlayer.GetPlayerID(), WrapHour(startHour), WrapHour(endHour) }); } } internal void RequestSetGuardPatrolRoute(IList route) { Player localPlayer = Player.m_localPlayer; if (Valid && !((Object)(object)localPlayer == (Object)null) && Role == SettlerRole.Guard) { _nview.InvokeRPC("hf_SetGuardPatrolRoute", new object[3] { localPlayer.GetPlayerID(), 1, ExilesHearth.EncodePatrolRoute(route) }); } } internal void RequestAutomaticGuardPatrolRoute() { Player localPlayer = Player.m_localPlayer; if (Valid && !((Object)(object)localPlayer == (Object)null) && Role == SettlerRole.Guard) { _nview.InvokeRPC("hf_SetGuardPatrolRoute", new object[3] { localPlayer.GetPlayerID(), 0, string.Empty }); } } private void RPC_SetGuardPatrolRoute(long sender, long requesterId, int configured, string encodedRoute) { //IL_0075: Unknown result type (might be due to invalid IL or missing references) if (!_nview.IsOwner() || Role != SettlerRole.Guard || (OwnerId != 0L && OwnerId != requesterId)) { return; } ZDO zDO = _nview.GetZDO(); if (configured == 0) { zDO.Set("hf_guard_patrol_configured", false); zDO.Set("hf_guard_patrol_route", string.Empty); Logger.LogInfo((object)("Hearthfolk[patrol]: " + PanelName + " returned to the automatic route.")); return; } ExilesHearth exilesHearth = ExilesHearth.FindFor(Home, OwnerId); if (!((Object)(object)exilesHearth == (Object)null)) { List source = PatrolPoint.PointsFor(exilesHearth); Dictionary byId = (from point in source where (Object)(object)point != (Object)null && point.PersistentId != ZDOID.None group point by point.PersistentId).ToDictionary((IGrouping group) => group.Key, (IGrouping group) => group.First()); List list = (from id in ExilesHearth.DecodePatrolRoute(encodedRoute).Where(byId.ContainsKey).Distinct() .Take(64) select byId[id]).ToList(); if (list.Count != 0) { zDO.Set("hf_guard_patrol_route", EncodeGuardPatrolRoute(list)); zDO.Set("hf_guard_patrol_configured", true); Logger.LogInfo((object)$"Hearthfolk[patrol]: saved {list.Count} route point(s) for {PanelName}."); } } } private List ResolveGuardPatrolPoints() { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) if (!Valid || !GuardPatrolConfigured) { return new List(); } ExilesHearth exilesHearth = ExilesHearth.FindFor(Home, OwnerId); if ((Object)(object)exilesHearth == (Object)null) { return new List(); } List list = DecodeGuardPatrolRoute(_nview.GetZDO().GetString("hf_guard_patrol_route", string.Empty)); List source = PatrolPoint.PointsFor(exilesHearth); HashSet used = new HashSet(); List list2 = new List(); foreach (GuardPatrolEntry entry in list) { PatrolPoint patrolPoint = (from point in source where (Object)(object)point != (Object)null && !used.Contains(point.PersistentId) && PointCreator(point) == entry.Creator && string.Equals(PointPrefab(point), entry.Prefab, StringComparison.Ordinal) && Vector3.Distance(point.Position, entry.Position) <= 0.85f orderby Vector3.Distance(point.Position, entry.Position) select point).FirstOrDefault(); if (!((Object)(object)patrolPoint == (Object)null)) { used.Add(patrolPoint.PersistentId); list2.Add(patrolPoint); } } return list2; } private static string EncodeGuardPatrolRoute(IEnumerable route) { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Expected O, but got Unknown //IL_006d: 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_008f: Unknown result type (might be due to invalid IL or missing references) List list = route?.Where((PatrolPoint point) => (Object)(object)point != (Object)null).Take(64).ToList() ?? new List(); ZPackage val = new ZPackage(); val.Write(1); val.Write(list.Count); foreach (PatrolPoint item in list) { val.Write(item.Position.x); val.Write(item.Position.y); val.Write(item.Position.z); val.Write(PointPrefab(item)); val.Write(PointCreator(item)); } return val.GetBase64(); } private static List DecodeGuardPatrolRoute(string encoded) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) List list = new List(); if (string.IsNullOrEmpty(encoded)) { return list; } try { ZPackage val = new ZPackage(encoded); if (val.ReadInt() != 1) { return list; } int num = Mathf.Clamp(val.ReadInt(), 0, 64); for (int i = 0; i < num; i++) { list.Add(new GuardPatrolEntry { Position = new Vector3(val.ReadSingle(), val.ReadSingle(), val.ReadSingle()), Prefab = val.ReadString(), Creator = val.ReadLong() }); } } catch (Exception ex) { Logger.LogWarning((object)("Hearthfolk[patrol]: invalid guard route: " + ex.Message)); list.Clear(); } return list; } private static string PointPrefab(PatrolPoint point) { Piece val = ((Component)point).GetComponent() ?? ((Component)point).GetComponentInParent(); return MaterialFilters.PrefabName(((Object)(object)val != (Object)null) ? ((Component)val).gameObject : ((Component)point).gameObject); } private static long PointCreator(PatrolPoint point) { Piece val = ((Component)point).GetComponent() ?? ((Component)point).GetComponentInParent(); if (!((Object)(object)val != (Object)null)) { return 0L; } return val.GetCreator(); } internal bool RequestDismiss() { Player localPlayer = Player.m_localPlayer; if (!Valid || (Object)(object)localPlayer == (Object)null || IsRespawning) { return false; } if (_inv == null || _inv.NrOfItems() != 0) { ((Character)localPlayer).Message((MessageType)2, "$hf_dismiss_not_empty", 0, (Sprite)null); return false; } _nview.InvokeRPC("hf_Dismiss", new object[1] { localPlayer.GetPlayerID() }); return true; } private void RPC_SetRole(long sender, long requesterId, int requestedRole) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) if (_nview.IsOwner() && (OwnerId == 0L || OwnerId == requesterId)) { SettlerRole settlerRole = (SettlerRole)Mathf.Clamp(requestedRole, 0, 6); ZDO zDO = _nview.GetZDO(); zDO.Set("hf_workstation", ZDOID.None); if (settlerRole == SettlerRole.Follower) { StopSleep(); ReleaseBed(); SetFollowerState(0L, string.Empty, FollowerMode.Returning, Position); } else if (Role == SettlerRole.Follower) { SetFollowerState(0L, string.Empty, FollowerMode.Returning, Position); } zDO.Set("hf_role", (int)settlerRole); if (settlerRole == SettlerRole.Guard && !zDO.GetBool("hf_guard_shift_initialized", false)) { zDO.Set("hf_guard_shift_start", 6); zDO.Set("hf_guard_shift_end", 22); zDO.Set("hf_guard_shift_initialized", true); } SetStatus(string.Empty); } } private void RPC_FollowerCommand(long sender, long requesterId, int requestedCommand) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) if (!_nview.IsOwner() || Role != SettlerRole.Follower) { return; } switch ((FollowerCommand)requestedCommand) { case FollowerCommand.FollowMe: { Player player = Player.GetPlayer(requesterId); if (!((Object)(object)player == (Object)null)) { SetFollowerState(requesterId, player.GetPlayerName(), FollowerMode.Following, Position); StopSleep(); StopWaitingSit(); SetStatus("$hf_status_follower_following"); } break; } case FollowerCommand.WaitHere: if (FollowerTargetId == requesterId) { SetFollowerState(requesterId, FollowerTargetName, FollowerMode.Waiting, Position); Hold(); SetStatus("$hf_status_follower_waiting"); } break; case FollowerCommand.ReturnHome: if (OwnerId == 0L || OwnerId == requesterId || FollowerTargetId == requesterId) { SetFollowerState(0L, string.Empty, FollowerMode.Returning, Position); SetStatus("$hf_status_follower_returning"); } break; } } private void RPC_SetFollowerCombatMode(long sender, long requesterId, int requestedMode) { if (_nview.IsOwner() && Role == SettlerRole.Follower && (OwnerId == 0L || OwnerId == requesterId)) { FollowerCombatMode followerCombatMode = (FollowerCombatMode)Mathf.Clamp(requestedMode, 0, 2); _nview.GetZDO().Set("hf_follower_combat_mode", (int)followerCombatMode); if (followerCombatMode == FollowerCombatMode.Passive) { _ai.ClearHostileTarget(); } } } private void SetFollowerState(long targetId, string targetName, FollowerMode mode, Vector3 waitPosition) { //IL_0053: Unknown result type (might be due to invalid IL or missing references) if (Valid && _nview.IsOwner()) { ZDO zDO = _nview.GetZDO(); zDO.Set("hf_follower_target", targetId); zDO.Set("hf_follower_target_name", targetName ?? string.Empty); zDO.Set("hf_follower_mode", (int)mode); zDO.Set("hf_follower_wait_position", waitPosition); } } private void RPC_SetGuardSchedule(long sender, long requesterId, int startHour, int endHour) { if (_nview.IsOwner() && (OwnerId == 0L || OwnerId == requesterId) && Role == SettlerRole.Guard) { ZDO zDO = _nview.GetZDO(); zDO.Set("hf_guard_shift_start", WrapHour(startHour)); zDO.Set("hf_guard_shift_end", WrapHour(endHour)); zDO.Set("hf_guard_shift_initialized", true); } } private static int WrapHour(int hour) { return (hour % 24 + 24) % 24; } private void RPC_SetFlags(long sender, long requesterId, int flags) { if (_nview.IsOwner() && (OwnerId == 0L || OwnerId == requesterId)) { _nview.GetZDO().Set("hf_flags", flags); } } private void RPC_SetCaretakerTasks(long sender, long requesterId, int tasks) { if (_nview.IsOwner() && (OwnerId == 0L || OwnerId == requesterId)) { _nview.GetZDO().Set("hf_caretaker_tasks", tasks & 0x3F); } } private void RPC_SetFarmerCrops(long sender, long requesterId, string permissions) { if (_nview.IsOwner() && (OwnerId == 0L || OwnerId == requesterId)) { _nview.GetZDO().Set("hf_farmer_crops", FarmCropCatalog.NormalizePermissions(permissions)); } } private void RPC_SetFarmerMode(long sender, long requesterId, int requestedMode) { if (_nview.IsOwner() && Role == SettlerRole.Farmer && (OwnerId == 0L || OwnerId == requesterId) && (requestedMode == 1 || requestedMode == 2 || requestedMode == 3)) { _nview.GetZDO().Set("hf_farmer_mode", requestedMode); } } private void RPC_SetFarmerMarkers(long sender, long requesterId, int configured, string encodedMarkers) { //IL_0055: Unknown result type (might be due to invalid IL or missing references) if (!_nview.IsOwner() || Role != SettlerRole.Farmer || (OwnerId != 0L && OwnerId != requesterId)) { return; } ZDO zDO = _nview.GetZDO(); if (configured == 0) { zDO.Set("hf_farmer_markers_configured", false); zDO.Set("hf_farmer_markers", string.Empty); return; } HashSet hashSet = (from marker in FarmMarker.MarkersFor(Home, OwnerId) select marker.PersistentId into id where id != ZDOID.None select id).ToHashSet(); List route = ExilesHearth.DecodePatrolRoute(encodedMarkers).Where(hashSet.Contains).Distinct() .Take(64) .ToList(); zDO.Set("hf_farmer_markers", ExilesHearth.EncodePatrolRoute(route)); zDO.Set("hf_farmer_markers_configured", true); } private void RPC_SetFarmerStockTarget(long sender, long requesterId, string cropKey, int target) { if (_nview.IsOwner() && Role == SettlerRole.Farmer && (OwnerId == 0L || OwnerId == requesterId)) { FarmCrop farmCrop = FarmCropCatalog.PermissionOptions().FirstOrDefault((FarmCrop option) => FarmCropCatalog.PermissionKey(option) == cropKey); if (farmCrop != null) { string serialized = _nview.GetZDO().GetString("hf_farmer_stock_targets", string.Empty); _nview.GetZDO().Set("hf_farmer_stock_targets", FarmCropCatalog.SetStockTarget(serialized, farmCrop, Mathf.Clamp(target, 0, 10000))); } } } private void RPC_SetStorage(long sender, long requesterId, ZDOID containerId) { //IL_001f: 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_0048: Unknown result type (might be due to invalid IL or missing references) if (_nview.IsOwner() && (OwnerId == 0L || OwnerId == requesterId)) { if (containerId == ZDOID.None) { StorageLink.Clear(_nview.GetZDO()); } else { StorageLink.Set(_nview.GetZDO(), containerId); } } } private void RPC_Dismiss(long sender, long requesterId) { if (_nview.IsOwner() && (OwnerId == 0L || OwnerId == requesterId) && !IsRespawning && _inv != null && _inv.NrOfItems() == 0) { _current?.Exit(this); StopSleep(); ReleaseWorkstation(); ReleaseBed(); StorageLink.Clear(_nview.GetZDO()); Diagnostics.Log($"Hearthfolk[dismiss]: {PanelName} dismissed by owner {requesterId}"); if ((Object)(object)ZNetScene.instance != (Object)null) { ZNetScene.instance.Destroy(((Component)this).gameObject); } } } private void RepairFriendlyState() { //IL_0016: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_body == (Object)null)) { ((Character)_body).m_faction = (Faction)0; string displayName = DisplayName; if (((Character)_body).m_name != displayName) { ((Character)_body).m_name = displayName; } if (_nview.IsOwner() && !((Character)_body).IsTamed()) { ((Character)_body).SetTamed(true); } } } internal void SetStatus(string statusKey) { if (Valid && _nview.IsOwner()) { ZDO zDO = _nview.GetZDO(); if (zDO.GetString("hf_status", string.Empty) != statusKey) { zDO.Set("hf_status", statusKey); } } } private void NormalizeEquipment() { if (_inv == null) { return; } foreach (ItemData allItem in _inv.GetAllItems()) { allItem.m_equipped = false; } SyncEquipment(); } private void SyncEquipment() { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Invalid comparison between Unknown and I4 //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Invalid comparison between Unknown and I4 //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Invalid comparison between Unknown and I4 if (_inv == null || (Object)(object)_body == (Object)null || ((Character)_body).InAttack()) { return; } foreach (ItemData allItem in _inv.GetAllItems()) { ItemType itemType = allItem.m_shared.m_itemType; if (itemType - 6 <= 1 || itemType - 11 <= 1 || itemType - 17 <= 1) { _body.EquipItem(allItem, false); } } switch ((SettlementAlertActive || ((Object)(object)_ai != (Object)null && _ai.HasHostileTarget())) ? SettlerRole.Guard : Role) { case SettlerRole.Lumberjack: { ItemData val4 = FindAxe(); if (val4 != null) { _body.EquipItem(val4, false); } break; } case SettlerRole.Miner: { ItemData val6 = FindPickaxe(); if (val6 != null) { _body.EquipItem(val6, false); } break; } case SettlerRole.Caretaker: { ItemData val5 = FindHammer(); if (val5 != null) { _body.EquipItem(val5, false); } break; } case SettlerRole.Farmer: { ItemData val3 = FindCultivator(); if (val3 != null) { _body.EquipItem(val3, false); } break; } case SettlerRole.Guard: case SettlerRole.Follower: { ItemData val = FindWeapon(); if (val != null) { _body.EquipItem(val, false); } ItemData val2 = ((IEnumerable)_inv.GetAllItems()).FirstOrDefault((Func)((ItemData i) => (int)i.m_shared.m_itemType == 5)); if (val2 != null) { _body.EquipItem(val2, false); } break; } } } internal void EquipTool(ItemData item) { if (item != null) { _body.EquipItem(item, false); } } internal ItemData FindAxe() { Inventory inv = _inv; if (inv == null) { return null; } return ((IEnumerable)inv.GetAllItems()).FirstOrDefault((Func)((ItemData item) => item != null && item.m_shared.m_damages.m_chop > 0f && (!item.m_shared.m_useDurability || item.m_durability > 0f))); } internal ItemData FindPickaxe() { Inventory inv = _inv; if (inv == null) { return null; } return ((IEnumerable)inv.GetAllItems()).FirstOrDefault((Func)((ItemData item) => item != null && item.m_shared.m_damages.m_pickaxe > 0f && (!item.m_shared.m_useDurability || item.m_durability > 0f))); } internal ItemData FindHammer() { Inventory inv = _inv; if (inv == null) { return null; } return ((IEnumerable)inv.GetAllItems()).FirstOrDefault((Func)((ItemData item) => item != null && item.m_shared.m_name == "$item_hammer" && (!item.m_shared.m_useDurability || item.m_durability > 0f))); } internal ItemData FindCultivator() { Inventory inv = _inv; if (inv == null) { return null; } return ((IEnumerable)inv.GetAllItems()).FirstOrDefault((Func)((ItemData item) => item != null && item.m_shared.m_name == "$item_cultivator" && (!item.m_shared.m_useDurability || item.m_durability > 0f))); } internal bool HasBrokenCultivator() { if (_inv != null) { return _inv.GetAllItems().Any((ItemData item) => item != null && item.m_shared.m_name == "$item_cultivator" && item.m_shared.m_useDurability && item.m_durability <= 0f); } return false; } internal void PlayInteractionGesture() { if ((Object)(object)((Character)(_body?)).m_zanim != (Object)null) { ((Character)_body).m_zanim.SetTrigger("interact"); } } internal bool HasBrokenHammer() { if (_inv != null) { return _inv.GetAllItems().Any((ItemData item) => item != null && item.m_shared.m_name == "$item_hammer" && item.m_shared.m_useDurability && item.m_durability <= 0f); } return false; } internal ItemData FindWeapon() { Inventory inv = _inv; if (inv == null) { return null; } return ((IEnumerable)inv.GetAllItems()).FirstOrDefault((Func)((ItemData item) => item != null && (!item.m_shared.m_useDurability || item.m_durability > 0f) && ((int)item.m_shared.m_itemType == 3 || (int)item.m_shared.m_itemType == 14 || (int)item.m_shared.m_itemType == 22 || (int)item.m_shared.m_itemType == 4))); } internal float DistanceTo(Vector3 point) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) return Utils.DistanceXZ(((Component)this).transform.position, point); } internal float DistanceTo3D(Vector3 point) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) return Vector3.Distance(((Component)this).transform.position, point); } internal bool CanInteractWith(GameObject target, float reach) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) return CanInteractFrom(((Component)this).transform.position, target, reach); } private bool CanInteractFrom(Vector3 standingPoint, GameObject target, float reach) { //IL_000b: 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) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: 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_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)target == (Object)null) { return false; } Vector3 val = standingPoint + Vector3.up * 1.05f; Vector3 point = InteractionPoint(target, val); return CanInteractWithPointFrom(standingPoint, point, target, reach); } private bool CanInteractWithBedFrom(Vector3 standingPoint) { //IL_003e: 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_0026: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_bed == (Object)null) { return false; } SettlerShelter settlerShelter = SettlerShelter.For(_bed); if (!((Object)(object)settlerShelter != (Object)null)) { return CanInteractFrom(standingPoint, ((Component)_bed).gameObject, 2.4f); } return CanInteractWithPointFrom(standingPoint, settlerShelter.InteractionPosition, ((Component)_bed).gameObject, 2.4f); } private bool CanInteractWithPointFrom(Vector3 standingPoint, Vector3 point, GameObject target, float reach) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0040: 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_005c: Unknown result type (might be due to invalid IL or missing references) Vector3 val = standingPoint + Vector3.up * 1.05f; if (Vector3.Distance(val, point) > reach) { return false; } Vector3 val2 = point - val; float magnitude = ((Vector3)(ref val2)).magnitude; if (magnitude <= 0.05f) { return true; } RaycastHit[] array = Physics.RaycastAll(val, val2 / magnitude, magnitude, -5, (QueryTriggerInteraction)1); for (int i = 0; i < array.Length; i++) { RaycastHit val3 = array[i]; Transform val4 = (((Object)(object)((RaycastHit)(ref val3)).collider != (Object)null) ? ((Component)((RaycastHit)(ref val3)).collider).transform : null); if (!((Object)(object)val4 == (Object)null) && !val4.IsChildOf(((Component)this).transform) && !val4.IsChildOf(target.transform) && !target.transform.IsChildOf(val4) && !((Object)(object)((Component)val4).GetComponentInParent() != (Object)null)) { return false; } } return true; } internal void GoTo(Vector3 point, float stopDistance, bool run) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) _ai.MoveTo(point, stopDistance, AllowCivilRun(run)); } internal void Approach(GameObject target, float stopDistance, bool run) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: 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_006e: 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_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)target == (Object)null) { Hold(); return; } Vector3 val = ((Component)this).transform.position + Vector3.up * 1.05f; if ((Object)(object)_approachTarget != (Object)(object)target || Vector3.Distance(_approachTargetPosition, target.transform.position) > 0.25f) { _approachTarget = target; _approachTargetPosition = target.transform.position; _approachPoint = InteractionPoint(target, val); } _ai.MoveTo(_approachPoint, stopDistance, AllowCivilRun(run)); } private static Vector3 InteractionPoint(GameObject target, Vector3 from) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_006a: 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_0044: 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_004b: 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_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) Vector3 val = target.transform.position; float num = Vector3.Distance(from, val); Collider[] componentsInChildren = target.GetComponentsInChildren(true); foreach (Collider val2 in componentsInChildren) { if (!((Object)(object)val2 == (Object)null) && !val2.isTrigger && val2.enabled) { Vector3 val3 = val2.ClosestPoint(from); float num2 = Vector3.Distance(from, val3); if (num2 < num) { val = val3; num = num2; } } } return val; } private bool AllowCivilRun(bool requestedRun) { if (ThreatMovement) { return true; } if (!FieldWorkerRunning) { if (requestedRun) { return !ShouldForceWalk; } return false; } return true; } internal void Hold() { _approachTarget = null; _ai.ClearMove(); } internal void ReturnHomeIfIdle() { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) UseRestMovement(); if (DistanceTo(Home) > 4f) { GoTo(Home, 2f, run: false); } else { Hold(); } } internal void TeleportFollowerNear(Player target) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0058: 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_00ad: Unknown result type (might be due to invalid IL or missing references) if (!Valid || !_nview.IsOwner() || (Object)(object)target == (Object)null) { return; } Vector3 position = FollowerFormationPosition(target) + Vector3.up * 0.35f; Hold(); ((Component)this).transform.position = position; _nview.GetZDO().SetPosition(position); if ((Object)(object)_body != (Object)null && (Object)(object)((Character)_body).m_body != (Object)null) { ((Character)_body).m_body.position = position; if (!((Character)_body).m_body.isKinematic) { ((Character)_body).m_body.linearVelocity = Vector3.zero; } } Diagnostics.Log("Hearthfolk[follower]: teleported " + PanelName + " near " + target.GetPlayerName()); } internal bool CanSwing() { return Time.time >= _nextSwing; } internal void FaceAndSwing(Vector3 point, bool allowTerrainHit = true) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0091: 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) Vector3 val = point - ((Character)_body).GetEyePoint(); if (((Vector3)(ref val)).sqrMagnitude > 0.001f) { ((Character)_body).SetLookDir(((Vector3)(ref val)).normalized, 0f); } Vector3 val2 = default(Vector3); ((Vector3)(ref val2))..ctor(point.x - ((Component)this).transform.position.x, 0f, point.z - ((Component)this).transform.position.z); if (((Vector3)(ref val2)).sqrMagnitude > 0.001f) { ((Component)this).transform.rotation = Quaternion.RotateTowards(((Component)this).transform.rotation, Quaternion.LookRotation(val2), 40f); } _nextSwing = Time.time + 1.6f; Attack val3 = _body.GetCurrentWeapon()?.m_shared.m_attack; bool hitTerrain = val3?.m_hitTerrain ?? false; if (val3 != null && !allowTerrainHit) { val3.m_hitTerrain = false; } bool flag; try { flag = ((Character)_body).StartAttack((Character)null, false); } finally { if (val3 != null && !allowTerrainHit) { val3.m_hitTerrain = hitTerrain; } } Diagnostics.Log($"Hearthfolk[work]: swing StartAttack={flag} terrain={allowTerrainHit}"); } internal void AnimateToolUse(ItemData tool, Vector3 point) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_006e: 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_0041: 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_009f: Unknown result type (might be due to invalid IL or missing references) if (tool != null && !((Object)(object)_body == (Object)null)) { EquipTool(tool); Vector3 val = point - ((Character)_body).GetEyePoint(); if (((Vector3)(ref val)).sqrMagnitude > 0.001f) { ((Character)_body).SetLookDir(((Vector3)(ref val)).normalized, 0f); } Vector3 val2 = default(Vector3); ((Vector3)(ref val2))..ctor(point.x - ((Component)this).transform.position.x, 0f, point.z - ((Component)this).transform.position.z); if (((Vector3)(ref val2)).sqrMagnitude > 0.001f) { ((Component)this).transform.rotation = Quaternion.LookRotation(val2); } string text = tool.m_shared.m_attack?.m_attackAnimation; if (!string.IsNullOrEmpty(text)) { ((Character)_body).m_zanim.SetTrigger(text); } } } internal void SpendDurability(ItemData tool) { if (tool != null && tool.m_shared.m_useDurability && _inv != null) { tool.m_durability = Mathf.Max(0f, tool.m_durability - Mathf.Max(0.1f, tool.m_shared.m_useDurabilityDrain)); _inv.Changed(); if (tool.m_durability <= 0f) { _body.UnequipItem(tool, false); } } } internal bool TryFindMineTarget(ItemData pick, out MineTarget target) { //IL_00b4: 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) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Unknown result type (might be due to invalid IL or missing references) //IL_01db: Unknown result type (might be due to invalid IL or missing references) //IL_01e7: Unknown result type (might be due to invalid IL or missing references) target = null; if (Time.time - _lastMineScan < 1f) { return false; } _lastMineScan = Time.time; List anchors = Anchors(); int num = pick?.m_shared.m_toolTier ?? 0; float num2 = float.MaxValue; int num3 = 0; int num4 = 0; MineRock5[] array = SceneObjectCache.Get(0.75f); foreach (MineRock5 val in array) { if ((Object)(object)val == (Object)null || !((Component)val).gameObject.activeInHierarchy || IsBlacklisted(((Object)((Component)val).gameObject).GetInstanceID()) || !MaterialFilters.Allowed(Flags, MaterialFilters.RockFlag(((Component)val).gameObject)) || !WorkArea.Contains(((Component)val).transform.position, anchors)) { continue; } MineTarget mineTarget = new MineTarget(val); if (!mineTarget.IsValid()) { continue; } num3++; if (val.m_minToolTier <= num) { num4++; float num5 = Vector3.Distance(((Component)this).transform.position, ((Component)val).transform.position); if (num5 < num2) { target = mineTarget; num2 = num5; } } } if (target == null) { Destructible[] array2 = SceneObjectCache.Get(0.75f); foreach (Destructible val2 in array2) { if ((Object)(object)val2 == (Object)null || !((Component)val2).gameObject.activeInHierarchy || !MineTarget.IsMineableRock(val2) || IsBlacklisted(((Object)((Component)val2).gameObject).GetInstanceID()) || !MaterialFilters.Allowed(Flags, MaterialFilters.RockFlag(((Component)val2).gameObject)) || !WorkArea.Contains(((Component)val2).transform.position, anchors)) { continue; } MineTarget mineTarget2 = new MineTarget(val2); if (!mineTarget2.IsValid()) { continue; } num3++; if (val2.m_minToolTier <= num) { num4++; float num6 = Vector3.Distance(((Component)this).transform.position, ((Component)val2).transform.position); if (num6 < num2) { target = mineTarget2; num2 = num6; } } } } LastMineTierBlocked = target == null && num4 == 0 && num3 > 0; if (target == null) { Diagnostics.Log($"Hearthfolk[mine]: no target — inArea={num3} tierOK(pickTier={num})={num4}" + (LastMineTierBlocked ? " [TIER-BLOCKED]" : string.Empty)); } else { Diagnostics.Log(string.Format("Hearthfolk[mine]: target {0} {1} at {2:0.0}m", target.IsVein ? "VEIN" : "boulder", MaterialFilters.PrefabName(target.GameObject), num2)); } return true; } internal void ForceMineScan() { _lastMineScan = -999f; } internal void ApplyManualPick(MineTarget target, ItemData pick, Vector3 point) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Expected O, but got Unknown if (target != null && target.IsValid()) { HitData val = new HitData { m_point = point }; Vector3 val2 = point - ((Component)this).transform.position; val.m_dir = ((Vector3)(ref val2)).normalized; val.m_toolTier = (short)(pick?.m_shared.m_toolTier ?? 0); HitData val3 = val; val3.m_damage.m_pickaxe = Mathf.Max(1f, HfConfig.PickDamage.Value); val3.SetAttacker((Character)(object)_body); target.Damage(val3); } } internal void ApplyManualChop(ChopTarget target, ItemData axe, Vector3 point) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Expected O, but got Unknown if (target != null && target.IsValid()) { HitData val = new HitData { m_point = point }; Vector3 val2 = point - ((Component)this).transform.position; val.m_dir = ((Vector3)(ref val2)).normalized; val.m_toolTier = (short)(axe?.m_shared.m_toolTier ?? 0); HitData val3 = val; val3.m_damage.m_chop = Mathf.Max(1f, HfConfig.ChopDamage.Value); val3.SetAttacker((Character)(object)_body); target.Damage(val3); } } internal void BlacklistTarget(ChopTarget target) { if (target != null && target.IsValid()) { _treeBlacklist[target.InstanceId] = Time.time + 20f; } } internal void BlacklistMineTarget(MineTarget target) { if (target != null && target.IsValid()) { _treeBlacklist[target.InstanceId] = Time.time + 20f; } } internal void BlacklistDrop(ItemDrop drop) { if ((Object)(object)drop != (Object)null) { _treeBlacklist[((Object)((Component)drop).gameObject).GetInstanceID()] = Time.time + 15f; } } internal void ForceDropScan() { _lastDropScan = -999f; } internal void ForceChopScan() { _lastTreeScan = -999f; } internal ItemDrop FindNearestWoodDrop() { return FindNearestDrop(WoodNames); } internal ItemDrop FindNearestOreDrop() { return FindNearestDrop(OreNames); } internal ItemDrop FindNearestCaretakerDrop() { //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Invalid comparison between Unknown and I4 //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: 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) if (Time.time - _lastDropScan < 1f || _inv == null) { return null; } _lastDropScan = Time.time; ItemDrop result = null; float num = float.MaxValue; ItemDrop[] array = SceneObjectCache.Get(0.5f); foreach (ItemDrop val in array) { if (!((Object)(object)val == (Object)null) && !((Object)(object)val.m_nview == (Object)null) && val.m_nview.IsValid() && val.m_itemData != null && (int)val.m_itemData.m_shared.m_itemType == 1 && !IsBlacklisted(((Object)((Component)val).gameObject).GetInstanceID()) && _inv.CanAddItem(val.m_itemData, val.m_itemData.m_stack) && !(Vector3.Distance(((Component)val).transform.position, Home) > WorkRadius)) { float num2 = Vector3.Distance(((Component)this).transform.position, ((Component)val).transform.position); if (num2 < num) { result = val; num = num2; } } } return result; } private ItemDrop FindNearestDrop(HashSet names) { //IL_00f7: 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_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) if (Time.time - _lastDropScan < 1f || _inv == null || !HasSpaceForWood()) { return null; } _lastDropScan = Time.time; List anchors = Anchors(); ItemDrop val = null; float num = float.MaxValue; ItemDrop[] array = SceneObjectCache.Get(0.5f); foreach (ItemDrop val2 in array) { if (!((Object)(object)val2 == (Object)null) && !((Object)(object)val2.m_nview == (Object)null) && val2.m_nview.IsValid() && names.Contains(val2.m_itemData.m_shared.m_name) && MaterialFilters.Allowed(Flags, MaterialFilters.ItemFlag(val2.m_itemData.m_shared.m_name)) && !IsBlacklisted(((Object)((Component)val2).gameObject).GetInstanceID()) && _inv.CanAddItem(val2.m_itemData, 1)) { Vector3 position = ((Component)val2).transform.position; float num2 = Vector3.Distance(((Component)this).transform.position, position); if ((WorkArea.Contains(position, anchors) || !(num2 > 12f)) && num2 < num) { val = val2; num = num2; } } } if ((Object)(object)val != (Object)null) { Diagnostics.Log($"Hearthfolk[work]: resource drop at {num:0.0}m"); } return val; } private bool IsBlacklisted(int instanceId) { if (_treeBlacklist.TryGetValue(instanceId, out var value)) { return Time.time < value; } return false; } internal bool TryFindChopTarget(ItemData axe, out ChopTarget target) { target = FindNearestChopTarget(axe, out var scanned); return scanned; } private ChopTarget FindNearestChopTarget(ItemData axe, out bool scanned) { //IL_00c7: 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_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: Unknown result type (might be due to invalid IL or missing references) scanned = false; if (Time.time - _lastTreeScan < 1f) { return null; } scanned = true; _lastTreeScan = Time.time; List list = Anchors(); int num = axe?.m_shared.m_toolTier ?? 0; ChopTarget chopTarget = null; float num2 = float.MaxValue; int num3 = 0; int num4 = 0; int num5 = 0; int num6 = 0; TreeLog[] array = SceneObjectCache.Get(0.75f); foreach (TreeLog val in array) { if (!((Object)(object)val == (Object)null) && ((Component)val).gameObject.activeInHierarchy && val.m_minToolTier <= num && !IsBlacklisted(((Object)((Component)val).gameObject).GetInstanceID()) && MaterialFilters.Allowed(Flags, MaterialFilters.TreeFlag(((Component)val).gameObject)) && WorkArea.Contains(((Component)val).transform.position, list)) { num3++; float num7 = Vector3.Distance(((Component)this).transform.position, ((Component)val).transform.position); if (num7 < num2) { chopTarget = new ChopTarget(val); num2 = num7; } } } if (chopTarget == null) { TreeBase[] array2 = SceneObjectCache.Get(0.75f); foreach (TreeBase val2 in array2) { if ((Object)(object)val2 == (Object)null || !((Component)val2).gameObject.activeInHierarchy) { continue; } num4++; if (!WorkArea.Contains(((Component)val2).transform.position, list)) { continue; } num5++; if (val2.m_minToolTier <= num && !IsBlacklisted(((Object)((Component)val2).gameObject).GetInstanceID()) && MaterialFilters.Allowed(Flags, MaterialFilters.TreeFlag(((Component)val2).gameObject))) { num6++; float num8 = Vector3.Distance(((Component)this).transform.position, ((Component)val2).transform.position); if (num8 < num2) { chopTarget = new ChopTarget(val2); num2 = num8; } } } } LastSearchTierBlocked = chopTarget == null && num3 == 0 && num6 == 0 && num5 > 0; if (chopTarget == null) { Diagnostics.Log($"Hearthfolk[lumber]: no target — logsOK={num3} trees seen={num4} " + $"inArea={num5} tierOK(axeTier={num})={num6} anchors={list.Count}" + (LastSearchTierBlocked ? " [TIER-BLOCKED]" : string.Empty)); } else { Diagnostics.Log(string.Format("Hearthfolk[lumber]: target {0} at {1:0.0}m ", chopTarget.IsLog ? "LOG" : "tree", num2) + $"(logsOK={num3}, anchors={list.Count})"); } return chopTarget; } internal void CollectNearbyWood() { CollectNearby(WoodNames); } internal void CollectNearbyOre() { CollectNearby(OreNames); } private void CollectNearby(HashSet names) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) if (_inv == null || !HasSpaceForWood()) { return; } int mask = LayerMask.GetMask(new string[1] { "item" }); Collider[] array = Physics.OverlapSphere(((Component)this).transform.position, 4f, mask); foreach (Collider val in array) { Rigidbody attachedRigidbody = val.attachedRigidbody; ItemDrop val2 = (((Object)(object)attachedRigidbody != (Object)null) ? ((Component)attachedRigidbody).GetComponent() : ((Component)val).GetComponent()); if (!((Object)(object)val2 == (Object)null) && !((Object)(object)val2.m_nview == (Object)null) && val2.m_nview.IsValid() && names.Contains(val2.m_itemData.m_shared.m_name) && MaterialFilters.Allowed(Flags, MaterialFilters.ItemFlag(val2.m_itemData.m_shared.m_name)) && _inv.CanAddItem(val2.m_itemData, 1)) { ItemData val3 = val2.m_itemData.Clone(); val3.m_stack = 1; if (val2.RemoveOne()) { _inv.AddItem(val3); } } } } internal bool HasSpaceForWood() { if (_inv != null) { return _inv.NrOfItems() < _inv.GetWidth() * _inv.GetHeight(); } return false; } internal bool TryPickup(ItemDrop drop, bool farmCargo = false) { if ((Object)(object)drop == (Object)null || (Object)(object)drop.m_nview == (Object)null || !drop.m_nview.IsValid() || _inv == null || (Object)(object)ZNetScene.instance == (Object)null) { return false; } ItemData itemData = drop.m_itemData; if (!_inv.CanAddItem(itemData, itemData.m_stack)) { return false; } if (!drop.m_nview.IsOwner()) { drop.m_nview.ClaimOwnership(); } ItemData val = itemData.Clone(); if (farmCargo) { val.m_customData["hf_farm_cargo"] = "1"; } if (!_inv.AddItem(val)) { return false; } ZNetScene.instance.Destroy(((Component)drop).gameObject); return true; } internal int FarmCargoCount() { Inventory inv = _inv; if (inv == null) { return 0; } return (from item in inv.GetAllItems() where item != null && item.m_stack > 0 && item.m_customData != null && item.m_customData.ContainsKey("hf_farm_cargo") select item).Sum((ItemData item) => item.m_stack); } internal bool DepositFarmCargo(Container storage) { if ((Object)(object)storage == (Object)null || (Object)(object)storage.m_nview == (Object)null || !storage.m_nview.IsValid() || _inv == null) { return false; } if (!storage.m_nview.IsOwner()) { storage.m_nview.ClaimOwnership(); } Inventory inventory = storage.GetInventory(); bool flag = false; foreach (ItemData item in (from candidate in _inv.GetAllItems() where candidate != null && candidate.m_stack > 0 && candidate.m_customData != null && candidate.m_customData.ContainsKey("hf_farm_cargo") select candidate).ToList()) { if (inventory != null && inventory.CanAddItem(item, item.m_stack)) { item.m_customData.Remove("hf_farm_cargo"); inventory.MoveItemToThis(_inv, item); flag = true; } } if (flag) { inventory.Changed(); _inv.Changed(); } return flag; } internal bool HasDepositableItems() { if (_inv != null) { return _inv.GetAllItems().Any(IsDepositable); } return false; } internal int DepositableCount() { if (_inv == null) { return 0; } int num = 0; foreach (ItemData allItem in _inv.GetAllItems()) { if (IsDepositable(allItem)) { num += allItem.m_stack; } } return num; } internal Container ResolveStorage() { //IL_000b: Unknown result type (might be due to invalid IL or missing references) if (!Valid) { return null; } ExilesHearth exilesHearth = ExilesHearth.FindFor(Home, OwnerId); if ((Object)(object)exilesHearth != (Object)null && exilesHearth.HasIntakeStorageFor(EffectiveRole)) { return exilesHearth.ResolveIntakeStorage((Component)(object)this); } return StorageLink.Resolve(_nview.GetZDO(), (Component)(object)this); } internal List ResolveIntakeStorages() { //IL_000f: Unknown result type (might be due to invalid IL or missing references) if (!Valid) { return new List(); } List list = ExilesHearth.FindFor(Home, OwnerId)?.ResolveIntakeStorages((Component)(object)this) ?? new List(); if (list.Count > 0) { return list; } Container val = StorageLink.Resolve(_nview.GetZDO(), (Component)(object)this); if (!((Object)(object)val != (Object)null)) { return new List(); } return new List { val }; } internal int InventoryItemCount(string sharedName) { if (_inv != null && !string.IsNullOrEmpty(sharedName)) { return (from i in _inv.GetAllItems() where i != null && i.m_shared.m_name == sharedName select i).Sum((ItemData i) => i.m_stack); } return 0; } internal int StorageItemCount(Container storage, string sharedName) { Inventory val = (((Object)(object)storage != (Object)null) ? storage.GetInventory() : null); if (val != null && !string.IsNullOrEmpty(sharedName)) { return (from i in val.GetAllItems() where i != null && i.m_shared.m_name == sharedName select i).Sum((ItemData i) => i.m_stack); } return 0; } internal int WithdrawFromStorage(Container storage, string sharedName, int requested, bool sortingCargo = false, string prefabName = null, int quality = 0) { if ((Object)(object)storage == (Object)null || (Object)(object)storage.m_nview == (Object)null || !storage.m_nview.IsValid() || _inv == null || requested <= 0) { return 0; } if (!storage.m_nview.IsOwner()) { storage.m_nview.ClaimOwnership(); } Inventory inventory = storage.GetInventory(); ItemData val = ((inventory != null) ? ((IEnumerable)inventory.GetAllItems()).FirstOrDefault((Func)((ItemData i) => i != null && i.m_shared.m_name == sharedName && i.m_stack > 0 && (string.IsNullOrEmpty(prefabName) || ((Object)(object)i.m_dropPrefab != (Object)null && ((Object)i.m_dropPrefab).name == prefabName && i.m_quality == Mathf.Max(1, quality))))) : null); if (val == null) { return 0; } int num = _inv.FindFreeStackSpace(sharedName, (float)val.m_worldLevel) + _inv.GetEmptySlots() * val.m_shared.m_maxStackSize; int num2 = Mathf.Min(requested, Mathf.Min(val.m_stack, num)); if (num2 <= 0) { return 0; } ItemData val2 = val.Clone(); val2.m_stack = num2; val2.m_equipped = false; if (sortingCargo) { val2.m_customData["hf_sort_cargo"] = "1"; } if (!_inv.CanAddItem(val2, num2) || !_inv.AddItem(val2)) { return 0; } if (!inventory.RemoveItem(val, num2)) { _inv.RemoveItem(sharedName, num2, -1, true); return 0; } inventory.Changed(); _inv.Changed(); Diagnostics.Log($"Hearthfolk[caretaker]: withdrew {num2} x {sharedName}"); return num2; } internal int WithdrawAvailableFromStorage(Container storage, string sharedName, int requested) { int i; int num; for (i = 0; i < requested; i += num) { num = WithdrawFromStorage(storage, sharedName, requested - i); if (num <= 0) { break; } } return i; } internal bool ConsumeInventoryItem(string sharedName) { if (_inv == null) { return false; } ItemData val = ((IEnumerable)_inv.GetAllItems()).FirstOrDefault((Func)((ItemData i) => i != null && i.m_shared.m_name == sharedName && i.m_stack > 0)); if (val != null) { return _inv.RemoveItem(val, 1); } return false; } internal string FindSortingCargoName() { Inventory inv = _inv; if (inv == null) { return null; } return ((IEnumerable)inv.GetAllItems()).FirstOrDefault((Func)((ItemData item) => item != null && item.m_stack > 0 && item.m_customData != null && item.m_customData.ContainsKey("hf_sort_cargo")))?.m_shared.m_name; } internal int DepositInventoryItem(Container storage, string sharedName, int requested) { if ((Object)(object)storage == (Object)null || (Object)(object)storage.m_nview == (Object)null || !storage.m_nview.IsValid() || _inv == null || string.IsNullOrEmpty(sharedName) || requested <= 0) { return 0; } ItemData val = ((IEnumerable)_inv.GetAllItems()).FirstOrDefault((Func)((ItemData i) => i != null && !i.m_equipped && i.m_shared.m_name == sharedName && i.m_stack > 0 && i.m_customData != null && i.m_customData.ContainsKey("hf_sort_cargo"))); Inventory inventory = storage.GetInventory(); if (val == null || inventory == null) { return 0; } int num = inventory.FindFreeStackSpace(sharedName, (float)val.m_worldLevel) + inventory.GetEmptySlots() * val.m_shared.m_maxStackSize; int num2 = Mathf.Min(requested, Mathf.Min(val.m_stack, num)); if (num2 <= 0) { return 0; } if (!storage.m_nview.IsOwner()) { storage.m_nview.ClaimOwnership(); } ItemData val2 = val.Clone(); val2.m_stack = num2; val2.m_equipped = false; val2.m_customData.Remove("hf_sort_cargo"); if (!_inv.RemoveItem(val, num2)) { return 0; } if (!inventory.AddItem(val2)) { val2.m_customData["hf_sort_cargo"] = "1"; _inv.AddItem(val2); _inv.Changed(); return 0; } inventory.Changed(); _inv.Changed(); Diagnostics.Log($"Hearthfolk[caretaker]: sorted {num2} x {sharedName}"); return num2; } internal bool HaulToStorage() { Container val = ResolveStorage(); if ((Object)(object)val == (Object)null) { SetStatus("$hf_status_no_storage"); return false; } if (!CanInteractWith(((Component)val).gameObject, 2.8f)) { if (Time.time < _storageUnreachableUntil) { Hold(); SetStatus("$hf_status_storage_unreachable"); return true; } Approach(((Component)val).gameObject, 2.38f, run: true); if (_ai.PathBlocked) { _storageUnreachableUntil = Time.time + 6f; Hold(); SetStatus("$hf_status_storage_unreachable"); return true; } SetStatus("$hf_status_to_storage"); return true; } _storageUnreachableUntil = 0f; if (val.IsInUse() || ((Object)(object)val.m_nview != (Object)null && val.m_nview.IsValid() && val.m_nview.GetZDO().GetInt(ZDOVars.s_inUse, 0) == 1)) { Hold(); SetStatus("$hf_status_to_storage"); return true; } Hold(); DepositInto(val); SetStatus("$hf_status_deposit"); return true; } private void DepositInto(Container storage) { if ((Object)(object)storage.m_nview == (Object)null || !storage.m_nview.IsValid()) { return; } if (!storage.m_nview.IsOwner()) { storage.m_nview.ClaimOwnership(); } Inventory inventory = storage.GetInventory(); foreach (ItemData item in _inv.GetAllItems().Where(IsDepositable).ToList()) { if (inventory.CanAddItem(item, item.m_stack)) { inventory.MoveItemToThis(_inv, item); } } } private static bool IsDepositable(ItemData item) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Invalid comparison between Unknown and I4 if (item != null && !item.m_equipped) { return (int)item.m_shared.m_itemType == 1; } return false; } private static string LocalizeRole(SettlerRole role) { return Localization.instance.Localize(role switch { SettlerRole.Lumberjack => "$hf_role_lumberjack", SettlerRole.Guard => "$hf_role_guard", SettlerRole.Caretaker => "$hf_role_caretaker", SettlerRole.Miner => "$hf_role_miner", SettlerRole.Follower => "$hf_role_follower", SettlerRole.Farmer => "$hf_role_farmer", _ => "$hf_role_idle", }); } private void MaintainRespawn() { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) EnterRespawnDormancy(); if (_nview.GetZDO().GetLong("hf_respawn_at", 0L) > DateTime.UtcNow.Ticks || ((Object)(object)_container != (Object)null && !_container.Bound)) { return; } Vector3 position = Home + Vector3.right * 2.2f + Vector3.up * 0.5f; ((Component)this).transform.position = position; _nview.GetZDO().SetPosition(position); if ((Object)(object)_body != (Object)null && (Object)(object)((Character)_body).m_body != (Object)null) { ((Character)_body).m_body.position = position; if (!((Character)_body).m_body.isKinematic) { ((Character)_body).m_body.linearVelocity = Vector3.zero; } } SetRespawnPresentation(visible: true); if ((Object)(object)_body != (Object)null) { ((Character)_body).SetHealth(((Character)_body).GetMaxHealth()); } _nview.GetZDO().Set("hf_respawning", false); _nview.GetZDO().Set("hf_respawn_at", 0L); _equipmentNormalized = false; SetStatus("$hf_status_respawned"); Diagnostics.Log("Hearthfolk[respawn]: " + PanelName + " returned at the hearth"); } private void EnterRespawnDormancy() { //IL_01ab: Unknown result type (might be due to invalid IL or missing references) if (_respawnHidden) { return; } _respawnRendererStates = ((Component)this).GetComponentsInChildren(true).ToDictionary((Renderer renderer) => renderer, (Renderer renderer) => renderer.enabled); _respawnColliderStates = ((Component)this).GetComponentsInChildren(true).ToDictionary((Collider collider) => collider, (Collider collider) => collider.enabled); foreach (Renderer key in _respawnRendererStates.Keys) { key.enabled = false; } foreach (Collider key2 in _respawnColliderStates.Keys) { key2.enabled = false; } if ((Object)(object)_ai != (Object)null) { _respawnAiWasEnabled = ((Behaviour)_ai).enabled; ((Behaviour)_ai).enabled = false; } if ((Object)(object)_body != (Object)null && (Object)(object)((Character)_body).m_body != (Object)null) { _respawnBodyWasEnabled = ((Behaviour)_body).enabled; _respawnBodyWasKinematic = ((Character)_body).m_body.isKinematic; if (!((Character)_body).m_body.isKinematic) { ((Character)_body).m_body.linearVelocity = Vector3.zero; } ((Character)_body).m_body.isKinematic = true; ((Behaviour)_body).enabled = false; } _respawnHidden = true; } private void SetRespawnPresentation(bool visible) { if (!visible || !_respawnHidden) { return; } foreach (KeyValuePair respawnRendererState in _respawnRendererStates) { if ((Object)(object)respawnRendererState.Key != (Object)null) { respawnRendererState.Key.enabled = respawnRendererState.Value; } } foreach (KeyValuePair respawnColliderState in _respawnColliderStates) { if ((Object)(object)respawnColliderState.Key != (Object)null) { respawnColliderState.Key.enabled = respawnColliderState.Value; } } if ((Object)(object)_ai != (Object)null) { ((Behaviour)_ai).enabled = _respawnAiWasEnabled; } if ((Object)(object)_body != (Object)null && (Object)(object)((Character)_body).m_body != (Object)null) { ((Character)_body).m_body.isKinematic = _respawnBodyWasKinematic; ((Behaviour)_body).enabled = _respawnBodyWasEnabled; } _respawnHidden = false; } private void OnSettlerDeath() { //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) if (!Valid || !_nview.IsOwner() || _deathHandled || IsRespawning) { return; } _deathHandled = true; _current?.Exit(this); try { ReleaseBed(); } catch (Exception ex) { Logger.LogWarning((object)("Hearthfolk: bed release on death failed: " + ex.Message)); } int retainedCount = 0; bool flag = false; try { string inventoryData = SerializeRespawnEquipment(out retainedCount); flag = TryCreateRespawnReplacement(inventoryData); } catch (Exception ex2) { Logger.LogWarning((object)("Hearthfolk: respawn scheduling failed: " + ex2.Message)); } if (_inv != null) { try { if (!flag) { foreach (ItemData item in _inv.GetAllItems().Where(IsRespawnEquipment).ToList()) { Vector2 val = Random.insideUnitCircle * 0.5f; ItemDrop.DropItem(item, item.m_stack, ((Component)this).transform.position + new Vector3(val.x, 0.7f, val.y), Quaternion.identity); } } } catch (Exception ex3) { Logger.LogWarning((object)("Hearthfolk: equipment fallback drop failed: " + ex3.Message)); } finally { _inv.RemoveAll(); } } string arg = (flag ? $"respawn queued for {HfConfig.RespawnMinutes.Value} minutes" : "replacement spawn failed; retained equipment dropped"); Diagnostics.Log($"Hearthfolk[death]: {PanelName} died; {retainedCount} equipment items retained, {arg}"); } private string SerializeRespawnEquipment(out int retainedCount) { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Expected O, but got Unknown //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Expected O, but got Unknown //IL_008e: Unknown result type (might be due to invalid IL or missing references) int num = ((_inv != null) ? _inv.GetWidth() : 8); int num2 = ((_inv != null) ? _inv.GetHeight() : 4); Inventory val = new Inventory("Hearthfolk respawn", (Sprite)null, num, num2); retainedCount = 0; if (_inv != null) { foreach (ItemData item in _inv.GetAllItems().Where(IsRespawnEquipment)) { ItemData val2 = item.Clone(); if (val.AddItem(val2, val2.m_gridPos)) { retainedCount++; } } } ZPackage val3 = new ZPackage(); val.Save(val3); return val3.GetBase64(); } private bool TryCreateRespawnReplacement(string inventoryData) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0035: 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_0040: 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_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Unknown result type (might be due to invalid IL or missing references) //IL_0276: Unknown result type (might be due to invalid IL or missing references) //IL_02bf: Unknown result type (might be due to invalid IL or missing references) //IL_0329: Unknown result type (might be due to invalid IL or missing references) //IL_0340: Unknown result type (might be due to invalid IL or missing references) //IL_034a: Expected O, but got Unknown PrefabManager instance = PrefabManager.Instance; GameObject val = ((instance != null) ? instance.GetPrefab("hf_settler") : null); if ((Object)(object)val == (Object)null) { return false; } ZDO zDO = _nview.GetZDO(); Vector3 home = Home; Vector3 val2 = home + Vector3.right * 2.2f + Vector3.up * 0.5f; GameObject val3 = Object.Instantiate(val, val2, ((Component)this).transform.rotation); ZNetView val4 = (((Object)(object)val3 != (Object)null) ? val3.GetComponent() : null); SettlerController settlerController = (((Object)(object)val3 != (Object)null) ? val3.GetComponent() : null); if ((Object)(object)val4 == (Object)null || !val4.IsValid() || (Object)(object)settlerController == (Object)null) { if ((Object)(object)val3 != (Object)null) { Object.Destroy((Object)(object)val3); } return false; } ZDO zDO2 = val4.GetZDO(); zDO2.Set("hf_owner", OwnerId); zDO2.Set("hf_home", home); zDO2.Set("hf_name", DisplayName); zDO2.Set("hf_identity", StableIdentity); zDO2.Set("hf_role", (int)Role); zDO2.Set("hf_flags", (int)Flags); zDO2.Set("hf_caretaker_tasks", (int)EnabledCaretakerTasks); zDO2.Set("hf_farmer_crops", FarmerCropPermissions); zDO2.Set("hf_farmer_mode", (int)FarmerMode); zDO2.Set("hf_farmer_markers_configured", FarmerMarkersConfigured); zDO2.Set("hf_farmer_markers", zDO.GetString("hf_farmer_markers", string.Empty)); zDO2.Set("hf_farmer_stock_targets", FarmerStockTargets); zDO2.Set("hf_workstation", ZDOID.None); zDO2.Set("hf_guard_shift_start", zDO.GetInt("hf_guard_shift_start", 6)); zDO2.Set("hf_guard_shift_end", zDO.GetInt("hf_guard_shift_end", 22)); zDO2.Set("hf_guard_shift_initialized", zDO.GetBool("hf_guard_shift_initialized", false)); zDO2.Set("hf_guard_patrol_configured", zDO.GetBool("hf_guard_patrol_configured", false)); zDO2.Set("hf_guard_patrol_route", zDO.GetString("hf_guard_patrol_route", string.Empty)); zDO2.Set("hf_follower_target", 0L); zDO2.Set("hf_follower_target_name", string.Empty); zDO2.Set("hf_follower_mode", 0); zDO2.Set("hf_follower_wait_position", home); zDO2.Set("hf_follower_combat_mode", zDO.GetInt("hf_follower_combat_mode", 0)); CopyAppearanceState(zDO, zDO2); zDO2.Set("hf_radius", zDO.GetFloat("hf_radius", 0f)); zDO2.Set("hf_bed", ZDOID.None); StorageLink.CopyAssignment(zDO, zDO2); CopyNeedsState(zDO, zDO2); zDO2.Set(ZDOVars.s_items, inventoryData); zDO2.Set("hf_respawn_at", DateTime.UtcNow.AddMinutes(Mathf.Max(1, HfConfig.RespawnMinutes.Value)).Ticks); zDO2.Set("hf_respawning", true); zDO2.SetPosition(val2); if (settlerController._inv != null) { settlerController._inv.Load(new ZPackage(inventoryData)); } settlerController.EnterRespawnDormancy(); return true; } private static bool IsRespawnEquipment(ItemData item) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Expected I4, but got Unknown if (item == null) { return false; } ItemType itemType = item.m_shared.m_itemType; switch (itemType - 3) { case 0: case 1: case 2: case 3: case 4: case 8: case 9: case 11: case 12: case 14: case 15: case 16: case 17: case 19: case 21: return true; default: return false; } } private void ReleaseWorkstation() { //IL_001a: Unknown result type (might be due to invalid IL or missing references) if (Valid) { ZDO zDO = _nview.GetZDO(); zDO.Set("hf_workstation", ZDOID.None); zDO.Set("hf_workstation_prev_role", 0); } } private void ReleaseBed() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_003b: 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) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) _leavingTentAfterSleep = false; _bed = null; _bedAccessBed = null; ZDO zDO = _nview.GetZDO(); ZDOID zDOID = zDO.GetZDOID("hf_bed"); zDO.Set("hf_bed", ZDOID.None); if (zDOID == ZDOID.None || (Object)(object)ZNetScene.instance == (Object)null) { return; } GameObject val = ZNetScene.instance.FindInstance(zDOID); Bed val2 = (((Object)(object)val != (Object)null) ? (val.GetComponent() ?? val.GetComponentInChildren(true)) : null); if ((Object)(object)val2 == (Object)null || (Object)(object)val2.m_nview == (Object)null || !val2.m_nview.IsValid()) { return; } if (!val2.m_nview.IsOwner()) { val2.m_nview.ClaimOwnership(); } ZDO zDO2 = val2.m_nview.GetZDO(); ZDOID zDOID2 = zDO2.GetZDOID("hf_claim"); string text = zDO2.GetString("hf_claim_identity", string.Empty); if ((string.IsNullOrEmpty(text) || !(text != StableIdentity)) && (!string.IsNullOrEmpty(text) || !(zDOID2 != MyZdoid))) { zDO2.Set("hf_claim", ZDOID.None); zDO2.Set("hf_claim_identity", string.Empty); if (SettlerShelter.IsDedicated(val2)) { SettlerShelter.MarkAvailable(val2); return; } zDO2.Set(ZDOVars.s_owner, 0L); zDO2.Set(ZDOVars.s_ownerName, string.Empty); } } internal static bool IsSeatReserved(Chair chair) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) if (!IsUsablePlacedSeat(chair)) { if ((Object)(object)chair != (Object)null) { SeatReservations.Remove(chair); } return false; } if ((Object)(object)chair != (Object)null && SeatReservations.TryGetValue(chair, out var value)) { return value != ZDOID.None; } return false; } private bool RunNeedsRoutine(SettlerRole role, bool hasBed, bool requiresSleep) { if ((Object)(object)EnvMan.instance == (Object)null || !Valid) { return false; } int num = RoutineDay(); EnsureNeedsInitialized(num); if (SettlementAlertActive) { _nview.GetZDO().Set("hf_threat_day", num); ReleaseMealSeat(); StopSleep(); return false; } if (_ai.HasHostileTarget()) { _nview.GetZDO().Set("hf_threat_day", num); ReleaseMealSeat(); StopSleep(); return false; } if (EnvMan.IsNight()) { if (NeedsMeal(MealKind.Dinner, num)) { if (role == SettlerRole.Guard && !IsGuardMealTurn()) { return false; } return MealTick(MealKind.Dinner, num, Role == SettlerRole.Follower); } if (!requiresSleep || !HfConfig.NightRest.Value || !hasBed) { StopSleep(); return RunWakeExitRoutine(); } if (role == SettlerRole.Guard && (SettlementAlertActive || IsGuardOnShift)) { CompleteSleep(num, morning: false); return RunWakeExitRoutine(); } RestTick(); return true; } if (requiresSleep) { CompleteSleep(num, morning: true); if (RunWakeExitRoutine()) { return true; } } else { StopSleep(); } if (NeedsMeal(MealKind.Breakfast, num)) { if (role == SettlerRole.Guard && !IsGuardMealTurn()) { return false; } return MealTick(MealKind.Breakfast, num, Role == SettlerRole.Follower); } EvaluateNeeds(num, role, hasBed, requiresSleep); if (!_leavingSettlement) { return !Valid; } return true; } private int RoutineDay() { int day = EnvMan.instance.GetDay(); if (!(EnvMan.instance.GetDayFraction() >= 0.75f)) { return day; } return day + 1; } private void EnsureNeedsInitialized(int day) { ZDO zDO = _nview.GetZDO(); if (!zDO.GetBool("hf_needs_init", false)) { zDO.Set("hf_needs_init", true); zDO.Set("hf_happiness", 70f); zDO.Set("hf_needs_eval_day", day); zDO.Set("hf_morale_reasons", "$hf_reason_new_home"); } } private bool NeedsMeal(MealKind kind, int day) { ZDO zDO = _nview.GetZDO(); string text = ((kind == MealKind.Dinner) ? "hf_dinner_day" : "hf_breakfast_day"); string text2 = ((kind == MealKind.Dinner) ? "hf_dinner_missed_day" : "hf_breakfast_missed_day"); if (zDO.GetInt(text, -1) != day) { return zDO.GetInt(text2, -1) != day; } return false; } private bool MealTick(MealKind kind, int day, bool carriedOnly) { UseRestMovement(); ZDO zDO = _nview.GetZDO(); if (zDO.GetInt("hf_meal_kind", 0) != (int)kind) { ReleaseMealSeat(); _mealStorage = null; _mealFoodName = null; zDO.Set("hf_meal_kind", (int)kind); zDO.Set("hf_meal_end", 0L); zDO.Set("hf_meal_search_until", WorldTimeMilliseconds + 30000); } long num = zDO.GetLong("hf_meal_end", 0L); if (num > 0) { if (WorldTimeMilliseconds >= num) { CompleteMeal(kind, day); return false; } MaintainEatingActivity(day, carriedOnly); SetStatus(carriedOnly ? "$hf_status_follower_eating_meal" : ((kind == MealKind.Dinner) ? "$hf_status_eating_dinner" : "$hf_status_eating_breakfast")); return true; } ItemData val = FindCarriedFood(); if (val == null) { if (carriedOnly) { MissMeal(kind, day); SetStatus("$hf_status_no_food"); return false; } if (!TryFetchFood()) { if (WorldTimeMilliseconds >= zDO.GetLong("hf_meal_search_until", 0L)) { MissMeal(kind, day); return false; } ReturnHomeIfIdle(); SetStatus("$hf_status_no_food"); } else { SetStatus("$hf_status_fetch_food"); } return true; } if (!(carriedOnly ? PrepareFollowerMealPlace() : PrepareMealPlace())) { SetStatus("$hf_status_find_seat"); return true; } if (!_inv.RemoveItem(val, 1)) { return true; } _inv.Changed(); zDO.Set("hf_last_food", val.m_shared.m_name); zDO.Set("hf_meal_end", WorldTimeMilliseconds + (long)Mathf.Clamp(HfConfig.MealMinutes.Value, 1, 5) * 60000L); if (_mealSitting) { zDO.Set("hf_seated_meal_day", day); } MarkSocialMeal(day); PlayEatAnimation(); Diagnostics.Log($"Hearthfolk[needs]: {PanelName} started {kind} with {val.m_shared.m_name}"); return true; } private ItemData FindCarriedFood() { if (_inv == null) { return null; } string last = _nview.GetZDO().GetString("hf_last_food", string.Empty); return (from item in _inv.GetAllItems().Where(IsNutritiousFood) orderby (item.m_shared.m_name == last) ? 1 : 0, FoodValue(item) select item).FirstOrDefault(); } internal bool TryFollowerEatForHealing() { if (!Valid || Role != SettlerRole.Follower || _inv == null || (Object)(object)_body == (Object)null || _nview.GetZDO().GetLong("hf_meal_end", 0L) > 0) { return false; } if (Time.time < _followerHealingPauseUntil) { Hold(); SetStatus("$hf_status_follower_eating_food"); return true; } if (Time.time < _nextFollowerHealingFood || ((Character)_body).GetHealth() >= ((Character)_body).GetMaxHealth() * 0.65f) { return false; } ItemData val = (from item in _inv.GetAllItems().Where(IsNutritiousFood) where item.m_shared.m_food > 0f orderby item.m_shared.m_food select item).FirstOrDefault(); if (val == null || !_inv.RemoveItem(val, 1)) { return false; } float num = Mathf.Max(1f, val.m_shared.m_food); ((Character)_body).SetHealth(Mathf.Min(((Character)_body).GetMaxHealth(), ((Character)_body).GetHealth() + num)); _inv.Changed(); _nextFollowerHealingFood = Time.time + 45f; _followerHealingPauseUntil = Time.time + 2.5f; PlayEatAnimation(); Hold(); SetStatus("$hf_status_follower_eating_food"); Diagnostics.Log($"Hearthfolk[follower]: {PanelName} ate {val.m_shared.m_name} and healed {num:0}"); return true; } private bool TryFetchFood() { if (!IsUsableMealStorage(_mealStorage) || string.IsNullOrEmpty(_mealFoodName) || StorageItemCount(_mealStorage, _mealFoodName) <= 0) { FindFoodStorage(out _mealStorage, out _mealFoodName); } if ((Object)(object)_mealStorage == (Object)null || string.IsNullOrEmpty(_mealFoodName)) { return false; } if (!CanInteractWith(((Component)_mealStorage).gameObject, 2.8f)) { Approach(((Component)_mealStorage).gameObject, 1.5f, run: false); return true; } if (WithdrawFromStorage(_mealStorage, _mealFoodName, 1) <= 0) { _mealStorage = null; _mealFoodName = null; return false; } _mealStorage = null; _mealFoodName = null; return true; } private void FindFoodStorage(out Container bestStorage, out string bestFood) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: 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) bestStorage = null; bestFood = null; float num = float.MinValue; ZDOID id = StorageLink.GetId(_nview.GetZDO()); string text = _nview.GetZDO().GetString("hf_last_food", string.Empty); Container[] array = SceneObjectCache.Get(1f); foreach (Container val in array) { if (!IsUsableMealStorage(val)) { continue; } Inventory inventory = val.GetInventory(); if (inventory == null) { continue; } foreach (ItemData item in inventory.GetAllItems().Where(IsNutritiousFood)) { float num2 = (ChestSortRules.IsConfigured(val) ? 10000f : 0f) + ((val.m_nview.GetZDO().m_uid == id) ? 5000f : 0f) + ((item.m_shared.m_name != text) ? 250f : 0f) - FoodValue(item); if (num2 > num) { num = num2; bestStorage = val; bestFood = item.m_shared.m_name; } } } } private bool IsUsableMealStorage(Container storage) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)storage == (Object)null || !ChestSortRules.IsStationaryPlayerChest(storage) || storage.IsInUse() || storage.m_nview.GetZDO().GetInt(ZDOVars.s_inUse, 0) == 1 || Vector3.Distance(((Component)storage).transform.position, Home) > WorkRadius) { return false; } if (storage.CheckAccess(OwnerId)) { return PrivateArea.CheckAccess(((Component)storage).transform.position, 0f, false, false); } return false; } private static bool IsNutritiousFood(ItemData item) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Invalid comparison between Unknown and I4 if (item != null && item.m_shared != null && (int)item.m_shared.m_itemType == 2) { if (!(item.m_shared.m_food > 0f) && !(item.m_shared.m_foodStamina > 0f)) { return item.m_shared.m_foodEitr > 0f; } return true; } return false; } private static float FoodValue(ItemData item) { return item.m_shared.m_food + item.m_shared.m_foodStamina + item.m_shared.m_foodEitr; } private bool PrepareMealPlace() { //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: 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_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_mealChair != (Object)null && !IsUsablePlacedSeat(_mealChair)) { ReleaseMealSeat(); } if (_mealSitting) { _waitingSitting = false; return true; } if ((Object)(object)_mealChair == (Object)null) { _mealChair = ReserveBestSeat(); } if ((Object)(object)_mealChair != (Object)null && (Object)(object)_mealChair.m_attachPoint != (Object)null) { Transform attachPoint = _mealChair.m_attachPoint; if ((Object)(object)Player.GetClosestPlayer(attachPoint.position, 0.6f) != (Object)null) { ReleaseMealSeat(); return false; } if (DistanceTo(attachPoint.position) > 1.5f) { GoTo(attachPoint.position, 1f, run: false); return false; } StartMealSit(_mealChair); return true; } if (DistanceTo(Home) > 4f) { GoTo(Home, 2.5f, run: false); return false; } Hold(); return true; } private bool PrepareFollowerMealPlace() { ReleaseMealSeat(); Hold(); return true; } internal bool WaitAtSeat(string statusKey = "$hf_status_resting") { //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) if (!Valid || (Object)(object)_ai == (Object)null || _ai.HasHostileTarget()) { StopWaitingSit(); return false; } UseRestMovement(); MarkSocialRestAvailable(); if ((Object)(object)_mealChair != (Object)null && !IsUsablePlacedSeat(_mealChair)) { ReleaseMealSeat(); } if ((Object)(object)_mealChair == (Object)null) { _mealChair = ReserveBestSeat(); } if ((Object)(object)_mealChair == (Object)null || (Object)(object)_mealChair.m_attachPoint == (Object)null) { if (TickSocialRest()) { Hold(); SetStatus("$hf_status_socializing"); return true; } if (_waitingSitting) { ReleaseMealSeat(); } return false; } _waitingSitting = true; Transform attachPoint = _mealChair.m_attachPoint; if ((Object)(object)Player.GetClosestPlayer(attachPoint.position, 0.6f) != (Object)null) { StopWaitingSit(); return false; } if (!_mealSitting && DistanceTo(attachPoint.position) > 1.5f) { GoTo(attachPoint.position, 1f, run: false); SetStatus("$hf_status_find_rest"); return true; } if (!_mealSitting) { StartMealSit(_mealChair); } _waitingSitting = true; MaintainMealPose(); SetStatus(TickSocialRest() ? "$hf_status_socializing" : statusKey); return true; } internal void StopWaitingSit() { StopSocialRest(); if (_waitingSitting) { ReleaseMealSeat(); } } private Chair ReserveBestSeat() { //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: 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) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) foreach (Chair item in SeatReservations.Keys.Where((Chair chair) => !IsUsablePlacedSeat(chair)).ToList()) { SeatReservations.Remove(item); } Chair val = null; float num = float.MaxValue; Chair[] array = SceneObjectCache.Get(1.5f); foreach (Chair val2 in array) { if (IsUsablePlacedSeat(val2) && !((Object)(object)((Component)val2).GetComponentInParent() != (Object)null) && !((Object)(object)((Component)val2).GetComponentInParent() != (Object)null) && !(Vector3.Distance(((Component)val2).transform.position, Home) > 15f) && !((Object)(object)Player.GetClosestPlayer(val2.m_attachPoint.position, 0.6f) != (Object)null) && (!SeatReservations.TryGetValue(val2, out var value) || !(value != MyZdoid))) { float num3 = Vector3.Distance(Position, val2.m_attachPoint.position); if (num3 < num) { val = val2; num = num3; } } } if ((Object)(object)val != (Object)null) { SeatReservations[val] = MyZdoid; } return val; } private static bool IsUsablePlacedSeat(Chair chair) { if ((Object)(object)chair == (Object)null || !((Behaviour)chair).isActiveAndEnabled || !((Component)chair).gameObject.activeInHierarchy || (Object)(object)chair.m_attachPoint == (Object)null || !((Component)chair.m_attachPoint).gameObject.activeInHierarchy) { return false; } Piece val = ((Component)chair).GetComponent() ?? ((Component)chair).GetComponentInParent(); ZNetView val2 = ((Component)chair).GetComponent() ?? ((Component)chair).GetComponentInParent(); if ((Object)(object)val != (Object)null && val.IsPlacedByPlayer() && (Object)(object)val2 != (Object)null && val2.IsValid()) { return val2.GetZDO() != null; } return false; } private void StartMealSit(Chair chair) { //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_0073: Unknown result type (might be due to invalid IL or missing references) if (!IsUsablePlacedSeat(chair)) { ReleaseMealSeat(); return; } _mealChair = chair; _mealSitting = true; _waitingSitting = false; Hold(); ((Component)this).transform.position = chair.m_attachPoint.position; ((Component)this).transform.rotation = chair.m_attachPoint.rotation; if (!((Character)_body).m_body.isKinematic) { ((Character)_body).m_body.linearVelocity = Vector3.zero; } ((Character)_body).m_body.useGravity = false; ((Character)_body).m_zanim.SetBool(chair.m_attachAnimation, true); } private void MaintainMealPose() { //IL_0025: 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_0067: Unknown result type (might be due to invalid IL or missing references) if (!IsUsablePlacedSeat(_mealChair)) { ReleaseMealSeat(); return; } ((Component)this).transform.position = _mealChair.m_attachPoint.position; ((Component)this).transform.rotation = _mealChair.m_attachPoint.rotation; if (!((Character)_body).m_body.isKinematic) { ((Character)_body).m_body.linearVelocity = Vector3.zero; } } private void ReleaseMealSeat() { //IL_002a: 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) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_mealChair != (Object)null && SeatReservations.TryGetValue(_mealChair, out var value) && (!Valid || value == MyZdoid)) { SeatReservations.Remove(_mealChair); } if (_mealSitting && (Object)(object)_body != (Object)null) { if ((Object)(object)_mealChair != (Object)null) { ((Character)_body).m_zanim.SetBool(_mealChair.m_attachAnimation, false); } if ((Object)(object)((Character)_body).m_body != (Object)null) { ((Character)_body).m_body.useGravity = true; } Transform transform = ((Component)this).transform; transform.position += Vector3.up * 0.3f; } _mealChair = null; _mealSitting = false; _waitingSitting = false; } private void MaintainEatingActivity(int day, bool carriedOnly) { if (carriedOnly ? PrepareFollowerMealPlace() : PrepareMealPlace()) { Hold(); if (Time.time >= _nextEatAnimation) { PlayEatAnimation(); } MarkSocialMeal(day); } } private void PlayEatAnimation() { _nextEatAnimation = Time.time + 12f; Humanoid body = _body; if (body != null) { ZSyncAnimation zanim = ((Character)body).m_zanim; if (zanim != null) { zanim.SetTrigger("eat"); } } } private void MarkSocialMeal(int day) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) foreach (SettlerController instance in Instances) { if (!((Object)(object)instance == (Object)null) && !((Object)(object)instance == (Object)(object)this) && instance.IsValidSettler && !(Vector3.Distance(instance.Position, Position) > 8f) && instance._nview.GetZDO().GetLong("hf_meal_end", 0L) > 0) { _nview.GetZDO().Set("hf_social_meal_day", day); break; } } } private void CompleteMeal(MealKind kind, int day) { _nview.GetZDO().Set((kind == MealKind.Dinner) ? "hf_dinner_day" : "hf_breakfast_day", day); ClearMealState(); Diagnostics.Log($"Hearthfolk[needs]: {PanelName} completed {kind}"); } private void MissMeal(MealKind kind, int day) { _nview.GetZDO().Set((kind == MealKind.Dinner) ? "hf_dinner_missed_day" : "hf_breakfast_missed_day", day); ClearMealState(); Diagnostics.Log($"Hearthfolk[needs]: {PanelName} missed {kind}; no food available"); } private void ClearMealState() { ReleaseMealSeat(); _mealStorage = null; _mealFoodName = null; ZDO zDO = _nview.GetZDO(); zDO.Set("hf_meal_kind", 0); zDO.Set("hf_meal_end", 0L); zDO.Set("hf_meal_search_until", 0L); } private void MarkSleepStarted() { int num = RoutineDay(); ZDO zDO = _nview.GetZDO(); if (zDO.GetInt("hf_sleep_started_day", -1) != num) { zDO.Set("hf_sleep_started_day", num); zDO.Set("hf_sleep_started_at", WorldTimeMilliseconds); } } private void CompleteSleep(int day, bool morning) { ZDO zDO = _nview.GetZDO(); if (zDO.GetInt("hf_slept_day", -1) == day) { if (morning && zDO.GetInt("hf_healed_day", -1) != day) { ((Character)_body).SetHealth(((Character)_body).GetMaxHealth()); zDO.Set("hf_healed_day", day); SetStatus("$hf_status_woke_healthy"); } StopSleep(); return; } if (zDO.GetInt("hf_sleep_missed_day", -1) == day) { StopSleep(); return; } bool flag = zDO.GetInt("hf_sleep_started_day", -1) == day; long num = zDO.GetLong("hf_sleep_started_at", 0L); if (flag && num > 0 && WorldTimeMilliseconds - num >= 60000) { zDO.Set("hf_slept_day", day); if (morning) { ((Character)_body).SetHealth(((Character)_body).GetMaxHealth()); zDO.Set("hf_healed_day", day); SetStatus("$hf_status_woke_healthy"); } Diagnostics.Log("Hearthfolk[needs]: " + PanelName + " completed sleep and recovered health"); } else if (morning) { zDO.Set("hf_sleep_missed_day", day); } StopSleep(); } private bool IsGuardMealTurn() { return !SettlementGuards().Any((SettlerController other) => (Object)(object)other != (Object)(object)this && other._nview.GetZDO().GetInt("hf_meal_kind", 0) != 0); } private List SettlementGuards() { return (from settler in Instances where (Object)(object)settler != (Object)null && settler.IsValidSettler && !settler.IsRespawning && settler.Role == SettlerRole.Guard && Vector3.Distance(settler.Home, Home) <= 6f orderby ((object)settler.MyZdoid/*cast due to .constrained prefix*/).GetHashCode() select settler).ToList(); } private void EvaluateNeeds(int day, SettlerRole role, bool hasBed, bool requiresSleep) { ZDO zDO = _nview.GetZDO(); int num = zDO.GetInt("hf_needs_eval_day", day); if (num >= day) { return; } if (day - num > 1) { zDO.Set("hf_needs_eval_day", day); return; } List list = new List(); float delta = 0f; if (requiresSleep) { if (zDO.GetInt("hf_slept_day", -1) == day) { delta += 8f; list.Add("$hf_reason_rested"); } else { delta -= 14f; list.Add(hasBed ? "$hf_reason_missed_sleep" : "$hf_reason_no_bed"); if (!hasBed) { delta -= 8f; } } } ScoreMeal(day, "hf_dinner_day", "$hf_reason_had_dinner", "$hf_reason_missed_dinner", list, ref delta); ScoreMeal(day, "hf_breakfast_day", "$hf_reason_had_breakfast", "$hf_reason_missed_breakfast", list, ref delta); if (zDO.GetInt("hf_seated_meal_day", -1) == day) { delta += 2f; list.Add("$hf_reason_sat_to_eat"); } if (zDO.GetInt("hf_social_meal_day", -1) == day) { delta += 2f; list.Add("$hf_reason_social_meal"); } if (zDO.GetInt("hf_threat_day", -1) == day) { delta -= 4f; list.Add("$hf_reason_threatened"); } else { delta += 2f; list.Add("$hf_reason_safe"); } if (HasShelteredFire()) { delta += 3f; list.Add("$hf_reason_comfortable"); } if (HasRoleEquipment(role)) { delta += 2f; list.Add("$hf_reason_equipped"); } else { delta -= 5f; list.Add("$hf_reason_unequipped"); } float num2 = Mathf.Clamp(zDO.GetFloat("hf_happiness", 70f) + delta, 0f, 100f); zDO.Set("hf_happiness", num2); zDO.Set("hf_morale_reasons", string.Join("|", list)); zDO.Set("hf_needs_eval_day", day); int num3 = ((num2 < 20f) ? (zDO.GetInt("hf_unhappy_days", 0) + 1) : 0); zDO.Set("hf_unhappy_days", num3); NotifyMorale(num2, num3); if (HfConfig.EnableDesertion.Value && num2 < 20f && num3 >= Mathf.Max(1, HfConfig.DesertionDays.Value)) { LeaveSettlement(); } } private void ScoreMeal(int day, string completedKey, string goodReason, string badReason, List reasons, ref float delta) { if (_nview.GetZDO().GetInt(completedKey, -1) == day) { delta += 5f; reasons.Add(goodReason); } else { delta -= 9f; reasons.Add(badReason); } } private bool HasShelteredFire() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) float num = default(float); bool flag = default(bool); Cover.GetCoverForPoint(Home + Vector3.up, ref num, ref flag, 0.5f); if (!flag) { return false; } return SceneObjectCache.Get(1.5f).Any((Fireplace fire) => (Object)(object)fire != (Object)null && (Object)(object)fire.m_nview != (Object)null && fire.m_nview.IsValid() && Vector3.Distance(((Component)fire).transform.position, Home) <= 12f && fire.m_nview.GetZDO().GetFloat(ZDOVars.s_fuel, 0f) > 0f); } private bool HasRoleEquipment(SettlerRole role) { return role switch { SettlerRole.Lumberjack => FindAxe() != null, SettlerRole.Miner => FindPickaxe() != null, SettlerRole.Guard => FindWeapon() != null, SettlerRole.Caretaker => FindHammer() != null, SettlerRole.Follower => FindWeapon() != null, SettlerRole.Farmer => FindCultivator() != null, _ => true, }; } private void NotifyMorale(float happiness, int unhappyDays) { if (!(happiness >= 40f)) { Player player = Player.GetPlayer(OwnerId); if (!((Object)(object)player == (Object)null)) { string text = ((happiness < 20f) ? "$hf_morale_critical" : "$hf_morale_warning"); string format = Localization.instance.Localize(text); int num = Mathf.Max(0, HfConfig.DesertionDays.Value - unhappyDays); ((Character)player).Message((MessageType)2, string.Format(format, DisplayName, Mathf.RoundToInt(happiness), num), 0, (Sprite)null); } } } private void LeaveSettlement() { if (!_leavingSettlement) { _leavingSettlement = true; Player player = Player.GetPlayer(OwnerId); if ((Object)(object)player != (Object)null) { string format = Localization.instance.Localize("$hf_settler_left"); ((Character)player).Message((MessageType)2, string.Format(format, DisplayName), 0, (Sprite)null); } _current?.Exit(this); StopSleep(); ReleaseMealSeat(); LeaveInventoryAtHearth(); ReleaseWorkstation(); ReleaseBed(); StorageLink.Clear(_nview.GetZDO()); Diagnostics.Log($"Hearthfolk[needs]: {PanelName} left the settlement at happiness {Happiness}"); if ((Object)(object)ZNetScene.instance != (Object)null) { ZNetScene.instance.Destroy(((Component)this).gameObject); } } } private void LeaveInventoryAtHearth() { //IL_010a: 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) //IL_0119: 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_0127: Unknown result type (might be due to invalid IL or missing references) //IL_0133: 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_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) if (_inv == null || _inv.NrOfItems() == 0) { return; } try { ZNetScene instance = ZNetScene.instance; GameObject obj = ((instance != null) ? instance.GetPrefab("Player") : null); GameObject val = ((obj == null) ? null : obj.GetComponent()?.m_tombstone); if ((Object)(object)val != (Object)null) { _body.UnequipAllItems(); GameObject val2 = Object.Instantiate(val, Home + Vector3.up * 0.8f, Quaternion.identity); Container component = val2.GetComponent(); TombStone component2 = val2.GetComponent(); if ((Object)(object)component != (Object)null && (Object)(object)component2 != (Object)null) { component.GetInventory().MoveAll(_inv); component2.Setup(DisplayName, OwnerId); return; } Object.Destroy((Object)(object)val2); } } catch (Exception ex) { Logger.LogWarning((object)("Hearthfolk: departure sack failed: " + ex.Message)); } foreach (ItemData item in _inv.GetAllItems().ToList()) { Vector2 val3 = Random.insideUnitCircle * 0.8f; ItemDrop.DropItem(item, item.m_stack, Home + new Vector3(val3.x, 0.8f, val3.y), Quaternion.identity); } _inv.RemoveAll(); } private static void CopyNeedsState(ZDO source, ZDO destination) { destination.Set("hf_needs_init", source.GetBool("hf_needs_init", false)); destination.Set("hf_happiness", source.GetFloat("hf_happiness", 70f)); destination.Set("hf_morale_reasons", source.GetString("hf_morale_reasons", string.Empty)); destination.Set("hf_needs_eval_day", source.GetInt("hf_needs_eval_day", -1)); destination.Set("hf_unhappy_days", source.GetInt("hf_unhappy_days", 0)); string[] array = new string[12] { "hf_dinner_day", "hf_dinner_missed_day", "hf_breakfast_day", "hf_breakfast_missed_day", "hf_sleep_started_day", "hf_slept_day", "hf_healed_day", "hf_sleep_missed_day", "hf_seated_meal_day", "hf_social_meal_day", "hf_threat_day", "hf_socialized_day" }; foreach (string text in array) { destination.Set(text, source.GetInt(text, -1)); } destination.Set("hf_sleep_started_at", source.GetLong("hf_sleep_started_at", 0L)); destination.Set("hf_last_food", source.GetString("hf_last_food", string.Empty)); destination.Set("hf_meal_kind", 0); destination.Set("hf_meal_end", 0L); destination.Set("hf_meal_search_until", 0L); } private void MarkSocialRestAvailable() { _socialAvailableUntil = Time.time + 0.9f; } private bool TickSocialRest() { MarkSocialRestAvailable(); if (!SocialRestEnabled || !Valid || !_nview.IsOwner() || SettlementAlertActive || (Object)(object)_ai == (Object)null || _ai.HasHostileTarget()) { StopSocialRest(); return false; } if (_socialGroup != null) { if (!MaintainSocialGroup(_socialGroup)) { StopSocialRest(); return false; } MaintainSocialLook(); return true; } if (Time.time < _nextSocialDecision) { return false; } _nextSocialDecision = Time.time + Random.Range(24f, 45f); int chance = ((HfConfig.SocialChancePercent != null) ? Mathf.Clamp(HfConfig.SocialChancePercent.Value, 0, 100) : 65); if (Random.Range(0, 100) >= chance) { _nextSocialDecision = Time.time + Random.Range(55f, 100f); return false; } List list = (from other in Instances where (Object)(object)other != (Object)null && (Object)(object)other != (Object)(object)this && other.CanJoinSocialGroup(this, chance) orderby Vector3.Distance(Position, other.Position) + Random.Range(0f, 3f) select other).ToList(); if (list.Count == 0) { return false; } int num = ((list.Count >= 2 && Random.value < 0.42f) ? 3 : 2); SocialGroup socialGroup = new SocialGroup { Id = ++_nextSocialGroupId, StartedAt = Time.time, EndsAt = Time.time + (float)Mathf.Clamp((HfConfig.SocialDurationSeconds != null) ? HfConfig.SocialDurationSeconds.Value : 90, 30, 300) * Random.Range(0.85f, 1.15f), NextLineAt = Time.time + Random.Range(2f, 5f) }; socialGroup.Members.Add(this); socialGroup.Members.AddRange(list.Take(num - 1)); foreach (SettlerController member in socialGroup.Members) { member._socialGroup = socialGroup; member._nextSocialLook = 0f; } Diagnostics.Log($"Hearthfolk[social]: group {socialGroup.Id} formed with " + string.Join(", ", socialGroup.Members.Select((SettlerController member) => member.PanelName))); return true; } private bool CanJoinSocialGroup(SettlerController initiator, int chance) { //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) if (Valid && !IsRespawning && _nview.IsOwner() && _socialGroup == null && Time.time <= _socialAvailableUntil && !SettlementAlertActive && (Object)(object)_ai != (Object)null && !_ai.HasHostileTarget() && Vector3.Distance(Home, initiator.Home) <= 6f && Vector3.Distance(Position, initiator.Position) <= 12f) { return Random.Range(0, 100) < chance; } return false; } private bool MaintainSocialGroup(SocialGroup group) { group.Members.RemoveAll((SettlerController member) => (Object)(object)member == (Object)null || !member.Valid || member.IsRespawning || Time.time > member._socialAvailableUntil || member.SettlementAlertActive || (Object)(object)member._ai == (Object)null || member._ai.HasHostileTarget()); if (group.Members.Count < 2) { EndSocialGroup(group, reward: false); return false; } if (Time.time >= group.EndsAt) { EndSocialGroup(group, reward: true); return false; } if ((Object)(object)group.Members[0] == (Object)(object)this && Time.time >= group.NextLineAt) { group.NextLineAt = Time.time + Random.Range(6f, 10f); SettlerController settlerController = group.Members[group.Turn % group.Members.Count]; group.Turn++; settlerController.PublishSocialLine(SocialLines[Random.Range(0, SocialLines.Length)]); if ((Object)(object)settlerController._body != (Object)null && (Object)(object)((Character)settlerController._body).m_zanim != (Object)null && Random.value < 0.45f) { ((Character)settlerController._body).m_zanim.SetTrigger("interact"); } } return true; } private void MaintainSocialLook() { //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_009e: 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_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: 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_00cf: Unknown result type (might be due to invalid IL or missing references) if (_socialGroup == null || _socialGroup.Members.Count < 2 || (Object)(object)_body == (Object)null || Time.time < _nextSocialLook) { return; } _nextSocialLook = Time.time + Random.Range(3f, 6f); List list = _socialGroup.Members.Where((SettlerController member) => (Object)(object)member != (Object)null && (Object)(object)member != (Object)(object)this).ToList(); if (list.Count != 0) { Vector3 val = list[Random.Range(0, list.Count)].Position + Vector3.up * 1.35f - ((Character)_body).GetEyePoint(); if (((Vector3)(ref val)).sqrMagnitude > 0.01f) { ((Character)_body).SetLookDir(((Vector3)(ref val)).normalized, 0.45f); } } } private void PublishSocialLine(string line) { if (Valid && _nview.IsOwner() && !string.IsNullOrEmpty(line)) { ZDO zDO = _nview.GetZDO(); zDO.Set("hf_social_line", line); zDO.Set("hf_social_line_time", WorldTimeMilliseconds); zDO.Set("hf_social_line_sequence", zDO.GetInt("hf_social_line_sequence", 0) + 1); } } private void MaintainSocialPresentation() { //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) if (!Valid || (Object)(object)Chat.instance == (Object)null) { return; } ZDO zDO = _nview.GetZDO(); int num = zDO.GetInt("hf_social_line_sequence", 0); if (num > 0 && num != _lastSocialLineSequence) { _lastSocialLineSequence = num; long num2 = WorldTimeMilliseconds - zDO.GetLong("hf_social_line_time", 0L); string text = zDO.GetString("hf_social_line", string.Empty); if (num2 >= 0 && num2 <= 6500 && !string.IsNullOrEmpty(text)) { Chat.instance.SetNpcText(((Component)this).gameObject, Vector3.up * 2.05f, 28f, 5.5f, DisplayName, text, false); } } } private void EndSocialGroup(SocialGroup group, bool reward) { if (group == null) { return; } List list = group.Members.ToList(); group.Members.Clear(); foreach (SettlerController item in list) { if (!((Object)(object)item == (Object)null) && item._socialGroup == group) { if (reward) { item.ApplySocialHappinessBonus(); } item._socialGroup = null; item._nextSocialDecision = Time.time + Random.Range(90f, 180f); } } } private void StopSocialRest() { SocialGroup socialGroup = _socialGroup; if (socialGroup != null) { socialGroup.Members.Remove(this); _socialGroup = null; _nextSocialDecision = Time.time + Random.Range(45f, 90f); if (socialGroup.Members.Count < 2) { EndSocialGroup(socialGroup, reward: false); } } } private void ApplySocialHappinessBonus() { if (!Valid || !_nview.IsOwner() || (Object)(object)EnvMan.instance == (Object)null) { return; } int day = EnvMan.instance.GetDay(); ZDO zDO = _nview.GetZDO(); if (zDO.GetInt("hf_socialized_day", -1) != day) { int num = Mathf.Clamp((HfConfig.SocialHappinessBonus != null) ? HfConfig.SocialHappinessBonus.Value : 4, 0, 20); zDO.Set("hf_socialized_day", day); zDO.Set("hf_happiness", Mathf.Clamp(zDO.GetFloat("hf_happiness", 70f) + (float)num, 0f, 100f)); List list = zDO.GetString("hf_morale_reasons", string.Empty).Split(new char[1] { '|' }, StringSplitOptions.RemoveEmptyEntries).ToList(); if (!list.Contains("$hf_reason_socialized")) { list.Add("$hf_reason_socialized"); zDO.Set("hf_morale_reasons", string.Join("|", list)); } } } } [HarmonyPatch(typeof(Character), "ApplyDamage")] internal static class SettlerArmorPatches { private static void Prefix(Character __instance, HitData hit) { if (hit != null && __instance is SettlerBody) { SettlerController component = ((Component)__instance).GetComponent(); float num = (((Object)(object)component != (Object)null) ? component.EquippedArmor : 0f); if (num > 0f) { hit.ApplyArmor(num); } } } } internal sealed class SettlerBody : Humanoid { private SettlerController _controller; private SettlerController Controller { get { if (!((Object)(object)_controller != (Object)null)) { return _controller = ((Component)this).GetComponent(); } return _controller; } } public override string GetHoverName() { if (!((Object)(object)Controller != (Object)null)) { return ((Character)this).GetHoverName(); } return Controller.HoverName(); } public override string GetHoverText() { if (!((Object)(object)Controller != (Object)null)) { return ((Character)this).GetHoverText(); } return Controller.HoverText(); } } internal static class SettlerConversion { private const BindingFlags DeclaredInstance = BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; internal static Humanoid Convert(GameObject clone) { //IL_0052: Unknown result type (might be due to invalid IL or missing references) Player component = clone.GetComponent(); if ((Object)(object)component == (Object)null) { Logger.LogError((object)"Hearthfolk: base prefab is not a Player; settler body cannot be built."); return null; } SettlerBody settlerBody = clone.AddComponent(); CopyDeclaredFields(typeof(Character), component, settlerBody); CopyDeclaredFields(typeof(Humanoid), component, settlerBody); ((Character)settlerBody).m_name = "$hf_settler"; ((Character)settlerBody).m_faction = (Faction)0; ((Character)settlerBody).m_group = string.Empty; ((Character)settlerBody).m_boss = false; ((Character)settlerBody).m_health = Mathf.Max(10f, HfConfig.SettlerHealth?.Value ?? 100f); ((Humanoid)settlerBody).m_defaultItems = Array.Empty(); ((Humanoid)settlerBody).m_randomWeapon = Array.Empty(); ((Humanoid)settlerBody).m_randomArmor = Array.Empty(); ((Humanoid)settlerBody).m_randomShield = Array.Empty(); ((Humanoid)settlerBody).m_randomSets = Array.Empty(); ((Humanoid)settlerBody).m_randomItems = Array.Empty(); StripComponent(clone); StripComponent(clone); StripComponent(clone); StripComponent(clone); ZNetView component2 = clone.GetComponent(); if ((Object)(object)component2 != (Object)null) { component2.m_persistent = true; } Animator[] componentsInChildren = clone.GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren.Length; i++) { componentsInChildren[i].cullingMode = (AnimatorCullingMode)0; } SettlerAI settlerAI = clone.AddComponent(); ((MonsterAI)settlerAI).m_attackPlayerObjects = false; ((MonsterAI)settlerAI).m_alertRange = 20f; ((BaseAI)settlerAI).m_randomMoveRange = 4f; ((BaseAI)settlerAI).m_randomMoveInterval = 8f; ((BaseAI)settlerAI).m_afraidOfFire = false; ((BaseAI)settlerAI).m_avoidFire = false; ((MonsterAI)settlerAI).m_fleeIfHurtWhenTargetCantBeReached = false; ((MonsterAI)settlerAI).m_fleeIfNotAlerted = false; ((MonsterAI)settlerAI).m_fleeIfLowHealth = 0f; ((MonsterAI)settlerAI).m_consumeItems = new List(); ((BaseAI)settlerAI).m_smoothMovement = false; ((BaseAI)settlerAI).m_moveMinAngle = 90f; return (Humanoid)(object)settlerBody; } private static void CopyDeclaredFields(Type declaringType, object from, object to) { FieldInfo[] fields = declaringType.GetFields(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo fieldInfo in fields) { if (!fieldInfo.IsInitOnly) { try { fieldInfo.SetValue(to, fieldInfo.GetValue(from)); } catch (Exception ex) { Logger.LogWarning((object)("Hearthfolk: could not copy field " + declaringType.Name + "." + fieldInfo.Name + ": " + ex.Message)); } } } } private static void StripComponent(GameObject go) where T : Component { T component = go.GetComponent(); if ((Object)(object)component != (Object)null) { Object.DestroyImmediate((Object)(object)component); } } } internal sealed class SettlerInventory : Container { internal bool Bound { get; private set; } private void Awake() { //IL_007e: Unknown result type (might be due to invalid IL or missing references) base.m_nview = ((Component)this).GetComponent(); if (!((Object)(object)base.m_nview == (Object)null) && base.m_nview.GetZDO() != null) { Humanoid component = ((Component)this).GetComponent(); if ((Object)(object)component == (Object)null) { Logger.LogError((object)"Hearthfolk: SettlerInventory requires a Humanoid on the same object."); return; } base.m_inventory = component.GetInventory(); base.m_name = "$hf_inventory"; base.m_width = base.m_inventory.GetWidth(); base.m_height = base.m_inventory.GetHeight(); base.m_privacy = (PrivacySetting)2; base.m_checkGuardStone = false; base.m_autoDestroyEmpty = false; base.m_inventory.m_onChanged = (Action)Delegate.Combine(base.m_inventory.m_onChanged, new Action(base.OnContainerChanged)); base.m_nview.Register("RequestOpen", (Action)base.RPC_RequestOpen); base.m_nview.Register("OpenRespons", (Action)base.RPC_OpenRespons); base.m_nview.Register("RPC_RequestStack", (Action)base.RPC_RequestStack); base.m_nview.Register("RPC_StackResponse", (Action)base.RPC_StackResponse); base.m_nview.Register("RequestTakeAll", (Action)base.RPC_RequestTakeAll); base.m_nview.Register("TakeAllRespons", (Action)base.RPC_TakeAllRespons); ((Container)this).Load(); ((MonoBehaviour)this).InvokeRepeating("CheckForChanges", 0f, 1f); Bound = true; } } } internal sealed class SettlerShelter : MonoBehaviour { private static readonly Color CanvasWhite = new Color(0.92f, 0.92f, 0.88f, 1f); internal const string AccessPointName = "hf_shelter_access"; internal const string InteriorExitPointName = "hf_shelter_exit_inside"; internal const string InteractionPointName = "hf_shelter_interaction"; private Bed _bed; private Transform _accessPoint; private Transform _interiorExitPoint; private Transform _interactionPoint; internal Bed Bed => _bed; internal Vector3 AccessPosition { get { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_accessPoint != (Object)null)) { return ((Component)this).transform.position; } return _accessPoint.position; } } internal Vector3 InteriorExitPosition { get { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_interiorExitPoint != (Object)null)) { return ((Component)this).transform.position; } return _interiorExitPoint.position; } } internal Vector3 InteractionPosition { get { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_interactionPoint != (Object)null)) { return ((Component)this).transform.position + Vector3.up * 0.45f; } return _interactionPoint.position; } } private void Awake() { _bed = ((Component)this).GetComponent() ?? ((Component)this).GetComponentInChildren(true); Transform[] componentsInChildren = ((Component)this).GetComponentsInChildren(true); _accessPoint = ((IEnumerable)componentsInChildren).FirstOrDefault((Func)((Transform candidate) => (Object)(object)candidate != (Object)null && ((Object)candidate).name == "hf_shelter_access")); _interiorExitPoint = ((IEnumerable)componentsInChildren).FirstOrDefault((Func)((Transform candidate) => (Object)(object)candidate != (Object)null && ((Object)candidate).name == "hf_shelter_exit_inside")); _interactionPoint = ((IEnumerable)componentsInChildren).FirstOrDefault((Func)((Transform candidate) => (Object)(object)candidate != (Object)null && ((Object)candidate).name == "hf_shelter_interaction")); ReserveForSettlers(); } private void Start() { ReserveForSettlers(); ApplyWhiteCanvas(); } internal static SettlerShelter For(Bed bed) { if ((Object)(object)bed == (Object)null) { return null; } return ((Component)bed).GetComponent() ?? ((Component)bed).GetComponentInParent() ?? ((Component)bed).GetComponentInChildren(true); } internal static bool IsDedicated(Bed bed) { return (Object)(object)For(bed) != (Object)null; } internal void ReserveForSettlers() { //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_bed == (Object)null) && !((Object)(object)_bed.m_nview == (Object)null) && _bed.m_nview.IsValid() && _bed.m_nview.IsOwner()) { ZDO zDO = _bed.m_nview.GetZDO(); if (zDO != null && !(zDO.GetZDOID("hf_claim") != ZDOID.None) && string.IsNullOrEmpty(zDO.GetString("hf_claim_identity", string.Empty)) && zDO.GetLong(ZDOVars.s_owner, 0L) == 0L) { MarkAvailable(zDO); } } } internal static void MarkAvailable(Bed bed) { if (!((Object)(object)For(bed) == (Object)null) && !((Object)(object)bed.m_nview == (Object)null) && bed.m_nview.IsValid()) { MarkAvailable(bed.m_nview.GetZDO()); } } private static void MarkAvailable(ZDO zdo) { if (zdo != null) { zdo.Set(ZDOVars.s_owner, 424242L); zdo.Set(ZDOVars.s_ownerName, "Hearthfolk settler"); } } private void ApplyWhiteCanvas() { //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Expected O, but got Unknown //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) Renderer[] componentsInChildren = ((Component)this).GetComponentsInChildren(true); foreach (Renderer val in componentsInChildren) { if (!((Object)(object)val == (Object)null) && !((Object)(object)val.sharedMaterial == (Object)null)) { string name = ((Object)val.sharedMaterial).name; if (!(name != "hf_tent_canvas") || !(name != "hf_tent_flap") || !(name != "hf_tent_trim")) { MaterialPropertyBlock val2 = new MaterialPropertyBlock(); val.GetPropertyBlock(val2); val2.SetColor("_Color", CanvasWhite); val2.SetColor("_BaseColor", CanvasWhite); val.SetPropertyBlock(val2); } } } } } [HarmonyPatch(typeof(Bed), "Interact")] internal static class SettlerShelterInteractPatch { [HarmonyPrefix] private static bool Prefix(Bed __instance, Humanoid human, ref bool __result) { if (!SettlerShelter.IsDedicated(__instance)) { return true; } Player val = (Player)(object)((human is Player) ? human : null); if (val != null && (Object)(object)val == (Object)(object)Player.m_localPlayer) { ((Character)val).Message((MessageType)2, "$hf_settler_shelter_reserved", 0, (Sprite)null); } __result = false; return false; } } [HarmonyPatch(typeof(Bed), "GetHoverText")] internal static class SettlerShelterHoverPatch { [HarmonyPostfix] private static void Postfix(Bed __instance, ref string __result) { if (SettlerShelter.IsDedicated(__instance)) { __result = __result + "\n" + Localization.instance.Localize("$hf_settler_shelter_reserved"); } } } internal static class StorageLink { private const float RecoveryRadius = 0.75f; internal static void Set(ZDO ownerZdo, ZDOID containerId) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) ownerZdo.Set("hf_storage", containerId); ClearRecoveryIdentity(ownerZdo); Container val = ResolveInstance(containerId, null); if ((Object)(object)val != (Object)null) { StoreRecoveryIdentity(ownerZdo, val); } } internal static void Clear(ZDO ownerZdo) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) ownerZdo.Set("hf_storage", ZDOID.None); ClearRecoveryIdentity(ownerZdo); } internal static ZDOID GetId(ZDO ownerZdo) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) return ownerZdo.GetZDOID("hf_storage"); } internal static void CopyAssignment(ZDO source, ZDO destination) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) destination.Set("hf_storage", source.GetZDOID("hf_storage")); destination.Set("hf_storage_pos", source.GetVec3("hf_storage_pos", Vector3.zero)); destination.Set("hf_storage_prefab", source.GetString("hf_storage_prefab", string.Empty)); destination.Set("hf_storage_creator", source.GetLong("hf_storage_creator", 0L)); } internal static Container Resolve(ZDO ownerZdo, Component self) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_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) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_014e: 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_016a: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: 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) ZDOID id = GetId(ownerZdo); if (id == ZDOID.None || (Object)(object)ZNetScene.instance == (Object)null) { return null; } Container val = ResolveInstance(id, self); if ((Object)(object)val != (Object)null) { StoreRecoveryIdentity(ownerZdo, val); return val; } string text = ownerZdo.GetString("hf_storage_prefab", string.Empty); if (string.IsNullOrEmpty(text)) { return null; } Vector3 vec = ownerZdo.GetVec3("hf_storage_pos", Vector3.zero); long num = ownerZdo.GetLong("hf_storage_creator", 0L); Container val2 = null; float num2 = 0.75f; Container[] array = SceneObjectCache.Get(1f); foreach (Container val3 in array) { if (IsUsable(val3, self) && string.Equals(MaterialFilters.PrefabName(((Component)val3).gameObject), text, StringComparison.Ordinal) && Creator(val3) == num) { float num3 = Vector3.Distance(((Component)val3).transform.position, vec); if (num3 <= num2) { val2 = val3; num2 = num3; } } } if ((Object)(object)val2 == (Object)null) { return null; } ZDOID uid = val2.m_nview.GetZDO().m_uid; ownerZdo.Set("hf_storage", uid); StoreRecoveryIdentity(ownerZdo, val2); Logger.LogInfo((object)("Hearthfolk[storage]: restored assigned chest " + text + " at " + $"{vec.x:0.0}, {vec.y:0.0}, {vec.z:0.0} ({id} -> {uid}).")); return val2; } private static Container ResolveInstance(ZDOID id, Component self) { //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_0021: Unknown result type (might be due to invalid IL or missing references) if (id == ZDOID.None || (Object)(object)ZNetScene.instance == (Object)null) { return null; } GameObject val = ZNetScene.instance.FindInstance(id); if ((Object)(object)val == (Object)null) { return null; } Container val2 = val.GetComponent() ?? val.GetComponentInChildren(true); if (!IsUsable(val2, self)) { return null; } return val2; } private static bool IsUsable(Container container, Component self) { if ((Object)(object)container != (Object)null && !(container is SettlerInventory) && ((Object)(object)self == (Object)null || (Object)(object)((Component)container).gameObject != (Object)(object)self.gameObject) && ((Component)container).gameObject.activeInHierarchy && (Object)(object)container.m_nview != (Object)null) { return container.m_nview.IsValid(); } return false; } private static long Creator(Container container) { Piece val = ((Component)container).GetComponent() ?? ((Component)container).GetComponentInParent(); if (!((Object)(object)val != (Object)null)) { return 0L; } return val.GetCreator(); } private static void StoreRecoveryIdentity(ZDO settlerZdo, Container container) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) string text = MaterialFilters.PrefabName(((Component)container).gameObject); if (!string.IsNullOrEmpty(text)) { settlerZdo.Set("hf_storage_pos", ((Component)container).transform.position); settlerZdo.Set("hf_storage_prefab", text); settlerZdo.Set("hf_storage_creator", Creator(container)); } } private static void ClearRecoveryIdentity(ZDO settlerZdo) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) settlerZdo.Set("hf_storage_pos", Vector3.zero); settlerZdo.Set("hf_storage_prefab", string.Empty); settlerZdo.Set("hf_storage_creator", 0L); } } internal sealed class TentFireArea : MonoBehaviour { private const float Radius = 3.6f; private float _nextPulse; private void Update() { //IL_0034: 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_0044: 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_005f: Unknown result type (might be due to invalid IL or missing references) if (Time.time < _nextPulse) { return; } _nextPulse = Time.time + 0.2f; Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer != (Object)null) { Vector3 val = ((Component)localPlayer).transform.position - ((Component)this).transform.position; if (((Vector3)(ref val)).sqrMagnitude <= 12.959999f) { ((Character)localPlayer).OnNearFire(((Component)this).transform.position); } } } } internal sealed class TentTorchFlicker : MonoBehaviour { private Light[] _lights; private float[] _baseIntensities; private float _seed; private void Awake() { //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) _lights = ((Component)this).GetComponentsInChildren(true); _baseIntensities = new float[_lights.Length]; for (int i = 0; i < _lights.Length; i++) { _baseIntensities[i] = _lights[i].intensity; } _seed = Mathf.Abs(((Component)this).transform.position.x * 17.13f + ((Component)this).transform.position.z * 31.71f); } private void Update() { float num = 0.84f + Mathf.PerlinNoise(_seed, Time.time * 7.5f) * 0.28f; for (int i = 0; i < _lights.Length; i++) { if ((Object)(object)_lights[i] != (Object)null) { _lights[i].intensity = _baseIntensities[i] * num; } } } } internal readonly struct WorkAnchor { internal readonly Vector3 Position; internal readonly float Radius; internal WorkAnchor(Vector3 position, float radius) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) Position = position; Radius = radius; } } internal static class WorkArea { private static float MaxLeash => Mathf.Max(20f, HfConfig.BannerMaxRange.Value); internal static List Anchors(Vector3 home, long ownerId, SettlerRole role) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) List list = new List { new WorkAnchor(home, Mathf.Max(8f, HfConfig.WorkRadius.Value)) }; foreach (WorkBanner instance in WorkBanner.Instances) { if (!((Object)(object)instance == (Object)null) && instance.IsValid && ((role != SettlerRole.Lumberjack && role != SettlerRole.Miner) || instance.Role == role) && !(Vector3.Distance(instance.Position, home) > MaxLeash)) { long ownerId2 = instance.OwnerId; if (ownerId == 0L || ownerId2 == 0L || ownerId2 == ownerId) { list.Add(new WorkAnchor(instance.Position, instance.Radius)); } } } return list; } internal static bool Contains(Vector3 point, List anchors) { //IL_0004: 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) for (int i = 0; i < anchors.Count; i++) { if (Vector3.Distance(point, anchors[i].Position) <= anchors[i].Radius) { return true; } } return false; } } internal sealed class WorkBanner : MonoBehaviour { internal static readonly List Instances = new List(); private ZNetView _nview; private Piece _piece; [SerializeField] private SettlerRole _role = SettlerRole.Lumberjack; internal bool IsValid { get { if ((Object)(object)_nview != (Object)null) { return _nview.IsValid(); } return false; } } internal Vector3 Position => ((Component)this).transform.position; internal float Radius => Mathf.Max(5f, HfConfig.BannerRadius.Value); internal SettlerRole Role => _role; internal string LocalizedName => Localization.instance.Localize((_role == SettlerRole.Miner) ? "$piece_hf_miner_banner" : "$piece_hf_lumber_banner"); internal long OwnerId { get { if (!((Object)(object)_piece != (Object)null)) { return 0L; } return _piece.GetCreator(); } } private void Awake() { _nview = ((Component)this).GetComponent(); _piece = ((Component)this).GetComponent(); if (!Instances.Contains(this)) { Instances.Add(this); } } private void OnDestroy() { Instances.Remove(this); } internal void Configure(SettlerRole role) { _role = ((role != SettlerRole.Miner) ? SettlerRole.Lumberjack : SettlerRole.Miner); } } } namespace Hearthfolk.Jobs { internal sealed class CaretakerJob : ISettlerJob { private enum ServiceKind { None, StructureRepair, ChestSort, ItemDrawerSort, FireplaceFuel, SmelterFuel, SmelterInput } private struct Candidate { internal GameObject Target; internal Container SourceStorage; internal ServiceKind Kind; internal string ItemName; internal string ItemPrefabName; internal int ItemQuality; internal string OrePrefabName; internal ItemDrawerBridge.Target DrawerTarget; internal int Amount; internal float Score; } private const float ScanInterval = 2f; private const float UseReach = 2.8f; private const float LowFraction = 0.35f; private const float FillFraction = 0.75f; private const float RepairBelowFraction = 0.9f; private const int MaxCarryBatch = 5; private static readonly Dictionary Reservations = new Dictionary(); private static readonly Dictionary RepairRetryAfter = new Dictionary(); private ServiceKind _serviceKind; private GameObject _serviceTarget; private int _reservedId; private string _itemName; private string _itemPrefabName; private int _itemQuality; private string _orePrefabName; private ItemDrawerBridge.Target _drawerTarget; private Container _sourceStorage; private int _remaining; private ItemDrop _dropTarget; private float _nextScan; private bool _lastScanMissingSupplies; private bool _lastScanNeedsHammer; private string _missingSupplyLabel; private string _missingTargetLabel; private float _toolRepairReadyAt; private float _toolRepairGiveUpUntil; public SettlerRole Role => SettlerRole.Caretaker; public void Enter(SettlerController s) { ClearService(); _dropTarget = null; _nextScan = 0f; _lastScanMissingSupplies = false; _lastScanNeedsHammer = false; _missingSupplyLabel = string.Empty; _missingTargetLabel = string.Empty; } public void Exit(SettlerController s) { s.StopWaitingSit(); ClearService(); _dropTarget = null; } public void Tick(SettlerController s) { List list = s.ResolveIntakeStorages(); Container val = list.FirstOrDefault() ?? s.ResolveStorage(); if (s.CaretakerTaskEnabled(CaretakerTasks.RepairStructures) && s.FindHammer() == null && s.HasBrokenHammer()) { s.StopWaitingSit(); if (RepairHammerTick(s)) { return; } } if (_serviceKind != ServiceKind.None) { s.StopWaitingSit(); if (!s.CaretakerTaskEnabled(TaskForService(_serviceKind))) { ClearService(); } else { if ((_serviceKind == ServiceKind.StructureRepair || (Object)(object)val != (Object)null) && ServiceTarget(s, val)) { return; } ClearService(); } } if (!string.IsNullOrEmpty(s.FindSortingCargoName())) { s.StopWaitingSit(); if (ReturnSortingCargo(s, val)) { return; } } if ((Object)(object)val != (Object)null && s.CaretakerTaskEnabled(CaretakerTasks.CollectOutputs) && PursueOutput(s)) { return; } if ((Object)(object)val != (Object)null && s.HasDepositableItems()) { s.StopWaitingSit(); if (s.HaulToStorage()) { return; } } if (Time.time >= _nextScan) { _nextScan = Time.time + 2f; if (TryFindService(s, val, list, out _lastScanMissingSupplies, out _lastScanNeedsHammer)) { s.StopWaitingSit(); ServiceTarget(s, val); return; } } string text = (((Object)(object)val == (Object)null) ? "$hf_status_no_storage" : (_lastScanMissingSupplies ? MissingSupplyStatus() : (_lastScanNeedsHammer ? "$hf_status_caretaker_need_hammer" : "$hf_status_caretaker_idle"))); if (!s.WaitAtSeat(text)) { s.ReturnHomeIfIdle(); s.SetStatus(text); } } private bool PursueOutput(SettlerController s) { //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_dropTarget == (Object)null || (Object)(object)_dropTarget.m_nview == (Object)null || !_dropTarget.m_nview.IsValid()) { _dropTarget = s.FindNearestCaretakerDrop(); if ((Object)(object)_dropTarget != (Object)null) { s.Hold(); } } if ((Object)(object)_dropTarget == (Object)null) { return false; } s.StopWaitingSit(); Vector3 position = ((Component)_dropTarget).transform.position; if (s.DistanceTo3D(position) <= 2.5f) { s.Hold(); if (!s.TryPickup(_dropTarget)) { s.BlacklistDrop(_dropTarget); } _dropTarget = null; s.ForceDropScan(); s.SetStatus("$hf_status_caretaker_collect"); return true; } s.GoTo(position, 1.2f, s.DistanceTo(position) > 8f); if (s.Ai.PathBlocked) { s.BlacklistDrop(_dropTarget); _dropTarget = null; return false; } s.SetStatus("$hf_status_caretaker_collect"); return true; } private bool ServiceTarget(SettlerController s, Container storage) { if ((Object)(object)_serviceTarget == (Object)null || !_serviceTarget.activeInHierarchy || _remaining <= 0) { return false; } if ((_serviceKind == ServiceKind.ChestSort || _serviceKind == ServiceKind.ItemDrawerSort) && !IsManagedStorage(s, _sourceStorage)) { return false; } if (_serviceKind == ServiceKind.ChestSort && !IsManagedStorage(s, _serviceTarget.GetComponent())) { return false; } if (_serviceKind == ServiceKind.ItemDrawerSort && (_drawerTarget == null || !_drawerTarget.Matches(_itemPrefabName, _itemQuality))) { return false; } if (!StillNeedsService()) { return false; } if (_serviceKind == ServiceKind.StructureRepair) { return RepairStructure(s); } if (s.InventoryItemCount(_itemName) <= 0) { Container val = ((_serviceKind == ServiceKind.ChestSort || _serviceKind == ServiceKind.ItemDrawerSort) ? _sourceStorage : FindSupplyStorage(s, storage, _itemName)); if ((Object)(object)val == (Object)null) { _lastScanMissingSupplies = _serviceKind != ServiceKind.ChestSort; if (_lastScanMissingSupplies) { MarkMissingSupply(_itemName, _serviceTarget); } return false; } if (!s.CanInteractWith(((Component)val).gameObject, 2.8f)) { s.Approach(((Component)val).gameObject, 2.38f, run: true); if (s.Ai.PathBlocked) { _nextScan = Time.time + 8f; return false; } s.SetStatus((_serviceKind == ServiceKind.ChestSort || _serviceKind == ServiceKind.ItemDrawerSort) ? "$hf_status_caretaker_sort_fetch" : "$hf_status_caretaker_fetch"); return true; } s.Hold(); int requested = ((_serviceKind == ServiceKind.ChestSort || _serviceKind == ServiceKind.ItemDrawerSort) ? _remaining : Mathf.Clamp(_remaining, 1, 5)); if (s.WithdrawFromStorage(val, _itemName, requested, _serviceKind == ServiceKind.ChestSort || _serviceKind == ServiceKind.ItemDrawerSort, (_serviceKind == ServiceKind.ItemDrawerSort) ? _itemPrefabName : null, (_serviceKind == ServiceKind.ItemDrawerSort) ? _itemQuality : 0) <= 0) { _lastScanMissingSupplies = _serviceKind != ServiceKind.ChestSort; if (_lastScanMissingSupplies) { MarkMissingSupply(_itemName, _serviceTarget); } _nextScan = Time.time + 5f; s.SetStatus((_serviceKind == ServiceKind.ChestSort || _serviceKind == ServiceKind.ItemDrawerSort) ? "$hf_status_caretaker_sort" : MissingSupplyStatus()); return false; } } if (!((_serviceKind == ServiceKind.ItemDrawerSort) ? ItemDrawerBridge.CanReach(s, _drawerTarget, 3.55f) : s.CanInteractWith(_serviceTarget, 2.8f))) { s.Approach(_serviceTarget, (_serviceKind == ServiceKind.ItemDrawerSort) ? 1.6800001f : 2.24f, run: true); if (s.Ai.PathBlocked) { _nextScan = Time.time + 8f; return false; } s.SetStatus(StatusForService()); return true; } s.Hold(); if (!StillNeedsService()) { return false; } if (_serviceKind == ServiceKind.ChestSort || _serviceKind == ServiceKind.ItemDrawerSort) { int num = ((_serviceKind == ServiceKind.ChestSort) ? s.DepositInventoryItem(_serviceTarget.GetComponent(), _itemName, _remaining) : ItemDrawerBridge.Deposit(s.Inv, _drawerTarget, _itemName, _itemPrefabName, _itemQuality, _remaining)); if (num <= 0) { return false; } _remaining -= num; s.SetStatus("$hf_status_caretaker_sort"); if (_remaining <= 0) { ClearService(); } return true; } if (!s.ConsumeInventoryItem(_itemName)) { return true; } switch (_serviceKind) { case ServiceKind.FireplaceFuel: { Fireplace component = _serviceTarget.GetComponent(); if (component != null) { component.AddFuel(1f); } break; } case ServiceKind.SmelterFuel: { ZNetView view2 = GetView((Component)(object)_serviceTarget.GetComponent()); if (view2 != null) { view2.InvokeRPC("RPC_AddFuel", Array.Empty()); } break; } case ServiceKind.SmelterInput: { ZNetView view = GetView((Component)(object)_serviceTarget.GetComponent()); if (view != null) { view.InvokeRPC("RPC_AddOre", new object[1] { _orePrefabName }); } break; } } _remaining--; s.SetStatus(StatusForService()); if (_remaining <= 0) { ClearService(); } return true; } private bool ReturnSortingCargo(SettlerController s, Container storage) { string text = s.FindSortingCargoName(); if (string.IsNullOrEmpty(text)) { return false; } if ((Object)(object)storage == (Object)null) { s.Hold(); s.SetStatus("$hf_status_no_storage"); return true; } if (!s.CanInteractWith(((Component)storage).gameObject, 2.8f)) { s.Approach(((Component)storage).gameObject, 2.38f, run: true); s.SetStatus("$hf_status_caretaker_sort_return"); return true; } s.Hold(); if (ContainerInUse(storage)) { s.SetStatus("$hf_status_caretaker_sort_return"); return true; } s.DepositInventoryItem(storage, text, int.MaxValue); s.SetStatus("$hf_status_caretaker_sort_return"); return true; } private string StatusForService() { return _serviceKind switch { ServiceKind.FireplaceFuel => "$hf_status_caretaker_fire", ServiceKind.StructureRepair => "$hf_status_caretaker_repair_base", ServiceKind.ChestSort => "$hf_status_caretaker_sort", ServiceKind.ItemDrawerSort => "$hf_status_caretaker_sort", ServiceKind.SmelterFuel => "$hf_status_caretaker_fuel", ServiceKind.SmelterInput => "$hf_status_caretaker_input", _ => "$hf_status_caretaker_idle", }; } private bool StillNeedsService() { switch (_serviceKind) { case ServiceKind.FireplaceFuel: { Fireplace component2 = _serviceTarget.GetComponent(); ZNetView view2 = GetView((Component)(object)component2); if ((Object)(object)component2 != (Object)null && (Object)(object)view2 != (Object)null && view2.IsValid()) { return (float)Mathf.CeilToInt(view2.GetZDO().GetFloat(ZDOVars.s_fuel, 0f)) < component2.m_maxFuel; } return false; } case ServiceKind.StructureRepair: { WearNTear component3 = _serviceTarget.GetComponent(); if ((Object)(object)component3 != (Object)null) { return HealthFraction(component3) < 0.999f; } return false; } case ServiceKind.ChestSort: { Container component4 = _serviceTarget.GetComponent(); if ((Object)(object)component4 != (Object)null && (Object)(object)component4.m_nview != (Object)null && component4.m_nview.IsValid()) { return !ContainerInUse(component4); } return false; } case ServiceKind.ItemDrawerSort: if (_drawerTarget != null) { return _drawerTarget.Matches(_itemPrefabName, _itemQuality); } return false; case ServiceKind.SmelterFuel: { Smelter component5 = _serviceTarget.GetComponent(); ZNetView view3 = GetView((Component)(object)component5); if ((Object)(object)component5 != (Object)null && (Object)(object)view3 != (Object)null && view3.IsValid()) { return view3.GetZDO().GetFloat(ZDOVars.s_fuel, 0f) <= (float)component5.m_maxFuel - 1f; } return false; } case ServiceKind.SmelterInput: { Smelter component = _serviceTarget.GetComponent(); ZNetView view = GetView((Component)(object)component); if ((Object)(object)component != (Object)null && (Object)(object)view != (Object)null && view.IsValid() && view.GetZDO().GetInt(ZDOVars.s_queued, 0) < component.m_maxOre) { return component.m_conversion.Any((ItemConversion c) => c != null && (Object)(object)c.m_from != (Object)null && ((Object)((Component)c.m_from).gameObject).name == _orePrefabName); } return false; } default: return false; } } private bool TryFindService(SettlerController s, Container storage, List intakeStorages, out bool missingSupplies, out bool needsHammer) { //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_01c4: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Unknown result type (might be due to invalid IL or missing references) //IL_06d4: Unknown result type (might be due to invalid IL or missing references) //IL_06e0: Unknown result type (might be due to invalid IL or missing references) missingSupplies = false; needsHammer = false; _missingSupplyLabel = string.Empty; _missingTargetLabel = string.Empty; Candidate best = default(Candidate); bool haveBest = false; ItemData val = s.FindHammer(); WearNTear[] array = SceneObjectCache.Get(1f); foreach (WearNTear val2 in array) { if (!s.CaretakerTaskEnabled(CaretakerTasks.RepairStructures) || !IsRepairablePiece(s, val2) || !CanReserve(((Component)val2).gameObject) || !CanRetryRepair(((Component)val2).gameObject)) { continue; } float num = HealthFraction(val2); if (!(num >= 0.9f)) { if (val == null) { needsHammer = true; continue; } Consider(ref best, ref haveBest, new Candidate { Target = ((Component)val2).gameObject, Kind = ServiceKind.StructureRepair, Amount = 1, Score = num + Vector3.Distance(s.Position, ((Component)val2).transform.position) * 1E-05f }); } } if (haveBest) { return BeginService(best); } if ((Object)(object)storage == (Object)null) { return false; } List storages = FindManagedStorages(s); Smelter[] array2 = SceneObjectCache.Get(1f); foreach (Smelter val3 in array2) { if (!IsManagedPiece(s, (Component)(object)val3) || !CanReserve(((Component)val3).gameObject)) { continue; } ZNetView view = GetView((Component)(object)val3); if ((Object)(object)view == (Object)null || !view.IsValid()) { continue; } ZDO zDO = view.GetZDO(); float num2 = Vector3.Distance(s.Position, ((Component)val3).transform.position); if (s.CaretakerTaskEnabled(CaretakerTasks.FuelMachines) && val3.m_maxFuel > 0 && (Object)(object)val3.m_fuelItem != (Object)null) { float num3 = zDO.GetFloat(ZDOVars.s_fuel, 0f); if (num3 <= (float)val3.m_maxFuel * 0.35f) { string name = val3.m_fuelItem.m_itemData.m_shared.m_name; int amount = Mathf.Max(1, Mathf.CeilToInt((float)val3.m_maxFuel * 0.75f - num3)); if (HasSupply(s, storages, name)) { Consider(ref best, ref haveBest, new Candidate { Target = ((Component)val3).gameObject, Kind = ServiceKind.SmelterFuel, ItemName = name, Amount = amount, Score = ((num3 <= 0f) ? 0f : (1f + num3 / (float)val3.m_maxFuel)) + num2 * 0.001f }); } else { missingSupplies = true; MarkMissingSupply(name, ((Component)val3).gameObject, ((Object)((Component)val3.m_fuelItem).gameObject).name); } } } if (!s.CaretakerTaskEnabled(CaretakerTasks.LoadMachines) || val3.m_maxOre <= 0 || val3.m_conversion == null || val3.m_conversion.Count == 0) { continue; } int num4 = zDO.GetInt(ZDOVars.s_queued, 0); if ((float)num4 > (float)val3.m_maxOre * 0.35f) { continue; } string queuedPrefab = ((num4 > 0) ? zDO.GetString(ZDOVars.s_item0, "") : string.Empty); ItemConversion val4 = ((!string.IsNullOrEmpty(queuedPrefab)) ? ((IEnumerable)val3.m_conversion).FirstOrDefault((Func)((ItemConversion c) => c != null && (Object)(object)c.m_from != (Object)null && ((Object)((Component)c.m_from).gameObject).name == queuedPrefab)) : ((IEnumerable)val3.m_conversion).FirstOrDefault((Func)((ItemConversion c) => c != null && (Object)(object)c.m_from != (Object)null && HasSupply(s, storages, c.m_from.m_itemData.m_shared.m_name)))); if (val4 == null || (Object)(object)val4.m_from == (Object)null) { missingSupplies = true; ItemConversion val5 = ((IEnumerable)val3.m_conversion).FirstOrDefault((Func)((ItemConversion c) => c != null && (Object)(object)c.m_from != (Object)null)); string sharedName = val5?.m_from?.m_itemData?.m_shared?.m_name; GameObject gameObject = ((Component)val3).gameObject; object prefabName; if (val5 == null) { prefabName = null; } else { ItemDrop obj = val5.m_from; prefabName = ((obj != null) ? ((Object)((Component)obj).gameObject).name : null); } MarkMissingSupply(sharedName, gameObject, (string)prefabName); continue; } string name2 = val4.m_from.m_itemData.m_shared.m_name; if (!HasSupply(s, storages, name2)) { missingSupplies = true; MarkMissingSupply(name2, ((Component)val3).gameObject, ((Object)((Component)val4.m_from).gameObject).name); continue; } Consider(ref best, ref haveBest, new Candidate { Target = ((Component)val3).gameObject, Kind = ServiceKind.SmelterInput, ItemName = name2, OrePrefabName = ((Object)((Component)val4.m_from).gameObject).name, Amount = Mathf.Max(1, Mathf.CeilToInt((float)val3.m_maxOre * 0.75f) - num4), Score = ((num4 <= 0) ? 0.25f : (1.25f + (float)num4 / (float)val3.m_maxOre)) + num2 * 0.001f }); } if (!haveBest && s.CaretakerTaskEnabled(CaretakerTasks.FuelFires)) { Fireplace[] array3 = SceneObjectCache.Get(1f); foreach (Fireplace val6 in array3) { if (!IsManagedPiece(s, (Component)(object)val6) || !CanReserve(((Component)val6).gameObject) || val6.m_infiniteFuel || !val6.m_canRefill || (Object)(object)val6.m_fuelItem == (Object)null || val6.m_maxFuel <= 0f) { continue; } ZNetView view2 = GetView((Component)(object)val6); if ((Object)(object)view2 == (Object)null || !view2.IsValid()) { continue; } float num5 = view2.GetZDO().GetFloat(ZDOVars.s_fuel, 0f); if (!(num5 > val6.m_maxFuel * 0.35f)) { string name3 = val6.m_fuelItem.m_itemData.m_shared.m_name; if (!HasSupply(s, storages, name3)) { missingSupplies = true; MarkMissingSupply(name3, ((Component)val6).gameObject, ((Object)((Component)val6.m_fuelItem).gameObject).name); continue; } float num6 = Vector3.Distance(s.Position, ((Component)val6).transform.position); Consider(ref best, ref haveBest, new Candidate { Target = ((Component)val6).gameObject, Kind = ServiceKind.FireplaceFuel, ItemName = name3, Amount = Mathf.Max(1, Mathf.CeilToInt(val6.m_maxFuel * 0.75f - num5)), Score = 10f + num5 / val6.m_maxFuel + num6 * 0.001f }); } } } if (!haveBest && s.CaretakerTaskEnabled(CaretakerTasks.SortStorage)) { foreach (Container intakeStorage in intakeStorages) { if (TryFindSortCandidate(s, intakeStorage, intakeStorages, storages, out var candidate)) { Consider(ref best, ref haveBest, candidate); } } } if (!haveBest) { return false; } return BeginService(best); } private static CaretakerTasks TaskForService(ServiceKind kind) { switch (kind) { case ServiceKind.StructureRepair: return CaretakerTasks.RepairStructures; case ServiceKind.ChestSort: case ServiceKind.ItemDrawerSort: return CaretakerTasks.SortStorage; case ServiceKind.FireplaceFuel: return CaretakerTasks.FuelFires; case ServiceKind.SmelterFuel: return CaretakerTasks.FuelMachines; case ServiceKind.SmelterInput: return CaretakerTasks.LoadMachines; default: return CaretakerTasks.All; } } private void MarkMissingSupply(string sharedName, GameObject target, string prefabName = null) { if (string.IsNullOrEmpty(_missingSupplyLabel)) { _missingSupplyLabel = FriendlyName(string.IsNullOrEmpty(prefabName) ? sharedName : prefabName); _missingTargetLabel = FriendlyName(((Object)(object)target != (Object)null) ? ((Object)target).name : "production machine"); } } private string MissingSupplyStatus() { if (string.IsNullOrEmpty(_missingSupplyLabel)) { return "$hf_status_caretaker_no_supplies"; } if (!string.IsNullOrEmpty(_missingTargetLabel)) { return "Missing " + _missingSupplyLabel + " for " + _missingTargetLabel; } return "Missing " + _missingSupplyLabel; } private static string FriendlyName(string raw) { if (string.IsNullOrEmpty(raw)) { return "supplies"; } raw = raw.Replace("(Clone)", string.Empty).Trim().TrimStart(new char[1] { '$' }); if (raw.StartsWith("item_")) { raw = raw.Substring(5); } if (raw.StartsWith("piece_")) { raw = raw.Substring(6); } switch (raw.ToLowerInvariant()) { case "fire_pit": return "Campfire"; case "charcoal_kiln": return "Charcoal kiln"; case "blastfurnace": return "Blast furnace"; case "spinningwheel": return "Spinning wheel"; case "piece_oven": case "oven": return "Stone oven"; case "copperore": return "Copper ore"; case "tinore": return "Tin ore"; case "ironore": return "Iron ore"; case "silverore": return "Silver ore"; case "flametalore": return "Flametal ore"; case "blackmetalscrap": return "Black metal scrap"; case "roundlog": return "Core wood"; default: { StringBuilder stringBuilder = new StringBuilder(raw.Length + 8); for (int i = 0; i < raw.Length; i++) { char c = raw[i]; if (c == '_' || c == '-') { stringBuilder.Append(' '); continue; } if (i > 0 && char.IsUpper(c) && raw[i - 1] != ' ') { stringBuilder.Append(' '); } stringBuilder.Append(c); } string text = stringBuilder.ToString().Trim().ToLowerInvariant(); if (text.Length != 0) { return char.ToUpperInvariant(text[0]) + text.Substring(1); } return "supplies"; } } } private bool BeginService(Candidate best) { if (!Reserve(best.Target)) { return false; } _serviceTarget = best.Target; _serviceKind = best.Kind; _itemName = best.ItemName; _itemPrefabName = best.ItemPrefabName; _itemQuality = best.ItemQuality; _orePrefabName = best.OrePrefabName; _drawerTarget = best.DrawerTarget; _sourceStorage = best.SourceStorage; _remaining = best.Amount; _dropTarget = null; Diagnostics.Log($"Hearthfolk[caretaker]: target={_serviceKind} item={_itemName} amount={_remaining}"); return true; } private bool RepairStructure(SettlerController s) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) WearNTear component = _serviceTarget.GetComponent(); ItemData val = s.FindHammer(); if (!IsRepairablePiece(s, component) || val == null) { _lastScanNeedsHammer = val == null; return false; } Vector3 point = RepairPoint(component, s.Position); if (!s.CanInteractWith(((Component)component).gameObject, 2.8f)) { s.Approach(((Component)component).gameObject, 1.9599999f, run: true); if (s.Ai.PathBlocked) { RepairRetryAfter[((Object)((Component)component).gameObject).GetInstanceID()] = Time.time + 20f; return false; } s.SetStatus("$hf_status_caretaker_repair_base"); return true; } s.Hold(); if (component.Repair()) { Piece component2 = ((Component)component).GetComponent(); s.AnimateToolUse(val, point); s.SpendDurability(val); if (component2 != null) { component2.m_placeEffect.Create(((Component)component2).transform.position, ((Component)component2).transform.rotation, (Transform)null, 1f, -1); } Diagnostics.Log("Hearthfolk[caretaker]: repaired " + ((Object)((Component)component).gameObject).name); } _remaining = 0; s.SetStatus("$hf_status_caretaker_repair_base"); ClearService(); return true; } private bool RepairHammerTick(SettlerController s) { //IL_0028: 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) if (Time.time < _toolRepairGiveUpUntil) { return false; } CraftingStation val = s.FindNearestCraftingStation(); if ((Object)(object)val == (Object)null) { return false; } if (s.DistanceTo(((Component)val).transform.position) > 2.5f) { s.GoTo(((Component)val).transform.position, 2f, run: true); if (s.Ai.PathBlocked) { _toolRepairGiveUpUntil = Time.time + 30f; return false; } _toolRepairReadyAt = 0f; s.SetStatus("$hf_status_repair"); return true; } s.Hold(); if (_toolRepairReadyAt <= 0f) { _toolRepairReadyAt = Time.time + 2.5f; } else if (Time.time >= _toolRepairReadyAt) { s.RepairAllTools(); _toolRepairReadyAt = 0f; } s.SetStatus("$hf_status_repair"); return true; } private static bool IsRepairablePiece(SettlerController s, WearNTear wear) { //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) if (!IsManagedPiece(s, (Component)(object)wear) || wear.m_health <= 0f || HealthFraction(wear) <= 0f) { return false; } Piece val = ((Component)wear).GetComponent() ?? ((Component)wear).GetComponentInParent(); if ((Object)(object)val == (Object)null || (Object)(object)((Component)wear).GetComponentInParent() != (Object)null || (Object)(object)((Component)wear).GetComponentInParent() != (Object)null || !PrivateArea.CheckAccess(((Component)val).transform.position, 0f, false, false)) { return false; } bool flag = (Object)(object)ZoneSystem.instance != (Object)null && ZoneSystem.instance.GetGlobalKey((GlobalKeys)22); if (!((Object)(object)val.m_craftingStation == (Object)null || flag)) { return Object.op_Implicit((Object)(object)CraftingStation.HaveBuildStationInRange(val.m_craftingStation.m_name, ((Component)val).transform.position)); } return true; } private static float HealthFraction(WearNTear wear) { ZNetView view = GetView((Component)(object)wear); if ((Object)(object)wear == (Object)null || (Object)(object)view == (Object)null || !view.IsValid() || wear.m_health <= 0f) { return 1f; } return Mathf.Clamp01(view.GetZDO().GetFloat(ZDOVars.s_health, wear.m_health) / wear.m_health); } private static Vector3 RepairPoint(WearNTear wear, Vector3 from) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_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_004b: 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_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) Vector3 val = ((Component)wear).transform.position; float num = Vector3.Distance(from, val); Collider[] componentsInChildren = ((Component)wear).GetComponentsInChildren(); foreach (Collider val2 in componentsInChildren) { if (!((Object)(object)val2 == (Object)null) && val2.enabled && !val2.isTrigger) { Bounds bounds = val2.bounds; Vector3 val3 = ((Bounds)(ref bounds)).ClosestPoint(from); float num2 = Vector3.Distance(from, val3); if (num2 < num) { val = val3; num = num2; } } } return val; } private static bool CanRetryRepair(GameObject target) { int instanceID = ((Object)target).GetInstanceID(); if (!RepairRetryAfter.TryGetValue(instanceID, out var value)) { return true; } if (Time.time < value) { return false; } RepairRetryAfter.Remove(instanceID); return true; } private static bool HasSupply(SettlerController s, IEnumerable storages, string itemName) { if (s.InventoryItemCount(itemName) <= 0) { return storages.Any((Container storage) => s.StorageItemCount(storage, itemName) > 0); } return true; } private static Container FindSupplyStorage(SettlerController s, Container preferred, string itemName) { //IL_004f: Unknown result type (might be due to invalid IL or missing references) if (IsManagedStorage(s, preferred) && s.StorageItemCount(preferred, itemName) > 0) { return preferred; } Container result = null; float num = float.MaxValue; foreach (Container item in FindManagedStorages(s)) { if (!((Object)(object)item == (Object)(object)preferred) && s.StorageItemCount(item, itemName) > 0) { float num2 = s.DistanceTo(((Component)item).transform.position); if (num2 < num) { result = item; num = num2; } } } return result; } private static bool TryFindSortCandidate(SettlerController s, Container inbox, List intakeStorages, List storages, out Candidate candidate) { //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_027f: Unknown result type (might be due to invalid IL or missing references) //IL_028b: Unknown result type (might be due to invalid IL or missing references) candidate = default(Candidate); Inventory val = ((inbox != null) ? inbox.GetInventory() : null); if (val == null || ContainerInUse(inbox)) { return false; } bool haveBest = false; List list = ItemDrawerBridge.FindTargets(s); foreach (ItemData allItem in val.GetAllItems()) { if (allItem == null || allItem.m_stack <= 0 || allItem.m_equipped || !ChestSortRules.IsSortable(allItem) || s.InventoryItemCount(allItem.m_shared.m_name) > 0) { continue; } foreach (ItemDrawerBridge.Target item in list) { if (ItemDrawerBridge.CanStore(allItem, item) && CanReserve(item.GameObject)) { Consider(ref candidate, ref haveBest, new Candidate { Target = item.GameObject, SourceStorage = inbox, DrawerTarget = item, Kind = ServiceKind.ItemDrawerSort, ItemName = allItem.m_shared.m_name, ItemPrefabName = ((Object)allItem.m_dropPrefab).name, ItemQuality = allItem.m_quality, Amount = allItem.m_stack, Score = -10f + Vector3.Distance(s.Position, item.Position) * 0.001f }); } } foreach (Container storage in storages) { if (intakeStorages.Contains(storage) || !CanReserve(((Component)storage).gameObject)) { continue; } Inventory inventory = storage.GetInventory(); if (inventory != null && ChestSortRules.Accepts(storage, allItem.m_shared.m_name)) { int num = inventory.FindFreeStackSpace(allItem.m_shared.m_name, (float)allItem.m_worldLevel); int num2 = num + inventory.GetEmptySlots() * allItem.m_shared.m_maxStackSize; int num3 = Mathf.Min(allItem.m_stack, num2); if (num3 > 0) { Consider(ref candidate, ref haveBest, new Candidate { Target = ((Component)storage).gameObject, SourceStorage = inbox, Kind = ServiceKind.ChestSort, ItemName = allItem.m_shared.m_name, Amount = num3, Score = ((num > 0) ? 0f : 1f) + Vector3.Distance(s.Position, ((Component)storage).transform.position) * 0.001f }); } } } } return haveBest; } private static List FindManagedStorages(SettlerController s) { List list = new List(); Container[] array = SceneObjectCache.Get(1f); foreach (Container val in array) { if (IsManagedStorage(s, val)) { list.Add(val); } } return list; } private static bool IsManagedStorage(SettlerController s, Container storage) { //IL_0063: 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_00b3: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)storage == (Object)null || storage is SettlerInventory || !((Component)storage).gameObject.activeInHierarchy || (Object)(object)storage.m_nview == (Object)null || !storage.m_nview.IsValid() || ContainerInUse(storage) || (Object)(object)storage.m_wagon != (Object)null || (Object)(object)((Component)storage).GetComponentInParent() != (Object)null || Vector3.Distance(((Component)storage).transform.position, s.Home) > s.WorkRadius) { return false; } Piece val = ((Component)storage).GetComponent() ?? ((Component)storage).GetComponentInParent(); if ((Object)(object)val != (Object)null && val.IsPlacedByPlayer() && storage.CheckAccess(s.SettlementOwnerId)) { return PrivateArea.CheckAccess(((Component)storage).transform.position, 0f, false, false); } return false; } private static bool ContainerInUse(Container storage) { if (!((Object)(object)storage == (Object)null) && !storage.IsInUse()) { if ((Object)(object)storage.m_nview != (Object)null && storage.m_nview.IsValid()) { return storage.m_nview.GetZDO().GetInt(ZDOVars.s_inUse, 0) == 1; } return false; } return true; } private static bool IsManagedPiece(SettlerController s, Component component) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)component == (Object)null || !component.gameObject.activeInHierarchy || Vector3.Distance(component.transform.position, s.Home) > s.WorkRadius) { return false; } Piece val = component.GetComponent() ?? component.GetComponentInParent(); if ((Object)(object)val != (Object)null) { return val.IsPlacedByPlayer(); } return false; } private static ZNetView GetView(Component component) { object obj; if (!((Object)(object)component == (Object)null)) { obj = component.GetComponent(); if (obj == null) { return component.GetComponentInParent(); } } else { obj = null; } return (ZNetView)obj; } private static void Consider(ref Candidate best, ref bool haveBest, Candidate candidate) { if (!haveBest || candidate.Score < best.Score) { best = candidate; haveBest = true; } } private static bool CanReserve(GameObject target) { if ((Object)(object)target == (Object)null) { return false; } if (Reservations.TryGetValue(((Object)target).GetInstanceID(), out var value)) { return value == null; } return true; } private bool Reserve(GameObject target) { if (!CanReserve(target)) { return false; } _reservedId = ((Object)target).GetInstanceID(); Reservations[_reservedId] = this; return true; } private void ClearService() { if (_reservedId != 0 && Reservations.TryGetValue(_reservedId, out var value) && value == this) { Reservations.Remove(_reservedId); } _reservedId = 0; _serviceKind = ServiceKind.None; _serviceTarget = null; _itemName = null; _itemPrefabName = null; _itemQuality = 0; _orePrefabName = null; _drawerTarget = null; _sourceStorage = null; _remaining = 0; } } internal sealed class FarmerJob : ISettlerJob { private FarmMarker _plantMarker; private FarmCrop _plantCrop; private Vector3? _plantPoint; private Pickable _harvestTarget; private FarmMarker _harvestMarker; private ItemDrop _dropTarget; private float _nextScan; private string _idleStatus; private float _repairReadyAt; private float _repairGiveUpUntil; private Vector3 _lastPosition; private float _stuckTime; private readonly Dictionary _stockCacheUntil = new Dictionary(); private readonly Dictionary _stockCacheReached = new Dictionary(); public SettlerRole Role => SettlerRole.Farmer; public void Enter(SettlerController s) { ClearTargets(); _stockCacheUntil.Clear(); _stockCacheReached.Clear(); _nextScan = 0f; _idleStatus = null; ResetStuck(s); } public void Exit(SettlerController s) { ClearTargets(); _idleStatus = null; s.StopWaitingSit(); } public void Tick(SettlerController s) { //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_040f: Unknown result type (might be due to invalid IL or missing references) //IL_0555: Unknown result type (might be due to invalid IL or missing references) ItemData val = s.FindCultivator(); if (s.FarmerCanPlant && val == null) { ClearTargets(); if (!s.HasBrokenCultivator() || !RepairTick(s)) { RestWhenIdle(s, "$hf_status_farmer_need_cultivator"); } return; } if (val != null) { s.EquipTool(val); } Container storage = s.ResolveStorage(); if ((Object)(object)storage == (Object)null) { ClearTargets(); RestWhenIdle(s, "$hf_status_no_storage"); return; } List list = FarmMarker.MarkersFor(s.Home, s.SettlementOwnerId); HashSet assignedIds = (s.FarmerMarkersConfigured ? new HashSet(s.FarmerMarkerIds) : null); List list2 = ((assignedIds == null) ? list : list.Where((FarmMarker marker) => assignedIds.Contains(marker.PersistentId)).ToList()); List markers = list2.Where((FarmMarker marker) => s.FarmerCropEnabled(marker.Crop)).ToList(); List markers2 = (s.FarmerCanHarvest ? markers : new List()); List list3 = (s.FarmerCanPlant ? markers.Where((FarmMarker marker) => !StockTargetReached(s, storage, marker, markers)).ToList() : new List()); int num = s.FarmCargoCount(); if (num > 0 && (markers.Count == 0 || num >= Mathf.Max(1, HfConfig.DepositThreshold.Value) || !s.HasSpaceForWood())) { ResumeWork(s); ClearTargets(); if (HaulHarvest(s, storage)) { return; } } if (markers.Count == 0) { ClearTargets(); string status = ((list.Count == 0) ? "$hf_status_farmer_no_field" : ((list2.Count == 0) ? "$hf_status_farmer_no_assigned_field" : "$hf_status_farmer_no_allowed_field")); RestWhenIdle(s, status); return; } if (num >= Mathf.Max(1, HfConfig.DepositThreshold.Value) || (num > 0 && !s.HasSpaceForWood())) { ResumeWork(s); ClearTargets(); if (HaulHarvest(s, storage)) { return; } } if (DropTick(s, markers2) || HarvestTick(s) || PlantTick(s, storage, val, list3)) { return; } if (Time.time < _nextScan) { if (!string.IsNullOrEmpty(_idleStatus)) { RestWhenIdle(s, _idleStatus); } else { s.Hold(); } return; } _nextScan = Time.time + 1f; _dropTarget = FindFarmDrop(s, markers2); if ((Object)(object)_dropTarget != (Object)null) { ResumeWork(s); return; } FindMatureCrop(s, markers2, out _harvestTarget, out _harvestMarker); if ((Object)(object)_harvestTarget != (Object)null) { ResumeWork(s); return; } if (s.FarmCargoCount() > 0) { ResumeWork(s); HaulHarvest(s, storage); return; } foreach (FarmMarker item in list3) { foreach (FarmCrop item2 in PlantingCrops(item)) { if (s.InventoryItemCount(item2.SeedSharedName) > 0 && (!IsRecoveryPartner(item, item2) || NeedsCyclePartner(s, storage, item, item2))) { Vector3? val2 = FindPlantPoint(item, item2); if (val2.HasValue) { SelectPlantTarget(s, item, item2, val2.Value); return; } } } } string text = string.Empty; foreach (FarmMarker item3 in list3) { foreach (FarmCrop item4 in PlantingCrops(item3)) { bool flag = IsCyclePartner(item3, item4); if (IsRecoveryPartner(item3, item4) && !NeedsCyclePartner(s, storage, item3, item4)) { continue; } Vector3? val3 = FindPlantPoint(item3, item4); if (val3.HasValue) { int num2 = ((!IsRecoveryPartner(item3, item4)) ? Mathf.Max(0, HfConfig.FarmSeedReserve.Value) : 0); int num3 = s.StorageItemCount(storage, item4.SeedSharedName); if (s.InventoryItemCount(item4.SeedSharedName) > 0 || num3 > num2) { SelectPlantTarget(s, item3, item4, val3.Value); return; } if ((!flag || item3.CombinedCycle) && string.IsNullOrEmpty(text)) { text = item4.SeedPrefabName; } } } } string status2 = (string.IsNullOrEmpty(text) ? "$hf_status_farmer_waiting" : ("Missing " + FarmCropCatalog.FriendlyName(text) + " above reserve")); RestWhenIdle(s, status2); } private bool DropTick(SettlerController s, List markers) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_dropTarget == (Object)null) { return false; } if (!ValidDrop(_dropTarget, markers)) { _dropTarget = null; return false; } Vector3 position = ((Component)_dropTarget).transform.position; if (s.DistanceTo3D(position) <= 2.5f) { s.Hold(); s.TryPickup(_dropTarget, farmCargo: true); _dropTarget = null; _nextScan = 0f; ResetStuck(s); return true; } s.GoTo(position, 1.2f, s.DistanceTo(position) > 8f); if (s.Ai.PathBlocked) { _dropTarget = null; _nextScan = Time.time + 1f; ResetStuck(s); return false; } s.SetStatus("$hf_status_farmer_collect"); return true; } private bool HarvestTick(SettlerController s) { //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: 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_00e0: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_harvestTarget == (Object)null) { return false; } if ((Object)(object)_harvestMarker == (Object)null || !_harvestMarker.IsValid || !s.FarmerCanHarvest || !s.FarmerMarkerEnabled(_harvestMarker) || !s.FarmerCropEnabled(_harvestMarker.Crop) || !_harvestTarget.CanBePicked() || !MatchesCropFamily(_harvestTarget, _harvestMarker.Crop) || Vector3.Distance(((Component)_harvestTarget).transform.position, _harvestMarker.Position) > _harvestMarker.Radius) { _harvestTarget = null; _harvestMarker = null; return false; } Vector3 position = ((Component)_harvestTarget).transform.position; if (s.DistanceTo(position) > 2.1f) { s.GoTo(position, 1.4f, s.DistanceTo(position) > 8f); if (s.Ai.PathBlocked) { _harvestTarget = null; _harvestMarker = null; ResetStuck(s); return false; } s.SetStatus("$hf_status_farmer_move_harvest"); return true; } s.Hold(); if (_harvestTarget.Interact(s.Char, false, false)) { s.PlayInteractionGesture(); } _harvestTarget = null; _harvestMarker = null; _nextScan = Time.time + 0.25f; ResetStuck(s); s.SetStatus("$hf_status_farmer_harvest"); return true; } private bool PlantTick(SettlerController s, Container storage, ItemData cultivator, List plantMarkers) { //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_0177: 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_018c: Unknown result type (might be due to invalid IL or missing references) //IL_020f: Unknown result type (might be due to invalid IL or missing references) if (!_plantPoint.HasValue || (Object)(object)_plantMarker == (Object)null || !_plantMarker.IsValid || _plantCrop == null || !plantMarkers.Contains(_plantMarker) || !FarmCropCatalog.IsCycleCrop(_plantMarker.Crop, _plantCrop)) { ClearPlantTarget(); return false; } if (s.InventoryItemCount(_plantCrop.SeedSharedName) <= 0) { bool flag = IsRecoveryPartner(_plantMarker, _plantCrop); int num = ((!flag) ? Mathf.Max(0, HfConfig.FarmSeedReserve.Value) : 0); int num2 = s.StorageItemCount(storage, _plantCrop.SeedSharedName) - num; if (num2 <= 0) { s.Hold(); s.SetStatus("Missing " + FarmCropCatalog.FriendlyName(_plantCrop.SeedPrefabName) + " above reserve"); return true; } if (!s.CanInteractWith(((Component)storage).gameObject, 2.8f)) { s.Approach(((Component)storage).gameObject, 2.38f, run: true); s.SetStatus("$hf_status_farmer_fetch_seed"); return true; } s.Hold(); int requested = (flag ? Mathf.Min(1, num2) : num2); if (s.WithdrawAvailableFromStorage(storage, _plantCrop.SeedSharedName, requested) <= 0) { s.SetStatus("Missing " + FarmCropCatalog.FriendlyName(_plantCrop.SeedPrefabName) + " above reserve"); return true; } } Vector3 value = _plantPoint.Value; if (s.DistanceTo(value) > 1.7f) { s.GoTo(value, 1.1f, s.DistanceTo(value) > 8f); if (s.Ai.PathBlocked) { ClearPlantTarget(); ResetStuck(s); return false; } s.SetStatus("$hf_status_farmer_move_plant"); return true; } s.Hold(); if (IsRecoveryPartner(_plantMarker, _plantCrop) && !NeedsCyclePartner(s, storage, _plantMarker, _plantCrop)) { ClearPlantTarget(); _nextScan = 0f; return false; } if (CreatePlant(s, _plantCrop, value)) { s.ConsumeInventoryItem(_plantCrop.SeedSharedName); s.SpendDurability(cultivator); s.PlayInteractionGesture(); _plantMarker.RecordCombinedPlant(_plantCrop); Diagnostics.Log("Hearthfolk[farm]: planted " + _plantCrop.PlantPrefabName); } ClearPlantTarget(); _nextScan = Time.time + 0.75f; ResetStuck(s); s.SetStatus("$hf_status_farmer_planting"); return true; } private void SelectPlantTarget(SettlerController s, FarmMarker marker, FarmCrop crop, Vector3 point) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) _plantMarker = marker; _plantCrop = crop; _plantPoint = point; ResumeWork(s); ResetStuck(s); } private void ResumeWork(SettlerController s) { _idleStatus = null; s.StopWaitingSit(); } private void RestWhenIdle(SettlerController s, string status) { _idleStatus = status; if (!s.WaitAtSeat(status)) { s.ReturnHomeIfIdle(); s.SetStatus(status); } } private static IEnumerable PlantingCrops(FarmMarker marker) { FarmCrop configured = marker?.Crop; if (configured != null) { FarmCrop partner = FarmCropCatalog.CyclePartner(configured); if (partner == null) { yield return configured; } else if (marker.CombinedPartnerNext) { yield return partner; yield return configured; } else { yield return configured; yield return partner; } } } private static bool IsCyclePartner(FarmMarker marker, FarmCrop crop) { FarmCrop farmCrop = marker?.Crop; if (farmCrop != null && crop != null && farmCrop.PlantPrefabName != crop.PlantPrefabName) { return FarmCropCatalog.IsCycleCrop(farmCrop, crop); } return false; } private static bool IsRecoveryPartner(FarmMarker marker, FarmCrop crop) { if (IsCyclePartner(marker, crop)) { return !marker.CombinedCycle; } return false; } private static bool NeedsCyclePartner(SettlerController s, Container storage, FarmMarker marker, FarmCrop partner) { FarmCrop farmCrop = marker?.Crop; if (!IsCyclePartner(marker, partner) || farmCrop == null) { return false; } int num = Mathf.Max(0, HfConfig.FarmSeedReserve.Value); int num2 = s.InventoryItemCount(farmCrop.SeedSharedName) + s.StorageItemCount(storage, farmCrop.SeedSharedName); int num3 = PendingCropCount(marker, partner) * Mathf.Max(1, partner.YieldAmount); return num2 + num3 <= num; } private bool StockTargetReached(SettlerController s, Container storage, FarmMarker marker, List allowedMarkers) { FarmCrop farmCrop = marker?.Crop; int num = s.FarmerStockTarget(farmCrop); if (farmCrop == null || num <= 0) { return false; } string familyKey = FarmCropCatalog.PermissionKey(farmCrop); if (_stockCacheUntil.TryGetValue(familyKey, out var value) && Time.time < value && _stockCacheReached.TryGetValue(familyKey, out var value2)) { return value2; } FarmCrop product = FarmCropCatalog.PermissionRepresentative(farmCrop); if (product == null) { return false; } bool flag = product.DropSharedNames.Sum((string sharedName) => s.StorageItemCount(storage, sharedName) + s.InventoryItemCount(sharedName)) + allowedMarkers.Where((FarmMarker candidate) => candidate?.Crop != null && FarmCropCatalog.PermissionKey(candidate.Crop) == familyKey).Sum((FarmMarker candidate) => PendingCropCount(candidate, product) * Mathf.Max(1, product.YieldAmount)) >= num; _stockCacheUntil[familyKey] = Time.time + 0.75f; _stockCacheReached[familyKey] = flag; return flag; } private static int PendingCropCount(FarmMarker marker, FarmCrop crop) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)marker == (Object)null || crop == null) { return 0; } HashSet hashSet = new HashSet(); Collider[] array = Physics.OverlapSphere(marker.Position, marker.Radius + 1f, -1, (QueryTriggerInteraction)2); foreach (Collider val in array) { if (!((Object)(object)val == (Object)null)) { Plant componentInParent = ((Component)val).GetComponentInParent(); if ((Object)(object)componentInParent != (Object)null && MatchesGrowingCrop(componentInParent, crop)) { hashSet.Add(((Object)((Component)((Component)componentInParent).transform.root).gameObject).GetInstanceID()); } Pickable componentInParent2 = ((Component)val).GetComponentInParent(); if ((Object)(object)componentInParent2 != (Object)null && MatchesCrop(componentInParent2, crop)) { hashSet.Add(((Object)((Component)((Component)componentInParent2).transform.root).gameObject).GetInstanceID()); } } } return hashSet.Count; } private static bool MatchesGrowingCrop(Plant plant, FarmCrop crop) { if ((Object)(object)plant == (Object)null || crop == null) { return false; } string text = FarmCropCatalog.CleanPrefabName(((Object)((Component)plant).gameObject).name); string text2 = FarmCropCatalog.CleanPrefabName(((Object)((Component)plant).transform.root).name); if (!(text == crop.PlantPrefabName)) { return text2 == crop.PlantPrefabName; } return true; } private static bool CreatePlant(SettlerController s, FarmCrop crop, Vector3 point) { //IL_0029: 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_00af: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)crop?.PlantPrefab == (Object)null || (Object)(object)ZNetScene.instance == (Object)null) { return false; } GameObject val = Object.Instantiate(crop.PlantPrefab, point, Quaternion.Euler(0f, Random.Range(0f, 360f), 0f)); ZNetView val2 = (((Object)(object)val != (Object)null) ? val.GetComponent() : null); Plant val3 = (((Object)(object)val != (Object)null) ? val.GetComponent() : null); if ((Object)(object)val2 == (Object)null || !val2.IsValid() || (Object)(object)val3 == (Object)null) { if ((Object)(object)val != (Object)null) { Object.Destroy((Object)(object)val); } return false; } val3.UpdateHealth(10.0); if ((int)val3.GetStatus() != 0) { val2.Destroy(); return false; } Piece component = val.GetComponent(); if (component != null) { component.SetCreator(s.SettlementOwnerId); } return true; } private static Vector3? FindPlantPoint(FarmMarker marker, FarmCrop crop) { //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_01e3: Unknown result type (might be due to invalid IL or missing references) //IL_01f7: Unknown result type (might be due to invalid IL or missing references) //IL_01fc: Unknown result type (might be due to invalid IL or missing references) //IL_0206: Unknown result type (might be due to invalid IL or missing references) //IL_020b: Unknown result type (might be due to invalid IL or missing references) //IL_0224: Unknown result type (might be due to invalid IL or missing references) Plant component = crop.PlantPrefab.GetComponent(); if ((Object)(object)component == (Object)null) { return null; } float spacing = Mathf.Max(1.15f, crop.GrowRadius * 2.15f); int num = Mathf.CeilToInt(marker.Radius / spacing); Plant[] source = SceneObjectCache.Get(0.5f); Pickable[] source2 = SceneObjectCache.Get(0.5f); Vector3 val = default(Vector3); float y = default(float); float num2 = default(float); bool flag = default(bool); for (int i = -num; i <= num; i++) { for (int j = -num; j <= num; j++) { ((Vector3)(ref val))..ctor((float)j * spacing, 0f, (float)i * spacing); if (((Vector3)(ref val)).magnitude < 1.2f || ((Vector3)(ref val)).magnitude > marker.Radius - spacing * 0.35f) { continue; } Vector3 point = marker.Position + ((Component)marker).transform.right * val.x + ((Component)marker).transform.forward * val.z; Heightmap val2 = Heightmap.FindHeightmap(point); if ((Object)(object)val2 == (Object)null || !val2.GetWorldHeight(point, ref y)) { continue; } point.y = y; if (component.m_needCultivatedGround && !val2.IsCultivated(point)) { continue; } Biome biome = val2.GetBiome(point, 0.02f, false); if (((int)component.m_biome == 0 || (component.m_biome & biome) != 0) && !source.Any((Plant plant) => (Object)(object)plant != (Object)null && Vector3.Distance(((Component)plant).transform.position, point) < spacing * 0.92f) && !source2.Any((Pickable pickable) => (Object)(object)pickable != (Object)null && Vector3.Distance(((Component)pickable).transform.position, point) < spacing * 0.92f) && HasVanillaGrowSpace(point, component.m_growRadius)) { Cover.GetCoverForPoint(point + Vector3.up * 0.5f, ref num2, ref flag, 0.5f); if (!flag) { return point; } } } } return null; } private static bool HasVanillaGrowSpace(Vector3 point, float radius) { //IL_0034: 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) int mask = LayerMask.GetMask(new string[5] { "Default", "static_solid", "Default_small", "piece", "piece_nonsolid" }); Collider[] array = Physics.OverlapSphere(point, Mathf.Max(0.1f, radius), mask, (QueryTriggerInteraction)1); foreach (Collider val in array) { Plant val2 = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponent() : null); if ((Object)(object)val2 != (Object)null && (int)val2.GetStatus() == 0) { return false; } } return true; } private static ItemDrop FindFarmDrop(SettlerController s, List markers) { //IL_0056: Unknown result type (might be due to invalid IL or missing references) ItemDrop result = null; float num = float.MaxValue; ItemDrop[] array = SceneObjectCache.Get(0.5f); foreach (ItemDrop val in array) { if (ValidDrop(val, markers) && s.Inv != null && s.Inv.CanAddItem(val.m_itemData, val.m_itemData.m_stack)) { float num2 = s.DistanceTo3D(((Component)val).transform.position); if (num2 < num) { result = val; num = num2; } } } return result; } private static bool ValidDrop(ItemDrop drop, List markers) { if ((Object)(object)drop == (Object)null || (Object)(object)drop.m_nview == (Object)null || !drop.m_nview.IsValid() || drop.m_itemData == null) { return false; } string prefabName = FarmCropCatalog.CleanPrefabName(((Object)(object)drop.m_itemData.m_dropPrefab != (Object)null) ? ((Object)drop.m_itemData.m_dropPrefab).name : ((Object)((Component)drop).gameObject).name); return markers.Any((FarmMarker marker) => marker?.Crop != null && Vector3.Distance(((Component)drop).transform.position, marker.Position) <= marker.Radius + 4f && FarmCropCatalog.All().Any((FarmCrop crop) => FarmCropCatalog.IsCycleCrop(marker.Crop, crop) && crop.DropPrefabNames.Contains(prefabName))); } private static void FindMatureCrop(SettlerController s, List markers, out Pickable best, out FarmMarker bestMarker) { //IL_0063: 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_0083: Unknown result type (might be due to invalid IL or missing references) best = null; bestMarker = null; float num = float.MaxValue; Pickable[] array = SceneObjectCache.Get(0.5f); foreach (FarmMarker marker in markers) { Pickable[] array2 = array; foreach (Pickable val in array2) { if (!((Object)(object)val == (Object)null) && val.CanBePicked() && MatchesCropFamily(val, marker.Crop) && !(Vector3.Distance(((Component)val).transform.position, marker.Position) > marker.Radius)) { float num2 = s.DistanceTo3D(((Component)val).transform.position); if (num2 < num) { best = val; bestMarker = marker; num = num2; } } } } } private static bool MatchesCrop(Pickable pickable, FarmCrop crop) { if ((Object)(object)pickable == (Object)null || crop == null) { return false; } string item = FarmCropCatalog.CleanPrefabName(((Object)((Component)pickable).gameObject).name); string item2 = FarmCropCatalog.CleanPrefabName(((Object)((Component)pickable).transform.root).name); if (!crop.MaturePrefabNames.Contains(item)) { return crop.MaturePrefabNames.Contains(item2); } return true; } private static bool MatchesCropFamily(Pickable pickable, FarmCrop configured) { return FarmCropCatalog.All().Any((FarmCrop crop) => FarmCropCatalog.IsCycleCrop(configured, crop) && MatchesCrop(pickable, crop)); } private bool HaulHarvest(SettlerController s, Container storage) { if (!s.CanInteractWith(((Component)storage).gameObject, 2.8f)) { s.Approach(((Component)storage).gameObject, 2.38f, run: true); s.SetStatus("$hf_status_farmer_deposit"); return true; } s.Hold(); s.DepositFarmCargo(storage); s.SetStatus("$hf_status_farmer_deposit"); return true; } private bool RepairTick(SettlerController s) { //IL_0028: 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) if (Time.time < _repairGiveUpUntil) { return false; } CraftingStation val = s.FindNearestCraftingStation(); if ((Object)(object)val == (Object)null) { return false; } if (s.DistanceTo(((Component)val).transform.position) > 2.5f) { s.GoTo(((Component)val).transform.position, 2f, run: true); if (s.Ai.PathBlocked) { _repairGiveUpUntil = Time.time + 30f; ResetStuck(s); return false; } _repairReadyAt = 0f; s.SetStatus("$hf_status_repair"); return true; } s.Hold(); ResetStuck(s); if (_repairReadyAt <= 0f) { _repairReadyAt = Time.time + 2.5f; } else if (Time.time >= _repairReadyAt) { s.RepairAllTools(); _repairReadyAt = 0f; } s.SetStatus("$hf_status_repair"); return true; } private bool IsStuck(SettlerController s) { //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) //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) float num = Vector3.Distance(s.Position, _lastPosition); _lastPosition = s.Position; _stuckTime = ((num < 0.15f) ? (_stuckTime + 0.3f) : 0f); return _stuckTime >= 3.5f; } private void ResetStuck(SettlerController s) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) _lastPosition = s.Position; _stuckTime = 0f; } private void ClearPlantTarget() { _plantMarker = null; _plantCrop = null; _plantPoint = null; } private void ClearTargets() { ClearPlantTarget(); _harvestTarget = null; _harvestMarker = null; _dropTarget = null; } } internal sealed class FollowerJob : ISettlerJob { private const float StartFollowingDistance = 4.5f; private const float StopFollowingDistance = 1.8f; private const float FormationStopDistance = 1.25f; private const float RunDistance = 10f; private const float TeleportDistance = 65f; private float _blockedSince; private bool _closingDistance; public SettlerRole Role => SettlerRole.Follower; public void Enter(SettlerController s) { _blockedSince = 0f; _closingDistance = false; s.StopWaitingSit(); } public void Exit(SettlerController s) { _blockedSince = 0f; _closingDistance = false; } public void Tick(SettlerController s) { //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: 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_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0172: 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_019f: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_023d: Unknown result type (might be due to invalid IL or missing references) if (s.Ai.HasHostileTarget()) { _blockedSince = 0f; _closingDistance = false; s.Hold(); s.SetStatus((s.FindWeapon() != null) ? "$hf_status_follower_defending" : "$hf_status_need_weapon"); } else { if (s.TryFollowerEatForHealing()) { return; } FollowerMode currentFollowerMode = s.CurrentFollowerMode; Player followedPlayer = s.FollowedPlayer; if (currentFollowerMode == FollowerMode.Following && (Object)(object)followedPlayer == (Object)null) { if (!SettlerController.IsPlayerConnected(s.FollowerTargetId)) { if (s.DistanceTo(s.Home) > 4f) { s.GoTo(s.Home, 2f, run: false); s.SetStatus("$hf_status_follower_returning"); } else { s.Hold(); s.SetStatus("$hf_status_follower_waiting_for_player"); } } else { s.Hold(); s.SetStatus("$hf_status_follower_waiting_for_player"); } return; } switch (currentFollowerMode) { case FollowerMode.Waiting: { _closingDistance = false; Vector3 followerWaitPosition = s.FollowerWaitPosition; if (s.DistanceTo(followerWaitPosition) > 1.8f) { s.GoTo(followerWaitPosition, 1.1f, run: false); s.SetStatus("$hf_status_follower_waiting"); } else { s.Hold(); s.SetStatus("$hf_status_follower_waiting"); } break; } case FollowerMode.Following: if (!((Object)(object)followedPlayer == (Object)null)) { if (s.DistanceTo3D(((Component)followedPlayer).transform.position) >= 65f) { s.TeleportFollowerNear(followedPlayer); _blockedSince = 0f; _closingDistance = false; break; } Vector3 point = s.FollowerFormationPosition(followedPlayer); float num = s.DistanceTo3D(point); if (s.Ai.PathBlocked && num > 10f) { if (_blockedSince <= 0f) { _blockedSince = Time.time; } else if (Time.time - _blockedSince >= 5f) { s.TeleportFollowerNear(followedPlayer); _blockedSince = 0f; _closingDistance = false; break; } } else { _blockedSince = 0f; } if (num >= 4.5f) { _closingDistance = true; } else if (num <= 1.8f) { _closingDistance = false; } if (_closingDistance) { s.GoTo(point, 1.25f, num >= 10f); s.SetStatus((num >= 10f) ? "$hf_status_follower_catching_up" : "$hf_status_follower_following"); } else { s.Hold(); s.SetStatus("$hf_status_follower_following"); } break; } goto default; default: _closingDistance = false; if (s.DistanceTo(s.Home) > 4f) { s.GoTo(s.Home, 2f, run: false); s.SetStatus("$hf_status_follower_returning"); } else { s.Hold(); s.SetStatus("$hf_status_follower_available"); } break; } } } } internal sealed class GuardJob : ISettlerJob { private int _patrolIndex; private float _waitUntil; private int _resolvedPatrolIndex; private Vector3 _resolvedMarker; private Vector3 _resolvedPatrolPoint; private bool _hasResolvedPatrolPoint; public SettlerRole Role => SettlerRole.Guard; public void Enter(SettlerController s) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) List guardPatrolRoute = s.GuardPatrolRoute; _patrolIndex = ((guardPatrolRoute.Count > 0) ? (Math.Abs(((object)s.PersistentId/*cast due to .constrained prefix*/).GetHashCode()) % guardPatrolRoute.Count) : 0); _waitUntil = 0f; InvalidatePatrolPoint(); } public void Exit(SettlerController s) { InvalidatePatrolPoint(); } public void Tick(SettlerController s) { //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_0159: 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_0157: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) if (s.Ai.HasHostileTarget()) { s.Ai.ClearMove(); s.SetStatus("$hf_status_guarding"); return; } if (s.FindWeapon() == null) { s.SetStatus("$hf_status_need_weapon"); } else { s.SetStatus("$hf_status_guarding"); } if (!s.SettlementAlertActive) { List guardPatrolRoute = s.GuardPatrolRoute; if (guardPatrolRoute.Count > 0) { _patrolIndex %= guardPatrolRoute.Count; Vector3 marker = guardPatrolRoute[_patrolIndex]; if (!ResolvePatrolPoint(s, marker)) { AdvancePatrol(guardPatrolRoute.Count); return; } Vector3 resolvedPatrolPoint = _resolvedPatrolPoint; if (s.DistanceTo(resolvedPatrolPoint) > 1.8f) { s.GoTo(resolvedPatrolPoint, 1.2f, run: false); if (s.Ai.PathBlocked) { s.Hold(); AdvancePatrol(guardPatrolRoute.Count); } else { s.SetStatus("$hf_status_patrolling"); } return; } s.Hold(); s.SetStatus("$hf_status_guarding"); if (_waitUntil <= 0f) { _waitUntil = Time.time + 3f; } else if (Time.time >= _waitUntil) { AdvancePatrol(guardPatrolRoute.Count); } return; } InvalidatePatrolPoint(); } Vector3 val = s.GuardPosition; if (s.Ai.TryFindNavigationPoint(val, 2.25f, out var point)) { val = point; } if (s.DistanceTo(val) > 12f) { s.GoTo(val, 2f, run: true); } else { s.Hold(); } } private bool ResolvePatrolPoint(SettlerController s, Vector3 marker) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0044: 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_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) if (_hasResolvedPatrolPoint && _resolvedPatrolIndex == _patrolIndex && Vector3.Distance(_resolvedMarker, marker) <= 0.25f) { return true; } _resolvedPatrolIndex = _patrolIndex; _resolvedMarker = marker; if (!s.Ai.TryFindNavigationPoint(marker, 2.25f, out _resolvedPatrolPoint)) { _resolvedPatrolPoint = marker; Diagnostics.Navigation($"Hearthfolk[guard]: patrol point {_patrolIndex + 1} " + "uses its raw physical position"); } _hasResolvedPatrolPoint = true; return true; } private void AdvancePatrol(int routeCount) { _waitUntil = 0f; _patrolIndex = ((routeCount > 0) ? ((_patrolIndex + 1) % routeCount) : 0); InvalidatePatrolPoint(); } private void InvalidatePatrolPoint() { //IL_000d: 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) _resolvedPatrolIndex = -1; _resolvedMarker = default(Vector3); _resolvedPatrolPoint = default(Vector3); _hasResolvedPatrolPoint = false; } } internal sealed class IdleJob : ISettlerJob { public SettlerRole Role => SettlerRole.Idle; public void Enter(SettlerController s) { } public void Exit(SettlerController s) { s.StopWaitingSit(); } public void Tick(SettlerController s) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) if (!s.WaitAtSeat()) { if (s.DistanceTo(s.Home) > 4f) { s.GoTo(s.Home, 2f, run: false); s.SetStatus("$hf_status_returning"); } else { s.Hold(); s.SetStatus("$hf_status_idle"); } } } } internal interface ISettlerJob { SettlerRole Role { get; } void Enter(SettlerController s); void Tick(SettlerController s); void Exit(SettlerController s); } internal sealed class LumberjackJob : ISettlerJob { private const float StuckProgress = 0.15f; private const float StuckTimeout = 3.5f; private const int MaxIneffectiveSwings = 3; private ChopTarget _target; private ItemDrop _dropTarget; private bool _swingPending; private float _healthBeforeSwing; private int _ineffectiveSwings; private Vector3 _lastPos; private float _stuckTimer; private float _repairReadyAt; private float _repairGiveUpUntil; public SettlerRole Role => SettlerRole.Lumberjack; public void Enter(SettlerController s) { _target = null; _dropTarget = null; _swingPending = false; _ineffectiveSwings = 0; ResetStuck(s); } public void Exit(SettlerController s) { _target = null; _dropTarget = null; _swingPending = false; s.StopWaitingSit(); } private void ResetStuck(SettlerController s) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) _lastPos = s.Position; _stuckTimer = 0f; } public void Tick(SettlerController s) { ItemData val = s.FindAxe(); if (val == null) { _target = null; _dropTarget = null; if (!s.HasBrokenTool() || !RepairTick(s)) { RestWhenIdle(s, "$hf_status_need_axe"); } return; } s.EquipTool(val); s.CollectNearbyWood(); if (s.DepositableCount() >= Mathf.Max(1, HfConfig.DepositThreshold.Value) || !s.HasSpaceForWood()) { _dropTarget = null; if (!s.HaulToStorage()) { RestWhenIdle(s, "$hf_status_inv_full"); } } else { if (SeekDrops(s)) { return; } if (!IsTargetValid(s)) { if (_target != null) { _target = null; s.ForceDropScan(); s.ForceChopScan(); } if (!s.TryFindChopTarget(val, out _target)) { return; } _swingPending = false; _ineffectiveSwings = 0; s.StopWaitingSit(); s.Hold(); ResetStuck(s); } if (_target == null) { if (s.DepositableCount() <= 0 || !s.HaulToStorage()) { RestWhenIdle(s, s.LastSearchTierBlocked ? "$hf_status_need_better_axe" : "$hf_status_no_tree"); } } else { ChopTick(s, val); } } } private bool SeekDrops(SettlerController s) { //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_dropTarget == (Object)null || (Object)(object)_dropTarget.m_nview == (Object)null || !_dropTarget.m_nview.IsValid()) { _dropTarget = s.FindNearestWoodDrop(); if ((Object)(object)_dropTarget != (Object)null) { s.StopWaitingSit(); s.Hold(); ResetStuck(s); } } if ((Object)(object)_dropTarget == (Object)null) { return false; } Vector3 position = ((Component)_dropTarget).transform.position; if (s.DistanceTo3D(position) <= 2.5f) { s.Hold(); if (!s.TryPickup(_dropTarget)) { Diagnostics.Log("Hearthfolk[lumber]: pickup failed, blacklisting drop"); s.BlacklistDrop(_dropTarget); } _dropTarget = null; ResetStuck(s); s.ForceDropScan(); return true; } s.GoTo(position, 1.2f, s.DistanceTo(position) > 8f); if (s.Ai.PathBlocked) { Diagnostics.Log("Hearthfolk[lumber]: wood drop unreachable, skipping"); s.BlacklistDrop(_dropTarget); _dropTarget = null; ResetStuck(s); return false; } s.SetStatus("$hf_status_collect"); return true; } private static void RestWhenIdle(SettlerController s, string status) { if (!s.WaitAtSeat(status)) { s.ReturnHomeIfIdle(); s.SetStatus(status); } } private void ChopTick(SettlerController s, ItemData axe) { //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) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0013: 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_011f: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) Vector3 point = _target.ClosestPoint(s.Position); float num = s.DistanceTo(point); bool flag = num <= 3.5f; s.GoTo(point, 2.3f, !flag); if (!flag) { if (s.Ai.PathBlocked) { Diagnostics.Log($"Hearthfolk[lumber]: unreachable target (dist={num:0.0}), blacklisting"); AbandonTarget(s); s.SetStatus("$hf_status_no_tree"); } else { s.SetStatus("$hf_status_move_tree"); } return; } ResetStuck(s); if (s.CanSwing() && !((Character)s.Char).InAttack()) { if (_swingPending) { if (_target.ReadHealth() >= _healthBeforeSwing - 0.01f) { s.ApplyManualChop(_target, axe, point); _ineffectiveSwings++; if (_ineffectiveSwings >= 3) { Diagnostics.Log("Hearthfolk[lumber]: target takes no damage (tier/protection), blacklisting"); AbandonTarget(s); s.SetStatus("$hf_status_need_better_axe"); return; } } else { _ineffectiveSwings = 0; } _swingPending = false; } _healthBeforeSwing = _target.ReadHealth(); s.FaceAndSwing(point); s.SpendDurability(axe); _swingPending = true; Diagnostics.Log(string.Format("Hearthfolk[lumber]: chop {0} dist={1:0.0} hp={2:0.0}", _target.IsLog ? "LOG" : "tree", num, _healthBeforeSwing)); } s.SetStatus("$hf_status_chopping"); } private bool RepairTick(SettlerController s) { //IL_0027: 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) //IL_002e: 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 (Time.time < _repairGiveUpUntil) { return false; } CraftingStation val = s.FindNearestCraftingStation(); if ((Object)(object)val == (Object)null) { return false; } Vector3 position = ((Component)val).transform.position; if (s.DistanceTo(position) > 2.5f) { s.GoTo(position, 2f, run: true); if (s.Ai.PathBlocked) { Diagnostics.Log("Hearthfolk[repair]: station unreachable, retrying later"); _repairGiveUpUntil = Time.time + 30f; ResetStuck(s); return false; } _repairReadyAt = 0f; s.SetStatus("$hf_status_repair"); return true; } s.Hold(); ResetStuck(s); if (_repairReadyAt <= 0f) { _repairReadyAt = Time.time + 2.5f; } else if (Time.time >= _repairReadyAt) { s.RepairAllTools(); _repairReadyAt = 0f; } s.SetStatus("$hf_status_repair"); return true; } private void AbandonTarget(SettlerController s) { s.BlacklistTarget(_target); _target = null; _swingPending = false; _ineffectiveSwings = 0; ResetStuck(s); } private bool IsStuck(SettlerController s) { //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) //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) float num = Vector3.Distance(s.Position, _lastPos); _lastPos = s.Position; _stuckTimer = ((num < 0.15f) ? (_stuckTimer + 0.3f) : 0f); return _stuckTimer >= 3.5f; } private bool IsTargetValid(SettlerController s) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) if (_target != null && _target.IsValid()) { return s.IsInWorkArea(_target.Center); } return false; } } internal sealed class MinerJob : ISettlerJob { private const float StuckProgress = 0.15f; private const float StuckTimeout = 3.5f; private const int MaxIneffectiveSwings = 3; private MineTarget _target; private ItemDrop _dropTarget; private bool _swingPending; private float _healthBeforeSwing; private int _ineffectiveSwings; private Vector3 _lastPos; private float _stuckTimer; private float _repairReadyAt; private float _repairGiveUpUntil; public SettlerRole Role => SettlerRole.Miner; public void Enter(SettlerController s) { _target = null; _dropTarget = null; _swingPending = false; _ineffectiveSwings = 0; ResetStuck(s); } public void Exit(SettlerController s) { _target = null; _dropTarget = null; _swingPending = false; s.StopWaitingSit(); } private void ResetStuck(SettlerController s) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) _lastPos = s.Position; _stuckTimer = 0f; } public void Tick(SettlerController s) { ItemData val = s.FindPickaxe(); if (val == null) { _target = null; _dropTarget = null; if (!s.HasBrokenTool() || !RepairTick(s)) { RestWhenIdle(s, "$hf_status_need_pick"); } return; } s.EquipTool(val); s.CollectNearbyOre(); if (s.DepositableCount() >= Mathf.Max(1, HfConfig.DepositThreshold.Value) || !s.HasSpaceForWood()) { _dropTarget = null; if (!s.HaulToStorage()) { RestWhenIdle(s, "$hf_status_inv_full"); } } else { if (SeekDrops(s)) { return; } if (!IsTargetValid(s)) { if (_target != null) { _target = null; s.ForceDropScan(); s.ForceMineScan(); } if (!s.TryFindMineTarget(val, out _target)) { return; } _swingPending = false; _ineffectiveSwings = 0; s.StopWaitingSit(); s.Hold(); ResetStuck(s); } if (_target == null) { if (s.DepositableCount() <= 0 || !s.HaulToStorage()) { RestWhenIdle(s, s.LastMineTierBlocked ? "$hf_status_need_better_pick" : "$hf_status_no_rock"); } } else { MineTick(s, val); } } } private bool SeekDrops(SettlerController s) { //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_dropTarget == (Object)null || (Object)(object)_dropTarget.m_nview == (Object)null || !_dropTarget.m_nview.IsValid()) { _dropTarget = s.FindNearestOreDrop(); if ((Object)(object)_dropTarget != (Object)null) { s.StopWaitingSit(); s.Hold(); ResetStuck(s); } } if ((Object)(object)_dropTarget == (Object)null) { return false; } Vector3 position = ((Component)_dropTarget).transform.position; if (s.DistanceTo3D(position) <= 2.5f) { s.Hold(); if (!s.TryPickup(_dropTarget)) { Diagnostics.Log("Hearthfolk[mine]: pickup failed, blacklisting drop"); s.BlacklistDrop(_dropTarget); } _dropTarget = null; ResetStuck(s); s.ForceDropScan(); return true; } s.GoTo(position, 1.2f, s.DistanceTo(position) > 8f); if (s.Ai.PathBlocked) { Diagnostics.Log("Hearthfolk[mine]: ore drop unreachable, skipping"); s.BlacklistDrop(_dropTarget); _dropTarget = null; ResetStuck(s); return false; } s.SetStatus("$hf_status_collect_ore"); return true; } private static void RestWhenIdle(SettlerController s, string status) { if (!s.WaitAtSeat(status)) { s.ReturnHomeIfIdle(); s.SetStatus(status); } } private void MineTick(SettlerController s, ItemData pick) { //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) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0013: 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_011f: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) Vector3 point = _target.ClosestPoint(s.Position); float num = s.DistanceTo(point); bool flag = num <= 3.5f; s.GoTo(point, 2.3f, !flag); if (!flag) { if (s.Ai.PathBlocked) { Diagnostics.Log($"Hearthfolk[mine]: unreachable target (dist={num:0.0}), blacklisting"); AbandonTarget(s); s.SetStatus("$hf_status_no_rock"); } else { s.SetStatus("$hf_status_move_rock"); } return; } ResetStuck(s); if (s.CanSwing() && !((Character)s.Char).InAttack()) { if (_swingPending) { if (_target.ReadHealth() >= _healthBeforeSwing - 0.01f) { s.ApplyManualPick(_target, pick, point); _ineffectiveSwings++; if (_ineffectiveSwings >= 3) { Diagnostics.Log("Hearthfolk[mine]: target takes no damage (tier/protection), blacklisting"); AbandonTarget(s); s.SetStatus("$hf_status_need_better_pick"); return; } } else { _ineffectiveSwings = 0; } _swingPending = false; } _healthBeforeSwing = _target.ReadHealth(); s.FaceAndSwing(point, allowTerrainHit: false); s.SpendDurability(pick); _swingPending = true; Diagnostics.Log(string.Format("Hearthfolk[mine]: swing {0} dist={1:0.0} hp={2:0.0}", _target.IsVein ? "VEIN" : "boulder", num, _healthBeforeSwing)); } s.SetStatus("$hf_status_mining"); } private bool RepairTick(SettlerController s) { //IL_0027: 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) //IL_002e: 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 (Time.time < _repairGiveUpUntil) { return false; } CraftingStation val = s.FindNearestCraftingStation(); if ((Object)(object)val == (Object)null) { return false; } Vector3 position = ((Component)val).transform.position; if (s.DistanceTo(position) > 2.5f) { s.GoTo(position, 2f, run: true); if (s.Ai.PathBlocked) { Diagnostics.Log("Hearthfolk[mine]: station unreachable, retrying later"); _repairGiveUpUntil = Time.time + 30f; ResetStuck(s); return false; } _repairReadyAt = 0f; s.SetStatus("$hf_status_repair"); return true; } s.Hold(); ResetStuck(s); if (_repairReadyAt <= 0f) { _repairReadyAt = Time.time + 2.5f; } else if (Time.time >= _repairReadyAt) { s.RepairAllTools(); _repairReadyAt = 0f; } s.SetStatus("$hf_status_repair"); return true; } private void AbandonTarget(SettlerController s) { s.BlacklistMineTarget(_target); _target = null; _swingPending = false; _ineffectiveSwings = 0; ResetStuck(s); } private bool IsStuck(SettlerController s) { //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) //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) float num = Vector3.Distance(s.Position, _lastPos); _lastPos = s.Position; _stuckTimer = ((num < 0.15f) ? (_stuckTimer + 0.3f) : 0f); return _stuckTimer >= 3.5f; } private bool IsTargetValid(SettlerController s) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) if (_target != null && _target.IsValid()) { return s.IsInWorkArea(_target.Center); } return false; } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { internal IgnoresAccessChecksToAttribute(string assemblyName) { } } }