Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of Hearthfolk v1.0.0
Hearthfolk.dll
Decompiled a day ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.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<string> _selected = new HashSet<string>(StringComparer.Ordinal); private List<ItemChoice> _choices = new List<ItemChoice>(); 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<ChestSortPanel>(); } 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<GUILayoutOption>()); 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<GUILayoutOption>()); GUILayout.Label(Localization.instance.Localize("$hf_chest_sort_desc"), Array.Empty<GUILayoutOption>()); GUILayout.Space(5f); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); 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<GUILayoutOption>()); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); if (GUILayout.Button(Localization.instance.Localize("$hf_chest_sort_select_present"), Array.Empty<GUILayoutOption>())) { SelectPresentMaterials(); } if (GUILayout.Button(Localization.instance.Localize("$hf_chest_sort_clear"), Array.Empty<GUILayoutOption>())) { _selected.Clear(); } GUILayout.EndHorizontal(); GUILayout.Space(5f); _scroll = GUILayout.BeginScrollView(_scroll, GUI.skin.box); List<ItemChoice> list = _choices.Where(MatchesSearch).ToList(); for (int i = 0; i < list.Count; i += 2) { GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); 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<GUILayoutOption>()); } GUILayout.EndScrollView(); GUILayout.Space(6f); GUILayout.Label(string.Format(Localization.instance.Localize("$hf_chest_sort_selected"), _selected.Count), Array.Empty<GUILayoutOption>()); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); if (GUILayout.Button(Localization.instance.Localize("$hf_chest_sort_save"), Array.Empty<GUILayoutOption>())) { 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<GUILayoutOption>())) { ChestSortRules.RequestSet(_container, Array.Empty<string>(), 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<GUILayoutOption>()); GUILayout.Label(Localization.instance.Localize("$hf_chest_intake_section"), HfGuiSkin.CardTitle, Array.Empty<GUILayoutOption>()); GUILayout.Label(Localization.instance.Localize("$hf_chest_intake_desc"), HfGuiSkin.MutedLabel, Array.Empty<GUILayoutOption>()); if ((Object)(object)exilesHearth == (Object)null) { GUILayout.Label(Localization.instance.Localize("$hf_chest_intake_no_hearth"), Array.Empty<GUILayoutOption>()); GUILayout.EndVertical(); return; } IntakeRoles intakeRoles = exilesHearth.IntakeRolesFor(_container); bool flag = intakeRoles != IntakeRoles.None; GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUILayout.Label(Localization.instance.Localize(flag ? "$hf_chest_intake_current" : "$hf_chest_intake_available"), Array.Empty<GUILayoutOption>()); 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<GUILayoutOption>()); 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<GUILayoutOption>())) { 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<ItemChoice> BuildChoices(Container container, HashSet<string> selected) { HashSet<string> hashSet = new HashSet<string>(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<ItemChoice> list = new List<ItemChoice>(); if ((Object)(object)ObjectDB.instance == (Object)null) { return list; } foreach (GameObject item in ObjectDB.instance.m_items) { ItemData val = ((item != null) ? item.GetComponent<ItemDrop>() : 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<long, string>("hf_SetChestSort", (Action<long, long, string>)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<string> ReadItems(Container container) { HashSet<string> hashSet = new HashSet<string>(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<string> 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<Ship>() != (Object)null || (Object)(object)((Component)container).GetComponentInParent<Vagon>() != (Object)null) { return false; } Piece val = ((Component)container).GetComponent<Piece>() ?? ((Component)container).GetComponentInParent<Piece>(); 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<Collider>(); 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<HeapEntry> _items = new List<HeapEntry>(); 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<Vector3> 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<Vector3> { 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<Vector3> list = new List<Vector3> { 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<Character>() != (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<Character>() != (Object)null) && !((Object)(object)((Component)val3).GetComponentInParent<Heightmap>() != (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<Vector3> Smooth(IReadOnlyList<Vector3> 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<Vector3> list = new List<Vector3>(); 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<Vector3> 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<ZDO> Cached = new List<ZDO>(); private static float _nextRefresh; internal static List<Record> ForHearth(ExilesHearth hearth, IEnumerable<ZDOID> instantiatedIds) { if ((Object)(object)hearth == (Object)null) { return new List<Record>(); } Refresh(); HashSet<ZDOID> liveIds = new HashSet<ZDOID>(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, string>((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<ZDO> list = new List<ZDO>(); 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<ExilesHearth> Instances = new List<ExilesHearth>(); 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<Door> _availableGatewayCache; private float _availableGatewayCacheAt; private List<Container> _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<Vector3> PatrolRoute => PatrolPoint.RouteFor(this); internal int PatrolPointCount => PatrolRoute.Count; internal int AvailablePatrolPointCount => PatrolPoint.PointsFor(this).Count; internal List<PatrolPoint> 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<ZDOID> SavedPatrolRoute => ResolveSavedRoute("hf_patrol_route", "hf_patrol_route_identity", PatrolPoint.PointsFor(this).Select(PatrolRouteEntry), "patrol"); internal List<ZDOID> 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<ZDOID> SavedGatewayDoorIds { get { List<ZDOID> list = ResolveSavedRoute("hf_gateway_doors", "hf_gateway_doors_identity", AvailableGatewayDoors.Select(GatewayRouteEntry), "gateway"); List<Door> 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<ZDOID> 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<Door> AvailableGatewayDoors { get { if (_availableGatewayCache == null || Time.time >= _availableGatewayCacheAt) { _availableGatewayCache = FindAvailableGatewayDoors(); _availableGatewayCacheAt = Time.time + 1f; } return _availableGatewayCache; } } internal int AvailableGatewayDoorCount => AvailableGatewayDoors.Count; internal List<Door> ConfiguredGatewayDoors { get { Dictionary<ZDOID, Door> 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<ZNetView>(); _piece = ((Component)this).GetComponent<Piece>(); if ((Object)(object)_nview != (Object)null && _nview.IsValid()) { _nview.Register<long>("hf_ToggleSettlementAlert", (Action<long, long>)RPC_ToggleAlert); _nview.Register("hf_SignalDefenseThreat", (Action<long>)RPC_SignalDefenseThreat); _nview.Register<long, int, string>("hf_SetPatrolRoute", (Action<long, long, int, string>)RPC_SetPatrolRoute); _nview.Register<long, ZDOID>("hf_SetIntakeStorage", (Action<long, long, ZDOID>)RPC_SetIntakeStorage); _nview.Register<long, ZDOID, int>("hf_SetIntakeStorageRoles", (Action<long, long, ZDOID, int>)RPC_SetIntakeStorageRoles); _nview.Register<long, int, string>("hf_SetGatewayDoors", (Action<long, long, int, string>)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[<color=yellow><b>$KEY_Use</b></color>] $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<ZDOID> 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<PatrolPoint> source = PatrolPoint.PointsFor(this); HashSet<ZDOID> validIds = new HashSet<ZDOID>(source.Select((PatrolPoint point) => point.PersistentId)); List<ZDOID> 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<ZDOID> 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<Door> availableGatewayDoors = AvailableGatewayDoors; HashSet<ZDOID> validIds = new HashSet<ZDOID>(from door in availableGatewayDoors where (Object)(object)door?.m_nview != (Object)null && door.m_nview.IsValid() select door.m_nview.GetZDO().m_uid); List<ZDOID> 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<Door> 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<Door> available, ICollection<ZDOID> 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<ZDOID> hashSet = new HashSet<ZDOID>(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<Door> available) { PersistGatewayMarkers(available, new List<ZDOID>()); } internal List<Container> 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<Container>(); } if (_intakeStorageCache == null || Time.time >= _intakeStorageCacheUntil) { _intakeStorageCache = (from container in SceneObjectCache.Get<Container>(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<Container> source = ResolveIntakeStorages(self); if ((Object)(object)settlerController != (Object)null && settlerController.CurrentRole == SettlerRole.Caretaker) { return source.FirstOrDefault(); } return ((IEnumerable<Container>)source).FirstOrDefault((Func<Container, bool>)((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<Container>() ?? val.GetComponentInChildren<Container>(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<Container>() ?? val.GetComponentInChildren<Container>(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<ZDOID> ResolveSavedRoute(string routeKey, string identityKey, IEnumerable<SavedRouteEntry> 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<ZDOID>(); } ZDO zDO = _nview.GetZDO(); List<ZDOID> list = DecodePatrolRoute(zDO.GetString(routeKey, string.Empty)); if (list.Count == 0) { return list; } List<SavedRouteEntry> source = (from entry in available where entry != null && entry.Id != ZDOID.None group entry by entry.Id into @group select @group.First()).ToList(); Dictionary<ZDOID, SavedRouteEntry> dictionary = source.ToDictionary((SavedRouteEntry entry) => entry.Id); Dictionary<ZDOID, SavedRouteEntry> dictionary2 = (from entry in DecodeRouteIdentity(zDO.GetString(identityKey, string.Empty)) where entry != null && entry.Id != ZDOID.None group entry by entry.Id).ToDictionary((IGrouping<ZDOID, SavedRouteEntry> group) => group.Key, (IGrouping<ZDOID, SavedRouteEntry> group) => group.First()); HashSet<ZDOID> used = new HashSet<ZDOID>(); List<SavedRouteEntry> list2 = new List<SavedRouteEntry>(); 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<ZDOID> 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<ZDOID> route, IEnumerable<SavedRouteEntry> available) { Dictionary<ZDOID, SavedRouteEntry> candidates = (from entry in available where entry != null && entry.Id != ZDOID.None group entry by entry.Id).ToDictionary((IGrouping<ZDOID, SavedRouteEntry> group) => group.Key, (IGrouping<ZDOID, SavedRouteEntry> group) => group.First()); List<SavedRouteEntry> 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<Piece>() ?? ((Component)point).GetComponentInParent<Piece>(); 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<Piece>() ?? ((Component)door).GetComponentInParent<Piece>(); 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<SavedRouteEntry> 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<SavedRouteEntry> list = entries?.Where((SavedRouteEntry entry) => entry != null).Take(64).ToList() ?? new List<SavedRouteEntry>(); 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<SavedRouteEntry> 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<SavedRouteEntry> list = new List<SavedRouteEntry>(); 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<ZDOID> 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<ZDOID> list = route?.Where((ZDOID id) => id != ZDOID.None).Distinct().Take(64) .ToList() ?? new List<ZDOID>(); ZPackage val = new ZPackage(); val.Write(list.Count); foreach (ZDOID item in list) { val.Write(item); } return val.GetBase64(); } internal static List<ZDOID> 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<ZDOID> list = new List<ZDOID>(); 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<SettlerController>() == (Object)null; } return false; } private void SignalDefenseThreat() { if (!((Object)(object)_nview == (Object)null) && _nview.IsValid()) { _nview.InvokeRPC("hf_SignalDefenseThreat", Array.Empty<object>()); } } 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<Door> FindAvailableGatewayDoors() { float radius = Mathf.Max(20f, (HfConfig.WorkRadius != null) ? (HfConfig.WorkRadius.Value + 10f) : 40f); return (from door in SceneObjectCache.Get<Door>(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<Piece>() ?? ((Component)door).GetComponentInParent<Piece>(); 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<GameObject>(prefab, val, Quaternion.LookRotation(((Component)this).transform.forward)); ZNetView component = val2.GetComponent<ZNetView>(); 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 UseI