Decompiled source of Gizmo v1.13.0

ComfyGizmo.dll

Decompiled 2 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using ComfyLib;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using SoftReferenceableAssets;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("ComfyGizmo")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ComfyGizmo")]
[assembly: AssemblyCopyright("Copyright © 2021")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("83d75858-7663-4c9b-abef-75ffd7e692e0")]
[assembly: AssemblyFileVersion("1.13.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.13.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.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 ComfyLib
{
	public static class AssetUtils
	{
		public static readonly string StandardShader = "7e6bbee7a32b746cb9396cd890ce7189";

		public static readonly AssetCache<Shader> ShaderCache = new AssetCache<Shader>();

		public static Shader GetShader(string guid)
		{
			return ShaderCache.GetAsset(StandardShader);
		}

		public static T LoadAsset<T>(string resourceName, string assetName) where T : Object
		{
			AssetBundle obj = AssetBundle.LoadFromMemory(LoadResourceFromAssembly(Assembly.GetExecutingAssembly(), resourceName));
			T result = obj.LoadAsset<T>(assetName);
			obj.UnloadAsync(false);
			return result;
		}

		public static byte[] LoadResourceFromAssembly(Assembly assembly, string resourceName)
		{
			Stream manifestResourceStream = assembly.GetManifestResourceStream(resourceName);
			byte[] array = new byte[manifestResourceStream.Length];
			manifestResourceStream.Read(array, 0, (int)manifestResourceStream.Length);
			return array;
		}
	}
	public sealed class AssetCache<T> where T : Object
	{
		private readonly Dictionary<string, T> _cache = new Dictionary<string, T>();

		public T GetAsset(string guid)
		{
			//IL_001c: 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)
			AssetID val = default(AssetID);
			if (!_cache.TryGetValue(guid, out var value) && AssetID.TryParse(guid, ref val))
			{
				SoftReference<T> val2 = default(SoftReference<T>);
				val2..ctor(val);
				val2.Load();
				value = val2.Asset;
				_cache[guid] = value;
			}
			return value;
		}
	}
	public static class ConfigFileExtensions
	{
		internal sealed class ConfigurationManagerAttributes
		{
			public Action<ConfigEntryBase> CustomDrawer;

			public bool? Browsable;

			public bool? HideDefaultButton;

			public bool? HideSettingName;

			public bool? IsAdvanced;

			public int? Order;

			public bool? ReadOnly;
		}

		private static readonly Dictionary<string, int> _sectionToSettingOrder = new Dictionary<string, int>();

		private static int GetSettingOrder(string section)
		{
			if (!_sectionToSettingOrder.TryGetValue(section, out var value))
			{
				value = 0;
			}
			_sectionToSettingOrder[section] = value - 1;
			return value;
		}

		public static ConfigEntry<T> BindInOrder<T>(this ConfigFile config, string section, string key, T defaultValue, string description, AcceptableValueBase acceptableValues, bool browsable = true, bool hideDefaultButton = false, bool hideSettingName = false, bool isAdvanced = false, bool readOnly = false)
		{
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Expected O, but got Unknown
			return config.Bind<T>(section, key, defaultValue, new ConfigDescription(description, acceptableValues, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Browsable = browsable,
					CustomDrawer = null,
					HideDefaultButton = hideDefaultButton,
					HideSettingName = hideSettingName,
					IsAdvanced = isAdvanced,
					Order = GetSettingOrder(section),
					ReadOnly = readOnly
				}
			}));
		}

		public static ConfigEntry<T> BindInOrder<T>(this ConfigFile config, string section, string key, T defaultValue, string description, Action<ConfigEntryBase> customDrawer = null, bool browsable = true, bool hideDefaultButton = false, bool hideSettingName = false, bool isAdvanced = false, bool readOnly = false)
		{
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Expected O, but got Unknown
			return config.Bind<T>(section, key, defaultValue, new ConfigDescription(description, (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Browsable = browsable,
					CustomDrawer = customDrawer,
					HideDefaultButton = hideDefaultButton,
					HideSettingName = hideSettingName,
					IsAdvanced = isAdvanced,
					Order = GetSettingOrder(section),
					ReadOnly = readOnly
				}
			}));
		}

		public static void OnSettingChanged<T>(this ConfigEntry<T> configEntry, Action settingChangedHandler)
		{
			configEntry.SettingChanged += delegate
			{
				settingChangedHandler();
			};
		}

		public static void OnSettingChanged<T>(this ConfigEntry<T> configEntry, Action<T> settingChangedHandler)
		{
			configEntry.SettingChanged += delegate(object _, EventArgs eventArgs)
			{
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				settingChangedHandler((T)((SettingChangedEventArgs)eventArgs).ChangedSetting.BoxedValue);
			};
		}

		public static void OnSettingChanged<T>(this ConfigEntry<T> configEntry, Action<ConfigEntry<T>> settingChangedHandler)
		{
			configEntry.SettingChanged += delegate(object _, EventArgs eventArgs)
			{
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				settingChangedHandler((ConfigEntry<T>)((SettingChangedEventArgs)eventArgs).ChangedSetting.BoxedValue);
			};
		}
	}
}
namespace ComfyGizmo
{
	[BepInPlugin("bruce.valheim.comfymods.gizmo", "ComfyGizmo", "1.13.0")]
	public sealed class ComfyGizmo : BaseUnityPlugin
	{
		public const string PluginGUID = "bruce.valheim.comfymods.gizmo";

		public const string PluginName = "ComfyGizmo";

		public const string PluginVersion = "1.13.0";

		private void Awake()
		{
			PluginConfig.BindConfig(((BaseUnityPlugin)this).Config);
			Runtime.MakeAllAssetsLoadable();
			Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "bruce.valheim.comfymods.gizmo");
		}
	}
	public abstract class AbstractRotator
	{
		protected Gizmos _gizmos;

		protected GhostGizmo _ghostGizmo;

		protected string _name;

		protected Vector3 _eulerAngles = Vector3.zero;

		public abstract void Rotate(Vector3 rotationAxis);

		public abstract void ResetRotation();

		public abstract void ResetAxis(Vector3 axis);

		public abstract void MatchPieceRotation(Piece target);

		public abstract Quaternion GetRotation();

		public void DisplayModeChangeHudeMessage()
		{
			if (Object.op_Implicit((Object)(object)MessageHud.m_instance))
			{
				MessageHud.m_instance.ShowMessage((MessageType)1, "Switchted to " + GetModeName() + " mode.", 0, (Sprite)null);
			}
		}

		public void Destroy()
		{
			DestroyGizmos();
			DestroyGhostGizmo();
		}

		private void DestroyGizmos()
		{
			if (_gizmos != null)
			{
				_gizmos.Destroy();
			}
		}

		private void DestroyGhostGizmo()
		{
			if (_ghostGizmo != null)
			{
				_ghostGizmo.Destroy();
			}
		}

		protected abstract Gizmos GetGizmos();

		public void ShowGizmos(Player player)
		{
			GetGizmos().Show(player);
		}

		public void HideGizmos()
		{
			GetGizmos().Hide();
		}

		public void ResetScales()
		{
			GetGizmos().ResetScale();
		}

		public void SetXScale(float scale)
		{
			GetGizmos().SetXScale(scale);
		}

		public void SetYScale(float scale)
		{
			GetGizmos().SetYScale(scale);
		}

		public void SetZScale(float scale)
		{
			GetGizmos().SetZScale(scale);
		}

		protected abstract string GetModeName();

		protected float GetAngle()
		{
			return 180f / (float)PluginConfig.SnapDivisions.Value;
		}
	}
	public sealed class DefaultRotator : AbstractRotator
	{
		public DefaultRotator()
		{
			_name = "Default Rotator";
			_gizmos = Gizmos.CreateGizmos();
			ResetRotation();
		}

		public override void Rotate(Vector3 rotationAxis)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			_eulerAngles += rotationAxis * GetAngle();
			_gizmos.SetLocalRotation(_eulerAngles);
		}

		public override void ResetRotation()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			_eulerAngles = Vector3.zero;
			_gizmos.SetLocalRotation(_eulerAngles);
		}

		public override void ResetAxis(Vector3 axis)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			if (axis == Vector3.up)
			{
				_eulerAngles.y = 0f;
			}
			if (axis == Vector3.right)
			{
				_eulerAngles.x = 0f;
			}
			if (axis == Vector3.forward)
			{
				_eulerAngles.z = 0f;
			}
			_gizmos.SetLocalRotation(_eulerAngles);
		}

		public override void MatchPieceRotation(Piece target)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			ResetRotation();
			_eulerAngles = ((Component)target).GetComponent<Transform>().eulerAngles;
			Rotate(Vector3.zero);
		}

		protected override string GetModeName()
		{
			return "default rotation";
		}

		protected override Gizmos GetGizmos()
		{
			return _gizmos;
		}

		public override Quaternion GetRotation()
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			return _gizmos.GetXGizmoRoot().rotation;
		}
	}
	public sealed class Gizmos
	{
		public static readonly Lazy<GameObject> GizmoPrefab = new Lazy<GameObject>((Func<GameObject>)LoadGizmoPrefab);

		private static readonly List<Gizmos> _gizmoInstances = new List<Gizmos>();

		private readonly GameObject _gizmo;

		private Transform _gizmoRoot;

		private Transform _xGizmo;

		private Transform _yGizmo;

		private Transform _zGizmo;

		private Transform _xGizmoRoot;

		private Transform _yGizmoRoot;

		private Transform _zGizmoRoot;

		private Material _xMaterial;

		private Material _yMaterial;

		private Material _zMaterial;

		public static Gizmos CreateGizmos()
		{
			Gizmos gizmos = new Gizmos();
			_gizmoInstances.Add(gizmos);
			return gizmos;
		}

		public static void ResetAllScales()
		{
			foreach (Gizmos gizmoInstance in _gizmoInstances)
			{
				gizmoInstance.ResetScale();
			}
		}

		public static void SetAllXColors()
		{
			foreach (Gizmos gizmoInstance in _gizmoInstances)
			{
				gizmoInstance.SetXGizmoColor();
			}
		}

		public static void SetAllYColors()
		{
			foreach (Gizmos gizmoInstance in _gizmoInstances)
			{
				gizmoInstance.SetYGizmoColor();
			}
		}

		public static void SetAllZColors()
		{
			foreach (Gizmos gizmoInstance in _gizmoInstances)
			{
				gizmoInstance.SetZGizmoColor();
			}
		}

		public Gizmos()
		{
			_gizmo = Object.Instantiate<GameObject>(GizmoPrefab.Value);
			SetupComponentsAndRoots();
		}

		public void Show(Player player)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)player.m_placementMarkerInstance))
			{
				SetActive(player);
				SetPosition(player.m_placementMarkerInstance.transform.position + Vector3.up * 0.5f);
			}
		}

		public void Hide()
		{
			((Component)_gizmoRoot).gameObject.SetActive(false);
		}

		public Transform GetXGizmoRoot()
		{
			return _xGizmoRoot;
		}

		public void ApplyRotation(Quaternion rotation)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			Transform gizmoRoot = _gizmoRoot;
			gizmoRoot.rotation *= rotation;
		}

		public void SetLocalRotation(Vector3 eulerAngles)
		{
			//IL_0006: 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_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			_xGizmoRoot.localRotation = Quaternion.Euler(eulerAngles.x, 0f, 0f);
			_yGizmoRoot.localRotation = Quaternion.Euler(0f, eulerAngles.y, 0f);
			_zGizmoRoot.localRotation = Quaternion.Euler(0f, 0f, eulerAngles.z);
		}

		public void SetAxisRotation(float angle, Vector3 axis)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			_gizmoRoot.rotation = Quaternion.AngleAxis(angle, axis);
		}

		public void SetLocalAxisRotation(float angle, Vector3 axis)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			_gizmoRoot.localRotation = Quaternion.AngleAxis(angle, axis);
		}

		public void ResetScale()
		{
			SetLocalScale(1f);
		}

		public void SetLocalScale(float scale)
		{
			SetXScale(scale);
			SetYScale(scale);
			SetZScale(scale);
		}

		public void SetXScale(float scale)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			_xGizmo.localScale = Vector3.one * scale;
		}

		public void SetYScale(float scale)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			_yGizmo.localScale = Vector3.one * scale;
		}

		public void SetZScale(float scale)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			_zGizmo.localScale = Vector3.one * scale;
		}

		public void SetXColor()
		{
			SetXGizmoColor();
		}

		public void SetYColor()
		{
			SetYGizmoColor();
		}

		public void SetZColor()
		{
			SetZGizmoColor();
		}

		public void SetRotation(Quaternion rotation)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			_gizmoRoot.rotation = rotation;
		}

		public void SetPosition(Vector3 position)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			_gizmoRoot.position = position;
		}

		public void SetActive(Player player)
		{
			((Component)_gizmoRoot).gameObject.SetActive(PluginConfig.ShowGizmoPrefab.Value && player.m_placementMarkerInstance.activeSelf);
		}

		public void SetXGizmoColor()
		{
			//IL_000b: 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)
			_xMaterial.color = PluginConfig.XGizmoColor.Value * PluginConfig.XEmissionColorFactor.Value;
		}

		public void SetYGizmoColor()
		{
			//IL_000b: 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)
			_yMaterial.color = PluginConfig.YGizmoColor.Value * PluginConfig.YEmissionColorFactor.Value;
		}

		public void SetZGizmoColor()
		{
			//IL_000b: 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)
			_zMaterial.color = PluginConfig.ZGizmoColor.Value * PluginConfig.ZEmissionColorFactor.Value;
		}

		public void Destroy()
		{
			Object.Destroy((Object)(object)_gizmo);
		}

		private void SetupComponentsAndRoots()
		{
			_gizmoRoot = _gizmo.transform;
			_xGizmo = _gizmoRoot.Find("YRoot/ZRoot/XRoot/X");
			_yGizmo = _gizmoRoot.Find("YRoot/Y");
			_zGizmo = _gizmoRoot.Find("YRoot/ZRoot/Z");
			_xMaterial = ((Component)_xGizmo).gameObject.GetComponent<Renderer>().material;
			SetupMaterial(_xMaterial);
			_yMaterial = ((Component)_yGizmo).gameObject.GetComponent<Renderer>().material;
			SetupMaterial(_yMaterial);
			_zMaterial = ((Component)_zGizmo).gameObject.GetComponent<Renderer>().material;
			SetupMaterial(_zMaterial);
			SetXGizmoColor();
			SetYGizmoColor();
			SetZGizmoColor();
			_xGizmoRoot = _gizmoRoot.Find("YRoot/ZRoot/XRoot");
			_yGizmoRoot = _gizmoRoot.Find("YRoot");
			_zGizmoRoot = _gizmoRoot.Find("YRoot/ZRoot");
		}

		private static void SetupMaterial(Material material)
		{
			material.shader = AssetUtils.GetShader(AssetUtils.StandardShader);
			material.DisableKeyword("_EMISSION");
			material.globalIlluminationFlags = (MaterialGlobalIlluminationFlags)4;
		}

		public static GameObject LoadGizmoPrefab()
		{
			return AssetUtils.LoadAsset<GameObject>("ComfyGizmo.Resources.gizmos", "GizmoRoot");
		}
	}
	public sealed class HammerTableManager
	{
		private static readonly string _searsCatalogGUID = "redseiko.valheim.searscatalog";

		private static readonly string _columnConfigSection = "BuildHud.Panel";

		private static readonly string _columnConfigKey = "buildHudPanelColumns";

		private static readonly int _defaultColumnCount = 15;

		private static BaseUnityPlugin _searsCatalog = null;

		private static ConfigEntry<int> _searsCatalogColumnsConfigEntry;

		private static Dictionary<string, Vector2Int> _pieceLocations = new Dictionary<string, Vector2Int>();

		private static int _cachedAvailablePieceCount = -1;

		private static bool _targetSelection = false;

		public static void Initialize()
		{
			if (IsSearsCatalogEnabled())
			{
				FindSearsCatalogPlugin();
			}
		}

		public static void SelectTargetPiece(Player player)
		{
			if (IsHammerTableChanged(player) || !IsHammerTableCached())
			{
				CacheHammerTable(player);
			}
			if (HasCachedPiece(player.GetHoveringPiece()))
			{
				_targetSelection = true;
				SetSelectedPiece(player, player.GetHoveringPiece());
			}
		}

		public static bool IsTargetSelected()
		{
			return _targetSelection;
		}

		public static int GetColumnCount()
		{
			if (!IsSearsCatalogEnabled())
			{
				return _defaultColumnCount;
			}
			return GetSearsCatalogColumnCount();
		}

		public static bool HasCachedPiece(Piece piece)
		{
			return _pieceLocations.ContainsKey(GetPieceIdentifier(piece));
		}

		public static void SetSelectedPiece(Player player, Piece piece)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			Vector2Int val = _pieceLocations[GetPieceIdentifier(piece)];
			PieceCategory selectedCategory = player.m_buildPieces.m_selectedCategory;
			player.m_buildPieces.m_selectedCategory = (PieceCategory)((Vector2Int)(ref val)).x;
			player.SetSelectedPiece(new Vector2Int(((Vector2Int)(ref val)).y % GetColumnCount(), ((Vector2Int)(ref val)).y / GetColumnCount()));
			player.SetupPlacementGhost();
			if (selectedCategory != player.m_buildPieces.m_selectedCategory)
			{
				Hud.m_instance.UpdatePieceList(player, new Vector2Int(((Vector2Int)(ref val)).y % 15, ((Vector2Int)(ref val)).y / 15), (PieceCategory)((Vector2Int)(ref val)).x, true);
			}
		}

		public static bool IsHammerTableCached()
		{
			return _cachedAvailablePieceCount != -1;
		}

		public static void CacheHammerTable(Player player)
		{
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			PieceTable buildPieces = player.m_buildPieces;
			_cachedAvailablePieceCount = 0;
			_pieceLocations = new Dictionary<string, Vector2Int>();
			for (int i = 0; i < buildPieces.m_availablePieces.Count; i++)
			{
				List<Piece> list = buildPieces.m_availablePieces[i];
				for (int j = 0; j < list.Count; j++)
				{
					if (!_pieceLocations.ContainsKey(GetPieceIdentifier(list[j])))
					{
						_pieceLocations.Add(GetPieceIdentifier(list[j]), new Vector2Int(i, j));
						_cachedAvailablePieceCount++;
					}
				}
			}
		}

		public static bool IsHammerTableChanged(Player player)
		{
			if (!Object.op_Implicit((Object)(object)player) || !Object.op_Implicit((Object)(object)player.m_buildPieces) || player.m_buildPieces.m_availablePieces == null)
			{
				return false;
			}
			int num = 0;
			for (int i = 0; i < player.m_buildPieces.m_availablePieces.Count; i++)
			{
				num += player.m_buildPieces.m_availablePieces[i].Count;
			}
			if (num == _cachedAvailablePieceCount)
			{
				return false;
			}
			return true;
		}

		private static string GetPieceIdentifier(Piece piece)
		{
			return piece.m_name + piece.m_description;
		}

		public static bool IsSearsCatalogEnabled()
		{
			FindSearsCatalogPlugin();
			if (!Object.op_Implicit((Object)(object)_searsCatalog))
			{
				return false;
			}
			return true;
		}

		public static int GetSearsCatalogColumnCount()
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Expected O, but got Unknown
			if (_searsCatalogColumnsConfigEntry != null)
			{
				return _searsCatalogColumnsConfigEntry.Value;
			}
			ConfigEntry<int> val = default(ConfigEntry<int>);
			if (_searsCatalog.Config.TryGetEntry<int>(new ConfigDefinition(_columnConfigSection, _columnConfigKey), ref val))
			{
				_searsCatalogColumnsConfigEntry = val;
				return val.Value;
			}
			return _defaultColumnCount;
		}

		private static void FindSearsCatalogPlugin()
		{
			IEnumerable<BaseUnityPlugin> loadedPlugins = GetLoadedPlugins();
			if (loadedPlugins != null && loadedPlugins.Where((BaseUnityPlugin plugin) => plugin.Info.Metadata.GUID == _searsCatalogGUID).ToDictionary((BaseUnityPlugin plugin) => plugin.Info.Metadata.GUID).TryGetValue(_searsCatalogGUID, out var value))
			{
				_searsCatalog = value;
			}
		}

		private static IEnumerable<BaseUnityPlugin> GetLoadedPlugins()
		{
			return from x in Chainloader.PluginInfos
				where x.Value != null && (Object)(object)x.Value.Instance != (Object)null
				select x.Value.Instance;
		}
	}
	public sealed class GhostGizmo
	{
		private readonly GameObject _prefab;

		private readonly Transform _root;

		public static GhostGizmo CreateGhostGizmo()
		{
			return new GhostGizmo();
		}

		public GhostGizmo()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			_prefab = new GameObject("ComfyGizmo");
			_root = _prefab.transform;
		}

		public void Destroy()
		{
			Object.Destroy((Object)(object)_prefab);
		}

		public void ApplyRotation(Quaternion rotation)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			Transform root = _root;
			root.rotation *= rotation;
		}

		public void ApplyLocalRotation(Quaternion rotation)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			Transform root = _root;
			root.localRotation *= rotation;
		}

		public void SetRotation(Quaternion rotation)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			_root.rotation = rotation;
		}

		public Quaternion GetRotation()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			return _root.rotation;
		}

		public void SetLocalRotation(Quaternion rotation)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			_root.localRotation = rotation;
		}

		public void SetAxisRotation(float angle, Vector3 axis)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			_root.rotation = Quaternion.AngleAxis(angle, axis);
		}

		public void SetLocalAxisRotation(float angle, Vector3 axis)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			_root.localRotation = Quaternion.AngleAxis(angle, axis);
		}
	}
	public static class RotationManager
	{
		private static DefaultRotator _defaultRotator;

		private static InternalRotator _internalRotator;

		private static LocalFrameRotator _localFrameRotator;

		private static RoofRotator _roofRotator;

		public static bool IsTerrainOpPrefab { get; private set; }

		public static void Initialize()
		{
			_defaultRotator = new DefaultRotator();
			_internalRotator = new InternalRotator();
			_localFrameRotator = new LocalFrameRotator();
			_roofRotator = new RoofRotator();
		}

		public static void Rotate(Vector3 rotationAxis)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			_defaultRotator.Rotate(rotationAxis);
			_internalRotator.Rotate(rotationAxis);
			_localFrameRotator.Rotate(rotationAxis);
			_roofRotator.Rotate(rotationAxis);
		}

		public static void ResetRotation()
		{
			_defaultRotator.ResetRotation();
			_internalRotator.ResetRotation();
			_localFrameRotator.ResetRotation();
			_roofRotator.ResetRotation();
		}

		public static void ResetRotationConditional()
		{
			if (PluginConfig.ResetRotationOnSnapDivisionChange.Value)
			{
				ResetRotation();
			}
		}

		public static void ResetAxis(Vector3 axis)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			_defaultRotator.ResetAxis(axis);
			_internalRotator.ResetAxis(axis);
			_localFrameRotator.ResetAxis(axis);
			_roofRotator.ResetAxis(axis);
		}

		public static void MatchPieceRotation(Piece target)
		{
			_defaultRotator.MatchPieceRotation(target);
			_internalRotator.MatchPieceRotation(target);
			_localFrameRotator.MatchPieceRotation(target);
			_roofRotator.MatchPieceRotation(target);
		}

		public static Quaternion GetRotation()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			return GetActiveRotator().GetRotation();
		}

		public static void ShowGizmos(Player player)
		{
			GetActiveRotator().ShowGizmos(player);
		}

		public static void HideGizmos()
		{
			_defaultRotator.HideGizmos();
			_internalRotator.HideGizmos();
			_localFrameRotator.HideGizmos();
			_roofRotator.HideGizmos();
		}

		public static void ResetScales()
		{
			_defaultRotator.ResetScales();
			_internalRotator.ResetScales();
			_localFrameRotator.ResetScales();
			_roofRotator.ResetScales();
		}

		public static void SetActiveXScale(float scale)
		{
			GetActiveRotator().SetXScale(scale);
		}

		public static void SetActiveYScale(float scale)
		{
			GetActiveRotator().SetYScale(scale);
		}

		public static void SetActiveZScale(float scale)
		{
			GetActiveRotator().SetZScale(scale);
		}

		public static void OnModeChange(Player player)
		{
			if (PluginConfig.ResetRotationOnModeChange.Value)
			{
				ResetRotation();
			}
			HideGizmos();
			GetActiveRotator().DisplayModeChangeHudeMessage();
			GetActiveRotator().ShowGizmos(player);
		}

		private static AbstractRotator GetActiveRotator()
		{
			if (PluginConfig.IsRoofModeEnabled.Value && RoofRotator.IsCornerRoofPieceSelected())
			{
				return _roofRotator;
			}
			if (PluginConfig.IsLocalFrameEnabled.Value)
			{
				return _localFrameRotator;
			}
			if (PluginConfig.IsOldRotationEnabled.Value)
			{
				return _internalRotator;
			}
			return _defaultRotator;
		}

		public static void DestroyRotators()
		{
			if (_defaultRotator != null)
			{
				_defaultRotator.Destroy();
				_defaultRotator = null;
			}
			if (_internalRotator != null)
			{
				_internalRotator.Destroy();
				_internalRotator = null;
			}
			if (_localFrameRotator != null)
			{
				_localFrameRotator.Destroy();
				_localFrameRotator = null;
			}
			if (_roofRotator != null)
			{
				_roofRotator.Destroy();
				_roofRotator = null;
			}
		}

		public static void DisableLocalFrameMode()
		{
			if (PluginConfig.IsLocalFrameEnabled.Value)
			{
				PluginConfig.IsRoofModeEnabled.Value = false;
				ShowMessage("Disabled roof mode.");
			}
		}

		public static void IncreaseSnapDivisions()
		{
			if (PluginConfig.SnapDivisions.Value * 2 <= PluginConfig.MaxSnapDivisions)
			{
				ShowMessage($"Snap divisions increased to {PluginConfig.SnapDivisions.Value * 2}");
				PluginConfig.SnapDivisions.Value = PluginConfig.SnapDivisions.Value * 2;
				ResetRotationConditional();
			}
		}

		public static void DecreaseSnapDivisions()
		{
			if (Math.Floor((float)PluginConfig.SnapDivisions.Value / 2f) == (double)((float)PluginConfig.SnapDivisions.Value / 2f) && PluginConfig.SnapDivisions.Value / 2 >= PluginConfig.MinSnapDivisions)
			{
				ShowMessage($"Snap divisions decreased to {PluginConfig.SnapDivisions.Value / 2}");
				PluginConfig.SnapDivisions.Value = PluginConfig.SnapDivisions.Value / 2;
				ResetRotationConditional();
			}
		}

		private static void ShowMessage(string message)
		{
			if (Object.op_Implicit((Object)(object)MessageHud.m_instance))
			{
				MessageHud.m_instance.ShowMessage((MessageType)1, message, 0, (Sprite)null);
			}
		}

		public static void OnSetupPlacementGhost(GameObject placementGhost)
		{
			if (Object.op_Implicit((Object)(object)placementGhost))
			{
				TerrainOp val = default(TerrainOp);
				IsTerrainOpPrefab = placementGhost.TryGetComponent<TerrainOp>(ref val);
			}
			else
			{
				IsTerrainOpPrefab = false;
			}
		}

		public static bool TryGetRotation(out Quaternion rotation)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			if (IsTerrainOpPrefab && PluginConfig.IgnoreTerrainOpPrefab.Value)
			{
				rotation = Quaternion.identity;
				return false;
			}
			rotation = GetRotation();
			return true;
		}
	}
	public sealed class InternalRotator : AbstractRotator
	{
		public InternalRotator()
		{
			_name = "Internal Rotator";
			_ghostGizmo = GhostGizmo.CreateGhostGizmo();
			_gizmos = Gizmos.CreateGizmos();
			ResetRotation();
		}

		public override void Rotate(Vector3 rotationAxis)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			_eulerAngles += rotationAxis * GetAngle();
			_ghostGizmo.SetLocalRotation(Quaternion.Euler(_eulerAngles));
			_gizmos.SetLocalRotation(_eulerAngles);
		}

		public override void ResetRotation()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: 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)
			_eulerAngles = Vector3.zero;
			_ghostGizmo.SetLocalRotation(Quaternion.Euler(_eulerAngles));
			_gizmos.SetLocalRotation(_eulerAngles);
		}

		public override void ResetAxis(Vector3 axis)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			if (axis == Vector3.up)
			{
				_eulerAngles.y = 0f;
			}
			if (axis == Vector3.right)
			{
				_eulerAngles.x = 0f;
			}
			if (axis == Vector3.forward)
			{
				_eulerAngles.z = 0f;
			}
			_ghostGizmo.SetLocalRotation(Quaternion.Euler(_eulerAngles));
			_gizmos.SetLocalRotation(_eulerAngles);
		}

		public override void MatchPieceRotation(Piece target)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			ResetRotation();
			_eulerAngles = ((Component)target).GetComponent<Transform>().eulerAngles;
			Rotate(Vector3.zero);
		}

		protected override string GetModeName()
		{
			return "old rotation";
		}

		protected override Gizmos GetGizmos()
		{
			return _gizmos;
		}

		public override Quaternion GetRotation()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			return _ghostGizmo.GetRotation();
		}
	}
	public sealed class LocalFrameRotator : AbstractRotator
	{
		public LocalFrameRotator()
		{
			_name = "Local Frame Rotator";
			_ghostGizmo = GhostGizmo.CreateGhostGizmo();
			_gizmos = Gizmos.CreateGizmos();
			ResetRotation();
		}

		public override void Rotate(Vector3 rotationAxis)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: 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_001f: Unknown result type (might be due to invalid IL or missing references)
			Quaternion rotation = Quaternion.AngleAxis(GetAngle(), rotationAxis);
			_ghostGizmo.ApplyRotation(rotation);
			_gizmos.ApplyRotation(rotation);
		}

		public override void ResetRotation()
		{
			//IL_0006: 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)
			_ghostGizmo.SetRotation(Quaternion.identity);
			_gizmos.SetRotation(Quaternion.identity);
		}

		public override void ResetAxis(Vector3 axis)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			_ghostGizmo.SetAxisRotation(0f, axis);
			_gizmos.SetAxisRotation(0f, axis);
		}

		public override void MatchPieceRotation(Piece target)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			_ghostGizmo.SetRotation(((Component)target).GetComponent<Transform>().localRotation);
			_gizmos.SetRotation(((Component)target).GetComponent<Transform>().localRotation);
		}

		protected override string GetModeName()
		{
			return "local frame rotation";
		}

		protected override Gizmos GetGizmos()
		{
			return _gizmos;
		}

		public override Quaternion GetRotation()
		{
			//IL_0023: 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)
			if (!PluginConfig.IsOldRotationEnabled.Value)
			{
				return _gizmos.GetXGizmoRoot().rotation;
			}
			return _ghostGizmo.GetRotation();
		}
	}
	public sealed class RoofRotator : AbstractRotator
	{
		private Quaternion _roofRotation;

		public static readonly HashSet<string> RoofCornerPieceNames = new HashSet<string> { "wood_roof_ocorner", "wood_roof_ocorner_45", "wood_roof_icorner", "wood_roof_icorner_45", "darkwood_roof_ocorner", "darkwood_roof_ocorner_45", "darkwood_roof_icorner", "darkwood_roof_icorner_45" };

		public RoofRotator()
		{
			_name = "Roof Rotator";
			_ghostGizmo = GhostGizmo.CreateGhostGizmo();
			_gizmos = Gizmos.CreateGizmos();
			ResetRotation();
		}

		public override void Rotate(Vector3 rotationAxis)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_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_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			_eulerAngles += rotationAxis * GetAngle();
			Vector3 val = ConvertAxisRoofMode(rotationAxis);
			_gizmos.SetLocalRotation(_eulerAngles);
			_roofRotation *= Quaternion.AngleAxis(GetAngle(), val);
		}

		public override void ResetRotation()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			_eulerAngles = Vector3.zero;
			_gizmos.SetLocalRotation(_eulerAngles);
			_roofRotation = GetBaseRotation();
		}

		public override void ResetAxis(Vector3 axis)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			if (axis == Vector3.up)
			{
				_eulerAngles.y = 0f;
			}
			if (axis == Vector3.right)
			{
				_eulerAngles.x = 0f;
			}
			if (axis == Vector3.forward)
			{
				_eulerAngles.z = 0f;
			}
			_gizmos.SetLocalRotation(_eulerAngles);
			_roofRotation = GetBaseRotation() * Quaternion.Euler(_eulerAngles);
		}

		public override void MatchPieceRotation(Piece target)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: 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_0051: Unknown result type (might be due to invalid IL or missing references)
			ResetRotation();
			Quaternion val = GetInverseBaseRotation() * Quaternion.Euler(((Component)target).transform.eulerAngles);
			_eulerAngles = ((Quaternion)(ref val)).eulerAngles;
			_gizmos.SetLocalRotation(_eulerAngles);
			_roofRotation = Quaternion.Euler(((Component)target).transform.eulerAngles);
		}

		protected override string GetModeName()
		{
			return "roof rotation";
		}

		protected override Gizmos GetGizmos()
		{
			return _gizmos;
		}

		public override Quaternion GetRotation()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			return _roofRotation;
		}

		private Vector3 ConvertAxisRoofMode(Vector3 rotationAxis)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			return Quaternion.Euler(0f, -45f, 0f) * rotationAxis;
		}

		private Quaternion GetBaseRotation()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			return Quaternion.AngleAxis(45f, Vector3.up);
		}

		private Quaternion GetInverseBaseRotation()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			return Quaternion.AngleAxis(-45f, Vector3.up);
		}

		public static bool IsCornerRoofPieceSelected()
		{
			if (Object.op_Implicit((Object)(object)Player.m_localPlayer) && Object.op_Implicit((Object)(object)Player.m_localPlayer.m_placementGhost))
			{
				return RoofCornerPieceNames.Contains(Utils.GetPrefabName(((Object)Player.m_localPlayer.m_placementGhost).name));
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(FejdStartup))]
	internal static class FejdStartupPatch
	{
		[HarmonyPostfix]
		[HarmonyPatch("Awake")]
		private static void AwakePostfix()
		{
			HammerTableManager.Initialize();
		}
	}
	[HarmonyPatch(typeof(Game))]
	internal static class GamePatch
	{
		[HarmonyPostfix]
		[HarmonyPatch("Start")]
		private static void StartPostfix()
		{
			RotationManager.Initialize();
		}
	}
	[HarmonyPatch(typeof(Player))]
	internal static class PlayerPatch
	{
		[HarmonyPostfix]
		[HarmonyPatch("UpdatePlacement")]
		private static void UpdatePlacementPostfix(Player __instance, bool takeInput)
		{
			//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_0030: 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_004f: 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_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			RotationManager.HideGizmos();
			RotationManager.ShowGizmos(__instance);
			if (!takeInput || !Object.op_Implicit((Object)(object)__instance.m_buildPieces) || Hud.IsPieceSelectionVisible())
			{
				return;
			}
			KeyboardShortcut value = PluginConfig.SnapDivisionIncrementKey.Value;
			if (ZInput.GetKeyDown(((KeyboardShortcut)(ref value)).MainKey, true))
			{
				RotationManager.IncreaseSnapDivisions();
			}
			value = PluginConfig.SnapDivisionDecrementKey.Value;
			if (ZInput.GetKeyDown(((KeyboardShortcut)(ref value)).MainKey, true))
			{
				RotationManager.DecreaseSnapDivisions();
			}
			value = PluginConfig.CopyPieceRotationKey.Value;
			if (ZInput.GetKeyDown(((KeyboardShortcut)(ref value)).MainKey, true) && (Object)(object)__instance.m_hoveringPiece != (Object)null)
			{
				RotationManager.MatchPieceRotation(__instance.m_hoveringPiece);
			}
			value = PluginConfig.ChangeRotationModeKey.Value;
			if (ZInput.GetKeyDown(((KeyboardShortcut)(ref value)).MainKey, true))
			{
				PluginConfig.IsLocalFrameEnabled.Value = !PluginConfig.IsLocalFrameEnabled.Value;
			}
			RotationManager.ResetScales();
			value = PluginConfig.ResetAllRotationKey.Value;
			if (ZInput.GetKey(((KeyboardShortcut)(ref value)).MainKey, true))
			{
				RotationManager.ResetRotation();
				return;
			}
			Vector3 rotationAxis = GetRotationAxis();
			value = PluginConfig.ResetRotationKey.Value;
			if (ZInput.GetKey(((KeyboardShortcut)(ref value)).MainKey, true))
			{
				RotationManager.ResetAxis(rotationAxis);
			}
			rotationAxis *= (float)GetSign();
			RotationManager.Rotate(rotationAxis);
		}

		private static int GetSign()
		{
			return Math.Sign(ZInput.GetMouseScrollWheel());
		}

		private static Vector3 GetRotationAxis()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			KeyboardShortcut value = PluginConfig.XRotationKey.Value;
			if (ZInput.GetKey(((KeyboardShortcut)(ref value)).MainKey, true))
			{
				RotationManager.SetActiveXScale(1.5f);
				return Vector3.right;
			}
			value = PluginConfig.ZRotationKey.Value;
			if (ZInput.GetKey(((KeyboardShortcut)(ref value)).MainKey, true))
			{
				RotationManager.SetActiveZScale(1.5f);
				return Vector3.forward;
			}
			RotationManager.SetActiveYScale(1.5f);
			return Vector3.up;
		}

		[HarmonyPostfix]
		[HarmonyPatch("SetupPlacementGhost")]
		private static void SetupPlacementGhostPostfix(Player __instance)
		{
			RotationManager.OnSetupPlacementGhost(__instance.m_placementGhost);
		}

		[HarmonyPrefix]
		[HarmonyPatch("UpdatePlacementGhost")]
		private static void UpdatePlacementGhostPrefix(Player __instance)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			KeyboardShortcut value = PluginConfig.SelectTargetPieceKey.Value;
			if (ZInput.GetKeyDown(((KeyboardShortcut)(ref value)).MainKey, true) && HasValidTargetPiece(__instance))
			{
				HammerTableManager.SelectTargetPiece(__instance);
			}
		}

		private static bool HasValidTargetPiece(Player player)
		{
			if (Object.op_Implicit((Object)(object)player) && Object.op_Implicit((Object)(object)player.GetHoveringPiece()) && Object.op_Implicit((Object)(object)player.m_buildPieces))
			{
				return player.m_buildPieces.m_availablePieces != null;
			}
			return false;
		}

		[HarmonyTranspiler]
		[HarmonyPatch("UpdatePlacementGhost")]
		private static IEnumerable<CodeInstruction> UpdatePlacementGhostTranspiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Expected O, but got Unknown
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Expected O, but got Unknown
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Expected O, but got Unknown
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Expected O, but got Unknown
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Expected O, but got Unknown
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Expected O, but got Unknown
			return new CodeMatcher(instructions, (ILGenerator)null).Start().MatchStartForward((CodeMatch[])(object)new CodeMatch[6]
			{
				new CodeMatch((OpCode?)OpCodes.Ldfld, (object)AccessTools.Field(typeof(Player), "m_placeRotation"), (string)null),
				new CodeMatch((OpCode?)OpCodes.Conv_R4, (object)null, (string)null),
				new CodeMatch((OpCode?)OpCodes.Mul, (object)null, (string)null),
				new CodeMatch((OpCode?)OpCodes.Ldc_R4, (object)null, (string)null),
				new CodeMatch((OpCode?)OpCodes.Call, (object)null, (string)null),
				new CodeMatch((OpCode?)OpCodes.Stloc_S, (object)null, (string)null)
			}).ThrowIfInvalid("Could not patch Player.UpdatePlacementGhost()! (place-rotation)")
				.Advance(5)
				.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
				{
					new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(PlayerPatch), "PlaceRotationDelegate", (Type[])null, (Type[])null))
				})
				.InstructionEnumeration();
		}

		private static Quaternion PlaceRotationDelegate(Quaternion rotation)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			if (RotationManager.TryGetRotation(out var rotation2))
			{
				return rotation2;
			}
			return rotation;
		}
	}
	public static class PluginConfig
	{
		public static readonly int MinSnapDivisions = 2;

		public static readonly int MaxSnapDivisions = 256;

		public static ConfigEntry<int> SnapDivisions { get; private set; }

		public static ConfigEntry<bool> ShowGizmoPrefab { get; private set; }

		public static ConfigEntry<bool> ResetRotationOnModeChange { get; private set; }

		public static ConfigEntry<bool> ResetRotationOnSnapDivisionChange { get; private set; }

		public static ConfigEntry<bool> IsLocalFrameEnabled { get; private set; }

		public static ConfigEntry<bool> IsOldRotationEnabled { get; private set; }

		public static ConfigEntry<bool> IsRoofModeEnabled { get; private set; }

		public static ConfigEntry<bool> IgnoreTerrainOpPrefab { get; private set; }

		public static ConfigEntry<KeyboardShortcut> XRotationKey { get; private set; }

		public static ConfigEntry<KeyboardShortcut> ZRotationKey { get; private set; }

		public static ConfigEntry<KeyboardShortcut> ResetRotationKey { get; private set; }

		public static ConfigEntry<KeyboardShortcut> ResetAllRotationKey { get; private set; }

		public static ConfigEntry<KeyboardShortcut> ChangeRotationModeKey { get; private set; }

		public static ConfigEntry<KeyboardShortcut> CopyPieceRotationKey { get; private set; }

		public static ConfigEntry<KeyboardShortcut> SelectTargetPieceKey { get; private set; }

		public static ConfigEntry<KeyboardShortcut> SnapDivisionIncrementKey { get; private set; }

		public static ConfigEntry<KeyboardShortcut> SnapDivisionDecrementKey { get; private set; }

		public static ConfigEntry<Color> XGizmoColor { get; private set; }

		public static ConfigEntry<Color> YGizmoColor { get; private set; }

		public static ConfigEntry<Color> ZGizmoColor { get; private set; }

		public static ConfigEntry<float> XEmissionColorFactor { get; private set; }

		public static ConfigEntry<float> YEmissionColorFactor { get; private set; }

		public static ConfigEntry<float> ZEmissionColorFactor { get; private set; }

		public static void BindConfig(ConfigFile config)
		{
			SnapDivisions = config.BindInOrder("Gizmo", "snapDivisions", 16, "Number of snap angles per 180 degrees. Vanilla uses 8.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(MinSnapDivisions, MaxSnapDivisions));
			SnapDivisions.OnSettingChanged<int>(RotationManager.ResetRotationConditional);
			BindKeysConfig(config);
			BindGizmoColorsConfig(config);
			ShowGizmoPrefab = config.BindInOrder("UI", "showGizmoPrefab", defaultValue: true, "Show the Gizmo prefab in placement mode.");
			ResetRotationOnSnapDivisionChange = config.BindInOrder("Reset", "resetOnSnapDivisionChange", defaultValue: true, "Resets the piece's rotation on snap division change.");
			ResetRotationOnModeChange = config.BindInOrder("Reset", "resetOnModeChange", defaultValue: true, "Resets the piece's rotation on mode switch.");
			IsRoofModeEnabled = config.BindInOrder("Modes", "isRoofModeEnabled", defaultValue: false, "Enables roof mode which allows corner roof piece rotation 45 deg compared to normal rotation.");
			IsRoofModeEnabled.OnSettingChanged<bool>((Action)delegate
			{
				RotationManager.ResetRotation();
				RotationManager.OnModeChange(Player.m_localPlayer);
			});
			IsOldRotationEnabled = config.BindInOrder("Modes", "isOldRotationModeEnabled", defaultValue: false, "Enables pre Gizmo-v1.4.0 rotation scheme.");
			IsOldRotationEnabled.OnSettingChanged<bool>((Action)delegate
			{
				RotationManager.OnModeChange(Player.m_localPlayer);
			});
			IsLocalFrameEnabled = config.BindInOrder("Modes", "isLocalFrameModeEnabled", defaultValue: false, "Enables localFrame rotation mode. Allows rotation around the piece's Y-axis rather than world-Y.");
			IsLocalFrameEnabled.OnSettingChanged<bool>((Action)delegate
			{
				RotationManager.OnModeChange(Player.m_localPlayer);
				RotationManager.DisableLocalFrameMode();
			});
			IgnoreTerrainOpPrefab = config.BindInOrder("Ignored", "ignoreTerrainOpPrefab", defaultValue: false, "If enabled, rotation will be ignored for terrain-modifying prefabs.");
		}

		public static void BindKeysConfig(ConfigFile config)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			XRotationKey = config.BindInOrder<KeyboardShortcut>("Keys", "xRotationKey", new KeyboardShortcut((KeyCode)304, Array.Empty<KeyCode>()), "Hold this key to rotate on the x-axis/plane (red circle).");
			ZRotationKey = config.BindInOrder<KeyboardShortcut>("Keys", "zRotationKey", new KeyboardShortcut((KeyCode)308, Array.Empty<KeyCode>()), "Hold this key to rotate on the z-axis/plane (blue circle).");
			ResetRotationKey = config.BindInOrder<KeyboardShortcut>("Keys", "resetRotationKey", new KeyboardShortcut((KeyCode)118, Array.Empty<KeyCode>()), "Press this key to reset the selected axis to zero rotation.");
			ResetAllRotationKey = config.BindInOrder<KeyboardShortcut>("Keys", "resetAllRotationKey", KeyboardShortcut.Empty, "Press this key to reset _all axis_ rotations to zero rotation.");
			ChangeRotationModeKey = config.BindInOrder<KeyboardShortcut>("Keys", "changeRotationMode", new KeyboardShortcut((KeyCode)96, Array.Empty<KeyCode>()), "Press this key to toggle rotation modes.");
			CopyPieceRotationKey = config.BindInOrder<KeyboardShortcut>("Keys", "copyPieceRotation", KeyboardShortcut.Empty, "Press this key to copy targeted piece's rotation.");
			SelectTargetPieceKey = config.BindInOrder<KeyboardShortcut>("Keys", "selectTargetPieceKey", new KeyboardShortcut((KeyCode)112, Array.Empty<KeyCode>()), "Selects target piece to be used.");
			SnapDivisionIncrementKey = config.BindInOrder<KeyboardShortcut>("Keys", "snapDivisionIncrement", new KeyboardShortcut((KeyCode)280, Array.Empty<KeyCode>()), "Doubles snap divisions from current.");
			SnapDivisionDecrementKey = config.BindInOrder<KeyboardShortcut>("Keys", "snapDivisionDecrement", new KeyboardShortcut((KeyCode)281, Array.Empty<KeyCode>()), "Doubles snap divisions from current.");
		}

		public static void BindGizmoColorsConfig(ConfigFile config)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			XGizmoColor = config.BindInOrder<Color>("GizmoColors - X", "xGizmoColor", new Color(1f, 0f, 0f, 0.502f), "Sets the color of x gizmo (rotations about x axis).");
			XGizmoColor.OnSettingChanged<Color>(Gizmos.SetAllXColors);
			YGizmoColor = config.BindInOrder<Color>("GizmoColors - Y", "yGizmoColor", new Color(0f, 1f, 0f, 0.502f), "Sets the color of y gizmo (rotations about y axis).");
			YGizmoColor.OnSettingChanged<Color>(Gizmos.SetAllYColors);
			ZGizmoColor = config.BindInOrder<Color>("GizmoColors - Z", "zGizmoColor", new Color(0f, 0f, 1f, 0.502f), "Sets the color of z gizmo (rotations about z axis).");
			ZGizmoColor.OnSettingChanged<Color>(Gizmos.SetAllZColors);
			XEmissionColorFactor = config.BindInOrder("GizmoColors - X", "emissionColorFactorX", 1f, "Factor to multiply the target color by and set as emission color.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 3f));
			XEmissionColorFactor.OnSettingChanged<float>(Gizmos.SetAllXColors);
			YEmissionColorFactor = config.BindInOrder("GizmoColors - Y", "emissionColorFactorY", 1f, "Factor to multiply the target color by and set as emission color.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 3f));
			YEmissionColorFactor.OnSettingChanged<float>(Gizmos.SetAllYColors);
			ZEmissionColorFactor = config.BindInOrder("GizmoColors - Z", "emissionColorFactorZ", 1f, "Factor to multiply the target color by and set as emission color.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 3f));
			ZEmissionColorFactor.OnSettingChanged<float>(Gizmos.SetAllZColors);
		}
	}
}