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 Shack Comfort Ascended v1.0.1
ShackComfortAscended.dll
Decompiled 2 days agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Jotunn.Utils; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("ShackComfortAscended")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.1.0")] [assembly: AssemblyInformationalVersion("1.0.1")] [assembly: AssemblyProduct("ShackComfortAscended")] [assembly: AssemblyTitle("ShackComfortAscended")] [assembly: AssemblyVersion("1.0.1.0")] [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 TheShack.ComfortAscended { internal static class BuildMenu { [HarmonyPatch(typeof(BuildUiPieceButton), "Setup")] private static class BuildUiPieceButton_Setup { private static void Postfix(BuildUiPieceButton __instance, Piece pieceInfo) { Transform val = ((Component)__instance).transform.Find("ShackComfortBadge"); if (!Settings.ShowInBuildMenu.Value || !Object.op_Implicit((Object)(object)pieceInfo) || pieceInfo.m_comfort <= 0) { if (Object.op_Implicit((Object)(object)val)) { ((Component)val).gameObject.SetActive(false); } return; } TMP_Text val2 = (Object.op_Implicit((Object)(object)val) ? ((Component)val).GetComponent<TMP_Text>() : CreateBadge(((Component)__instance).transform)); if (Object.op_Implicit((Object)(object)val2)) { val2.text = "+" + pieceInfo.m_comfort; ((Component)val2).gameObject.SetActive(true); } } } [HarmonyPatch(typeof(Hud), "SetupPieceInfo")] private static class Hud_SetupPieceInfo { private static void Postfix(Hud __instance, Piece piece) { if (Settings.ShowInBuildMenu.Value && Object.op_Implicit((Object)(object)piece) && piece.m_comfort > 0 && Object.op_Implicit((Object)(object)__instance.m_pieceDescription)) { TMP_Text pieceDescription = __instance.m_pieceDescription; pieceDescription.text = pieceDescription.text + "\n" + Line(piece); } } } private const string BadgeName = "ShackComfortBadge"; private static readonly Color BadgeColor = new Color(1f, 0.85f, 0.35f); private static string Line(Piece piece) { //IL_001b: 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) string arg = (Object.op_Implicit((Object)(object)piece.m_comfortObject) ? ", while lit" : ""); string arg2 = (((int)piece.m_comfortGroup == 0) ? "each different one counts" : ("only your best " + GroupName(piece.m_comfortGroup) + " counts")); return $"<color=#FFD966>Comfort +{piece.m_comfort}</color> <color=#C8C8C8>({arg2}{arg})</color>"; } private unsafe static string GroupName(ComfortGroup group) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected I4, but got Unknown //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Invalid comparison between Unknown and I4 switch (group - 4) { default: if ((int)group != 11) { break; } return "leisure piece"; case 0: return "seat"; case 2: return "rug"; case 4: return "decoration"; case 1: case 3: break; } return ((object)(*(ComfortGroup*)(&group))/*cast due to .constrained prefix*/).ToString().ToLowerInvariant(); } private static TMP_Text CreateBadge(Transform button) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Expected O, but got Unknown //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) TMP_Text val = (Object.op_Implicit((Object)(object)Hud.instance) ? Hud.instance.m_pieceDescription : null); if (!Object.op_Implicit((Object)(object)val)) { return null; } GameObject val2 = new GameObject("ShackComfortBadge", new Type[1] { typeof(RectTransform) }); val2.transform.SetParent(button, false); RectTransform val3 = (RectTransform)val2.transform; val3.anchorMin = Vector2.zero; val3.anchorMax = new Vector2(1f, 0.5f); val3.pivot = Vector2.zero; val3.offsetMin = new Vector2(4f, 2f); val3.offsetMax = new Vector2(-4f, 0f); TextMeshProUGUI obj = val2.AddComponent<TextMeshProUGUI>(); ((TMP_Text)obj).font = val.font; ((TMP_Text)obj).fontSharedMaterial = val.fontSharedMaterial; ((TMP_Text)obj).enableAutoSizing = true; ((TMP_Text)obj).fontSizeMin = 8f; ((TMP_Text)obj).fontSizeMax = 18f; ((TMP_Text)obj).fontStyle = (FontStyles)1; ((TMP_Text)obj).alignment = (TextAlignmentOptions)1025; ((TMP_Text)obj).overflowMode = (TextOverflowModes)0; ((Graphic)obj).color = BadgeColor; ((Graphic)obj).raycastTarget = false; val2.transform.SetAsLastSibling(); return (TMP_Text)(object)obj; } } internal static class Access { private static FieldInfo allComfortPiecesField; private static HashSet<Piece> allComfortPieces; public static FieldRef<Player, GameObject> PlacementGhost; public static HashSet<Piece> AllComfortPieces => allComfortPieces ?? (allComfortPieces = (HashSet<Piece>)allComfortPiecesField.GetValue(null)); public static void Init() { allComfortPiecesField = AccessTools.Field(typeof(Piece), "s_allComfortPieces") ?? throw new MissingFieldException("Piece", "s_allComfortPieces"); PlacementGhost = AccessTools.FieldRefAccess<Player, GameObject>("m_placementGhost"); } } internal static class Chain { public struct Link { public Vector3 From; public Vector3 To; } private struct RoofState { public bool Roofed; public float Until; } private const float RoofRecheck = 10f; private const int MaxPieces = 3000; private static readonly Dictionary<Piece, RoofState> roofs = new Dictionary<Piece, RoofState>(); private static readonly Dictionary<Piece, Vector3> anchors = new Dictionary<Piece, Vector3>(); private static float nextPurge; private static int roofMask; private static int ghostLayer = -1; private static readonly RaycastHit[] hits = (RaycastHit[])(object)new RaycastHit[32]; private static readonly List<Piece> nodes = new List<Piece>(); private static readonly Dictionary<Vector3Int, List<int>> cells = new Dictionary<Vector3Int, List<int>>(); private static readonly Stack<List<int>> spareCells = new Stack<List<int>>(); private static readonly Queue<int> queue = new Queue<int>(); private static readonly HashSet<Piece> already = new HashSet<Piece>(); private static int[] parent = new int[0]; private static float cellSize; private static readonly List<Piece> dead = new List<Piece>(); public static void AddChain(Vector3 center, float radius, List<Piece> result) { //IL_0009: 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) Snapshot(); for (int i = 0; i < nodes.Count; i++) { if (Vector3.Distance(center, ((Component)nodes[i]).transform.position) < radius && Linkable(nodes[i])) { parent[i] = -2; queue.Enqueue(i); } } Spread(); already.Clear(); already.UnionWith(result); for (int j = 0; j < nodes.Count; j++) { if (parent[j] != -1 && already.Add(nodes[j])) { result.Add(nodes[j]); } } } public static void Links(Piece focus, bool ghost, List<Link> links) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_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_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) links.Clear(); Snapshot(); Vector3 val = (ghost ? GhostAnchor(focus) : Anchor(focus)); if (ghost) { if (Settings.RoofedOnly.Value && !CheckRoof(focus, val)) { return; } Vector3 position = ((Component)focus).transform.position; for (int i = 0; i < nodes.Count; i++) { if (Vector3.Distance(position, ((Component)nodes[i]).transform.position) < Settings.LinkRange.Value && Linkable(nodes[i])) { parent[i] = -3; queue.Enqueue(i); } } } else { int num = nodes.IndexOf(focus); if (num < 0 || !Linkable(focus)) { return; } parent[num] = -2; queue.Enqueue(num); } Spread(); for (int j = 0; j < nodes.Count; j++) { if (parent[j] >= 0) { links.Add(new Link { From = Anchor(nodes[j]), To = Anchor(nodes[parent[j]]) }); } else if (parent[j] == -3) { links.Add(new Link { From = Anchor(nodes[j]), To = val }); } } } private static void Snapshot() { //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Unknown result type (might be due to invalid IL or missing references) if (ghostLayer < 0) { ghostLayer = LayerMask.NameToLayer("ghost"); roofMask = LayerMask.GetMask(new string[6] { "Default", "static_solid", "Default_small", "piece", "terrain", "vehicle" }); } PurgeCaches(); nodes.Clear(); queue.Clear(); foreach (List<int> value2 in cells.Values) { value2.Clear(); spareCells.Push(value2); } cells.Clear(); cellSize = Mathf.Max(1f, Settings.LinkRange.Value); foreach (Piece allComfortPiece in Access.AllComfortPieces) { if (Object.op_Implicit((Object)(object)allComfortPiece) && ((Component)allComfortPiece).gameObject.layer != ghostLayer) { nodes.Add(allComfortPiece); } } if (parent.Length < nodes.Count) { parent = new int[nodes.Count * 2]; } for (int i = 0; i < nodes.Count; i++) { parent[i] = -1; Vector3Int key = CellOf(((Component)nodes[i]).transform.position); if (!cells.TryGetValue(key, out var value)) { value = ((spareCells.Count > 0) ? spareCells.Pop() : new List<int>()); cells[key] = value; } value.Add(i); } } private static void Spread() { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_003c: 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_0042: 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_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) float value = Settings.LinkRange.Value; int num = queue.Count; while (queue.Count > 0) { int num2 = queue.Dequeue(); Vector3 position = ((Component)nodes[num2]).transform.position; Vector3Int val = CellOf(position); for (int i = -1; i <= 1; i++) { for (int j = -1; j <= 1; j++) { for (int k = -1; k <= 1; k++) { if (!cells.TryGetValue(new Vector3Int(((Vector3Int)(ref val)).x + i, ((Vector3Int)(ref val)).y + j, ((Vector3Int)(ref val)).z + k), out var value2)) { continue; } foreach (int item in value2) { if (parent[item] == -1 && !(Vector3.Distance(position, ((Component)nodes[item]).transform.position) >= value) && Linkable(nodes[item])) { parent[item] = num2; queue.Enqueue(item); if (++num >= 3000) { queue.Clear(); return; } } } } } } } } private static Vector3Int CellOf(Vector3 position) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0022: 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) return new Vector3Int(Mathf.FloorToInt(position.x / cellSize), Mathf.FloorToInt(position.y / cellSize), Mathf.FloorToInt(position.z / cellSize)); } private static bool Linkable(Piece piece) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) if (!Settings.RoofedOnly.Value) { return true; } float time = Time.time; if (roofs.TryGetValue(piece, out var value) && time < value.Until) { return value.Roofed; } bool flag = CheckRoof(piece, Anchor(piece)); roofs[piece] = new RoofState { Roofed = flag, Until = time + 10f + Random.Range(0f, 3f) }; return flag; } private static bool CheckRoof(Piece piece, Vector3 from) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) int num = Physics.SphereCastNonAlloc(from, 0.1f, Vector3.up, hits, 100f, roofMask); for (int i = 0; i < num; i++) { Collider collider = ((RaycastHit)(ref hits[i])).collider; if (Object.op_Implicit((Object)(object)collider) && !((Component)collider).CompareTag("leaky") && !((Object)(object)((Component)collider).GetComponentInParent<Piece>() == (Object)(object)piece)) { return true; } } return false; } private static Vector3 Anchor(Piece piece) { //IL_0022: 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_001c: Unknown result type (might be due to invalid IL or missing references) if (!anchors.TryGetValue(piece, out var value)) { value = Middle(piece); anchors[piece] = value; } return value; } private static Vector3 GhostAnchor(Piece ghost) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return Middle(ghost); } private static Vector3 Middle(Piece piece) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) bool flag = false; Bounds val = default(Bounds); Collider[] componentsInChildren = ((Component)piece).GetComponentsInChildren<Collider>(); foreach (Collider val2 in componentsInChildren) { if (val2.enabled && !val2.isTrigger) { if (flag) { ((Bounds)(ref val)).Encapsulate(val2.bounds); continue; } val = val2.bounds; flag = true; } } if (!flag) { return ((Component)piece).transform.position + Vector3.up * 0.5f; } return ((Bounds)(ref val)).center; } private static void PurgeCaches() { if (!(Time.time < nextPurge)) { nextPurge = Time.time + 60f; Purge(roofs); Purge(anchors); } } private static void Purge<T>(Dictionary<Piece, T> cache) { dead.Clear(); foreach (Piece key in cache.Keys) { if (!Object.op_Implicit((Object)(object)key)) { dead.Add(key); } } foreach (Piece item in dead) { cache.Remove(item); } } } internal static class ComfortPatches { [HarmonyPatch(typeof(SE_Rested), "CalculateComfortLevel", new Type[] { typeof(bool), typeof(Vector3) })] private static class SE_Rested_CalculateComfortLevel { private static void Prefix(Vector3 position) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) counting = Settings.Enabled.Value && !failed; center = position; } private static void Finalizer() { counting = false; } } [HarmonyPatch(typeof(Piece), "GetAllComfortPiecesInRadius")] private static class Piece_GetAllComfortPiecesInRadius { private static void Postfix(float radius, List<Piece> pieces) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) if (!counting) { return; } counting = false; try { Chain.AddChain(center, radius, pieces); } catch (Exception arg) { failed = true; Plugin.Log.LogError((object)$"Comfort chains failed; comfort is vanilla until the game restarts. {arg}"); } } } private static bool counting; private static Vector3 center; private static bool failed; } internal static class Dots { private const float Refresh = 0.1f; private const float Linger = 1f; private const int MaxLines = 150; private static GameObject prefab; private static bool prefabMissing; private static readonly List<GameObject> lines = new List<GameObject>(); private static readonly List<Chain.Link> links = new List<Chain.Link>(); private static float nextRefresh; private static float hideAt; public static void Update() { if (Time.time < nextRefresh) { return; } nextRefresh = Time.time + 0.1f; Player localPlayer = Player.m_localPlayer; if (!Object.op_Implicit((Object)(object)localPlayer) || !Settings.Enabled.Value || !Settings.ShowDots.Value || !Prefab()) { Clear(); return; } bool ghost; Piece val = Focus(localPlayer, out ghost); if (Object.op_Implicit((Object)(object)val)) { Chain.Links(val, ghost, links); if (links.Count == 0) { Clear(); return; } Show(); hideAt = Time.time + 1f; } else if (Time.time >= hideAt) { Clear(); } } private static Piece Focus(Player player, out bool ghost) { ghost = false; if (((Character)player).InPlaceMode()) { GameObject val = Access.PlacementGhost.Invoke(player); Piece val2 = ((Object.op_Implicit((Object)(object)val) && val.activeInHierarchy) ? val.GetComponent<Piece>() : null); if (Object.op_Implicit((Object)(object)val2) && val2.m_comfort > 0) { ghost = true; return val2; } val2 = player.GetHoveringPiece(); if (Object.op_Implicit((Object)(object)val2) && val2.m_comfort > 0) { return val2; } } GameObject hoverObject = ((Humanoid)player).GetHoverObject(); Piece val3 = (Object.op_Implicit((Object)(object)hoverObject) ? hoverObject.GetComponentInParent<Piece>() : null); if (!Object.op_Implicit((Object)(object)val3) || val3.m_comfort <= 0) { return null; } return val3; } private static void Show() { //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) int num = Mathf.Min(links.Count, 150); for (int i = 0; i < num; i++) { if (i == lines.Count) { lines.Add(Object.Instantiate<GameObject>(prefab)); } else if (!Object.op_Implicit((Object)(object)lines[i])) { lines[i] = Object.Instantiate<GameObject>(prefab); } Place(lines[i], links[i].From, links[i].To); } for (int num2 = lines.Count - 1; num2 >= num; num2--) { Destroy(lines[num2]); lines.RemoveAt(num2); } } private static void Place(GameObject line, Vector3 from, Vector3 to) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_002b: 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_005f: Unknown result type (might be due to invalid IL or missing references) Vector3 val = to - from; if (((Vector3)(ref val)).sqrMagnitude < 0.01f) { line.SetActive(false); return; } line.SetActive(true); line.transform.position = from; line.transform.rotation = Quaternion.LookRotation(((Vector3)(ref val)).normalized); line.transform.localScale = new Vector3(1f, 1f, ((Vector3)(ref val)).magnitude); } private static void Clear() { foreach (GameObject line in lines) { Destroy(line); } lines.Clear(); } private static void Destroy(GameObject line) { if (Object.op_Implicit((Object)(object)line)) { Object.Destroy((Object)(object)line); } } private static bool Prefab() { if (Object.op_Implicit((Object)(object)prefab)) { return true; } if (prefabMissing || !Object.op_Implicit((Object)(object)ZNetScene.instance)) { return false; } GameObject val = ZNetScene.instance.GetPrefab("piece_workbench_ext1"); StationExtension val2 = (Object.op_Implicit((Object)(object)val) ? val.GetComponent<StationExtension>() : null); prefab = (Object.op_Implicit((Object)(object)val2) ? val2.m_connectionPrefab : null); if (!Object.op_Implicit((Object)(object)prefab)) { prefabMissing = true; Plugin.Log.LogWarning((object)"The workbench extensions' connection effect wasn't found; comfort chains work but show no dots."); } return Object.op_Implicit((Object)(object)prefab); } } [BepInPlugin("theshack.comfortascended", "Shack Comfort Ascended", "1.0.1")] [BepInDependency(/*Could not decode attribute arguments.*/)] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] [SynchronizationMode(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { public const string PluginGuid = "theshack.comfortascended"; public const string PluginName = "Shack Comfort Ascended"; public const string PluginVersion = "1.0.1"; internal static ManualLogSource Log; private static bool ready; private void Awake() { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; Settings.Bind(((BaseUnityPlugin)this).Config); Harmony val = new Harmony("theshack.comfortascended"); try { Access.Init(); val.PatchAll(Assembly.GetExecutingAssembly()); } catch (Exception arg) { val.UnpatchSelf(); Log.LogError((object)string.Format("{0} could not hook into this game version; comfort stays vanilla. {1}", "Shack Comfort Ascended", arg)); return; } ready = true; Log.LogInfo((object)(string.Format("{0} {1} ready (link range {2} m, ", "Shack Comfort Ascended", "1.0.1", Settings.LinkRange.Value) + $"only roofed objects link: {Settings.RoofedOnly.Value}).")); } private void Update() { if (ready) { Dots.Update(); } } } internal static class Settings { public static ConfigEntry<bool> ShowDots; public static ConfigEntry<bool> ShowInBuildMenu; public static ConfigEntry<bool> Enabled; public static ConfigEntry<float> LinkRange; public static ConfigEntry<bool> RoofedOnly; public static void Bind(ConfigFile config) { int order = 100; ShowDots = Personal<bool>("0 - This PC", "Show chain dots", value: true, "Moving dots along the links of a comfort chain while you look at one of its objects (with the hammer out for rugs and banners) or place a comfort object, like the workbench and its extensions."); ShowInBuildMenu = Personal<bool>("0 - This PC", "Show comfort in build menu", value: true, "The hammer's build menu marks pieces that give comfort with \"+N\" on their icon, and the piece info says how much comfort it gives and which kind it counts as (only the best of each kind counts)."); Enabled = Bind<bool>("1 - General", "Enabled", value: true, "Comfort objects link into chains, and a chain counts as one. Off: vanilla comfort (only objects within 10 m)."); LinkRange = Bind<float>("1 - General", "Link range", 10f, "Two comfort objects link when they're closer than this, in meters. 10 = the game's own comfort radius.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 30f)); RoofedOnly = Bind<bool>("1 - General", "Only roofed objects link", value: true, "Only comfort objects under a roof join a chain, so banners and fires out in the yard don't bridge two houses. Unroofed objects still count the vanilla way when they're within 10 m of you."); ConfigEntry<T> Bind<T>(string section, string key, T value, string description, AcceptableValueBase range = null) { //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_0040: Expected O, but got Unknown //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Expected O, but got Unknown return config.Bind<T>(section, key, value, new ConfigDescription(description, range, new object[1] { (object)new ConfigurationManagerAttributes { IsAdminOnly = true, Order = order-- } })); } ConfigEntry<T> Personal<T>(string section, string key, T value, string description, AcceptableValueBase range = null) { //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_0039: Expected O, but got Unknown //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Expected O, but got Unknown return config.Bind<T>(section, key, value, new ConfigDescription(description, range, new object[1] { (object)new ConfigurationManagerAttributes { Order = order-- } })); } } } }