Decompiled source of Shack Comfort Ascended v1.0.1

ShackComfortAscended.dll

Decompiled 2 days ago
using 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--
				} }));
			}
		}
	}
}