Decompiled source of ValheimArchitect v0.5.19

BepInEx\plugins\ValheimArchitect\ValheimArchitect.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyVersion("0.0.0.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 ValheimArchitect
{
	internal sealed class ArchitectFeatures
	{
		private const string Section = "Функции";

		public readonly FeatureToggle ResourceCalculator;

		public readonly FeatureToggle AlignmentLines;

		public readonly FeatureToggle PinAlignmentGrid;

		public readonly FeatureToggle GhostLayout;

		public readonly IReadOnlyList<FeatureToggle> All;

		public ArchitectFeatures(ConfigFile config)
		{
			ResourceCalculator = Bind(config, "Калькулятор ресурсов", "Показывает общее количество ресурсов, необходимое для текущего фантомного макета.");
			AlignmentLines = Bind(config, "Лазерный уровень", "Показывает уровень земли по сетке 1×1 м и помогает выровнять участок перед строительством.");
			PinAlignmentGrid = Bind(config, "Закрепить уровень", "Фиксирует текущую высоту лазерного уровня. F10 переключает закрепление.");
			GhostLayout = Bind(config, "Фантомный макет", "Позволяет планировать строительство без расхода ресурсов. Детали макета отображаются синим цветом и не становятся настоящими постройками. Для удобства при больших проектах можно использовать отдельный мод со свободной камерой.");
			All = new List<FeatureToggle> { ResourceCalculator, AlignmentLines, PinAlignmentGrid, GhostLayout };
		}

		private static FeatureToggle Bind(ConfigFile config, string label, string description)
		{
			ConfigEntry<bool> config2 = config.Bind<bool>("Функции", label, false, description);
			return new FeatureToggle(label, description, config2);
		}
	}
	internal sealed class ArchitectMenu
	{
		private const int WindowId = 170335943;

		private readonly ArchitectFeatures _features;

		private Rect _windowRect = new Rect(0f, 0f, 760f, 680f);

		private bool _visible;

		private bool _sizeInitialized;

		private FeatureToggle _hovered;

		public bool IsVisible => _visible;

		public ArchitectMenu(ArchitectFeatures features)
		{
			//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)
			_features = features;
		}

		public void Toggle()
		{
			_visible = !_visible;
			_hovered = null;
		}

		public void Draw()
		{
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Expected O, but got Unknown
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			ArchitectStyle.EnsureInitialized();
			if (_features.GhostLayout.Value)
			{
				DrawGhostBanner();
			}
			if (_visible)
			{
				if (!_sizeInitialized)
				{
					((Rect)(ref _windowRect)).width = 760f;
					((Rect)(ref _windowRect)).height = 680f;
					((Rect)(ref _windowRect)).x = ((float)Screen.width - ((Rect)(ref _windowRect)).width) / 2f;
					((Rect)(ref _windowRect)).y = ((float)Screen.height - ((Rect)(ref _windowRect)).height) / 2f;
					_sizeInitialized = true;
				}
				else
				{
					((Rect)(ref _windowRect)).x = Mathf.Clamp(((Rect)(ref _windowRect)).x, 10f, Mathf.Max(10f, (float)Screen.width - ((Rect)(ref _windowRect)).width - 10f));
					((Rect)(ref _windowRect)).y = Mathf.Clamp(((Rect)(ref _windowRect)).y, 10f, Mathf.Max(10f, (float)Screen.height - ((Rect)(ref _windowRect)).height - 10f));
				}
				_windowRect = GUI.Window(170335943, _windowRect, new WindowFunction(DrawWindow), GUIContent.none, ArchitectStyle.Window);
			}
		}

		private void DrawGhostBanner()
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: 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)
			float num = 760f;
			float num2 = 82f;
			float num3 = ((float)Screen.width - num) * 0.5f;
			float num4 = 18f;
			GUI.Box(new Rect(num3, num4, num, num2), GUIContent.none, ArchitectStyle.Tooltip);
			GUI.Label(new Rect(num3 + 18f, num4 + 8f, num - 36f, 26f), "ФАНТОМНЫЙ МАКЕТ", ArchitectStyle.Title);
			GUI.Label(new Rect(num3 + 18f, num4 + 36f, num - 36f, 16f), "Планирование без расхода ресурсов", ArchitectStyle.Subtitle);
			ValheimArchitectPlugin instance = ValheimArchitectPlugin.Instance;
			int num5 = (((Object)(object)instance != (Object)null && instance.Ghost != null) ? instance.Ghost.BlueprintCount : 0);
			GUI.Label(new Rect(num3 + 18f, num4 + 57f, num - 36f, 14f), $"Деталей: {num5}    •    F11 — очистить макет", ArchitectStyle.Small);
		}

		private void DrawWindow(int id)
		{
			//IL_0027: 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_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01de: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0201: Unknown result type (might be due to invalid IL or missing references)
			//IL_0229: Unknown result type (might be due to invalid IL or missing references)
			//IL_022e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0253: Unknown result type (might be due to invalid IL or missing references)
			//IL_0289: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c2: Unknown result type (might be due to invalid IL or missing references)
			_hovered = null;
			GUI.Box(new Rect(16f, 16f, ((Rect)(ref _windowRect)).width - 32f, 82f), GUIContent.none, ArchitectStyle.Header);
			GUI.Label(new Rect(32f, 24f, ((Rect)(ref _windowRect)).width - 64f, 32f), "VALHEIM ARCHITECT", ArchitectStyle.Title);
			GUI.Label(new Rect(32f, 58f, ((Rect)(ref _windowRect)).width - 64f, 18f), "СТРОИТЕЛЬНЫЙ ИНСТРУМЕНТ", ArchitectStyle.Subtitle);
			if (GUI.Button(new Rect(((Rect)(ref _windowRect)).width - 50f, 28f, 26f, 26f), "×", ArchitectStyle.Close))
			{
				_visible = false;
				return;
			}
			GUILayout.BeginArea(new Rect(22f, 112f, ((Rect)(ref _windowRect)).width - 44f, ((Rect)(ref _windowRect)).height - 132f));
			GUILayout.Label("ПЛАНИРОВАНИЕ", ArchitectStyle.Section, Array.Empty<GUILayoutOption>());
			GUILayout.Space(6f);
			DrawFeature(_features.GhostLayout, "◆");
			DrawFeature(_features.ResourceCalculator, "◇");
			GUILayout.Space(14f);
			GUILayout.Label("ВЫРАВНИВАНИЕ", ArchitectStyle.Section, Array.Empty<GUILayoutOption>());
			GUILayout.Space(6f);
			DrawFeature(_features.AlignmentLines, "╋");
			DrawFeature(_features.PinAlignmentGrid, "□");
			GUILayout.Space(14f);
			DrawTooltipPanel();
			GUILayout.Space(10f);
			Rect rect = GUILayoutUtility.GetRect(0f, 18f);
			GUI.Label(new Rect(0f, ((Rect)(ref rect)).y, ((Rect)(ref _windowRect)).width - 48f, 18f), "F10 — закрепить / открепить уровень    •    F8 — закрыть", ArchitectStyle.Hint);
			GUILayout.Space(6f);
			rect = GUILayoutUtility.GetRect(0f, 46f);
			float y = ((Rect)(ref rect)).y;
			GUI.Box(new Rect(0f, y, ((Rect)(ref _windowRect)).width - 48f, 44f), GUIContent.none, ArchitectStyle.Tooltip);
			GUI.Label(new Rect(10f, y + 4f, ((Rect)(ref _windowRect)).width - 68f, 36f), "* Демонстрационный прототип. Мод создан при помощи ИИ для проверки и демонстрации идеи.", ArchitectStyle.Credits);
			GUILayout.EndArea();
			GUI.DragWindow(new Rect(20f, 16f, ((Rect)(ref _windowRect)).width - 92f, 82f));
		}

		private void DrawFeature(FeatureToggle feature, string icon)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			Rect rect = GUILayoutUtility.GetRect(0f, 60f, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) });
			GUIStyle val = (feature.Value ? ArchitectStyle.FeatureOn : ArchitectStyle.Feature);
			if (GUI.Button(rect, feature.Label, val))
			{
				feature.Value = !feature.Value;
			}
			GUIStyle val2 = (feature.Value ? ArchitectStyle.FeatureIconOn : ArchitectStyle.FeatureIcon);
			GUI.Label(new Rect(((Rect)(ref rect)).x + 12f, ((Rect)(ref rect)).y + 8f, 26f, ((Rect)(ref rect)).height - 16f), icon, val2);
			GUI.Label(new Rect(((Rect)(ref rect)).xMax - 82f, ((Rect)(ref rect)).y + 14f, 64f, 26f), feature.Value ? "ВКЛ" : "ВЫКЛ", feature.Value ? ArchitectStyle.StateOn : ArchitectStyle.StateOff);
			if (((Rect)(ref rect)).Contains(Event.current.mousePosition))
			{
				_hovered = feature;
			}
		}

		private void DrawTooltipPanel()
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			Rect rect = GUILayoutUtility.GetRect(0f, 142f, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) });
			GUI.Box(rect, GUIContent.none, ArchitectStyle.Tooltip);
			if (_hovered == null)
			{
				GUI.Label(new Rect(((Rect)(ref rect)).x + 14f, ((Rect)(ref rect)).y + 12f, ((Rect)(ref rect)).width - 28f, 22f), "ПОДСКАЗКА", ArchitectStyle.TooltipTitle);
				GUI.Label(new Rect(((Rect)(ref rect)).x + 14f, ((Rect)(ref rect)).y + 40f, ((Rect)(ref rect)).width - 28f, 70f), "Наведите курсор на функцию, чтобы увидеть, что она делает.", ArchitectStyle.TooltipBody);
			}
			else
			{
				GUI.Label(new Rect(((Rect)(ref rect)).x + 14f, ((Rect)(ref rect)).y + 10f, ((Rect)(ref rect)).width - 28f, 24f), _hovered.Label, ArchitectStyle.TooltipTitle);
				GUI.Label(new Rect(((Rect)(ref rect)).x + 14f, ((Rect)(ref rect)).y + 38f, ((Rect)(ref rect)).width - 28f, 84f), _hovered.Description, ArchitectStyle.TooltipBody);
			}
		}
	}
	internal static class ArchitectStyle
	{
		public static readonly Color WoodDark = new Color(0.07f, 0.04f, 0.02f, 0.985f);

		public static readonly Color Wood = new Color(0.12f, 0.067f, 0.032f, 0.99f);

		public static readonly Color WoodLight = new Color(0.17f, 0.095f, 0.045f, 1f);

		public static readonly Color WoodHover = new Color(0.205f, 0.115f, 0.052f, 1f);

		public static readonly Color WoodPressed = new Color(0.25f, 0.14f, 0.06f, 1f);

		public static readonly Color Bronze = new Color(0.45f, 0.27f, 0.1f, 1f);

		public static readonly Color BronzeBright = new Color(0.73f, 0.47f, 0.16f, 1f);

		public static readonly Color Gold = new Color(0.88f, 0.69f, 0.27f, 1f);

		public static readonly Color GoldBright = new Color(1f, 0.84f, 0.42f, 1f);

		public static readonly Color Text = new Color(0.94f, 0.89f, 0.78f, 1f);

		public static readonly Color Muted = new Color(0.66f, 0.59f, 0.47f, 1f);

		public static readonly Color Dim = new Color(0.45f, 0.39f, 0.3f, 1f);

		public static readonly Color Blue = new Color(0.34f, 0.82f, 0.96f, 1f);

		public static readonly Color BlueSoft = new Color(0.1f, 0.18f, 0.21f, 1f);

		private static GUIStyle _window;

		private static GUIStyle _windowCompact;

		private static GUIStyle _header;

		private static GUIStyle _headerCompact;

		private static GUIStyle _title;

		private static GUIStyle _subtitle;

		private static GUIStyle _section;

		private static GUIStyle _feature;

		private static GUIStyle _featureOn;

		private static GUIStyle _featureIcon;

		private static GUIStyle _featureIconOn;

		private static GUIStyle _state;

		private static GUIStyle _stateOn;

		private static GUIStyle _stateOff;

		private static GUIStyle _hint;

		private static GUIStyle _tooltip;

		private static GUIStyle _tooltipTitle;

		private static GUIStyle _tooltipBody;

		private static GUIStyle _small;

		private static GUIStyle _credits;

		private static GUIStyle _resourceName;

		private static GUIStyle _resourceAmount;

		private static GUIStyle _resourceHeader;

		private static GUIStyle _close;

		private static GUIStyle _closeSmall;

		private static GUIStyle _resourceRowA;

		private static GUIStyle _resourceRowB;

		private static bool _initialized;

		public static GUIStyle Window => _window;

		public static GUIStyle WindowCompact => _windowCompact;

		public static GUIStyle Header => _header;

		public static GUIStyle HeaderCompact => _headerCompact;

		public static GUIStyle Title => _title;

		public static GUIStyle Subtitle => _subtitle;

		public static GUIStyle Section => _section;

		public static GUIStyle Feature => _feature;

		public static GUIStyle FeatureOn => _featureOn;

		public static GUIStyle FeatureIcon => _featureIcon;

		public static GUIStyle FeatureIconOn => _featureIconOn;

		public static GUIStyle StateOn => _stateOn;

		public static GUIStyle StateOff => _stateOff;

		public static GUIStyle Hint => _hint;

		public static GUIStyle Tooltip => _tooltip;

		public static GUIStyle TooltipTitle => _tooltipTitle;

		public static GUIStyle TooltipBody => _tooltipBody;

		public static GUIStyle Small => _small;

		public static GUIStyle Credits => _credits;

		public static GUIStyle ResourceName => _resourceName;

		public static GUIStyle ResourceAmount => _resourceAmount;

		public static GUIStyle ResourceHeader => _resourceHeader;

		public static GUIStyle Close => _close;

		public static GUIStyle CloseSmall => _closeSmall;

		public static GUIStyle ResourceRowA => _resourceRowA;

		public static GUIStyle ResourceRowB => _resourceRowB;

		public static void EnsureInitialized()
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: 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_003e: 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_006a: Expected O, but got Unknown
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: 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_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Expected O, but got Unknown
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: 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_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Expected O, but got Unknown
			//IL_018d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Expected O, but got Unknown
			//IL_019b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: 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_01e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_0211: Unknown result type (might be due to invalid IL or missing references)
			//IL_0216: Unknown result type (might be due to invalid IL or missing references)
			//IL_022b: Unknown result type (might be due to invalid IL or missing references)
			//IL_024f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0254: Unknown result type (might be due to invalid IL or missing references)
			//IL_0276: Unknown result type (might be due to invalid IL or missing references)
			//IL_0280: Expected O, but got Unknown
			//IL_0284: 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_02ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02db: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e5: Expected O, but got Unknown
			//IL_02e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0311: Unknown result type (might be due to invalid IL or missing references)
			//IL_0335: Unknown result type (might be due to invalid IL or missing references)
			//IL_034e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0353: Unknown result type (might be due to invalid IL or missing references)
			//IL_0358: Unknown result type (might be due to invalid IL or missing references)
			//IL_037e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0397: Unknown result type (might be due to invalid IL or missing references)
			//IL_039c: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fa: Unknown result type (might be due to invalid IL or missing references)
			if (!_initialized)
			{
				_window = MakeFramedBox(WoodDark, Bronze, 4, 0.98f);
				_window.padding = new RectOffset(18, 18, 18, 16);
				_windowCompact = MakeFramedBox(WoodDark, Bronze, 4, 0.985f);
				_windowCompact.padding = new RectOffset(16, 16, 16, 14);
				_header = MakeFramedBox(Wood, BronzeBright, 3, 1f);
				_headerCompact = MakeFramedBox(Wood, BronzeBright, 3, 1f);
				_title = MakeLabel(24, (FontStyle)1, (TextAnchor)4, GoldBright, wrap: false);
				_subtitle = MakeLabel(11, (FontStyle)0, (TextAnchor)4, Muted, wrap: false);
				_section = MakeLabel(11, (FontStyle)1, (TextAnchor)3, Gold, wrap: false);
				_section.padding = new RectOffset(4, 0, 0, 0);
				_feature = MakeButton(Wood, WoodHover, WoodPressed, Text, 13, 44);
				_featureOn = MakeButton(new Color(0.17f, 0.12f, 0.065f, 1f), new Color(0.22f, 0.15f, 0.075f, 1f), new Color(0.29f, 0.19f, 0.09f, 1f), GoldBright, 13, 44);
				_feature.padding = new RectOffset(44, 88, 0, 0);
				_featureOn.padding = new RectOffset(44, 88, 0, 0);
				_featureIcon = MakeLabel(16, (FontStyle)1, (TextAnchor)4, BronzeBright, wrap: false);
				_featureIconOn = MakeLabel(16, (FontStyle)1, (TextAnchor)4, GoldBright, wrap: false);
				_state = MakeLabel(10, (FontStyle)1, (TextAnchor)4, Muted, wrap: false);
				_stateOn = MakePill(new Color(0.12f, 0.2f, 0.22f, 1f), Blue, 10);
				_stateOff = MakePill(new Color(0.12f, 0.075f, 0.035f, 1f), Muted, 10);
				_hint = MakeLabel(10, (FontStyle)0, (TextAnchor)4, Dim, wrap: false);
				_tooltip = MakeFramedBox(new Color(0.055f, 0.032f, 0.017f, 0.985f), Bronze, 2, 1f);
				_tooltip.padding = new RectOffset(14, 14, 11, 10);
				_tooltipTitle = MakeLabel(12, (FontStyle)1, (TextAnchor)3, GoldBright, wrap: false);
				_tooltipBody = MakeLabel(11, (FontStyle)0, (TextAnchor)0, Text, wrap: true);
				_small = MakeLabel(9, (FontStyle)0, (TextAnchor)4, Muted, wrap: false);
				_credits = MakeLabel(13, (FontStyle)1, (TextAnchor)4, GoldBright, wrap: true);
				_credits.padding = new RectOffset(10, 10, 2, 2);
				_resourceHeader = MakeLabel(16, (FontStyle)1, (TextAnchor)4, GoldBright, wrap: false);
				_resourceName = MakeLabel(13, (FontStyle)0, (TextAnchor)3, Text, wrap: false);
				_resourceAmount = MakeLabel(15, (FontStyle)1, (TextAnchor)5, GoldBright, wrap: false);
				_close = MakeButton(new Color(0.18f, 0.1f, 0.045f, 1f), new Color(0.29f, 0.17f, 0.07f, 1f), Bronze, Muted, 14, 0);
				_closeSmall = MakeButton(new Color(0.18f, 0.1f, 0.045f, 1f), new Color(0.29f, 0.17f, 0.07f, 1f), Bronze, Muted, 12, 0);
				_resourceRowA = MakeFramedBox(new Color(0.11f, 0.062f, 0.03f, 0.94f), Bronze, 1, 1f);
				_resourceRowB = MakeFramedBox(new Color(0.14f, 0.08f, 0.037f, 0.94f), BronzeSoft(), 1, 1f);
				_initialized = true;
			}
		}

		private static Color BronzeSoft()
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			return new Color(0.3f, 0.17f, 0.065f, 1f);
		}

		private static GUIStyle MakeLabel(int size, FontStyle style, TextAnchor anchor, Color color, bool wrap)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0047: Expected O, but got Unknown
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Expected O, but got Unknown
			//IL_0057: Expected O, but got Unknown
			GUIStyle val = new GUIStyle(GUI.skin.label)
			{
				fontSize = size,
				fontStyle = style,
				alignment = anchor,
				wordWrap = wrap
			};
			val.normal.textColor = color;
			val.padding = new RectOffset(0, 0, 0, 0);
			val.margin = new RectOffset(0, 0, 0, 0);
			return val;
		}

		private static GUIStyle MakeButton(Color normal, Color hover, Color active, Color textColor, int fontSize, int dummy)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Expected O, but got Unknown
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Expected O, but got Unknown
			//IL_00b5: Expected O, but got Unknown
			GUIStyle val = new GUIStyle(GUI.skin.button)
			{
				fontSize = fontSize,
				fontStyle = (FontStyle)1,
				alignment = (TextAnchor)3
			};
			val.normal.background = FramedTexture(normal, Bronze, 2);
			val.normal.textColor = textColor;
			val.hover.background = FramedTexture(hover, BronzeBright, 2);
			val.hover.textColor = GoldBright;
			val.active.background = FramedTexture(active, BronzeBright, 2);
			val.active.textColor = Color.white;
			val.border = new RectOffset(2, 2, 2, 2);
			val.margin = new RectOffset(0, 0, 4, 4);
			return val;
		}

		private static GUIStyle MakePill(Color bg, Color text, int fontSize)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: 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_003b: 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_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Expected O, but got Unknown
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Expected O, but got Unknown
			//IL_0066: Expected O, but got Unknown
			GUIStyle val = new GUIStyle(GUI.skin.label)
			{
				fontSize = fontSize,
				fontStyle = (FontStyle)1,
				alignment = (TextAnchor)4
			};
			val.normal.background = FramedTexture(bg, Bronze, 1);
			val.normal.textColor = text;
			val.border = new RectOffset(1, 1, 1, 1);
			val.padding = new RectOffset(8, 8, 3, 3);
			return val;
		}

		private static GUIStyle MakeFramedBox(Color fill, Color border, int thickness, float alpha)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: 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_002d: 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_0048: Expected O, but got Unknown
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Expected O, but got Unknown
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Expected O, but got Unknown
			//IL_0067: Expected O, but got Unknown
			GUIStyle val = new GUIStyle(GUI.skin.box);
			val.normal.background = FramedTexture(new Color(fill.r, fill.g, fill.b, alpha), border, thickness);
			val.border = new RectOffset(thickness, thickness, thickness, thickness);
			val.padding = new RectOffset(0, 0, 0, 0);
			val.margin = new RectOffset(0, 0, 0, 0);
			return val;
		}

		private static Texture2D FramedTexture(Color fill, Color border, int thickness)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: 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: Expected O, but got Unknown
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(48, 48, (TextureFormat)4, false)
			{
				hideFlags = (HideFlags)61,
				filterMode = (FilterMode)1,
				wrapMode = (TextureWrapMode)1
			};
			for (int i = 0; i < 48; i++)
			{
				float num = (Mathf.Sin((float)i * 0.55f) + Mathf.Sin((float)i * 0.17f)) * 0.012f;
				for (int j = 0; j < 48; j++)
				{
					Color val2 = (Color)((j < thickness || i < thickness || j >= 48 - thickness || i >= 48 - thickness) ? border : new Color(Mathf.Clamp01(fill.r + num), Mathf.Clamp01(fill.g + num * 0.7f), Mathf.Clamp01(fill.b + num * 0.45f), fill.a));
					val.SetPixel(j, i, val2);
				}
			}
			val.Apply();
			return val;
		}
	}
	internal sealed class BuildAssistController : IDisposable
	{
		private readonly ArchitectFeatures _features;

		private Camera _camera;

		private Material _lineMaterial;

		private bool _disposed;

		private bool _anchorValid;

		private bool _lastPinned;

		private Vector3 _anchor;

		private readonly bool[,] _blockedCells = new bool[12, 12];

		private float _obstacleCheckTimer;

		private const float ObstacleCheckInterval = 0.12f;

		private const int CellCount = 12;

		private const float GridSize = 1f;

		private const int Half = 6;

		private const float PlaneLift = 0.035f;

		private const float ObstacleProbeHeight = 0.62f;

		public BuildAssistController(ArchitectFeatures features)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Expected O, but got Unknown
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Expected O, but got Unknown
			_features = features;
			Camera.onPostRender = (CameraCallback)Delegate.Combine((Delegate?)(object)Camera.onPostRender, (Delegate?)new CameraCallback(OnPostRender));
		}

		public void Update()
		{
			if (_disposed)
			{
				return;
			}
			if ((Object)(object)_camera == (Object)null)
			{
				_camera = Camera.main;
			}
			if (!_features.AlignmentLines.Value)
			{
				_anchorValid = false;
				_lastPinned = false;
				Array.Clear(_blockedCells, 0, _blockedCells.Length);
				return;
			}
			if (_features.PinAlignmentGrid.Value && !_lastPinned)
			{
				CaptureAnchor();
			}
			else if (!_features.PinAlignmentGrid.Value && _lastPinned)
			{
				_anchorValid = false;
			}
			_lastPinned = _features.PinAlignmentGrid.Value;
			if (!_features.PinAlignmentGrid.Value)
			{
				UpdateFollowAnchor();
			}
			if (_anchorValid)
			{
				_obstacleCheckTimer -= Time.unscaledDeltaTime;
				if (_obstacleCheckTimer <= 0f)
				{
					_obstacleCheckTimer = 0.12f;
					RefreshBlockedCells();
				}
			}
		}

		public bool TryGetAnchor(out Vector3 anchor)
		{
			//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)
			anchor = _anchor;
			return _anchorValid;
		}

		public void TogglePinned()
		{
			_features.PinAlignmentGrid.Value = !_features.PinAlignmentGrid.Value;
			if (_features.PinAlignmentGrid.Value)
			{
				CaptureAnchor();
			}
			else
			{
				_anchorValid = false;
			}
			_lastPinned = _features.PinAlignmentGrid.Value;
			_obstacleCheckTimer = 0f;
		}

		private void CaptureAnchor()
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			if (!((Object)(object)localPlayer == (Object)null))
			{
				Vector3 position = ((Component)localPlayer).transform.position;
				float playerFootHeight = GetPlayerFootHeight(localPlayer);
				_anchor = new Vector3(position.x, playerFootHeight, position.z);
				_anchorValid = true;
				_obstacleCheckTimer = 0f;
			}
		}

		private void UpdateFollowAnchor()
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			if (!((Object)(object)localPlayer == (Object)null))
			{
				Vector3 position = ((Component)localPlayer).transform.position;
				float playerFootHeight = GetPlayerFootHeight(localPlayer);
				_anchor = new Vector3(position.x, playerFootHeight, position.z);
				_anchorValid = true;
			}
		}

		private void OnPostRender(Camera current)
		{
			if (!_disposed && _features.AlignmentLines.Value && !((Object)(object)current == (Object)null))
			{
				if ((Object)(object)_camera == (Object)null)
				{
					_camera = Camera.main;
				}
				if (!((Object)(object)_camera == (Object)null) && !((Object)(object)current != (Object)(object)_camera) && _anchorValid)
				{
					DrawAlignmentLines(current);
				}
			}
		}

		private void DrawAlignmentLines(Camera current)
		{
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0222: Unknown result type (might be due to invalid IL or missing references)
			//IL_022c: Unknown result type (might be due to invalid IL or missing references)
			//IL_022d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0237: Unknown result type (might be due to invalid IL or missing references)
			//IL_023c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0246: Unknown result type (might be due to invalid IL or missing references)
			//IL_0247: Unknown result type (might be due to invalid IL or missing references)
			//IL_0251: Unknown result type (might be due to invalid IL or missing references)
			//IL_0256: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: 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_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e2: Unknown result type (might be due to invalid IL or missing references)
			EnsureLineMaterial();
			if ((Object)(object)_lineMaterial == (Object)null)
			{
				return;
			}
			Vector3 val = default(Vector3);
			((Vector3)(ref val))..ctor(_anchor.x, _anchor.y + 0.035f, _anchor.z);
			_lineMaterial.SetPass(0);
			GL.Begin(1);
			float num = 6f;
			Vector3 val2 = default(Vector3);
			Vector3 end = default(Vector3);
			for (int i = 0; i <= 12; i++)
			{
				float num2 = 0f - num + (float)i * 1f;
				int num3 = i - 1;
				int num4 = i;
				for (int j = 0; j < 12; j++)
				{
					((Vector3)(ref val2))..ctor(val.x - num + (float)j * 1f, val.y, val.z + num2);
					((Vector3)(ref end))..ctor(val2.x + 1f, val.y, val2.z);
					bool blocked = (num3 >= 0 && num3 < 12 && _blockedCells[j, num3]) || (num4 >= 0 && num4 < 12 && _blockedCells[j, num4]);
					DrawSegment(val2, end, blocked, i == 6);
				}
			}
			Vector3 val3 = default(Vector3);
			Vector3 end2 = default(Vector3);
			for (int k = 0; k <= 12; k++)
			{
				float num5 = 0f - num + (float)k * 1f;
				int num6 = k - 1;
				int num7 = k;
				for (int l = 0; l < 12; l++)
				{
					((Vector3)(ref val3))..ctor(val.x + num5, val.y, val.z - num + (float)l * 1f);
					((Vector3)(ref end2))..ctor(val3.x, val.y, val3.z + 1f);
					bool blocked2 = (num6 >= 0 && num6 < 12 && _blockedCells[num6, l]) || (num7 >= 0 && num7 < 12 && _blockedCells[num7, l]);
					DrawSegment(val3, end2, blocked2, k == 6);
				}
			}
			GL.Color(new Color(0.35f, 0.95f, 1f, 1f));
			GL.Vertex(val + Vector3.down * 1.25f);
			GL.Vertex(val + Vector3.up * 1.25f);
			GL.End();
		}

		private void RefreshBlockedCells()
		{
			//IL_00ba: 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_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: 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)
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null || !_anchorValid)
			{
				return;
			}
			float y = _anchor.y;
			float num = 6f;
			Vector3 val = default(Vector3);
			((Vector3)(ref val))..ctor(0.47f, 0.31f, 0.47f);
			int num2 = -5;
			Array.Clear(_blockedCells, 0, _blockedCells.Length);
			for (int i = 0; i < 12; i++)
			{
				for (int j = 0; j < 12; j++)
				{
					float num3 = _anchor.x - num + ((float)i + 0.5f) * 1f;
					float num4 = _anchor.z - num + ((float)j + 0.5f) * 1f;
					Collider[] array = Physics.OverlapBox(new Vector3(num3, y + 0.035f + 0.31f, num4), val, Quaternion.identity, num2, (QueryTriggerInteraction)1);
					bool flag = false;
					foreach (Collider val2 in array)
					{
						if (!((Object)(object)val2 == (Object)null) && !((Object)(object)((Component)val2).transform == (Object)(object)((Component)localPlayer).transform) && !((Component)val2).transform.IsChildOf(((Component)localPlayer).transform))
						{
							Bounds bounds = val2.bounds;
							if (((Bounds)(ref bounds)).max.y > y + 0.035f + 0.02f)
							{
								flag = true;
								break;
							}
						}
					}
					_blockedCells[i, j] = flag;
				}
			}
		}

		private float GetPlayerFootHeight(Player player)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: 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_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			RaycastHit[] array = Physics.RaycastAll(((Component)player).transform.position + Vector3.up * 0.6f, Vector3.down, 3f, -5, (QueryTriggerInteraction)1);
			float num = float.NegativeInfinity;
			for (int i = 0; i < array.Length; i++)
			{
				Collider collider = ((RaycastHit)(ref array[i])).collider;
				if (!((Object)(object)collider == (Object)null) && !((Object)(object)((Component)collider).transform == (Object)(object)((Component)player).transform) && !((Component)collider).transform.IsChildOf(((Component)player).transform) && ((RaycastHit)(ref array[i])).point.y <= ((Component)player).transform.position.y + 0.5f && ((RaycastHit)(ref array[i])).point.y > num)
				{
					num = ((RaycastHit)(ref array[i])).point.y;
				}
			}
			if (num > float.NegativeInfinity)
			{
				return num;
			}
			Collider component = ((Component)player).GetComponent<Collider>();
			if ((Object)(object)component != (Object)null && component.enabled)
			{
				Bounds bounds = component.bounds;
				return ((Bounds)(ref bounds)).min.y;
			}
			return ((Component)player).transform.position.y - 0.9f;
		}

		private void DrawSegment(Vector3 start, Vector3 end, bool blocked, bool center)
		{
			//IL_0051: 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_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			GL.Color(blocked ? new Color(1f, 0.1f, 0.1f, 1f) : (center ? new Color(0.35f, 0.95f, 1f, 1f) : new Color(1f, 0.9f, 0.25f, 1f)));
			GL.Vertex(start);
			GL.Vertex(end);
		}

		private void EnsureLineMaterial()
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Expected O, but got Unknown
			if (!((Object)(object)_lineMaterial != (Object)null))
			{
				Shader val = Shader.Find("Hidden/Internal-Colored");
				if (!((Object)(object)val == (Object)null))
				{
					_lineMaterial = new Material(val)
					{
						hideFlags = (HideFlags)61
					};
					_lineMaterial.SetInt("_SrcBlend", 5);
					_lineMaterial.SetInt("_DstBlend", 10);
					_lineMaterial.SetInt("_Cull", 0);
					_lineMaterial.SetInt("_ZWrite", 0);
					_lineMaterial.SetInt("_ZTest", 8);
				}
			}
		}

		public void Dispose()
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Expected O, but got Unknown
			if (!_disposed)
			{
				_disposed = true;
				Camera.onPostRender = (CameraCallback)Delegate.Remove((Delegate?)(object)Camera.onPostRender, (Delegate?)new CameraCallback(OnPostRender));
				if ((Object)(object)_lineMaterial != (Object)null)
				{
					Object.Destroy((Object)(object)_lineMaterial);
					_lineMaterial = null;
				}
			}
		}
	}
	internal sealed class FeatureToggle
	{
		public string Label { get; }

		public string Description { get; }

		public ConfigEntry<bool> Config { get; }

		public bool Value
		{
			get
			{
				return Config.Value;
			}
			set
			{
				Config.Value = value;
			}
		}

		public FeatureToggle(string label, string description, ConfigEntry<bool> config)
		{
			Label = label;
			Description = description;
			Config = config;
		}
	}
	internal sealed class GhostLayoutController : IDisposable
	{
		private sealed class BlueprintPiece
		{
			public string PrefabName;

			public Vector3 Position;

			public Quaternion Rotation;
		}

		[HarmonyPatch(typeof(ZNetView), "Awake")]
		private static class ZNetViewGhostSpawnPatch
		{
			private static bool Prefix()
			{
				return !IsGhostSpawnInProgress;
			}
		}

		[HarmonyPatch]
		private static class PlayerHaveRequirementsPatch
		{
			private static IEnumerable<MethodBase> TargetMethods()
			{
				MethodInfo[] methods = typeof(Player).GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				foreach (MethodInfo methodInfo in methods)
				{
					if (!(methodInfo.Name != "HaveRequirements") && !(methodInfo.ReturnType != typeof(bool)))
					{
						ParameterInfo[] parameters = methodInfo.GetParameters();
						if (parameters.Length != 0 && parameters[0].ParameterType == typeof(Piece))
						{
							yield return methodInfo;
						}
					}
				}
			}

			private static bool Prefix(Player __instance, object[] __args, ref bool __result)
			{
				if (!IsGhostModeActive(__instance))
				{
					return true;
				}
				Piece val = null;
				if (__args != null)
				{
					foreach (object obj in __args)
					{
						Piece val2 = (Piece)((obj is Piece) ? obj : null);
						if (val2 != null)
						{
							val = val2;
							break;
						}
					}
				}
				if ((Object)(object)val == (Object)null || !IsPieceUnlocked(__instance, val))
				{
					return true;
				}
				__result = true;
				return false;
			}
		}

		[HarmonyPatch]
		private static class PlayerConsumeResourcesPatch
		{
			private static IEnumerable<MethodBase> TargetMethods()
			{
				MethodInfo[] methods = typeof(Player).GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				foreach (MethodInfo methodInfo in methods)
				{
					if (methodInfo.Name == "ConsumeResources")
					{
						yield return methodInfo;
					}
				}
			}

			private static bool Prefix(Player __instance)
			{
				if (!IsGhostModeActive(__instance))
				{
					return true;
				}
				Piece val = null;
				try
				{
					val = __instance.GetSelectedPiece();
				}
				catch
				{
					return true;
				}
				if ((Object)(object)val == (Object)null || !IsPieceUnlocked(__instance, val))
				{
					return true;
				}
				return false;
			}
		}

		[HarmonyPatch]
		private static class PlayerGetPlaceDurabilityPatch
		{
			private static IEnumerable<MethodBase> TargetMethods()
			{
				MethodInfo[] methods = typeof(Player).GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				foreach (MethodInfo methodInfo in methods)
				{
					if (!(methodInfo.Name != "GetPlaceDurability") && !(methodInfo.ReturnType != typeof(float)))
					{
						ParameterInfo[] parameters = methodInfo.GetParameters();
						if (parameters.Length == 1 && parameters[0].ParameterType == typeof(ItemData))
						{
							yield return methodInfo;
						}
					}
				}
			}

			private static bool Prefix(ItemData __0, ref float __result)
			{
				if (!IsGhostBuildToolItem(__0))
				{
					return true;
				}
				__result = 0f;
				return false;
			}
		}

		[HarmonyPatch]
		private static class HumanoidDrainEquippedItemDurabilityPatch
		{
			private static IEnumerable<MethodBase> TargetMethods()
			{
				MethodInfo[] methods = typeof(Humanoid).GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				foreach (MethodInfo methodInfo in methods)
				{
					if (!(methodInfo.Name != "DrainEquipedItemDurability"))
					{
						ParameterInfo[] parameters = methodInfo.GetParameters();
						if (parameters.Length >= 1 && parameters[0].ParameterType == typeof(ItemData))
						{
							yield return methodInfo;
						}
					}
				}
			}

			private static bool Prefix(Humanoid __instance, object[] __args)
			{
				if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer)
				{
					return true;
				}
				ItemData item = null;
				if (__args != null)
				{
					foreach (object obj in __args)
					{
						ItemData val = (ItemData)((obj is ItemData) ? obj : null);
						if (val != null)
						{
							item = val;
							break;
						}
					}
				}
				if (!IsGhostBuildToolItem(item))
				{
					return true;
				}
				return false;
			}
		}

		[HarmonyPatch]
		private static class PlayerCheckCanRemovePiecePatch
		{
			private static IEnumerable<MethodBase> TargetMethods()
			{
				MethodInfo[] methods = typeof(Player).GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				foreach (MethodInfo methodInfo in methods)
				{
					if (methodInfo.Name == "CheckCanRemovePiece" && methodInfo.ReturnType == typeof(bool))
					{
						yield return methodInfo;
					}
				}
			}

			private static bool Prefix(Player __instance, object[] __args, ref bool __result)
			{
				if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer)
				{
					return true;
				}
				Piece val = null;
				if (__args != null)
				{
					foreach (object obj in __args)
					{
						Piece val2 = (Piece)((obj is Piece) ? obj : null);
						if (val2 != null)
						{
							val = val2;
							break;
						}
					}
				}
				if ((Object)(object)val != (Object)null && ValheimArchitectPlugin.Instance?.Ghost != null && ValheimArchitectPlugin.Instance.Ghost.IsGhostPiece(val))
				{
					__result = true;
					return false;
				}
				return true;
			}
		}

		[HarmonyPatch]
		private static class PlayerRemovePiecePatch
		{
			private static IEnumerable<MethodBase> TargetMethods()
			{
				MethodInfo[] methods = typeof(Player).GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				foreach (MethodInfo methodInfo in methods)
				{
					if (methodInfo.Name == "RemovePiece" && methodInfo.ReturnType == typeof(bool))
					{
						yield return methodInfo;
					}
				}
			}

			private static bool Prefix(Player __instance, ref bool __result)
			{
				if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer)
				{
					return true;
				}
				GhostLayoutController ghostLayoutController = ValheimArchitectPlugin.Instance?.Ghost;
				if (ghostLayoutController == null)
				{
					return true;
				}
				if (ghostLayoutController.TryRemoveGhostUnderCrosshair(__instance))
				{
					__result = true;
					return false;
				}
				return true;
			}
		}

		[HarmonyPatch(typeof(Player), "PlacePiece")]
		private static class PlayerPlacePiecePatch
		{
			private static bool Prefix(Player __instance, Piece piece, Vector3 pos, Quaternion rot, bool doAttack)
			{
				//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)
				if (!IsGhostModeActive(__instance))
				{
					return true;
				}
				ValheimArchitectPlugin instance = ValheimArchitectPlugin.Instance;
				if (instance?.Ghost == null || (Object)(object)piece == (Object)null)
				{
					return true;
				}
				if (!IsPieceUnlocked(__instance, piece))
				{
					return true;
				}
				instance.Ghost.CreateGhost(piece, pos, rot, saveToBlueprint: true);
				return false;
			}
		}

		private readonly ArchitectFeatures _features;

		private readonly Harmony _harmony;

		private readonly List<GameObject> _ghosts = new List<GameObject>();

		private readonly Dictionary<GameObject, BlueprintPiece> _ghostToBlueprint = new Dictionary<GameObject, BlueprintPiece>();

		private readonly List<BlueprintPiece> _blueprint = new List<BlueprintPiece>();

		private readonly List<string> _pieceNames = new List<string>();

		private readonly string _blueprintFile;

		private bool _disposed;

		private int _blueprintRevision;

		private readonly Dictionary<string, List<ResourceCostLine>> _resourceCostCache = new Dictionary<string, List<ResourceCostLine>>(StringComparer.Ordinal);

		private readonly Dictionary<string, Piece> _prefabPieceCache = new Dictionary<string, Piece>(StringComparer.Ordinal);

		private readonly Dictionary<string, string> _localizedNameCache = new Dictionary<string, string>(StringComparer.Ordinal);

		private bool _loadedForCurrentScene;

		private bool _lastGhostMode;

		private int _loadCooldownFrames;

		private const string HarmonyId = "ValheimArchitect.GhostLayout";

		internal static bool IsGhostSpawnInProgress;

		private static MethodInfo _isRecipeKnownMethod;

		private static FieldInfo _knownRecipesField;

		private static MethodInfo _localizeMethod;

		private static object _localizeInstance;

		public IReadOnlyList<string> PieceNames => _pieceNames;

		public int GhostCount => _ghosts.Count;

		public int BlueprintCount => _blueprint.Count;

		public int BlueprintRevision => _blueprintRevision;

		public bool HasSavedBlueprint
		{
			get
			{
				if (File.Exists(_blueprintFile))
				{
					return _blueprint.Count > 0;
				}
				return false;
			}
		}

		public GhostLayoutController(ArchitectFeatures features)
		{
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Expected O, but got Unknown
			_features = features;
			_harmony = new Harmony("ValheimArchitect.GhostLayout");
			_harmony.PatchAll(typeof(GhostLayoutController).Assembly);
			string text = Path.Combine(Paths.ConfigPath, "ValheimArchitect");
			Directory.CreateDirectory(text);
			_blueprintFile = Path.Combine(text, "LastBlueprint.va");
			LoadBlueprintFile();
			_lastGhostMode = _features.GhostLayout.Value;
			SceneManager.sceneUnloaded += OnSceneUnloaded;
			SceneManager.sceneLoaded += OnSceneLoaded;
		}

		private static bool IsGhostModeActive(Player player)
		{
			ValheimArchitectPlugin instance = ValheimArchitectPlugin.Instance;
			if ((Object)(object)instance != (Object)null && instance.Ghost != null && instance.Features != null && instance.Features.GhostLayout.Value && (Object)(object)player != (Object)null)
			{
				return (Object)(object)player == (Object)(object)Player.m_localPlayer;
			}
			return false;
		}

		private static bool IsPieceUnlocked(Player player, Piece piece)
		{
			if ((Object)(object)player == (Object)null || (Object)(object)piece == (Object)null || string.IsNullOrWhiteSpace(piece.m_name))
			{
				return false;
			}
			try
			{
				if (_isRecipeKnownMethod == null)
				{
					_isRecipeKnownMethod = typeof(Player).GetMethod("IsRecipeKnown", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[1] { typeof(string) }, null);
				}
				if (_isRecipeKnownMethod != null && _isRecipeKnownMethod.Invoke(player, new object[1] { piece.m_name }) is bool result)
				{
					return result;
				}
			}
			catch
			{
			}
			try
			{
				if (_knownRecipesField == null)
				{
					_knownRecipesField = typeof(Player).GetField("m_knownRecipes", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				}
				if (_knownRecipesField?.GetValue(player) is IEnumerable enumerable)
				{
					foreach (object item in enumerable)
					{
						if (item is string a && string.Equals(a, piece.m_name, StringComparison.Ordinal))
						{
							return true;
						}
					}
				}
			}
			catch
			{
			}
			return false;
		}

		public void Update()
		{
			if (_disposed)
			{
				return;
			}
			bool value = _features.GhostLayout.Value;
			if (Input.GetKeyDown((KeyCode)292) && value)
			{
				ClearAndForgetBlueprint();
			}
			if (value != _lastGhostMode)
			{
				_lastGhostMode = value;
				if (value)
				{
					_loadedForCurrentScene = false;
					_loadCooldownFrames = 10;
				}
				else
				{
					DestroyGhostObjectsOnly();
				}
			}
			if (value && !_loadedForCurrentScene)
			{
				if (_loadCooldownFrames > 0)
				{
					_loadCooldownFrames--;
				}
				else
				{
					TryRestoreBlueprint();
				}
			}
		}

		private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
		{
			_loadedForCurrentScene = false;
			_loadCooldownFrames = 30;
		}

		private static bool IsGhostBuildToolItem(ItemData item)
		{
			if (item == null || item.m_shared == null || (Object)(object)item.m_shared.m_buildPieces == (Object)null)
			{
				return false;
			}
			Player localPlayer = Player.m_localPlayer;
			if (!IsGhostModeActive(localPlayer))
			{
				return false;
			}
			try
			{
				Piece selectedPiece = localPlayer.GetSelectedPiece();
				return (Object)(object)selectedPiece != (Object)null && IsPieceUnlocked(localPlayer, selectedPiece);
			}
			catch
			{
				return false;
			}
		}

		private void CreateGhost(Piece source, Vector3 position, Quaternion rotation, bool saveToBlueprint, BlueprintPiece existingBlueprint = null)
		{
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)source == (Object)null || (Object)(object)((Component)source).gameObject == (Object)null)
			{
				return;
			}
			string text = ((Object)((Component)source).gameObject).name.Replace("(Clone)", string.Empty).Trim();
			if (string.IsNullOrWhiteSpace(text))
			{
				text = ((Object)source).name.Replace("(Clone)", string.Empty).Trim();
			}
			GameObject val;
			try
			{
				IsGhostSpawnInProgress = true;
				val = Object.Instantiate<GameObject>(((Component)source).gameObject, position, rotation);
			}
			catch (Exception arg)
			{
				ValheimArchitectPlugin.Log.LogError((object)$"Ghost instantiate failed: {arg}");
				return;
			}
			finally
			{
				IsGhostSpawnInProgress = false;
			}
			PrepareGhostVisual(val);
			_ghosts.Add(val);
			_pieceNames.Add(text);
			BlueprintPiece blueprintPiece = existingBlueprint;
			if (blueprintPiece == null && saveToBlueprint)
			{
				blueprintPiece = new BlueprintPiece
				{
					PrefabName = text,
					Position = position,
					Rotation = rotation
				};
				_blueprint.Add(blueprintPiece);
				_blueprintRevision++;
				SaveBlueprintFile();
			}
			if (blueprintPiece != null)
			{
				_ghostToBlueprint[val] = blueprintPiece;
			}
		}

		private static void PrepareGhostVisual(GameObject ghost)
		{
			if ((Object)(object)ghost == (Object)null)
			{
				return;
			}
			((Object)ghost).name = "[ValheimArchitect Ghost] " + ((Object)ghost).name;
			((Object)ghost).hideFlags = (HideFlags)61;
			Behaviour[] componentsInChildren = ghost.GetComponentsInChildren<Behaviour>(true);
			foreach (Behaviour val in componentsInChildren)
			{
				if ((Object)(object)val != (Object)null && !(val is Piece))
				{
					val.enabled = false;
				}
			}
			int num = LayerMask.NameToLayer("piece_nonsolid");
			int num2 = LayerMask.NameToLayer("piece");
			int num3 = ((num >= 0) ? num : num2);
			if (num3 >= 0)
			{
				SetLayerRecursively(ghost.transform, num3);
			}
			Collider[] componentsInChildren2 = ghost.GetComponentsInChildren<Collider>(true);
			foreach (Collider val2 in componentsInChildren2)
			{
				if ((Object)(object)val2 != (Object)null)
				{
					val2.enabled = true;
					val2.isTrigger = false;
				}
			}
			Rigidbody[] componentsInChildren3 = ghost.GetComponentsInChildren<Rigidbody>(true);
			foreach (Rigidbody val3 in componentsInChildren3)
			{
				if ((Object)(object)val3 != (Object)null)
				{
					val3.isKinematic = true;
					val3.detectCollisions = false;
				}
			}
			ZNetView[] componentsInChildren4 = ghost.GetComponentsInChildren<ZNetView>(true);
			for (int i = 0; i < componentsInChildren4.Length; i++)
			{
				Object.Destroy((Object)(object)componentsInChildren4[i]);
			}
			WearNTear[] componentsInChildren5 = ghost.GetComponentsInChildren<WearNTear>(true);
			for (int i = 0; i < componentsInChildren5.Length; i++)
			{
				Object.Destroy((Object)(object)componentsInChildren5[i]);
			}
			ApplyGhostMaterials(ghost);
		}

		private static void SetLayerRecursively(Transform root, int layer)
		{
			((Component)root).gameObject.layer = layer;
			for (int i = 0; i < root.childCount; i++)
			{
				SetLayerRecursively(root.GetChild(i), layer);
			}
		}

		private static void ApplyGhostMaterials(GameObject ghost)
		{
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Expected O, but got Unknown
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Expected O, but got Unknown
			if ((Object)(object)ghost == (Object)null)
			{
				return;
			}
			Renderer[] componentsInChildren = ghost.GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val in componentsInChildren)
			{
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				Material[] sharedMaterials = val.sharedMaterials;
				Material[] array = (Material[])(object)new Material[sharedMaterials.Length];
				for (int j = 0; j < sharedMaterials.Length; j++)
				{
					Material val2 = sharedMaterials[j];
					if ((Object)(object)val2 == (Object)null)
					{
						continue;
					}
					Material val3 = null;
					try
					{
						val3 = new Material(val2);
						ConfigureGhostMaterial(val3);
					}
					catch
					{
						val3 = null;
					}
					if ((Object)(object)val3 == (Object)null)
					{
						Shader val4 = Shader.Find("Unlit/Transparent") ?? Shader.Find("Legacy Shaders/Transparent/Diffuse") ?? Shader.Find("Standard");
						if ((Object)(object)val4 != (Object)null)
						{
							try
							{
								val3 = new Material(val4);
								if (val2.HasProperty("_MainTex") && val3.HasProperty("_MainTex"))
								{
									val3.SetTexture("_MainTex", val2.GetTexture("_MainTex"));
								}
								if (val2.HasProperty("_BaseMap") && val3.HasProperty("_BaseMap"))
								{
									val3.SetTexture("_BaseMap", val2.GetTexture("_BaseMap"));
								}
								ConfigureGhostMaterial(val3);
							}
							catch
							{
								val3 = null;
							}
						}
					}
					array[j] = val3 ?? val2;
				}
				val.materials = array;
				val.receiveShadows = false;
				val.shadowCastingMode = (ShadowCastingMode)0;
			}
		}

		private static void ConfigureGhostMaterial(Material mat)
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: 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_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00cd: 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_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: 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_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)mat == (Object)null))
			{
				Color val = default(Color);
				((Color)(ref val))..ctor(0.42f, 0.88f, 1f, 0.58f);
				bool flag = false;
				if (mat.HasProperty("_BaseColor"))
				{
					Color color = mat.GetColor("_BaseColor");
					color.r = Mathf.Lerp(color.r, val.r, 0.55f);
					color.g = Mathf.Lerp(color.g, val.g, 0.55f);
					color.b = Mathf.Lerp(color.b, val.b, 0.55f);
					color.a = val.a;
					mat.SetColor("_BaseColor", color);
					flag = true;
				}
				if (mat.HasProperty("_Color"))
				{
					Color color2 = mat.GetColor("_Color");
					color2.r = Mathf.Lerp(color2.r, val.r, 0.55f);
					color2.g = Mathf.Lerp(color2.g, val.g, 0.55f);
					color2.b = Mathf.Lerp(color2.b, val.b, 0.55f);
					color2.a = val.a;
					mat.SetColor("_Color", color2);
					flag = true;
				}
				if (mat.HasProperty("_EmissionColor"))
				{
					mat.SetColor("_EmissionColor", new Color(0.1f, 0.55f, 0.75f, 1f));
					mat.EnableKeyword("_EMISSION");
				}
				if (mat.HasProperty("_Mode"))
				{
					mat.SetFloat("_Mode", 3f);
				}
				if (mat.HasProperty("_Surface"))
				{
					mat.SetFloat("_Surface", 1f);
				}
				if (mat.HasProperty("_Blend"))
				{
					mat.SetFloat("_Blend", 0f);
				}
				if (mat.HasProperty("_SrcBlend"))
				{
					mat.SetInt("_SrcBlend", 5);
				}
				if (mat.HasProperty("_DstBlend"))
				{
					mat.SetInt("_DstBlend", 10);
				}
				if (mat.HasProperty("_ZWrite"))
				{
					mat.SetInt("_ZWrite", 0);
				}
				if (mat.HasProperty("_AlphaClip"))
				{
					mat.SetFloat("_AlphaClip", 0f);
				}
				if (mat.HasProperty("_Cutoff"))
				{
					mat.SetFloat("_Cutoff", 0f);
				}
				mat.DisableKeyword("_ALPHATEST_ON");
				mat.EnableKeyword("_ALPHABLEND_ON");
				mat.EnableKeyword("_SURFACE_TYPE_TRANSPARENT");
				mat.renderQueue = 3000;
				if (!flag)
				{
					mat.renderQueue = -1;
				}
			}
		}

		internal bool IsGhostPiece(Piece piece)
		{
			if ((Object)(object)piece == (Object)null)
			{
				return false;
			}
			if ((Object)(object)((Component)piece).gameObject == (Object)null)
			{
				return false;
			}
			foreach (GameObject ghost in _ghosts)
			{
				if (!((Object)(object)ghost == (Object)null) && ((Object)(object)((Component)piece).transform == (Object)(object)ghost.transform || ((Component)piece).transform.IsChildOf(ghost.transform)))
				{
					return true;
				}
			}
			return false;
		}

		internal bool TryRemoveGhostUnderCrosshair(Player player)
		{
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)player == (Object)null || (Object)(object)GameCamera.instance == (Object)null || !Object.op_Implicit((Object)(object)GameCamera.instance) || _ghosts.Count == 0)
			{
				return false;
			}
			try
			{
				int num = -5;
				FieldInfo fieldInfo = AccessTools.Field(typeof(Player), "m_removeRayMask");
				if (fieldInfo != null)
				{
					num = (int)fieldInfo.GetValue(player);
				}
				float num2 = 4f;
				FieldInfo fieldInfo2 = AccessTools.Field(typeof(Player), "m_maxPlaceDistance");
				if (fieldInfo2 != null)
				{
					num2 = Mathf.Max(1f, (float)fieldInfo2.GetValue(player));
				}
				Vector3 position = ((Component)GameCamera.instance).transform.position;
				Vector3 forward = ((Component)GameCamera.instance).transform.forward;
				RaycastHit[] array = Physics.RaycastAll(position, forward, num2, num);
				Array.Sort(array, (RaycastHit a, RaycastHit b) => ((RaycastHit)(ref a)).distance.CompareTo(((RaycastHit)(ref b)).distance));
				RaycastHit[] array2 = array;
				for (int num3 = 0; num3 < array2.Length; num3++)
				{
					RaycastHit val = array2[num3];
					if (!((Object)(object)((RaycastHit)(ref val)).collider == (Object)null))
					{
						GameObject gameObject = ((Component)((RaycastHit)(ref val)).collider).gameObject;
						while ((Object)(object)gameObject != (Object)null && !IsTrackedGhostRoot(gameObject) && !((Object)(object)gameObject.transform.parent == (Object)null))
						{
							gameObject = ((Component)gameObject.transform.parent).gameObject;
						}
						if (!((Object)(object)gameObject == (Object)null) && IsTrackedGhostRoot(gameObject))
						{
							return RemoveGhostObject(gameObject);
						}
					}
				}
			}
			catch (Exception ex)
			{
				ValheimArchitectPlugin.Log.LogWarning((object)("Ghost removal check failed: " + ex.Message));
			}
			return false;
		}

		private bool IsTrackedGhostRoot(GameObject go)
		{
			if ((Object)(object)go != (Object)null)
			{
				return _ghosts.Contains(go);
			}
			return false;
		}

		private bool RemoveGhostObject(GameObject ghost)
		{
			if ((Object)(object)ghost == (Object)null)
			{
				return false;
			}
			if (!_ghostToBlueprint.TryGetValue(ghost, out var value) || value == null)
			{
				value = FindBlueprintRecordForGhost(ghost);
			}
			int num = ((value != null) ? _blueprint.IndexOf(value) : (-1));
			if (value != null)
			{
				_blueprint.Remove(value);
				_blueprintRevision++;
			}
			_ghostToBlueprint.Remove(ghost);
			_ghosts.Remove(ghost);
			if (num >= 0 && num < _pieceNames.Count)
			{
				_pieceNames.RemoveAt(num);
			}
			Object.Destroy((Object)(object)ghost);
			SaveBlueprintFile();
			return true;
		}

		private BlueprintPiece FindBlueprintRecordForGhost(GameObject ghost)
		{
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)ghost == (Object)null)
			{
				return null;
			}
			string b = ((Object)ghost).name.Replace("[ValheimArchitect Ghost] ", string.Empty).Replace("(Clone)", string.Empty).Trim();
			BlueprintPiece result = null;
			float num = 0.08f;
			foreach (BlueprintPiece item in _blueprint)
			{
				if (string.Equals(item.PrefabName, b, StringComparison.Ordinal))
				{
					float num2 = Vector3.Distance(item.Position, ghost.transform.position);
					if (num2 < num)
					{
						num = num2;
						result = item;
					}
				}
			}
			return result;
		}

		private void TryRestoreBlueprint()
		{
			//IL_0096: 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)
			if (_blueprint.Count == 0)
			{
				_loadedForCurrentScene = true;
			}
			else
			{
				if ((Object)(object)Player.m_localPlayer == (Object)null)
				{
					return;
				}
				ZNetScene val = Object.FindObjectOfType<ZNetScene>();
				if ((Object)(object)val == (Object)null)
				{
					return;
				}
				int num = 0;
				int num2 = 0;
				foreach (BlueprintPiece item in _blueprint)
				{
					GameObject val2 = FindPrefab(val, item.PrefabName);
					Piece val3 = (((Object)(object)val2 != (Object)null) ? val2.GetComponent<Piece>() : null);
					if (!((Object)(object)val3 == (Object)null))
					{
						if (!IsPieceUnlocked(Player.m_localPlayer, val3))
						{
							num2++;
							continue;
						}
						CreateGhost(val3, item.Position, item.Rotation, saveToBlueprint: false, item);
						num++;
					}
				}
				_loadedForCurrentScene = true;
				ValheimArchitectPlugin.Log.LogInfo((object)$"Blueprint restored: {num}/{_blueprint.Count} ghost pieces. Hidden locked pieces: {num2}.");
			}
		}

		private static GameObject FindPrefab(ZNetScene znet, string prefabName)
		{
			if ((Object)(object)znet == (Object)null || string.IsNullOrWhiteSpace(prefabName))
			{
				return null;
			}
			try
			{
				MethodInfo method = typeof(ZNetScene).GetMethod("GetPrefab", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[1] { typeof(string) }, null);
				if (method != null)
				{
					object? obj = method.Invoke(znet, new object[1] { prefabName });
					return (GameObject)((obj is GameObject) ? obj : null);
				}
			}
			catch
			{
			}
			Transform[] componentsInChildren = ((Component)znet).GetComponentsInChildren<Transform>(true);
			foreach (Transform val in componentsInChildren)
			{
				if ((Object)(object)val != (Object)null && ((Object)val).name == prefabName)
				{
					return ((Component)val).gameObject;
				}
			}
			return null;
		}

		internal List<ResourceCostLine> GetResourceCosts()
		{
			Dictionary<string, int> dictionary = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase);
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null || _blueprint.Count == 0)
			{
				return new List<ResourceCostLine>();
			}
			ZNetScene val = Object.FindObjectOfType<ZNetScene>();
			if ((Object)(object)val == (Object)null)
			{
				return new List<ResourceCostLine>();
			}
			Dictionary<string, int> dictionary2 = new Dictionary<string, int>(StringComparer.Ordinal);
			foreach (BlueprintPiece item in _blueprint)
			{
				if (!string.IsNullOrWhiteSpace(item.PrefabName))
				{
					dictionary2.TryGetValue(item.PrefabName, out var value);
					dictionary2[item.PrefabName] = value + 1;
				}
			}
			foreach (KeyValuePair<string, int> item2 in dictionary2)
			{
				Piece cachedPiece = GetCachedPiece(val, item2.Key);
				if ((Object)(object)cachedPiece == (Object)null || !IsPieceUnlocked(localPlayer, cachedPiece))
				{
					continue;
				}
				foreach (ResourceCostLine item3 in GetCachedResourceCostsForPrefab(item2.Key, cachedPiece))
				{
					if (!dictionary.ContainsKey(item3.Name))
					{
						dictionary[item3.Name] = 0;
					}
					dictionary[item3.Name] += item3.Amount * item2.Value;
				}
			}
			List<ResourceCostLine> list = new List<ResourceCostLine>();
			foreach (KeyValuePair<string, int> item4 in dictionary)
			{
				list.Add(new ResourceCostLine(item4.Key, item4.Value));
			}
			list.Sort((ResourceCostLine a, ResourceCostLine b) => string.Compare(a.Name, b.Name, StringComparison.CurrentCultureIgnoreCase));
			return list;
		}

		private Piece GetCachedPiece(ZNetScene znet, string prefabName)
		{
			if (_prefabPieceCache.TryGetValue(prefabName, out var value) && (Object)(object)value != (Object)null)
			{
				return value;
			}
			GameObject val = FindPrefab(znet, prefabName);
			Piece val2 = (((Object)(object)val != (Object)null) ? val.GetComponent<Piece>() : null);
			_prefabPieceCache[prefabName] = val2;
			return val2;
		}

		private List<ResourceCostLine> GetCachedResourceCostsForPrefab(string prefabName, Piece piece)
		{
			if (_resourceCostCache.TryGetValue(prefabName, out var value))
			{
				return value;
			}
			List<ResourceCostLine> list = new List<ResourceCostLine>();
			try
			{
				if (GetMemberValue(piece, "m_resources") is IEnumerable enumerable)
				{
					foreach (object item in enumerable)
					{
						if (item == null)
						{
							continue;
						}
						int intMember = GetIntMember(item, "m_amount");
						if (intMember <= 0)
						{
							continue;
						}
						object memberValue = GetMemberValue(item, "m_resItem");
						string resourceName = GetResourceDisplayName(memberValue);
						if (!string.IsNullOrWhiteSpace(resourceName))
						{
							ResourceCostLine resourceCostLine = list.Find((ResourceCostLine x) => string.Equals(x.Name, resourceName, StringComparison.OrdinalIgnoreCase));
							if (resourceCostLine != null)
							{
								resourceCostLine.Amount += intMember;
							}
							else
							{
								list.Add(new ResourceCostLine(resourceName, intMember));
							}
						}
					}
				}
			}
			catch (Exception ex)
			{
				ValheimArchitectPlugin.Log.LogWarning((object)("Resource calculator failed for '" + prefabName + "': " + ex.Message));
			}
			_resourceCostCache[prefabName] = list;
			return list;
		}

		internal static int GetKnownRecipeSignature(Player player)
		{
			if ((Object)(object)player == (Object)null)
			{
				return 0;
			}
			try
			{
				if (_knownRecipesField == null)
				{
					_knownRecipesField = typeof(Player).GetField("m_knownRecipes", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				}
				if (!(_knownRecipesField?.GetValue(player) is IEnumerable enumerable))
				{
					return 0;
				}
				int num = 17;
				foreach (object item in enumerable)
				{
					num = ((!(item is string obj)) ? (num * 31 + (item?.GetHashCode() ?? 0)) : (num * 31 + StringComparer.Ordinal.GetHashCode(obj)));
				}
				return num;
			}
			catch
			{
				return 0;
			}
		}

		private static object GetMemberValue(object target, string memberName)
		{
			if (target == null)
			{
				return null;
			}
			Type type = target.GetType();
			FieldInfo field = type.GetField(memberName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (field != null)
			{
				return field.GetValue(target);
			}
			PropertyInfo property = type.GetProperty(memberName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (property != null && property.CanRead)
			{
				return property.GetValue(target, null);
			}
			return null;
		}

		private static int GetIntMember(object target, string memberName)
		{
			object memberValue = GetMemberValue(target, memberName);
			if (memberValue == null)
			{
				return 0;
			}
			try
			{
				return Convert.ToInt32(memberValue, CultureInfo.InvariantCulture);
			}
			catch
			{
				return 0;
			}
		}

		private string GetResourceDisplayName(object itemDrop)
		{
			if (itemDrop == null)
			{
				return null;
			}
			string text = GetMemberValue(GetMemberValue(GetMemberValue(itemDrop, "m_itemData"), "m_shared"), "m_name") as string;
			if (string.IsNullOrWhiteSpace(text))
			{
				return null;
			}
			text = text.Trim();
			if (_localizedNameCache.TryGetValue(text, out var value))
			{
				return value;
			}
			string text2 = null;
			try
			{
				Type type = AccessTools.TypeByName("Localization");
				if (type != null)
				{
					if (_localizeMethod == null)
					{
						MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
						foreach (MethodInfo methodInfo in methods)
						{
							if (string.Equals(methodInfo.Name, "Localize", StringComparison.Ordinal))
							{
								ParameterInfo[] parameters = methodInfo.GetParameters();
								if (parameters.Length == 1 && parameters[0].ParameterType == typeof(string) && methodInfo.ReturnType == typeof(string))
								{
									_localizeMethod = methodInfo;
									break;
								}
							}
						}
					}
					if (_localizeInstance == null)
					{
						_localizeInstance = type.GetField("instance", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(null);
					}
					if (_localizeMethod != null && _localizeInstance != null)
					{
						text2 = _localizeMethod.Invoke(_localizeInstance, new object[1] { text }) as string;
						if ((string.IsNullOrWhiteSpace(text2) || string.Equals(text2, text, StringComparison.Ordinal)) && !text.StartsWith("$", StringComparison.Ordinal))
						{
							text2 = _localizeMethod.Invoke(_localizeInstance, new object[1] { "$item_" + text.ToLowerInvariant() }) as string;
						}
					}
				}
			}
			catch
			{
				text2 = null;
			}
			string text3 = StripRichText(text2 ?? string.Empty).Trim();
			if (string.IsNullOrWhiteSpace(text3) || string.Equals(text3, text, StringComparison.Ordinal))
			{
				text3 = RussianResourceName(text);
				if (string.IsNullOrWhiteSpace(text3))
				{
					text3 = text.TrimStart('$');
					if (text3.StartsWith("item_", StringComparison.OrdinalIgnoreCase))
					{
						text3 = text3.Substring(5);
					}
					text3 = text3.Replace('_', ' ');
					if (!string.IsNullOrWhiteSpace(text3))
					{
						text3 = char.ToUpper(text3[0]) + text3.Substring(1);
					}
				}
			}
			_localizedNameCache[text] = text3;
			return text3;
		}

		private static string RussianResourceName(string rawName)
		{
			if (string.IsNullOrWhiteSpace(rawName))
			{
				return null;
			}
			string text = rawName.Trim().TrimStart('$');
			if (text.StartsWith("item_", StringComparison.OrdinalIgnoreCase))
			{
				text = text.Substring(5);
			}
			return text.ToLowerInvariant() switch
			{
				"wood" => "Древесина", 
				"finewood" => "Тонкая древесина", 
				"corewood" => "Цельная древесина", 
				"yggdrasilwood" => "Древесина Иггдрасиля", 
				"stone" => "Камень", 
				"resin" => "Смола", 
				"coal" => "Уголь", 
				"iron" => "Железо", 
				"ironscrap" => "Железный лом", 
				"bronze" => "Бронза", 
				"copper" => "Медь", 
				"tin" => "Олово", 
				"silver" => "Серебро", 
				"blackmetal" => "Чёрный металл", 
				"ancientbark" => "Древняя кора", 
				"tar" => "Дёготь", 
				"crystal" => "Кристалл", 
				"flametal" => "Огненный металл", 
				"blackmarble" => "Чёрный мрамор", 
				"bronzenails" => "Бронзовые гвозди", 
				"ironnails" => "Железные гвозди", 
				"surtlingcore" => "Ядро суртлинга", 
				"trollhide" => "Шкура тролля", 
				"sulfurnstone" => "Серный камень", 
				"sulfurstone" => "Серный камень", 
				"proustitepowder" => "Порошок прустита", 
				"barberkit" => "Набор парикмахера", 
				"witheredbone" => "Иссохшая кость", 
				"chain" => "Цепь", 
				"eitr" => "Эйтр", 
				"refinedeitr" => "Очищенный эйтр", 
				"sap" => "Сок", 
				"softtissue" => "Мягкая ткань", 
				"blackcore" => "Чёрное ядро", 
				"mandible" => "Нижняя челюсть", 
				"needle" => "Игла", 
				"guck" => "Слизь", 
				"bilebag" => "Желчный мешок", 
				"bloodbag" => "Кровяной мешок", 
				"jotunpuffs" => "Пуховка йотунов", 
				"yggdrasilpith" => "Сердцевина Иггдрасиля", 
				"crystals" => "Кристаллы", 
				"greydwarfeye" => "Глаз грейдворфа", 
				"flax" => "Лён", 
				"linen" => "Льняная нить", 
				"witheringbone" => "Иссохшая кость", 
				_ => null, 
			};
		}

		private static string StripRichText(string value)
		{
			if (string.IsNullOrWhiteSpace(value))
			{
				return value;
			}
			return Regex.Replace(value, "<.*?>", string.Empty);
		}

		private void SaveBlueprintFile()
		{
			try
			{
				using StreamWriter streamWriter = new StreamWriter(_blueprintFile, append: false);
				streamWriter.WriteLine("VALHEIM_ARCHITECT_BLUEPRINT_V1");
				foreach (BlueprintPiece item in _blueprint)
				{
					streamWriter.Write(item.PrefabName.Replace("\t", "_"));
					streamWriter.Write('\t');
					streamWriter.Write(item.Position.x.ToString("R", CultureInfo.InvariantCulture));
					streamWriter.Write('\t');
					streamWriter.Write(item.Position.y.ToString("R", CultureInfo.InvariantCulture));
					streamWriter.Write('\t');
					streamWriter.Write(item.Position.z.ToString("R", CultureInfo.InvariantCulture));
					streamWriter.Write('\t');
					streamWriter.Write(item.Rotation.x.ToString("R", CultureInfo.InvariantCulture));
					streamWriter.Write('\t');
					streamWriter.Write(item.Rotation.y.ToString("R", CultureInfo.InvariantCulture));
					streamWriter.Write('\t');
					streamWriter.Write(item.Rotation.z.ToString("R", CultureInfo.InvariantCulture));
					streamWriter.Write('\t');
					streamWriter.WriteLine(item.Rotation.w.ToString("R", CultureInfo.InvariantCulture));
				}
			}
			catch (Exception ex)
			{
				ValheimArchitectPlugin.Log.LogError((object)("Could not save blueprint: " + ex.Message));
			}
		}

		private void LoadBlueprintFile()
		{
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			_blueprint.Clear();
			_pieceNames.Clear();
			if (!File.Exists(_blueprintFile))
			{
				return;
			}
			try
			{
				string[] array = File.ReadAllLines(_blueprintFile);
				if (array.Length == 0 || array[0].Trim() != "VALHEIM_ARCHITECT_BLUEPRINT_V1")
				{
					return;
				}
				for (int i = 1; i < array.Length; i++)
				{
					if (!string.IsNullOrWhiteSpace(array[i]))
					{
						string[] array2 = array[i].Split('\t');
						if (array2.Length == 8 && float.TryParse(array2[1], NumberStyles.Float, CultureInfo.InvariantCulture, out var result) && float.TryParse(array2[2], NumberStyles.Float, CultureInfo.InvariantCulture, out var result2) && float.TryParse(array2[3], NumberStyles.Float, CultureInfo.InvariantCulture, out var result3) && float.TryParse(array2[4], NumberStyles.Float, CultureInfo.InvariantCulture, out var result4) && float.TryParse(array2[5], NumberStyles.Float, CultureInfo.InvariantCulture, out var result5) && float.TryParse(array2[6], NumberStyles.Float, CultureInfo.InvariantCulture, out var result6) && float.TryParse(array2[7], NumberStyles.Float, CultureInfo.InvariantCulture, out var result7))
						{
							_blueprint.Add(new BlueprintPiece
							{
								PrefabName = array2[0],
								Position = new Vector3(result, result2, result3),
								Rotation = new Quaternion(result4, result5, result6, result7)
							});
							_pieceNames.Add(array2[0]);
						}
					}
				}
				_blueprintRevision++;
				ValheimArchitectPlugin.Log.LogInfo((object)$"Blueprint loaded from disk: {_blueprint.Count} pieces.");
			}
			catch (Exception ex)
			{
				ValheimArchitectPlugin.Log.LogError((object)("Could not load blueprint: " + ex.Message));
			}
		}

		private void DestroyGhostObjectsOnly()
		{
			for (int num = _ghosts.Count - 1; num >= 0; num--)
			{
				if ((Object)(object)_ghosts[num] != (Object)null)
				{
					Object.Destroy((Object)(object)_ghosts[num]);
				}
			}
			_ghosts.Clear();
			_ghostToBlueprint.Clear();
		}

		public void ClearAndForgetBlueprint()
		{
			DestroyGhostObjectsOnly();
			_blueprint.Clear();
			_pieceNames.Clear();
			_blueprintRevision++;
			_loadedForCurrentScene = true;
			try
			{
				if (File.Exists(_blueprintFile))
				{
					File.Delete(_blueprintFile);
				}
			}
			catch (Exception ex)
			{
				ValheimArchitectPlugin.Log.LogError((object)("Could not delete blueprint: " + ex.Message));
			}
		}

		private void OnSceneUnloaded(Scene scene)
		{
			DestroyGhostObjectsOnly();
			_loadedForCurrentScene = false;
		}

		public void Dispose()
		{
			if (!_disposed)
			{
				_disposed = true;
				SceneManager.sceneUnloaded -= OnSceneUnloaded;
				SceneManager.sceneLoaded -= OnSceneLoaded;
				DestroyGhostObjectsOnly();
				_harmony.UnpatchSelf();
			}
		}
	}
	internal static class GhostSkillPatch
	{
		[HarmonyPatch]
		private static class RaiseSkillPatch
		{
			private static IEnumerable<MethodBase> TargetMethods()
			{
				Type[] array = new Type[2]
				{
					AccessTools.TypeByName("Skills"),
					AccessTools.TypeByName("Player")
				};
				Type[] array2 = array;
				foreach (Type type in array2)
				{
					if (type == null)
					{
						continue;
					}
					MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					foreach (MethodInfo methodInfo in methods)
					{
						if (string.Equals(methodInfo.Name, "RaiseSkill", StringComparison.Ordinal))
						{
							yield return methodInfo;
						}
					}
				}
			}

			private static bool Prefix(object[] __args)
			{
				if (!IsGhostModeActive())
				{
					return true;
				}
				if (__args == null)
				{
					return true;
				}
				foreach (object obj in __args)
				{
					if (obj != null)
					{
						if (obj is string a && string.Equals(a, "Building", StringComparison.OrdinalIgnoreCase))
						{
							return false;
						}
						Type type = obj.GetType();
						if (type.IsEnum && string.Equals(Enum.GetName(type, obj), "Building", StringComparison.OrdinalIgnoreCase))
						{
							return false;
						}
					}
				}
				return true;
			}
		}

		internal static bool IsGhostModeActive()
		{
			ValheimArchitectPlugin instance = ValheimArchitectPlugin.Instance;
			if ((Object)(object)instance != (Object)null && instance.Ghost != null && instance.Features != null && instance.Features.GhostLayout.Value)
			{
				return (Object)(object)Player.m_localPlayer != (Object)null;
			}
			return false;
		}
	}
	[BepInPlugin("ValheimArchitect", "Valheim Architect", "0.5.19")]
	public sealed class ValheimArchitectPlugin : BaseUnityPlugin
	{
		internal static ManualLogSource Log;

		private ArchitectFeatures _features;

		private ArchitectMenu _menu;

		private BuildAssistController _assist;

		private ResourceCalculatorController _calculator;

		internal GhostLayoutController Ghost { get; private set; }

		internal ArchitectFeatures Features => _features;

		internal BuildAssistController Assist => _assist;

		internal static ValheimArchitectPlugin Instance { get; private set; }

		private void Awake()
		{
			Log = ((BaseUnityPlugin)this).Logger;
			Instance = this;
			_features = new ArchitectFeatures(((BaseUnityPlugin)this).Config);
			_menu = new ArchitectMenu(_features);
			_assist = new BuildAssistController(_features);
			Ghost = new GhostLayoutController(_features);
			_calculator = new ResourceCalculatorController(_features, Ghost);
			Log.LogInfo((object)"Plugin loaded");
			Log.LogInfo((object)"Valheim Architect 0.5.19: persistent ghost blueprint + snap + resource calculator; F8 menu");
		}

		private void Update()
		{
			if (Input.GetKeyDown((KeyCode)289))
			{
				_menu.Toggle();
			}
			if (Input.GetKeyDown((KeyCode)291) && _features.AlignmentLines.Value)
			{
				_assist.TogglePinned();
			}
			_assist.Update();
			Ghost?.Update();
			_calculator?.Update();
		}

		private void OnGUI()
		{
			_menu.Draw();
			_calculator?.Draw();
		}

		private void OnDestroy()
		{
			Ghost?.Dispose();
			if (_assist != null)
			{
				_assist.Dispose();
			}
			Instance = null;
		}
	}
	internal static class PluginInfo
	{
		public const string PLUGIN_GUID = "ValheimArchitect";

		public const string PLUGIN_NAME = "Valheim Architect";

		public const string PLUGIN_VERSION = "0.5.19";
	}
	internal sealed class ResourceCalculatorController
	{
		private const int WindowId = 170335953;

		private readonly ArchitectFeatures _features;

		private readonly GhostLayoutController _ghost;

		private Rect _rect = new Rect(0f, 0f, 380f, 410f);

		private Vector2 _scroll;

		private List<ResourceCostLine> _costs = new List<ResourceCostLine>();

		private bool _initialized;

		private int _lastBlueprintRevision = -1;

		private int _lastRecipeSignature;

		private bool _hasRecipeSignature;

		private bool _recalculationPending;

		private float _recipeSignatureTimer;

		private bool _dragging;

		public ResourceCalculatorController(ArchitectFeatures features, GhostLayoutController ghost)
		{
			//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)
			_features = features;
			_ghost = ghost;
		}

		public void Update()
		{
			if (!_features.ResourceCalculator.Value)
			{
				_recalculationPending = false;
				_dragging = false;
				return;
			}
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				return;
			}
			if (_lastBlueprintRevision != _ghost.BlueprintRevision)
			{
				_lastBlueprintRevision = _ghost.BlueprintRevision;
				_recalculationPending = true;
			}
			_recipeSignatureTimer -= Time.unscaledDeltaTime;
			if (_recipeSignatureTimer <= 0f)
			{
				_recipeSignatureTimer = 1f;
				int knownRecipeSignature = GhostLayoutController.GetKnownRecipeSignature(localPlayer);
				if (!_hasRecipeSignature || knownRecipeSignature != _lastRecipeSignature)
				{
					_lastRecipeSignature = knownRecipeSignature;
					_hasRecipeSignature = true;
					_recalculationPending = true;
				}
			}
			if (_recalculationPending)
			{
				_recalculationPending = false;
				_costs = _ghost.GetResourceCosts();
			}
		}

		public void Draw()
		{
			//IL_010f: 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_012f: Expected O, but got Unknown
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			if (_features.ResourceCalculator.Value)
			{
				ArchitectStyle.EnsureInitialized();
				if (!_initialized)
				{
					((Rect)(ref _rect)).width = 380f;
					((Rect)(ref _rect)).height = 410f;
					((Rect)(ref _rect)).x = Mathf.Max(12f, (float)Screen.width - ((Rect)(ref _rect)).width - 24f);
					((Rect)(ref _rect)).y = 18f;
					_initialized = true;
				}
				((Rect)(ref _rect)).x = Mathf.Clamp(((Rect)(ref _rect)).x, 8f, Mathf.Max(8f, (float)Screen.width - ((Rect)(ref _rect)).width - 8f));
				((Rect)(ref _rect)).y = Mathf.Clamp(((Rect)(ref _rect)).y, 8f, Mathf.Max(8f, (float)Screen.height - ((Rect)(ref _rect)).height - 8f));
				_rect = GUI.Window(170335953, _rect, new WindowFunction(DrawCalculatorWindow), GUIContent.none, ArchitectStyle.WindowCompact);
			}
		}

		private void DrawCalculatorWindow(int id)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: 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_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0202: Unknown result type (might be due to invalid IL or missing references)
			//IL_0207: Unknown result type (might be due to invalid IL or missing references)
			//IL_020c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_024d: Unknown result type (might be due to invalid IL or missing references)
			//IL_029f: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e1: Unknown result type (might be due to invalid IL or missing references)
			Rect val = default(Rect);
			((Rect)(ref val))..ctor(14f, 14f, ((Rect)(ref _rect)).width - 28f, 74f);
			GUI.Box(val, GUIContent.none, ArchitectStyle.HeaderCompact);
			GUI.Label(new Rect(28f, 21f, ((Rect)(ref _rect)).width - 56f, 30f), "КАЛЬКУЛЯТОР МАКЕТА", ArchitectStyle.ResourceHeader);
			GUI.Label(new Rect(28f, 51f, ((Rect)(ref _rect)).width - 56f, 18f), $"Деталей в макете: {_ghost.BlueprintCount}", ArchitectStyle.Small);
			if (GUI.Button(new Rect(((Rect)(ref _rect)).width - 42f, 28f, 22f, 22f), "×", ArchitectStyle.CloseSmall))
			{
				_features.ResourceCalculator.Value = false;
				GUIUtility.ExitGUI();
				return;
			}
			HandleHeaderDrag(val);
			if (_ghost.BlueprintCount == 0)
			{
				GUI.Label(new Rect(24f, 108f, ((Rect)(ref _rect)).width - 48f, 42f), "Макет пуст.", ArchitectStyle.ResourceName);
				return;
			}
			if (_costs.Count == 0)
			{
				GUI.Label(new Rect(24f, 108f, ((Rect)(ref _rect)).width - 48f, 72f), "Нет доступных ресурсов для деталей этого макета.", ArchitectStyle.ResourceName);
				return;
			}
			Rect val2 = default(Rect);
			((Rect)(ref val2))..ctor(18f, 100f, ((Rect)(ref _rect)).width - 36f, ((Rect)(ref _rect)).height - 116f);
			float num = Mathf.Max(230f, (float)_costs.Count * 46f + 14f);
			_scroll = GUI.BeginScrollView(val2, _scroll, new Rect(0f, 0f, ((Rect)(ref val2)).width - 18f, num));
			float num2 = 8f;
			Rect val3 = default(Rect);
			for (int i = 0; i < _costs.Count; i++)
			{
				ResourceCostLine resourceCostLine = _costs[i];
				((Rect)(ref val3))..ctor(0f, num2, ((Rect)(ref val2)).width - 18f, 40f);
				GUI.Box(val3, GUIContent.none, (i % 2 == 0) ? ArchitectStyle.ResourceRowA : ArchitectStyle.ResourceRowB);
				GUI.Label(new Rect(((Rect)(ref val3)).x + 14f, ((Rect)(ref val3)).y + 2f, ((Rect)(ref val3)).width - 100f, ((Rect)(ref val3)).height - 4f), resourceCostLine.Name, ArchitectStyle.ResourceName);
				GUI.Label(new Rect(((Rect)(ref val3)).xMax - 72f, ((Rect)(ref val3)).y + 2f, 60f, ((Rect)(ref val3)).height - 4f), resourceCostLine.Amount.ToString(), ArchitectStyle.ResourceAmount);
				num2 += 46f;
			}
			GUI.EndScrollView();
		}

		private void HandleHeaderDrag(Rect headerRect)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Invalid comparison between Unknown and I4
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Invalid comparison between Unknown and I4