Decompiled source of MasterBuilderHeeler v1.2.1

MasterBuilderHeeler.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using ConditionalConfigSync;
using HarmonyLib;
using Jotunn.Configs;
using Jotunn.Extensions;
using Jotunn.Managers;
using Jotunn.Utils;
using MasterBuilderHeeler.Configuration;
using MasterBuilderHeeler.Core.Camera;
using MasterBuilderHeeler.Core.Input;
using MasterBuilderHeeler.Core.Placement;
using MasterBuilderHeeler.Core.Rotation;
using MasterBuilderHeeler.Core.Rotation.Rotators;
using MasterBuilderHeeler.Core.Sampling;
using MasterBuilderHeeler.Core.State;
using MasterBuilderHeeler.Core.Translation;
using MasterBuilderHeeler.Core.UI;
using MasterBuilderHeeler.Core.UI.Panels;
using MasterBuilderHeeler.Core.Validation;
using MasterBuilderHeeler.Core.Visuals.Gizmo;
using MasterBuilderHeeler.Core.Visuals.Gizmo.Themes.Wireframe;
using MasterBuilderHeeler.Core.Visuals.Grid;
using MasterBuilderHeeler.Utilities;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("DreamWraith (https://github.com/dreamwraith)")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("Copyright (c) 2026 DreamWraith")]
[assembly: AssemblyDescription("Precision building tools for Valheim: pitch, yaw, and roll rotation, grid snapping, piece nudging, ghost freeze, in-place piece moving, piece sampling, build camera, and build info panels.")]
[assembly: AssemblyFileVersion("1.2.1.0")]
[assembly: AssemblyInformationalVersion("1.2.1+825b6969d1a0b763de57bddaaef5e5b2ae627313")]
[assembly: AssemblyProduct("MasterBuilderHeeler")]
[assembly: AssemblyTitle("MasterBuilderHeeler")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/dreamwraith/Valheim-MasterBuilderHeeler")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.2.1.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[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 MasterBuilderHeeler
{
	[BepInPlugin("dreamwraith.MasterBuilderHeeler", "MasterBuilderHeeler", "1.2.1")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInIncompatibility("Azumatt_and_ValheimPlusDevs.PerfectPlacement")]
	[BepInIncompatibility("Azumatt.BuildCameraCHE")]
	[BepInIncompatibility("infinity_hammer")]
	public class Plugin : BaseUnityPlugin
	{
		public const string ModGUID = "dreamwraith.MasterBuilderHeeler";

		public const string ModName = "MasterBuilderHeeler";

		public const string ModVersion = "1.2.1";

		public const string MinimumCompatibleVersion = "0.0.1";

		private Harmony? _harmony;

		internal static ManualLogSource Log { get; private set; }

		private void Awake()
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			Log = ((BaseUnityPlugin)this).Logger;
			ModConfig.Initialize(((BaseUnityPlugin)this).Config);
			new ConfigFileWatcher(((BaseUnityPlugin)this).Config, 1000L);
			if (!GUIManager.IsHeadless())
			{
				ModInputManager.Initialize();
				HudTheme.Initialize();
				HudKeybindFormatter.Initialize();
				BuildInputRouter.Initialize();
				BuildStateManager.Initialize();
				PlacementGhostController.Initialize();
				BuildCameraRig.Initialize();
				GizmoRendering.Initialize();
				HudManager.Initialize();
				_harmony = Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "dreamwraith.MasterBuilderHeeler");
				Log.LogInfo((object)"MasterBuilderHeeler v1.2.1 initialized.");
			}
		}

		private void OnDestroy()
		{
			if (!GUIManager.IsHeadless())
			{
				if (_harmony != null)
				{
					_harmony.UnpatchSelf();
				}
				PlacementGhostController.ResetBuildSession();
				PlacementGhostController.Cleanup();
				HudManager.Cleanup();
				HudKeybindFormatter.Cleanup();
				HudTheme.Cleanup();
				GizmoRendering.Cleanup();
				GridOverlayRenderer.Cleanup();
				BuildCameraRig.Cleanup();
				BuildStateManager.Cleanup();
			}
		}

		internal static void LogInfo(string message)
		{
			if (ModConfig.IsInfoLogging)
			{
				Log.LogInfo((object)message);
			}
		}

		internal static void LogDebug(string message)
		{
			if (ModConfig.IsDebugLogging)
			{
				Log.LogInfo((object)("[DEBUG] " + message));
			}
		}
	}
	internal static class VersionInfo
	{
		public const string Version = "1.2.1";
	}
}
namespace MasterBuilderHeeler.Utilities
{
	public static class CameraUtils
	{
		public static Camera? GetActiveCamera()
		{
			if (!Object.op_Implicit((Object)(object)GameCamera.instance) || !Object.op_Implicit((Object)(object)GameCamera.instance.m_camera))
			{
				return Camera.main;
			}
			return GameCamera.instance.m_camera;
		}
	}
	public static class HudMessageUtils
	{
		public static void ShowTopLeft(string message)
		{
			if (Object.op_Implicit((Object)(object)MessageHud.instance))
			{
				MessageHud.instance.ShowMessage((MessageType)1, message, 0, (Sprite)null, false, true);
			}
		}

		public static void ShowCenter(string message)
		{
			if (Object.op_Implicit((Object)(object)MessageHud.instance))
			{
				MessageHud.instance.ShowMessage((MessageType)2, message, 0, (Sprite)null, false, true);
			}
		}
	}
	public static class InputUtils
	{
		public static bool IsTextInputOrMenuOpen()
		{
			if (Object.op_Implicit((Object)(object)Chat.instance) && Chat.instance.HasFocus())
			{
				return true;
			}
			if (Console.IsVisible() || TextInput.IsVisible() || Menu.IsVisible() || InventoryGui.IsVisible() || StoreGui.IsVisible() || Hud.IsPieceSelectionVisible() || Hud.InRadial())
			{
				return true;
			}
			if (Minimap.InTextInput())
			{
				return true;
			}
			if (Object.op_Implicit((Object)(object)Hud.instance) && Object.op_Implicit((Object)(object)Hud.instance.m_buildUi) && Hud.instance.m_buildUi.SearchFieldFocused)
			{
				return true;
			}
			if (PlayerCustomizaton.IsBarberGuiVisible())
			{
				return true;
			}
			return false;
		}

		public static Vector3 GetBuildCameraMoveDirection(Transform cameraTransform)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: 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)
			//IL_001e: 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_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: 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_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: 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_0064: 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_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: 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_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = Vector3.zero;
			if (ZInput.GetButton("Forward"))
			{
				val += cameraTransform.forward;
			}
			if (ZInput.GetButton("Backward"))
			{
				val -= cameraTransform.forward;
			}
			if (ZInput.GetButton("Right"))
			{
				val += cameraTransform.right;
			}
			if (ZInput.GetButton("Left"))
			{
				val -= cameraTransform.right;
			}
			if (ZInput.GetButton("Jump"))
			{
				val += Vector3.up;
			}
			if (ZInput.GetButton("Crouch"))
			{
				val += Vector3.down;
			}
			return val;
		}
	}
	public static class KeyLabelFormatter
	{
		private static readonly StringBuilder SharedBuilder = new StringBuilder(64);

		private static readonly Dictionary<ConfigEntryBase, string> LabelCache = new Dictionary<ConfigEntryBase, string>(32);

		public static void ClearCache()
		{
			LabelCache.Clear();
		}

		public static string Format(ConfigEntry<KeyboardShortcut> entry)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			if (LabelCache.TryGetValue((ConfigEntryBase)(object)entry, out string value))
			{
				return value;
			}
			string text = Format(entry.Value);
			LabelCache[(ConfigEntryBase)(object)entry] = text;
			return text;
		}

		public static string Format(KeyboardShortcut shortcut)
		{
			//IL_0002: 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_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: 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)
			if ((int)((KeyboardShortcut)(ref shortcut)).MainKey == 0)
			{
				return "Unbound";
			}
			SharedBuilder.Clear();
			foreach (KeyCode modifier in ((KeyboardShortcut)(ref shortcut)).Modifiers)
			{
				if ((int)modifier != 0)
				{
					if (SharedBuilder.Length > 0)
					{
						SharedBuilder.Append('+');
					}
					SharedBuilder.Append(FormatKeyCode(modifier));
				}
			}
			if (SharedBuilder.Length > 0)
			{
				SharedBuilder.Append('+');
			}
			SharedBuilder.Append(FormatKeyCode(((KeyboardShortcut)(ref shortcut)).MainKey));
			return SharedBuilder.ToString();
		}

		public static string FormatKeyCode(KeyCode keyCode)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			return GetKeyDisplayName(keyCode).Replace("Page ", "Pg");
		}

		private unsafe static string GetKeyDisplayName(KeyCode keyCode)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			string text = ZInput.KeyCodeToDisplayName(keyCode);
			if (string.IsNullOrEmpty(text) || text.StartsWith("$KeyCode", StringComparison.Ordinal))
			{
				return ((object)(*(KeyCode*)(&keyCode))/*cast due to .constrained prefix*/).ToString();
			}
			if (text[0] == '$')
			{
				return Localization.instance.Localize(text);
			}
			return text;
		}
	}
	public static class MathUtils
	{
		public static float SnapScalar(float value, float step)
		{
			return Mathf.Round(value / step) * step;
		}

		public static string FormatEulerPlain(Vector3 euler)
		{
			//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)
			return $"({euler.x:0.#} deg, {euler.y:0.#} deg, {euler.z:0.#} deg)";
		}
	}
	public static class PieceUtils
	{
		public static string GetDisplayName(Piece piece)
		{
			if (!string.IsNullOrEmpty(piece.m_name))
			{
				return Localization.instance.Localize(piece.m_name);
			}
			return Utils.GetPrefabName(((Component)piece).gameObject);
		}

		public static string FormatPanelName(Piece piece, bool showName, bool showPrefab)
		{
			string prefabName = Utils.GetPrefabName(((Component)piece).gameObject);
			if (!showName)
			{
				return prefabName;
			}
			string displayName = GetDisplayName(piece);
			if (!showPrefab)
			{
				return displayName;
			}
			return displayName + " (" + prefabName + ")";
		}
	}
}
namespace MasterBuilderHeeler.Patches
{
	[HarmonyPatch(typeof(CraftingStation), "HaveBuildStationInRange")]
	public static class CraftingStationPatches
	{
		[HarmonyPrefix]
		private static void HaveBuildStationInRangePrefix(ref Vector3 point)
		{
			PlacementValidator.OverrideStationRangePoint(ref point);
		}
	}
	[HarmonyPatch(typeof(Player), "CheckCanRemovePiece")]
	public static class PlayerStationCheckPatches
	{
		[HarmonyPrefix]
		private static void Prefix(Piece piece)
		{
			PlacementValidator.RepairOrRemoveTarget = piece;
		}

		[HarmonyFinalizer]
		private static void Finalizer()
		{
			PlacementValidator.RepairOrRemoveTarget = null;
		}
	}
	[HarmonyPatch(typeof(GameCamera), "UpdateCamera")]
	public static class GameCameraPatches
	{
		[HarmonyPrefix]
		[HarmonyPriority(700)]
		private static bool UpdateCameraPrefix(float dt, GameCamera __instance, out float __state)
		{
			return BuildCameraController.InterceptCameraUpdate(dt, __instance, out __state);
		}

		[HarmonyPostfix]
		private static void UpdateCameraPostfix(GameCamera __instance, float __state)
		{
			BuildCameraController.RestoreZoomSensitivity(__instance, __state);
		}
	}
	[HarmonyPatch(typeof(Hud))]
	public static class HudPatches
	{
		[HarmonyPatch("Awake")]
		[HarmonyPostfix]
		private static void AwakePostfix(Hud __instance)
		{
			HudManager.AttachToHud(__instance);
		}

		[HarmonyPatch("UpdateCrosshair")]
		[HarmonyPostfix]
		private static void UpdateCrosshairPostfix(Hud __instance)
		{
			HudManager.UpdateNativePieceHealthBar(__instance);
		}
	}
	[HarmonyPatch(typeof(Player), "CopyPiece")]
	public static class PieceCopyPatches
	{
		[HarmonyPrefix]
		private static bool Prefix(Player __instance)
		{
			return PieceEyedropper.ResolveNativeCopy(__instance);
		}

		[HarmonyPostfix]
		private static void Postfix(Player __instance, bool __result)
		{
			if (__result)
			{
				PieceRotationEngine.SyncNativeYaw(__instance);
			}
		}
	}
	[HarmonyPatch(typeof(Player))]
	public static class PlacementGhostPatches
	{
		private static readonly FieldInfo PlayerPlaceRotationField = AccessTools.Field(typeof(Player), "m_placeRotation");

		private static readonly MethodInfo QuaternionEulerMethod = AccessTools.Method(typeof(Quaternion), "Euler", new Type[3]
		{
			typeof(float),
			typeof(float),
			typeof(float)
		}, (Type[])null);

		private static readonly MethodInfo ResolveTargetRotationMethod = AccessTools.Method(typeof(PieceRotationEngine), "ResolveTargetRotation", (Type[])null, (Type[])null);

		[HarmonyPatch("UpdatePlacement")]
		[HarmonyPrefix]
		private static void UpdatePlacementPrefix(ref bool takeInput)
		{
			PlacementGhostController.SuppressPlacementInputIfEditing(ref takeInput);
		}

		[HarmonyPatch("SetSelectedPiece", new Type[] { typeof(Vector2Int) })]
		[HarmonyPrefix]
		private static void SetSelectedPiecePrefix(Player __instance, Vector2Int p)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			PlacementGhostController.OnSelectedPieceChanging(__instance, p);
		}

		[HarmonyPatch("SetupPlacementGhost")]
		[HarmonyPrefix]
		private static void SetupPlacementGhostPrefix(Player __instance)
		{
			PlacementGhostController.BeforeSetupPlacementGhost(__instance);
		}

		[HarmonyPatch("SetupPlacementGhost")]
		[HarmonyPostfix]
		private static void SetupPlacementGhostPostfix(Player __instance)
		{
			PlacementGhostController.AfterSetupPlacementGhost(__instance);
		}

		[HarmonyPatch("TryPlacePiece")]
		[HarmonyPostfix]
		private static void TryPlacePiecePostfix(Player __instance, bool __result)
		{
			PlacementGhostController.OnTryPlacePieceCompleted(__instance, __result);
		}

		[HarmonyPatch("PlacePiece")]
		[HarmonyPostfix]
		private static void PlacePiecePostfix()
		{
			PlacementGhostController.OnPiecePlaced();
		}

		[HarmonyPatch("UpdatePlacementGhost")]
		[HarmonyPrefix]
		[HarmonyPriority(800)]
		private static bool UpdatePlacementGhostPrefix(Player __instance, bool flashGuardStone)
		{
			return PlacementGhostController.TryOverridePlacementGhost(__instance, flashGuardStone);
		}

		[HarmonyPatch("UpdatePlacementGhost")]
		[HarmonyPostfix]
		[HarmonyPriority(700)]
		private static void UpdatePlacementGhostPostfix(Player __instance, bool flashGuardStone)
		{
			PlacementGhostController.ApplyPrecisionGhostOffset(__instance, flashGuardStone);
		}

		[HarmonyPatch("CanRotatePiece")]
		[HarmonyPostfix]
		private static void CanRotatePiecePostfix(ref bool __result)
		{
			PieceRotationEngine.OverrideCanRotatePiece(ref __result);
		}

		[HarmonyPatch("UpdatePlacementGhost")]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> UpdatePlacementGhostTranspiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0002: 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_0025: Expected O, but got Unknown
			//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_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Expected O, but got Unknown
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Expected O, but got Unknown
			return new CodeMatcher(instructions, (ILGenerator)null).MatchEndForward((CodeMatch[])(object)new CodeMatch[5]
			{
				new CodeMatch((OpCode?)OpCodes.Ldfld, (object)PlayerPlaceRotationField, (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)QuaternionEulerMethod, (string)null)
			}).ThrowIfInvalid("Could not locate Player.UpdatePlacementGhost placeRotation Euler calculation.").Advance(1)
				.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
				{
					new CodeInstruction(OpCodes.Call, (object)ResolveTargetRotationMethod)
				})
				.InstructionEnumeration();
		}
	}
	[HarmonyPatch]
	public static class PlayerLifecyclePatches
	{
		[HarmonyPatch(typeof(Player), "SetLocalPlayer")]
		[HarmonyPostfix]
		private static void SetLocalPlayerPostfix(Player __instance)
		{
			PlacementGhostController.OnLocalPlayerReady(__instance);
		}

		[HarmonyPatch(typeof(Player), "OnDestroy")]
		[HarmonyPrefix]
		private static void OnDestroyPrefix(Player __instance)
		{
			PlacementGhostController.OnPlayerDestroyed(__instance);
		}

		[HarmonyPatch(typeof(Player), "Update")]
		[HarmonyPostfix]
		private static void UpdatePostfix(Player __instance)
		{
			PlacementGhostController.UpdateSessionLifecycle(__instance);
			BuildInputRouter.ProcessInput(__instance);
		}

		[HarmonyPatch(typeof(PlayerController), "TakeInput")]
		[HarmonyPostfix]
		private static void TakeInputPostfix(ref bool __result)
		{
			BuildCameraController.OverrideTakeInput(ref __result);
		}
	}
	[HarmonyPatch]
	public static class PlayerReachPatches
	{
		[HarmonyTargetMethods]
		private static IEnumerable<MethodBase> TargetMethods()
		{
			yield return AccessTools.DeclaredMethod(typeof(Player), "PieceRayTest", (Type[])null, (Type[])null);
			yield return AccessTools.DeclaredMethod(typeof(Player), "UpdateWearNTearHover", (Type[])null, (Type[])null);
			yield return AccessTools.DeclaredMethod(typeof(Player), "CopyPiece", (Type[])null, (Type[])null);
			yield return AccessTools.DeclaredMethod(typeof(Player), "RemovePiece", (Type[])null, (Type[])null);
		}

		[HarmonyPrefix]
		[HarmonyPriority(800)]
		private static void Prefix(Player __instance, out float __state)
		{
			BuildReachService.ApplyReachExpansion(__instance, out __state);
		}

		[HarmonyPostfix]
		private static void Postfix(Player __instance, float __state)
		{
			BuildReachService.RestoreReach(__instance, __state);
		}
	}
	[HarmonyPatch(typeof(WearNTearUpdater), "Update")]
	public static class WearNTearPatches
	{
		[HarmonyPrefix]
		private static void UpdatePrefix(WearNTearUpdater __instance)
		{
			PieceEditController.DeferWearNTearIfEditing(__instance);
		}
	}
}
namespace MasterBuilderHeeler.Core.Visuals
{
	internal static class OverlayShaderUtils
	{
		public static Shader? FindUnlitVertexColorShader()
		{
			Shader val = Shader.Find("Sprites/Default");
			if (Object.op_Implicit((Object)(object)val))
			{
				return val;
			}
			val = Shader.Find("Hidden/Internal-Colored");
			if (Object.op_Implicit((Object)(object)val))
			{
				return val;
			}
			val = Shader.Find("UI/Default");
			if (Object.op_Implicit((Object)(object)val))
			{
				return val;
			}
			return null;
		}
	}
}
namespace MasterBuilderHeeler.Core.Visuals.Grid
{
	internal sealed class GridMeshBuilder
	{
		internal readonly struct GridBuildSpec
		{
			public readonly GridFrame Frame;

			public readonly GridSurface Surface;

			public readonly float Step;

			public readonly float Radius;

			public readonly float HeightOffset;

			public readonly Color BaseColor;

			public readonly Vector3 Origin;

			public readonly Quaternion Rotation;

			public readonly int FocusCellX;

			public readonly int FocusCellZ;

			public bool FollowTerrain => Surface == GridSurface.Terrain;

			public GridBuildSpec(GridFrame frame, GridSurface surface, float step, float radius, float heightOffset, Color baseColor, Vector3 origin, Quaternion rotation, int focusCellX, int focusCellZ)
			{
				//IL_0026: Unknown result type (might be due to invalid IL or missing references)
				//IL_0028: Unknown result type (might be due to invalid IL or missing references)
				//IL_002e: 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_0036: 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)
				Frame = frame;
				Surface = surface;
				Step = step;
				Radius = radius;
				HeightOffset = heightOffset;
				BaseColor = baseColor;
				Origin = origin;
				Rotation = rotation;
				FocusCellX = focusCellX;
				FocusCellZ = focusCellZ;
			}
		}

		private readonly struct GridMeshContext
		{
			public readonly GridBuildSpec BuildSpec;

			public readonly int HalfLineCount;

			public readonly int SubdivisionsPerCell;

			public readonly float SampleStep;

			public readonly float CenterLocalX;

			public readonly float CenterLocalZ;

			public readonly float RadiusSquared;

			public readonly float InnerRadius;

			public readonly float InnerRadiusSquared;

			public readonly int MaxHalfSamples;

			public readonly int GridSide;

			public GridMeshContext(in GridBuildSpec buildSpec)
			{
				BuildSpec = buildSpec;
				HalfLineCount = Mathf.Max(1, Mathf.CeilToInt(buildSpec.Radius / buildSpec.Step));
				SubdivisionsPerCell = Mathf.Max(1, Mathf.RoundToInt(buildSpec.Step / 1f));
				SampleStep = buildSpec.Step / (float)SubdivisionsPerCell;
				CenterLocalX = (float)buildSpec.FocusCellX * buildSpec.Step;
				CenterLocalZ = (float)buildSpec.FocusCellZ * buildSpec.Step;
				RadiusSquared = buildSpec.Radius * buildSpec.Radius;
				InnerRadius = buildSpec.Radius * 0.65f;
				InnerRadiusSquared = InnerRadius * InnerRadius;
				if (buildSpec.FollowTerrain)
				{
					MaxHalfSamples = Mathf.Max(HalfLineCount * SubdivisionsPerCell, Mathf.CeilToInt(buildSpec.Radius / SampleStep));
					GridSide = 2 * MaxHalfSamples + 1;
				}
				else
				{
					MaxHalfSamples = 0;
					GridSide = 0;
				}
			}
		}

		private const float InnerFadeFraction = 0.65f;

		private const float MaxTerrainSampleSpacing = 1f;

		private const int MajorLineInterval = 4;

		private const int FlatFadeSegments = 6;

		private const int FlatOuterChordSegments = 8;

		private readonly List<Vector3> _vertices = new List<Vector3>(2048);

		private readonly List<Color32> _colors = new List<Color32>(2048);

		private readonly List<int> _indices = new List<int>(4096);

		private Heightmap? _cachedHeightmap;

		private float[] _sampleHeights = Array.Empty<float>();

		private int[] _sampleStamps = Array.Empty<int>();

		private int _currentSampleStamp;

		public bool HasGeometry => _indices.Count > 0;

		public void RebuildPlaneMesh(Mesh mesh, in GridBuildSpec buildSpec)
		{
			_vertices.Clear();
			_colors.Clear();
			_indices.Clear();
			EmitPlaneLines(in buildSpec);
			_cachedHeightmap = null;
			mesh.Clear();
			if (_vertices.Count > 0)
			{
				mesh.SetVertices(_vertices);
				mesh.SetColors(_colors);
				mesh.SetIndices(_indices, (MeshTopology)3, 0, true, 0);
				mesh.RecalculateBounds();
			}
		}

		private static Color ResolveLineHierarchyColor(Color baseColor, bool isOriginAxis, bool isMajorLine)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0004: 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_0016: 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_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: 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_0031: 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_003c: 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_0044: 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)
			if (isOriginAxis)
			{
				Color result = Color.Lerp(baseColor, Color.white, 0.35f);
				result.a = Mathf.Clamp01(baseColor.a * 1.15f);
				return result;
			}
			if (isMajorLine)
			{
				Color result2 = Color.Lerp(baseColor, Color.white, 0.18f);
				result2.a = baseColor.a;
				return result2;
			}
			Color result3 = baseColor;
			result3.a = baseColor.a * 0.55f;
			return result3;
		}

		private static Color32 ApplyRadialFade(in GridMeshContext context, Color lineColor, float offsetA, float offsetB)
		{
			//IL_0011: 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_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			float num = offsetA * offsetA + offsetB * offsetB;
			if (num <= context.InnerRadiusSquared)
			{
				return Color32.op_Implicit(lineColor);
			}
			if (num >= context.RadiusSquared)
			{
				lineColor.a = 0f;
				return Color32.op_Implicit(lineColor);
			}
			float num2 = Mathf.Sqrt(num);
			float num3 = (context.BuildSpec.Radius - num2) / (context.BuildSpec.Radius - context.InnerRadius);
			float num4 = num3 * num3 * (3f - 2f * num3);
			lineColor.a *= num4;
			return Color32.op_Implicit(lineColor);
		}

		private void EmitPlaneLines(in GridBuildSpec buildSpec)
		{
			GridMeshContext context = new GridMeshContext(in buildSpec);
			if (buildSpec.FollowTerrain)
			{
				PrepareTerrainSampleCache(context.GridSide * context.GridSide);
			}
			for (int i = -context.HalfLineCount; i <= context.HalfLineCount; i++)
			{
				float num = (float)i * buildSpec.Step;
				float num2 = num * num;
				if (!(num2 >= context.RadiusSquared))
				{
					EmitGridLine(in context, alongZ: true, i, num, num2);
					EmitGridLine(in context, alongZ: false, i, num, num2);
				}
			}
		}

		private void EmitGridLine(in GridMeshContext context, bool alongZ, int lineOffset, float deltaPerpendicular, float perpendicularSquared)
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: 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_0204: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d2: 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_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//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_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			ref readonly GridBuildSpec buildSpec = ref context.BuildSpec;
			int num = (alongZ ? buildSpec.FocusCellX : buildSpec.FocusCellZ) + lineOffset;
			float num2 = (alongZ ? context.CenterLocalX : context.CenterLocalZ) + deltaPerpendicular;
			float num3 = (alongZ ? context.CenterLocalZ : context.CenterLocalX);
			Color lineColor = ResolveLineHierarchyColor(buildSpec.BaseColor, num == 0, num % 4 == 0);
			int count = _vertices.Count;
			if (buildSpec.FollowTerrain)
			{
				int num4 = Mathf.Min(context.MaxHalfSamples, Mathf.Max(1, Mathf.CeilToInt(Mathf.Sqrt(context.RadiusSquared - perpendicularSquared) / context.SampleStep)));
				int num5 = lineOffset * context.SubdivisionsPerCell;
				for (int i = -num4; i <= num4; i++)
				{
					float num6 = (float)i * context.SampleStep;
					float num7 = num3 + num6;
					float num8 = (alongZ ? num2 : num7);
					float num9 = (alongZ ? num7 : num2);
					Vector3 val = buildSpec.Origin + buildSpec.Rotation * new Vector3(num8, 0f, num9);
					int num10 = (alongZ ? num5 : i) + context.MaxHalfSamples;
					int num11 = (alongZ ? i : num5) + context.MaxHalfSamples;
					val.y = GetOrSampleTerrainY(num10 * context.GridSide + num11, val.x, val.z, buildSpec.Origin.y, buildSpec.HeightOffset);
					_vertices.Add(val);
					_colors.Add(ApplyRadialFade(in context, lineColor, deltaPerpendicular, num6));
				}
				AppendPolylineIndices(count, 2 * num4);
			}
			else
			{
				float num12 = Mathf.Sqrt(context.RadiusSquared - perpendicularSquared);
				if (perpendicularSquared < context.InnerRadiusSquared)
				{
					float num13 = Mathf.Sqrt(context.InnerRadiusSquared - perpendicularSquared);
					AppendSegment(in context, alongZ, num2, num3, deltaPerpendicular, 0f - num12, 0f - num13, 6, lineColor);
					AppendSegment(in context, alongZ, num2, num3, deltaPerpendicular, num13, num12, 6, lineColor);
					AppendPolylineIndices(count, 13);
				}
				else
				{
					AppendSegment(in context, alongZ, num2, num3, deltaPerpendicular, 0f - num12, num12, 8, lineColor);
					AppendPolylineIndices(count, 8);
				}
			}
		}

		private void AppendSegment(in GridMeshContext context, bool alongZ, float localPerpendicular, float centerParallel, float deltaPerpendicular, float startDelta, float endDelta, int segmentCount, Color lineColor)
		{
			//IL_003e: 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_0054: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i <= segmentCount; i++)
			{
				float num = Mathf.Lerp(startDelta, endDelta, (float)i / (float)segmentCount);
				float num2 = centerParallel + num;
				float num3 = (alongZ ? localPerpendicular : num2);
				float num4 = (alongZ ? num2 : localPerpendicular);
				_vertices.Add(new Vector3(num3, context.BuildSpec.HeightOffset, num4));
				_colors.Add(ApplyRadialFade(in context, lineColor, deltaPerpendicular, num));
			}
		}

		private void PrepareTerrainSampleCache(int requiredCount)
		{
			if (_sampleHeights.Length < requiredCount)
			{
				_sampleHeights = new float[requiredCount];
				_sampleStamps = new int[requiredCount];
			}
			if (_currentSampleStamp == int.MaxValue)
			{
				Array.Clear(_sampleStamps, 0, _sampleStamps.Length);
				_currentSampleStamp = 0;
			}
			_currentSampleStamp++;
		}

		private float GetOrSampleTerrainY(int cacheIndex, float worldX, float worldZ, float fallbackHeight, float heightOffset)
		{
			if (_sampleStamps[cacheIndex] == _currentSampleStamp)
			{
				return _sampleHeights[cacheIndex];
			}
			float num = SampleGroundHeight(worldX, worldZ, fallbackHeight) + heightOffset;
			_sampleStamps[cacheIndex] = _currentSampleStamp;
			_sampleHeights[cacheIndex] = num;
			return num;
		}

		private float SampleGroundHeight(float worldX, float worldZ, float fallbackHeight)
		{
			//IL_000b: 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)
			Vector3 val = default(Vector3);
			((Vector3)(ref val))..ctor(worldX, fallbackHeight, worldZ);
			if (TrySampleHeightmapBilinear(val, out var groundHeight))
			{
				return groundHeight;
			}
			ZoneSystem instance = ZoneSystem.instance;
			float result = default(float);
			if (Object.op_Implicit((Object)(object)instance) && instance.GetGroundHeight(val, ref result))
			{
				return result;
			}
			return fallbackHeight;
		}

		private bool TrySampleHeightmapBilinear(Vector3 worldPosition, out float groundHeight)
		{
			//IL_001d: 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_006c: 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)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			Heightmap val = _cachedHeightmap;
			if (!Object.op_Implicit((Object)(object)val) || !val.IsPointInside(worldPosition, 0f))
			{
				val = (_cachedHeightmap = Heightmap.FindHeightmap(worldPosition));
			}
			if (!Object.op_Implicit((Object)(object)val))
			{
				groundHeight = 0f;
				return false;
			}
			int width = val.m_width;
			int num = width + 1;
			List<float> heights = val.m_heights;
			if (width <= 0 || heights.Count < num * num)
			{
				groundHeight = 0f;
				return false;
			}
			Vector3 position = ((Component)val).transform.position;
			float scale = val.m_scale;
			float num2 = (float)width * scale * 0.5f;
			float num3 = Mathf.Clamp((worldPosition.x - position.x + num2) / scale, 0f, (float)width);
			float num4 = Mathf.Clamp((worldPosition.z - position.z + num2) / scale, 0f, (float)width);
			int num5 = Mathf.Min(Mathf.FloorToInt(num3), width - 1);
			int num6 = Mathf.Min(Mathf.FloorToInt(num4), width - 1);
			float num7 = num3 - (float)num5;
			float num8 = num4 - (float)num6;
			int num9 = num6 * num;
			int num10 = num9 + num;
			float num11 = heights[num9 + num5];
			float num12 = heights[num9 + num5 + 1];
			float num13 = heights[num10 + num5];
			float num14 = heights[num10 + num5 + 1];
			float num15 = num11 + (num12 - num11) * num7;
			float num16 = num13 + (num14 - num13) * num7;
			groundHeight = position.y + num15 + (num16 - num15) * num8;
			return true;
		}

		private void AppendPolylineIndices(int startVertexIndex, int segmentCount)
		{
			for (int i = 0; i < segmentCount; i++)
			{
				int num = startVertexIndex + i;
				_indices.Add(num);
				_indices.Add(num + 1);
			}
		}
	}
	public sealed class GridOverlayRenderer : MonoBehaviour
	{
		private const float TerrainRefreshInterval = 0.5f;

		private static GridOverlayRenderer? _instance;

		private readonly GridMeshBuilder _meshBuilder = new GridMeshBuilder();

		private Mesh? _gridMesh;

		private Material? _material;

		private GridMeshBuilder.GridBuildSpec _builtSpec;

		private float _nextTerrainRefreshTime;

		private bool _hasValidMesh;

		private void Awake()
		{
			_instance = this;
		}

		private void LateUpdate()
		{
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: 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_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: 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_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: 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_00e5: 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_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: 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_017d: 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_0191: Unknown result type (might be due to invalid IL or missing references)
			if (!ModConfig.EnableMod.Value || !BuildStateManager.IsGridOverlayVisible)
			{
				_hasValidMesh = false;
				return;
			}
			Player localPlayer = Player.m_localPlayer;
			if (!Object.op_Implicit((Object)(object)localPlayer))
			{
				_hasValidMesh = false;
				return;
			}
			if (!((Character)localPlayer).InPlaceMode() && !BuildStateManager.HasActiveSpecialMode)
			{
				_hasValidMesh = false;
				return;
			}
			GridFrame activeGridFrame = BuildStateManager.ActiveGridFrame;
			GridSurface activeGridSurface = BuildStateManager.ActiveGridSurface;
			float gridCellSize = BuildStateManager.GridCellSize;
			float radius = Mathf.Clamp(ModConfig.GridOverlayRadius.Value, 4f, 64f);
			float heightOffset = ResolveHeightOffset(activeGridFrame, activeGridSurface);
			Color baseColor = ((activeGridFrame == GridFrame.Local) ? ModConfig.LocalGridColor.Value : ModConfig.WorldGridColor.Value);
			Vector3 val = (Vector3)((activeGridFrame == GridFrame.Local) ? BuildStateManager.LocalGridOrigin : new Vector3(0f, ((Component)localPlayer).transform.position.y, 0f));
			Quaternion val2 = ((activeGridFrame == GridFrame.Local) ? BuildStateManager.LocalGridRotation : Quaternion.identity);
			Vector3 val3 = ResolveFocusPosition(localPlayer);
			Vector3 val4 = Quaternion.Inverse(val2) * (val3 - val);
			int focusCellX = Mathf.RoundToInt(val4.x / gridCellSize);
			int focusCellZ = Mathf.RoundToInt(val4.z / gridCellSize);
			GridMeshBuilder.GridBuildSpec buildSpec = new GridMeshBuilder.GridBuildSpec(activeGridFrame, activeGridSurface, gridCellSize, radius, heightOffset, baseColor, val, val2, focusCellX, focusCellZ);
			if (NeedsRebuild(in buildSpec))
			{
				RebuildMesh(in buildSpec);
			}
			if (Object.op_Implicit((Object)(object)_gridMesh) && _meshBuilder.HasGeometry)
			{
				Material orCreateMaterial = GetOrCreateMaterial();
				if (Object.op_Implicit((Object)(object)orCreateMaterial))
				{
					Matrix4x4 val5 = (buildSpec.FollowTerrain ? Matrix4x4.identity : Matrix4x4.TRS(val, val2, Vector3.one));
					Graphics.DrawMesh(_gridMesh, val5, orCreateMaterial, 0);
				}
			}
		}

		private void OnDestroy()
		{
			ReleaseResources();
			if (_instance == this)
			{
				_instance = null;
			}
		}

		public static void EnsureRenderer(Player player)
		{
			GridOverlayRenderer gridOverlayRenderer = default(GridOverlayRenderer);
			if (!((Component)player).TryGetComponent<GridOverlayRenderer>(ref gridOverlayRenderer))
			{
				((Component)player).gameObject.AddComponent<GridOverlayRenderer>();
			}
		}

		public static void Cleanup()
		{
			if (Object.op_Implicit((Object)(object)_instance))
			{
				_instance.ReleaseResources();
				Object.Destroy((Object)(object)_instance);
				_instance = null;
			}
		}

		private static Vector3 ResolveFocusPosition(Player player)
		{
			//IL_0027: 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)
			if (BuildStateManager.IsBuildCameraActive)
			{
				Camera activeCamera = CameraUtils.GetActiveCamera();
				if (Object.op_Implicit((Object)(object)activeCamera))
				{
					return ((Component)activeCamera).transform.position;
				}
			}
			return ((Component)player).transform.position;
		}

		private static float ResolveHeightOffset(GridFrame frame, GridSurface surface)
		{
			if (surface == GridSurface.Terrain)
			{
				return ModConfig.TerrainGridHeight.Value;
			}
			if (frame != GridFrame.Local)
			{
				return ModConfig.WorldFlatGridHeight.Value;
			}
			return ModConfig.LocalFlatGridHeight.Value;
		}

		private bool NeedsRebuild(in GridMeshBuilder.GridBuildSpec buildSpec)
		{
			//IL_0090: 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_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: 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_0113: Unknown result type (might be due to invalid IL or missing references)
			if (!_hasValidMesh || !Object.op_Implicit((Object)(object)_gridMesh) || buildSpec.Frame != _builtSpec.Frame || buildSpec.Surface != _builtSpec.Surface || !Mathf.Approximately(buildSpec.Step, _builtSpec.Step) || !Mathf.Approximately(buildSpec.Radius, _builtSpec.Radius) || !Mathf.Approximately(buildSpec.HeightOffset, _builtSpec.HeightOffset) || buildSpec.BaseColor != _builtSpec.BaseColor || buildSpec.FocusCellX != _builtSpec.FocusCellX || buildSpec.FocusCellZ != _builtSpec.FocusCellZ)
			{
				return true;
			}
			if (!buildSpec.FollowTerrain)
			{
				return false;
			}
			if (buildSpec.Frame == GridFrame.Local)
			{
				Vector3 val = buildSpec.Origin - _builtSpec.Origin;
				if (((Vector3)(ref val)).sqrMagnitude > 0.0001f || Quaternion.Angle(buildSpec.Rotation, _builtSpec.Rotation) > 0.01f)
				{
					return true;
				}
			}
			if (BuildStateManager.IsTerrainOpGhostActive)
			{
				return Time.time >= _nextTerrainRefreshTime;
			}
			return false;
		}

		private void RebuildMesh(in GridMeshBuilder.GridBuildSpec buildSpec)
		{
			//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_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_0032: Expected O, but got Unknown
			if (!Object.op_Implicit((Object)(object)_gridMesh))
			{
				_gridMesh = new Mesh
				{
					name = "MBH_GridOverlayMesh",
					indexFormat = (IndexFormat)1,
					hideFlags = (HideFlags)61
				};
				_gridMesh.MarkDynamic();
			}
			_meshBuilder.RebuildPlaneMesh(_gridMesh, in buildSpec);
			if (buildSpec.FollowTerrain)
			{
				_nextTerrainRefreshTime = Time.time + 0.5f;
			}
			_builtSpec = buildSpec;
			_hasValidMesh = true;
		}

		private Material? GetOrCreateMaterial()
		{
			//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_0025: 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_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Expected O, but got Unknown
			if (!Object.op_Implicit((Object)(object)_material))
			{
				Shader val = OverlayShaderUtils.FindUnlitVertexColorShader();
				if (!Object.op_Implicit((Object)(object)val))
				{
					return null;
				}
				_material = new Material(val)
				{
					color = Color.white,
					renderQueue = 3100,
					hideFlags = (HideFlags)61
				};
			}
			return _material;
		}

		private void ReleaseResources()
		{
			if (Object.op_Implicit((Object)(object)_gridMesh))
			{
				Object.Destroy((Object)(object)_gridMesh);
				_gridMesh = null;
			}
			if (Object.op_Implicit((Object)(object)_material))
			{
				Object.Destroy((Object)(object)_material);
				_material = null;
			}
			_hasValidMesh = false;
		}
	}
}
namespace MasterBuilderHeeler.Core.Visuals.Gizmo
{
	public sealed class GizmoController : MonoBehaviour
	{
		private const float DefaultRadius = 1.8f;

		private const float MinRadius = 1.325f;

		private const float MaxRadius = 6f;

		private const float RadiusPaddingFactor = 1.425f;

		private const int MaxRadiusRetries = 10;

		private static readonly List<Collider> ColliderBuffer = new List<Collider>(16);

		private IGizmoRenderer? _activeTheme;

		private int _trackedTargetInstanceId;

		private float _calculatedRadius = 1.8f;

		private int _radiusRetryCount;

		private bool _radiusCalculated;

		private bool _wasVisible;

		private void Awake()
		{
			GizmoRendering.RegisterController(this);
			SetStyle(ModConfig.GizmoRendererStyle.Value);
			((Behaviour)this).enabled = BuildStateManager.IsPrecisionModeActive;
		}

		private void OnDisable()
		{
			HideIfVisible();
		}

		private void LateUpdate()
		{
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: 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_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: 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_00ab: 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_00bf: 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)
			GameObject activeTargetObject = BuildStateManager.GetActiveTargetObject(Player.m_localPlayer);
			if (_activeTheme == null || !ModConfig.EnableMod.Value || !BuildStateManager.IsPrecisionModeActive || !Object.op_Implicit((Object)(object)activeTargetObject) || !activeTargetObject.activeInHierarchy || BuildStateManager.IsTerrainOpGhostActive)
			{
				HideIfVisible();
				if (!Object.op_Implicit((Object)(object)activeTargetObject))
				{
					_trackedTargetInstanceId = 0;
				}
				return;
			}
			UpdateTargetBounds(activeTargetObject);
			Transform transform = activeTargetObject.transform;
			Quaternion rotation = transform.rotation;
			Quaternion ringBasis = BuildFrameBasis.ResolveGizmoBasis(rotation);
			BuildFrameBasis.ResolveTranslationAxes(rotation, out var rightAxis, out var upAxis, out var forwardAxis);
			GizmoDrawContext context = new GizmoDrawContext(transform.position, _calculatedRadius, ringBasis, BuildStateManager.ActiveAxis, rightAxis, upAxis, forwardAxis, ThemeColorConfig.GizmoPitchRingColor.Value, ThemeColorConfig.GizmoYawRingColor.Value, ThemeColorConfig.GizmoRollRingColor.Value, ThemeColorConfig.GizmoRightArrowColor.Value, ThemeColorConfig.GizmoUpArrowColor.Value, ThemeColorConfig.GizmoForwardArrowColor.Value);
			_activeTheme.Scale = ModConfig.GizmoScale.Value;
			_activeTheme.Render(in context);
			_wasVisible = true;
		}

		private void OnDestroy()
		{
			DisposeActiveTheme();
			GizmoRendering.UnregisterController(this);
		}

		public void SetStyle(GizmoStyle style)
		{
			if (_activeTheme == null || _activeTheme.Style != style)
			{
				DisposeActiveTheme();
				_activeTheme = GizmoRendering.CreateTheme(style);
				_wasVisible = false;
			}
		}

		private void HideIfVisible()
		{
			if (_wasVisible)
			{
				if (_activeTheme != null)
				{
					_activeTheme.OnHide();
				}
				_wasVisible = false;
			}
		}

		private void DisposeActiveTheme()
		{
			if (_activeTheme != null)
			{
				if (_wasVisible)
				{
					_activeTheme.OnHide();
					_wasVisible = false;
				}
				_activeTheme.Dispose();
				_activeTheme = null;
			}
		}

		private void UpdateTargetBounds(GameObject targetObject)
		{
			int instanceID = ((Object)targetObject).GetInstanceID();
			if (instanceID != _trackedTargetInstanceId)
			{
				_trackedTargetInstanceId = instanceID;
				_calculatedRadius = 1.8f;
				_radiusRetryCount = 0;
				_radiusCalculated = false;
			}
			if (!_radiusCalculated)
			{
				CalculateRadius(targetObject);
			}
		}

		private void CalculateRadius(GameObject targetObject)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: 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_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			targetObject.GetComponentsInChildren<Collider>(ColliderBuffer);
			int count = ColliderBuffer.Count;
			int num = 0;
			Bounds val = default(Bounds);
			for (int i = 0; i < count; i++)
			{
				Collider val2 = ColliderBuffer[i];
				if (Object.op_Implicit((Object)(object)val2) && val2.enabled && !val2.isTrigger)
				{
					if (num == 0)
					{
						val = val2.bounds;
					}
					else
					{
						((Bounds)(ref val)).Encapsulate(val2.bounds);
					}
					num++;
				}
			}
			ColliderBuffer.Clear();
			if (num == 0)
			{
				_calculatedRadius = 1.8f;
				_radiusCalculated = true;
				return;
			}
			Vector3 size = ((Bounds)(ref val)).size;
			if (((Vector3)(ref size)).sqrMagnitude < 0.0001f)
			{
				_calculatedRadius = 1.8f;
				_radiusRetryCount++;
				if (_radiusRetryCount >= 10)
				{
					_radiusCalculated = true;
					if (ModConfig.IsDebugLogging)
					{
						Plugin.LogDebug($"[GizmoController] Target '{((Object)targetObject).name}' collider bounds remained zero after {10} frames. Locking default radius ({1.8f:F2}m).");
					}
				}
				else if (_radiusRetryCount == 1 && ModConfig.IsDebugLogging)
				{
					Plugin.LogDebug("[GizmoController] Target '" + ((Object)targetObject).name + "' collider bounds uninitialized on frame 0. Deferring radius calculation.");
				}
			}
			else
			{
				float num2 = Mathf.Max(((Bounds)(ref val)).extents.x, ((Bounds)(ref val)).extents.z);
				_calculatedRadius = Mathf.Clamp(num2 * 1.425f, 1.325f, 6f);
				_radiusCalculated = true;
				if (ModConfig.IsDebugLogging)
				{
					Plugin.LogDebug($"[GizmoController] Resolved bounds for '{((Object)targetObject).name}': extent={num2:F2}m across {num} solid colliders -> radius={_calculatedRadius:F2}m.");
				}
			}
		}
	}
	public readonly struct GizmoDrawContext
	{
		public readonly Vector3 Center;

		public readonly float Radius;

		public readonly Quaternion RingBasis;

		public readonly RotationAxis ActiveAxes;

		public readonly Vector3 RightAxis;

		public readonly Vector3 UpAxis;

		public readonly Vector3 ForwardAxis;

		public readonly Color PitchRingColor;

		public readonly Color YawRingColor;

		public readonly Color RollRingColor;

		public readonly Color RightArrowColor;

		public readonly Color UpArrowColor;

		public readonly Color ForwardArrowColor;

		public GizmoDrawContext(Vector3 center, float radius, Quaternion ringBasis, RotationAxis activeAxes, Vector3 rightAxis, Vector3 upAxis, Vector3 forwardAxis, Color pitchRingColor, Color yawRingColor, Color rollRingColor, Color rightArrowColor, Color upArrowColor, Color forwardArrowColor)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: 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_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: 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_0036: 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: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: 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_0060: Unknown result type (might be due to invalid IL or missing references)
			Center = center;
			Radius = radius;
			RingBasis = ringBasis;
			ActiveAxes = activeAxes;
			RightAxis = rightAxis;
			UpAxis = upAxis;
			ForwardAxis = forwardAxis;
			PitchRingColor = pitchRingColor;
			YawRingColor = yawRingColor;
			RollRingColor = rollRingColor;
			RightArrowColor = rightArrowColor;
			UpArrowColor = upArrowColor;
			ForwardArrowColor = forwardArrowColor;
		}
	}
	public static class GizmoRendering
	{
		private static GizmoController? _controller;

		public static void Initialize()
		{
			Cleanup();
			ModConfig.GizmoRendererStyle.SettingChanged += OnRendererSettingChanged;
			ModConfig.EnablePrecision.SettingChanged += OnRendererSettingChanged;
			BuildStateManager.PrecisionModeChanged += OnPrecisionModeChanged;
		}

		public static void Cleanup()
		{
			ModConfig.GizmoRendererStyle.SettingChanged -= OnRendererSettingChanged;
			ModConfig.EnablePrecision.SettingChanged -= OnRendererSettingChanged;
			BuildStateManager.PrecisionModeChanged -= OnPrecisionModeChanged;
			DestroyController();
		}

		public static void EnsureController(Player player)
		{
			if (ModConfig.GizmoRendererStyle.Value != GizmoStyle.Disabled && ModConfig.EnablePrecision.Value)
			{
				GizmoController gizmoController = default(GizmoController);
				if (!((Component)player).TryGetComponent<GizmoController>(ref gizmoController))
				{
					gizmoController = ((Component)player).gameObject.AddComponent<GizmoController>();
				}
				((Behaviour)gizmoController).enabled = BuildStateManager.IsPrecisionModeActive;
			}
		}

		public static IGizmoRenderer? CreateTheme(GizmoStyle style)
		{
			if (style == GizmoStyle.ProceduralWireframe)
			{
				return new WireframeGizmoRenderer();
			}
			return null;
		}

		internal static void RegisterController(GizmoController controller)
		{
			_controller = controller;
		}

		internal static void UnregisterController(GizmoController controller)
		{
			if ((Object)(object)_controller == (Object)(object)controller)
			{
				_controller = null;
			}
		}

		private static void DestroyController()
		{
			if (Object.op_Implicit((Object)(object)_controller))
			{
				Object.Destroy((Object)(object)_controller);
				_controller = null;
			}
		}

		private static void OnRendererSettingChanged(object sender, EventArgs eventArgs)
		{
			GizmoStyle value = ModConfig.GizmoRendererStyle.Value;
			if (value == GizmoStyle.Disabled || !ModConfig.EnablePrecision.Value)
			{
				DestroyController();
				return;
			}
			if (Object.op_Implicit((Object)(object)_controller))
			{
				_controller.SetStyle(value);
				((Behaviour)_controller).enabled = BuildStateManager.IsPrecisionModeActive;
				return;
			}
			Player localPlayer = Player.m_localPlayer;
			if (Object.op_Implicit((Object)(object)localPlayer))
			{
				EnsureController(localPlayer);
			}
		}

		private static void OnPrecisionModeChanged(bool active)
		{
			if (Object.op_Implicit((Object)(object)_controller))
			{
				((Behaviour)_controller).enabled = active;
			}
		}
	}
	public interface IGizmoRenderer : IDisposable
	{
		GizmoStyle Style { get; }

		float Scale { get; set; }

		void Render(in GizmoDrawContext context);

		void OnHide();
	}
}
namespace MasterBuilderHeeler.Core.Visuals.Gizmo.Themes.Wireframe
{
	internal static class WireframeGizmoMeshBuilder
	{
		private const float UnitRadius = 1f;

		private const int ArcSegments = 72;

		private const int KnobAngleDegrees = 45;

		private const int TickIntervalDegrees = 45;

		private const float KnobArcHalfLength = 0.065f;

		private const float KnobHalfWidth = 0.05525f;

		private const float TickHalfLength = 0.061f;

		private const float ArrowShaftLength = 0.9f;

		private const float ArrowTipLength = 1f;

		private const float ArrowHeadHalfWidth = 0.05f;

		public static Mesh CreateUnitRingMesh(Vector3 normalAxis)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: 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_0024: Expected O, but got Unknown
			//IL_0024: 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_007e: 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_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: 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_0111: 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_011a: 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)
			//IL_0131: 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_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01eb: 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_01f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0209: Unknown result type (might be due to invalid IL or missing references)
			//IL_020a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0212: Unknown result type (might be due to invalid IL or missing references)
			Mesh val = new Mesh
			{
				name = $"MBH_WireframeRing_{normalAxis}",
				hideFlags = (HideFlags)61
			};
			ResolveRingBasis(normalAxis, out var axisU, out var axisV);
			float num = 0.065f;
			float num2 = (float)Math.PI / 4f;
			float num3 = num2 + num;
			float num4 = (float)Math.PI * 2f - 2f * num;
			List<Vector3> list = new List<Vector3>(91);
			List<int> list2 = new List<int>(182);
			for (int i = 0; i <= 72; i++)
			{
				float angleRadians = num3 + num4 * (float)i / 72f;
				list.Add(PointOnRing(axisU, axisV, angleRadians, 1f));
				if (i < 72)
				{
					AppendLine(list2, i, i + 1);
				}
			}
			int startIndex = 0;
			int startIndex2 = 72;
			Vector3 val2 = PointOnRing(axisU, axisV, num2, 1f);
			int count = list.Count;
			list.Add(PointOnRing(axisU, axisV, num2, 1.05525f));
			int count2 = list.Count;
			list.Add(val2 + normalAxis * 0.05525f);
			int count3 = list.Count;
			list.Add(PointOnRing(axisU, axisV, num2, 0.94475f));
			int count4 = list.Count;
			list.Add(val2 - normalAxis * 0.05525f);
			AppendLine(list2, startIndex, count);
			AppendLine(list2, startIndex, count2);
			AppendLine(list2, startIndex, count3);
			AppendLine(list2, startIndex, count4);
			AppendLine(list2, startIndex2, count);
			AppendLine(list2, startIndex2, count2);
			AppendLine(list2, startIndex2, count3);
			AppendLine(list2, startIndex2, count4);
			AppendLine(list2, count, count2);
			AppendLine(list2, count2, count3);
			AppendLine(list2, count3, count4);
			AppendLine(list2, count4, count);
			for (int j = 0; j < 360; j += 45)
			{
				if (j != 45)
				{
					float angleRadians2 = (float)j * ((float)Math.PI / 180f);
					int count5 = list.Count;
					list.Add(PointOnRing(axisU, axisV, angleRadians2, 0.939f));
					int count6 = list.Count;
					list.Add(PointOnRing(axisU, axisV, angleRadians2, 1.061f));
					AppendLine(list2, count5, count6);
				}
			}
			val.SetVertices(list);
			val.SetIndices(list2, (MeshTopology)3, 0, true, 0);
			val.RecalculateBounds();
			return val;
		}

		public static Mesh CreateUnitArrowMesh()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Expected O, but got Unknown
			//IL_0019: 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)
			//IL_0028: 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_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: 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_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: 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_0068: 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_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: 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_008e: 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_0096: 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_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_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: 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_00c6: Unknown result type (might be due to invalid IL or missing references)
			Mesh val = new Mesh
			{
				name = "MBH_WireframeArrow",
				hideFlags = (HideFlags)61
			};
			Vector3 val2 = Vector3.forward * 0.9f;
			Vector3 val3 = Vector3.forward * 1f;
			Vector3[] vertices = (Vector3[])(object)new Vector3[7]
			{
				Vector3.zero,
				val2,
				val3,
				val2 + Vector3.left * 0.05f,
				val2 + Vector3.right * 0.05f,
				val2 + Vector3.up * 0.05f,
				val2 + Vector3.down * 0.05f
			};
			int[] array = new int[18]
			{
				0, 1, 2, 3, 2, 4, 2, 5, 2, 6,
				3, 5, 5, 4, 4, 6, 6, 3
			};
			val.vertices = vertices;
			val.SetIndices(array, (MeshTopology)3, 0);
			val.RecalculateBounds();
			return val;
		}

		private static void ResolveRingBasis(Vector3 normalAxis, out Vector3 axisU, out Vector3 axisV)
		{
			//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_0024: 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_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_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_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)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			if (normalAxis == Vector3.right)
			{
				axisU = Vector3.up;
				axisV = Vector3.forward;
			}
			else if (normalAxis == Vector3.up)
			{
				axisU = Vector3.right;
				axisV = Vector3.forward;
			}
			else
			{
				axisU = Vector3.right;
				axisV = Vector3.up;
			}
		}

		private static Vector3 PointOnRing(Vector3 axisU, Vector3 axisV, float angleRadians, float ringRadius)
		{
			//IL_0000: 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)
			//IL_000e: 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_001c: Unknown result type (might be due to invalid IL or missing references)
			return axisU * (Mathf.Cos(angleRadians) * ringRadius) + axisV * (Mathf.Sin(angleRadians) * ringRadius);
		}

		private static void AppendLine(List<int> indices, int startIndex, int endIndex)
		{
			indices.Add(startIndex);
			indices.Add(endIndex);
		}
	}
	public sealed class WireframeGizmoRenderer : IGizmoRenderer, IDisposable
	{
		private const float ActiveRingAlpha = 0.95f;

		private const float InactiveRingAlpha = 0.45f;

		private const float ActiveRingScaleMultiplier = 1.12f;

		private const float ArrowLengthScale = 1.35f;

		private static readonly int ColorPropertyId = Shader.PropertyToID("_Color");

		private readonly MaterialPropertyBlock _propertyBlock = new MaterialPropertyBlock();

		private Mesh? _xRingMesh;

		private Mesh? _yRingMesh;

		private Mesh? _zRingMesh;

		private Mesh? _arrowMesh;

		private Material? _material;

		public GizmoStyle Style => GizmoStyle.ProceduralWireframe;

		public float Scale { get; set; } = 1f;

		public void Render(in GizmoDrawContext context)
		{
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: 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_00e9: 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_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			EnsureResources();
			if (Object.op_Implicit((Object)(object)_material) && Object.op_Implicit((Object)(object)_xRingMesh) && Object.op_Implicit((Object)(object)_yRingMesh) && Object.op_Implicit((Object)(object)_zRingMesh) && Object.op_Implicit((Object)(object)_arrowMesh))
			{
				DrawAxisRing(in context, _xRingMesh, _material, RotationAxis.Pitch, context.PitchRingColor);
				DrawAxisRing(in context, _yRingMesh, _material, RotationAxis.Yaw, context.YawRingColor);
				DrawAxisRing(in context, _zRingMesh, _material, RotationAxis.Roll, context.RollRingColor);
				float scale = context.Radius * Scale * 1.35f;
				DrawArrow(_arrowMesh, _material, context.Center, context.RightAxis, context.RightArrowColor, scale);
				DrawArrow(_arrowMesh, _material, context.Center, context.UpAxis, context.UpArrowColor, scale);
				DrawArrow(_arrowMesh, _material, context.Center, context.ForwardAxis, context.ForwardArrowColor, scale);
			}
		}

		public void OnHide()
		{
		}

		public void Dispose()
		{
			DestroyUnityObject<Material>(ref _material);
			DestroyUnityObject<Mesh>(ref _xRingMesh);
			DestroyUnityObject<Mesh>(ref _yRingMesh);
			DestroyUnityObject<Mesh>(ref _zRingMesh);
			DestroyUnityObject<Mesh>(ref _arrowMesh);
		}

		private static void DestroyUnityObject<T>(ref T? unityObject) where T : Object
		{
			if (Object.op_Implicit((Object)(object)unityObject))
			{
				Object.Destroy((Object)(object)unityObject);
				unityObject = default(T);
			}
		}

		private void EnsureResources()
		{
			//IL_000e: 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_0048: 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_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Expected O, but got Unknown
			if (!Object.op_Implicit((Object)(object)_xRingMesh))
			{
				_xRingMesh = WireframeGizmoMeshBuilder.CreateUnitRingMesh(Vector3.right);
			}
			if (!Object.op_Implicit((Object)(object)_yRingMesh))
			{
				_yRingMesh = WireframeGizmoMeshBuilder.CreateUnitRingMesh(Vector3.up);
			}
			if (!Object.op_Implicit((Object)(object)_zRingMesh))
			{
				_zRingMesh = WireframeGizmoMeshBuilder.CreateUnitRingMesh(Vector3.forward);
			}
			if (!Object.op_Implicit((Object)(object)_arrowMesh))
			{
				_arrowMesh = WireframeGizmoMeshBuilder.CreateUnitArrowMesh();
			}
			if (!Object.op_Implicit((Object)(object)_material))
			{
				Shader val = OverlayShaderUtils.FindUnlitVertexColorShader();
				if (Object.op_Implicit((Object)(object)val))
				{
					_material = new Material(val)
					{
						renderQueue = 3101,
						hideFlags = (HideFlags)61
					};
				}
			}
		}

		private void DrawAxisRing(in GizmoDrawContext context, Mesh ringMesh, Material material, RotationAxis ringAxis, Color baseColor)
		{
			//IL_000d: 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_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: 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_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			bool flag = (context.ActiveAxes & ringAxis) != 0;
			Color val = baseColor;
			val.a *= (flag ? 0.95f : 0.45f);
			float num = context.Radius * Scale * (flag ? 1.12f : 1f);
			_propertyBlock.SetColor(ColorPropertyId, val);
			Matrix4x4 val2 = Matrix4x4.TRS(context.Center, context.RingBasis, Vector3.one * num);
			Graphics.DrawMesh(ringMesh, val2, material, 0, (Camera)null, 0, _propertyBlock);
		}

		private void DrawArrow(Mesh arrowMesh, Material material, Vector3 origin, Vector3 direction, Color color, float scale)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: 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_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: 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_0035: 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_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: 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)
			_propertyBlock.SetColor(ColorPropertyId, color);
			Quaternion val = ((((Vector3)(ref direction)).sqrMagnitude > 0.0001f) ? Quaternion.FromToRotation(Vector3.forward, direction) : Quaternion.identity);
			Matrix4x4 val2 = Matrix4x4.TRS(origin, val, Vector3.one * scale);
			Graphics.DrawMesh(arrowMesh, val2, material, 0, (Camera)null, 0, _propertyBlock);
		}

		void IGizmoRenderer.Render(in GizmoDrawContext context)
		{
			Render(in context);
		}
	}
}
namespace MasterBuilderHeeler.Core.Validation
{
	public static class PlacementValidator
	{
		public const string OutsideActiveZoneMessage = "Outside active world zone";

		private static readonly int WaterLayer = LayerMask.NameToLayer("Water");

		private static readonly int PieceLayerMask = LayerMask.GetMask(new string[2] { "piece", "piece_nonsolid" });

		private static readonly Collider[] OverlapColliderBuffer = (Collider[])(object)new Collider[128];

		private static readonly List<Collider> TargetColliderBuffer = new List<Collider>(16);

		private static readonly List<Character> NearbyCharacterBuffer = new List<Character>(16);

		private static readonly RaycastHit[] SurfaceHitBuffer = (RaycastHit[])(object)new RaycastHit[16];

		private static bool _isValidatingEditedPiece;

		private static PlacementStatus _prePostfixEditStatus;

		public static bool IsValidatingEditedPiece => _isValidatingEditedPiece;

		public static Piece? RepairOrRemoveTarget { get; set; }

		public static bool IsInsideActiveLoadedZone(Vector3 position)
		{
			//IL_0005: 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)
			if (!ZNetScene.instance.OutsideActiveArea(position))
			{
				return ZoneSystem.instance.IsZoneLoaded(position);
			}
			return false;
		}

		public static void RejectGhostOutsideActiveZone(Player player)
		{
			//IL_0001: 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_0021: Unknown result type (might be due to invalid IL or missing references)
			if ((int)player.m_placementStatus == 0 && !IsInsideActiveLoadedZone(player.m_placementGhost.transform.position))
			{
				player.m_placementStatus = (PlacementStatus)1;
				player.SetPlacementGhostValid(false);
			}
		}

		public static void OverrideStationRangePoint(ref Vector3 point)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: 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)
			if (!ModConfig.EnableMod.Value || (!BuildStateManager.IsBuildCameraActive && !ModConfig.ValidateStationRangeAtPieceLocation.Value))
			{
				return;
			}
			Player localPlayer = Player.m_localPlayer;
			if (!Object.op_Implicit((Object)(object)localPlayer))
			{
				return;
			}
			Vector3 val = point - ((Component)localPlayer).transform.position;
			if (!(((Vector3)(ref val)).sqrMagnitude > 0.01f))
			{
				GameObject val2 = (GameObject)(Object.op_Implicit((Object)(object)RepairOrRemoveTarget) ? ((object)((Component)RepairOrRemoveTarget).gameObject) : ((object)BuildStateManager.GetActiveTargetObject(localPlayer)));
				if (Object.op_Implicit((Object)(object)val2) && val2.activeInHierarchy)
				{
					point = val2.transform.position;
				}
			}
		}

		public static PlacementStatus ValidateEditedPiece(Player player, Piece editedPiece, bool flashGuardStone)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: 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_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: 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_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: 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)
			GameObject placementGhost = player.m_placementGhost;
			_isValidatingEditedPiece = true;
			_prePostfixEditStatus = (PlacementStatus)0;
			player.m_placementGhost = ((Component)editedPiece).gameObject;
			try
			{
				player.UpdatePlacementGhost(flashGuardStone);
				PlacementStatus placementStatus = player.m_placementStatus;
				if ((int)_prePostfixEditStatus != 0 && (int)placementStatus == 0)
				{
					editedPiece.SetInvalidPlacementHeightlight(false);
				}
				else if ((int)placementStatus != 0)
				{
					editedPiece.SetInvalidPlacementHeightlight(true);
				}
				return placementStatus;
			}
			finally
			{
				player.m_placementGhost = placementGhost;
				_isValidatingEditedPiece = false;
			}
		}

		public static void ValidateEditedGhostInPrefix(Player player, bool flashGuardStone)
		{
			//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)
			_prePostfixEditStatus = ValidateGhost(player, flashGuardStone);
		}

		public static PlacementStatus ValidateGhost(Player player, bool flashGuardStone)
		{
			//IL_0024: 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)
			GameObject placementGhost = player.m_placementGhost;
			Piece piece = default(Piece);
			if (Object.op_Implicit((Object)(object)placementGhost) && placementGhost.TryGetComponent<Piece>(ref piece))
			{
				return Validate(player, placementGhost, piece, flashGuardStone);
			}
			return player.m_placementStatus;
		}

		public static string GetStatusMessage(PlacementStatus status)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Expected I4, but got Unknown
			return (status - 1) switch
			{
				2 => "$msg_nobuildzone", 
				1 => "$msg_blocked", 
				3 => "$msg_privatezone", 
				4 => "$msg_needspace", 
				5 => "$msg_noteleportarea", 
				0 => "$msg_invalidplacement", 
				11 => "$msg_invalidplacement", 
				6 => "$msg_extensionmissingstation", 
				7 => "$msg_wrongbiome", 
				8 => "$msg_needcultivated", 
				9 => "$msg_needdirt", 
				10 => "$msg_notindungeon", 
				12 => "$msg_snowtoodeep", 
				13 => "$msg_nosnow", 
				_ => "$msg_invalidplacement", 
			};
		}

		private static PlacementStatus Validate(Player player, GameObject ghost, Piece piece, bool flashGuardStone)
		{
			//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_000c: 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_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)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: 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_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: 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_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: 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_010f: 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_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_0259: Unknown result type (might be due to invalid IL or missing references)
			//IL_025d: Invalid comparison between Unknown and I4
			//IL_024b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: 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_04b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0375: Unknown result type (might be due to invalid IL or missing references)
			//IL_0361: 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_03aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_03be: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_040e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0419: Unknown result type (might be due to invalid IL or missing references)
			//IL_0422: Unknown result type (might be due to invalid IL or missing references)
			//IL_0430: Invalid comparison between Unknown and I4
			//IL_0404: Unknown result type (might be due to invalid IL or missing references)
			//IL_0487: Unknown result type (might be due to invalid IL or missing references)
			//IL_048b: Invalid comparison between Unknown and I4
			//IL_0463: Unknown result type (might be due to invalid IL or missing references)
			//IL_04af: Unknown result type (might be due to invalid IL or missing references)
			//IL_0479: Unknown result type (might be due to invalid IL or missing references)
			//IL_049a: Unknown result type (might be due to invalid IL or missing references)
			//IL_044c: Unknown result type (might be due to invalid IL or missing references)
			Vector3 position = ghost.transform.position;
			if (!IsInsideActiveLoadedZone(position))
			{
				return SetStatus(player, piece, (PlacementStatus)1);
			}
			if (Location.IsInsideNoBuildLocation(position))
			{
				return SetStatus(player, piece, (PlacementStatus)3);
			}
			PrivateArea val = default(PrivateArea);
			bool flag = ((Component)piece).TryGetComponent<PrivateArea>(ref val);
			float num = (flag ? val.m_radius : 0f);
			if (!PrivateArea.CheckAccess(position, num, flashGuardStone, flag))
			{
				return SetStatus(player, piece, (PlacementStatus)4);
			}
			if (IsBlockedByCharacter(ghost, position))
			{
				return SetStatus(player, piece, (PlacementStatus)2);
			}
			Biome val2 = Heightmap.FindBiome(position);
			if ((int)piece.m_onlyInBiome != 0 && (val2 & piece.m_onlyInBiome) == 0)
			{
				return SetStatus(player, piece, (PlacementStatus)8);
			}
			if (!piece.m_allowedInDungeons && Character.InInterior(position) && (!Object.op_Implicit((Object)(object)EnvMan.instance) || !EnvMan.instance.CheckInteriorBuildingOverride()) && (!Object.op_Implicit((Object)(object)ZoneSystem.instance) || !ZoneSystem.instance.GetGlobalKey((GlobalKeys)34)))
			{
				return SetStatus(player, piece, (PlacementStatus)11);
			}
			if (piece.m_onlyInTeleportArea && !Object.op_Implicit((Object)(object)EffectArea.IsPointInsideArea(position, (Type)16, 0f)))
			{
				return SetStatus(player, piece, (PlacementStatus)6);
			}
			StationExtension val3 = default(StationExtension);
			if (((Component)piece).TryGetComponent<StationExtension>(ref val3))
			{
				CraftingStation val4 = val3.FindClosestStationInRange(position);
				if (!Object.op_Implicit((Object)(object)val4))
				{
					val3.StopConnectionEffect();
					return SetStatus(player, piece, (PlacementStatus)7);
				}
				val3.StartConnectionEffect(val4, 1f);
				if (val3.OtherExtensionInRange(piece.m_spaceRequirement))
				{
					return SetStatus(player, piece, (PlacementStatus)5);
				}
			}
			if (piece.m_blockRadius > 0f && piece.m_blockingPieces.Count > 0)
			{
				int num2 = Physics.OverlapSphereNonAlloc(position, piece.m_blockRadius, OverlapColliderBuffer, PieceLayerMask);
				bool flag2 = false;
				for (int i = 0; i < num2; i++)
				{
					if (flag2)
					{
						break;
					}
					Piece componentInParent = ((Component)OverlapColliderBuffer[i]).GetComponentInParent<Piece>();
					if (!Object.op_Implicit((Object)(object)componentInParent) || (Object)(object)componentInParent == (Object)(object)piece)
					{
						continue;
					}
					for (int j = 0; j < piece.m_blockingPieces.Count; j++)
					{
						Piece val5 = piece.m_blockingPieces[j];
						if (Object.op_Implicit((Object)(object)val5) && string.Equals(val5.m_name, componentInParent.m_name, StringComparison.Ordinal))
						{
							flag2 = true;
							break;
						}
					}
				}
				Array.Clear(OverlapColliderBuffer, 0, num2);
				if (flag2)
				{
					return SetStatus(player, piece, (PlacementStatus)5);
				}
			}
			if (piece.m_noClipping && IsClippingBlocked(player, ghost, 0.2f))
			{
				return SetStatus(player, piece, (PlacementStatus)1);
			}
			bool flag3 = !piece.m_allowedInDeepSnow && (int)val2 == 64;
			if (piece.m_groundOnly || piece.m_groundPiece || piece.m_waterPiece || piece.m_noInWater || piece.m_notOnTiltingSurface || piece.m_cultivatedGroundOnly || piece.m_vegetationGroundOnly || flag3 || piece.m_requireDeepSnow)
			{
				int rayMask = ((piece.m_waterPiece || piece.m_noInWater) ? player.m_placeWaterRayMask : player.m_placeRayMask);
				float maxDistance = (piece.m_waterPiece ? 4.5f : 1.5f);
				RaycastHit closestHit;
				bool flag4 = TryRaycastSurface(position, rayMask, maxDistance, ((Component)piece).transform, out closestHit);
				Heightmap val6 = null;
				Heightmap val7 = default(Heightmap);
				if (flag4 && ((Component)((RaycastHit)(ref closestHit)).collider).TryGetComponent<Heightmap>(ref val7))
				{
					val6 = val7;
				}
				bool flag5 = flag4 && ((Component)((RaycastHit)(ref closestHit)).collider).gameObject.layer == WaterLayer;
				bool flag6 = ZInput.GetButton("AltPlace") || ZInput.GetButton("JoyAltPlace");
				if (piece.m_waterPiece && !flag5 && !flag6)
				{
					return SetStatus(player, piece, (PlacementStatus)1);
				}
				if (piece.m_noInWater && flag5)
				{
					return SetStatus(player, piece, (PlacementStatus)1);
				}
				if ((piece.m_groundOnly || piece.m_groundPiece) && !Object.op_Implicit((Object)(object)val6))
				{
					return SetStatus(player, piece, (PlacementStatus)1);
				}
				if (piece.m_notOnTiltingSurface && flag4 && ((RaycastHit)(ref closestHit)).normal.y < 0.8f)
				{
					return SetStatus(player, piece, (PlacementStatus)1);
				}
				if (piece.m_cultivatedGroundOnly && (!Object.op_Implicit((Object)(object)val6) || !val6.IsCultivated(((RaycastHit)(ref closestHit)).point)))
				{
					return SetStatus(player, piece, (PlacementStatus)9);
				}
				if (piece.m_vegetationGroundOnly)
				{
					if (!Object.op_Implicit((Object)(object)val6))
					{
						return SetStatus(player, piece, (PlacementStatus)10);
					}
					Biome biome = val6.GetBiome(((RaycastHit)(ref closestHit)).point, 0.02f, false);
					float vegetationMask = val6.GetVegetationMask(((RaycastHit)(ref closestHit)).point);
					if (((int)biome == 32) ? (vegetationMask > 0.1f) : (vegetationMask < 0.25f))
					{
						return SetStatus(player, piece, (PlacementStatus)10);
					}
				}
				if (flag3 && Object.op_Implicit((Object)(object)val6) && val6.GetCultivationMask(((RaycastHit)(ref closestHit)).point) > player.m_deepSnowBuildHeight)
				{
					return SetStatus(player, piece, (PlacementStatus)13);
				}
				if (piece.m_requireDeepSnow && ((int)val2 != 64 || !Object.op_Implicit((Object)(object)val6) || val6.GetCultivationMask(((RaycastHit)(ref closestHit)).point) <= 0f))
				{
					return SetStatus(player, piece, (PlacementStatus)14);
				}
			}
			return SetStatus(player, piece, (PlacementStatus)0);
		}

		private static bool IsBlockedByCharacter(GameObject targetObject, Vector3 position)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: 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)
			TargetColliderBuffer.Clear();
			targetObject.GetComponentsInChildren<Collider>(TargetColliderBuffer);
			if (TargetColliderBuffer.Count == 0)
			{
				return false;
			}
			NearbyCharacterBuffer.Clear();
			Character.GetCharactersInRange(position, 30f, NearbyCharacterBuffer);
			bool flag = false;
			Vector3 val4 = default(Vector3);
			float num = default(float);
			for (int i = 0; i < TargetColliderBuffer.Count; i++)
			{
				if (flag)
				{
					break;
				}
				Collider val = TargetColliderBuffer[i];
				if (!Object.op_Implicit((Object)(object)val) || !val.enabled || val.isTrigger)
				{
					continue;
				}
				MeshCollider val2 = (MeshCollider)(object)((val is MeshCollider) ? val : null);
				if (val2 != null && !val2.convex)
				{
					continue;
				}
				for (int j = 0; j < NearbyCharacterBuffer.Count; j++)
				{
					Character val3 = NearbyCharacterBuffer[j];
					if (Object.op_Implicit((Object)(object)val3) && !val3.IsDead())
					{
						Collider collider = (Collider)(object)val3.GetCollider();
						if (Object.op_Implicit((Object)(object)collider) && collider.enabled && Physics.ComputePenetration(val, ((Component)val).transform.position, ((Component)val).transform.rotation, collider, ((Component)collider).transform.position, ((Component)collider).transform.rotation, ref val4, ref num))
						{
							flag = true;
							break;
						}
					}
				}
			}
			TargetColliderBuffer.Clear();
			NearbyCharacterBuffer.Clear();
			return flag;
		}

		private static bool IsClippingBlocked(Player player, GameObject targetObject, float maxPenetration)
		{
			if (!_isValidatingEditedPiece || HasInvalidClipping(targetObject, player.m_placeRayMask, maxPenetration))
			{
				return player.TestGhostClipping(targetObject, maxPenetration);
			}
			return false;
		}

		private static bool HasInvalidClipping(GameObject targetObject, int placeRayMask, float maxPenetration)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: 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_0103: Unknown result type (might be due to invalid IL or missing references)
			Transform transform = targetObject.transform;
			TargetColliderBuffer.Clear();
			targetObject.GetComponentsInChildren<Collider>(TargetColliderBuffer);
			if (TargetColliderBuffer.Count == 0)
			{
				return false;
			}
			int nu