Decompiled source of BuilderToolkit v0.1.1

plugins/BuilderToolkit.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Reflection;
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 HarmonyLib;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("assembly_utils")]
[assembly: IgnoresAccessChecksTo("assembly_valheim")]
[assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")]
[assembly: AssemblyCompany("BuilderToolkit")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("BuilderToolkit")]
[assembly: AssemblyTitle("BuilderToolkit")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace BuilderToolkit
{
	[HarmonyPatch]
	internal static class BuilderCam
	{
		private const float CollisionRadius = 0.35f;

		private const float GroundClearance = 0.4f;

		private const float EnemyCheckInterval = 0.5f;

		private static Vector3 _pos;

		private static float _yaw;

		private static float _pitch;

		private static bool _tookDamage;

		private static float _enemyCheckTimer;

		private static int _collisionMask;

		private static int _reachDepth;

		private static float _savedReach;

		public static bool Active { get; private set; }

		public static float DistanceFromPlayer
		{
			get
			{
				//IL_001a: 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)
				if (!Active || !((Object)(object)Player.m_localPlayer != (Object)null))
				{
					return 0f;
				}
				return Vector3.Distance(_pos, ((Character)Player.m_localPlayer).m_eye.position);
			}
		}

		public static float ReachBonus
		{
			get
			{
				if (!Active)
				{
					return 0f;
				}
				return ModConfig.CamReachBonus.Value;
			}
		}

		public static void HandleInput()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			if (GameState.KeyDown(ModConfig.KeyBuilderCam.Value) && !GameState.UiBlocksInput())
			{
				if (Active)
				{
					Exit("Builder cam off");
				}
				else
				{
					TryEnter();
				}
			}
		}

		private static void TryEnter()
		{
			//IL_0088: 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_0097: 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_00a0: 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_00ac: 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_00b9: Unknown result type (might be due to invalid IL or missing references)
			Player val = GameState.LocalBuilder();
			GameCamera instance = GameCamera.instance;
			if ((Object)(object)val == (Object)null || (Object)(object)instance == (Object)null)
			{
				return;
			}
			string text = CheckBlocked(val);
			if (text != null)
			{
				PlacementTweaks.ShowMessage("Builder cam unavailable: " + text);
				return;
			}
			if (_collisionMask == 0)
			{
				_collisionMask = LayerMask.GetMask(new string[6] { "Default", "static_solid", "Default_small", "piece", "terrain", "vehicle" });
			}
			Transform transform = ((Component)instance).transform;
			_pos = transform.position;
			Quaternion rotation = transform.rotation;
			Vector3 eulerAngles = ((Quaternion)(ref rotation)).eulerAngles;
			_yaw = eulerAngles.y;
			_pitch = ((eulerAngles.x > 180f) ? (eulerAngles.x - 360f) : eulerAngles.x);
			_tookDamage = false;
			_enemyCheckTimer = 0f;
			Active = true;
			PlacementTweaks.ShowMessage("Builder cam on");
		}

		public static void Exit(string message)
		{
			if (Active)
			{
				Active = false;
				if (message != null)
				{
					PlacementTweaks.ShowMessage(message);
				}
			}
		}

		private static string CheckBlocked(Player player)
		{
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			if (((Character)player).IsAttached() || ((Character)player).IsAttachedToShip())
			{
				return "dismount first";
			}
			if (player.InDebugFlyMode())
			{
				return "debug fly is on";
			}
			if (ModConfig.CamRequireBuildMode.Value && !((Character)player).InPlaceMode())
			{
				return "equip a build tool";
			}
			float value = ModConfig.CamEnemyCheckRange.Value;
			if (value > 0f && BaseAI.HaveEnemyInRange((Character)(object)player, ((Component)player).transform.position, value))
			{
				return "enemies nearby";
			}
			return null;
		}

		[HarmonyPatch(typeof(GameCamera), "UpdateCamera")]
		[HarmonyPrefix]
		private static bool UpdateCamera_Prefix(GameCamera __instance, float dt)
		{
			if (!Active)
			{
				return true;
			}
			Player val = GameState.LocalBuilder();
			if ((Object)(object)val == (Object)null)
			{
				Exit(null);
				return true;
			}
			if (!StillAllowed(val, dt))
			{
				return true;
			}
			Fly(val, ((Component)__instance).transform, dt);
			return false;
		}

		private static bool StillAllowed(Player player, float dt)
		{
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			if (_tookDamage)
			{
				_tookDamage = false;
				if (ModConfig.CamExitOnDamage.Value)
				{
					Exit("Builder cam: you're taking damage!");
					return false;
				}
			}
			if (ModConfig.CamRequireBuildMode.Value && !((Character)player).InPlaceMode())
			{
				Exit("Builder cam off");
				return false;
			}
			if (((Character)player).IsAttached() || player.InDebugFlyMode())
			{
				Exit(null);
				return false;
			}
			_enemyCheckTimer -= dt;
			if (_enemyCheckTimer <= 0f)
			{
				_enemyCheckTimer = 0.5f;
				float value = ModConfig.CamEnemyCheckRange.Value;
				if (value > 0f && BaseAI.HaveEnemyInRange((Character)(object)player, ((Component)player).transform.position, value))
				{
					Exit("Builder cam: enemies nearby!");
					return false;
				}
			}
			return true;
		}

		private static void Fly(Player player, Transform camT, float dt)
		{
			//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_0087: 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_0008: 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_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: 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_00a6: 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_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: 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_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//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_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: 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_00ec: 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_00fc: 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_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: 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_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			bool num = GameState.UiBlocksInput();
			if (!num)
			{
				Vector2 val = ZInput.GetMouseDelta() * PlayerController.m_mouseSens * ModConfig.CamSensitivity.Value;
				_yaw += val.x;
				_pitch += (PlayerController.m_invertMouse ? val.y : (0f - val.y));
				_pitch = Mathf.Clamp(_pitch, -89f, 89f);
			}
			Quaternion val2 = Quaternion.Euler(_pitch, _yaw, 0f);
			Vector3 val3 = Vector3.zero;
			if (!num)
			{
				Vector3 val4 = Quaternion.Euler(0f, _yaw, 0f) * Vector3.forward;
				Vector3 val5 = Quaternion.Euler(0f, _yaw, 0f) * Vector3.right;
				if (GameState.KeyHeld((KeyCode)119))
				{
					val3 += val4;
				}
				if (GameState.KeyHeld((KeyCode)115))
				{
					val3 -= val4;
				}
				if (GameState.KeyHeld((KeyCode)100))
				{
					val3 += val5;
				}
				if (GameState.KeyHeld((KeyCode)97))
				{
					val3 -= val5;
				}
				if (GameState.KeyHeld(ModConfig.KeyCamUp.Value))
				{
					val3 += Vector3.up;
				}
				if (GameState.KeyHeld(ModConfig.KeyCamDown.Value))
				{
					val3 -= Vector3.up;
				}
			}
			if (((Vector3)(ref val3)).sqrMagnitude > 0f)
			{
				float num2 = ModConfig.CamSpeed.Value;
				if (GameState.KeyHeld(ModConfig.KeyCamFast.Value))
				{
					num2 *= ModConfig.CamFastMultiplier.Value;
				}
				_pos = MoveWithCollision(_pos, ((Vector3)(ref val3)).normalized * num2 * dt);
			}
			_pos = ApplyLeash(player, _pos);
			camT.SetPositionAndRotation(_pos, val2);
		}

		private static Vector3 MoveWithCollision(Vector3 from, Vector3 delta)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: 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_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_005e: 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_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: 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_0090: 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_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			if (!ModConfig.CamCollision.Value)
			{
				return from + delta;
			}
			float magnitude = ((Vector3)(ref delta)).magnitude;
			Vector3 val = delta / magnitude;
			RaycastHit val2 = default(RaycastHit);
			if (Physics.SphereCast(from, 0.35f, val, ref val2, magnitude, _collisionMask, (QueryTriggerInteraction)1))
			{
				Vector3 val3 = from + val * Mathf.Max(0f, ((RaycastHit)(ref val2)).distance - 0.01f);
				Vector3 val4 = Vector3.ProjectOnPlane(delta - (val3 - from), ((RaycastHit)(ref val2)).normal);
				RaycastHit val5 = default(RaycastHit);
				if (((Vector3)(ref val4)).sqrMagnitude > 1E-06f && !Physics.SphereCast(val3, 0.35f, ((Vector3)(ref val4)).normalized, ref val5, ((Vector3)(ref val4)).magnitude, _collisionMask, (QueryTriggerInteraction)1))
				{
					val3 += val4;
				}
				return val3;
			}
			return from + delta;
		}

		private static Vector3 ApplyLeash(Player player, Vector3 pos)
		{
			//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_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_002e: 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_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: 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_005f: Unknown result type (might be due to invalid IL or missing references)
			Vector3 position = ((Character)player).m_eye.position;
			float value = ModConfig.CamMaxDistance.Value;
			Vector3 val = pos - position;
			if (((Vector3)(ref val)).sqrMagnitude > value * value)
			{
				pos = position + ((Vector3)(ref val)).normalized * value;
			}
			if ((Object)(object)ZoneSystem.instance != (Object)null)
			{
				float num = ZoneSystem.instance.GetGroundHeight(pos) + 0.4f;
				if (pos.y < num)
				{
					pos.y = num;
				}
			}
			return pos;
		}

		public static float EffectiveReach(Player player)
		{
			if (_reachDepth <= 0)
			{
				return player.m_maxPlaceDistance + ReachBonus;
			}
			return player.m_maxPlaceDistance;
		}

		private static void BeginReach(Player player)
		{
			if (!((Object)(object)player != (Object)(object)Player.m_localPlayer) && _reachDepth++ == 0)
			{
				_savedReach = player.m_maxPlaceDistance;
				player.m_maxPlaceDistance = _savedReach + ReachBonus;
			}
		}

		private static void EndReach(Player player)
		{
			if (!((Object)(object)player != (Object)(object)Player.m_localPlayer) && _reachDepth != 0 && --_reachDepth == 0)
			{
				player.m_maxPlaceDistance = _savedReach;
			}
		}

		[HarmonyPatch(typeof(Player), "UpdatePlacement")]
		[HarmonyPrefix]
		private static void UpdatePlacement_Prefix(Player __instance)
		{
			BeginReach(__instance);
		}

		[HarmonyPatch(typeof(Player), "UpdatePlacement")]
		[HarmonyFinalizer]
		private static void UpdatePlacement_Finalizer(Player __instance)
		{
			EndReach(__instance);
		}

		[HarmonyPatch(typeof(Player), "UpdatePlacementGhost")]
		[HarmonyPrefix]
		private static void UpdatePlacementGhost_Prefix(Player __instance)
		{
			BeginReach(__instance);
		}

		[HarmonyPatch(typeof(Player), "UpdatePlacementGhost")]
		[HarmonyFinalizer]
		private static void UpdatePlacementGhost_Finalizer(Player __instance)
		{
			EndReach(__instance);
		}

		[HarmonyPatch(typeof(Character), "ApplyDamage")]
		[HarmonyPostfix]
		private static void ApplyDamage_Postfix(Character __instance, HitData hit)
		{
			if (Active && (Object)(object)__instance == (Object)(object)Player.m_localPlayer && hit != null && hit.GetTotalDamage() > 0.1f)
			{
				_tookDamage = true;
			}
		}

		[HarmonyPatch(typeof(PlayerController), "TakeInput")]
		[HarmonyPostfix]
		private static void PlayerControllerTakeInput_Postfix(ref bool __result)
		{
			if (Active)
			{
				__result = false;
			}
		}

		[HarmonyPatch(typeof(Player), "SetMouseLook")]
		[HarmonyPrefix]
		private static bool SetMouseLook_Prefix(Player __instance)
		{
			if (Active)
			{
				return !((Object)(object)__instance == (Object)(object)Player.m_localPlayer);
			}
			return true;
		}
	}
	internal static class BuildHud
	{
		private static GUIStyle _box;

		private static GUIStyle _label;

		private static GUIStyle _dim;

		private static readonly StringBuilder Sb = new StringBuilder(512);

		public static void HandleInput()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			if (GameState.KeyDown(ModConfig.KeyToggleHud.Value) && !GameState.UiBlocksInput())
			{
				ModConfig.HudVisible.Value = !ModConfig.HudVisible.Value;
			}
		}

		public static void Draw()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Invalid comparison between Unknown and I4
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Invalid comparison between Unknown and I4
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: 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_00e7: 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_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: 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_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_022f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0234: Unknown result type (might be due to invalid IL or missing references)
			//IL_0248: Unknown result type (might be due to invalid IL or missing references)
			//IL_0257: Unknown result type (might be due to invalid IL or missing references)
			//IL_0266: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0308: Expected O, but got Unknown
			//IL_031c: Unknown result type (might be due to invalid IL or missing references)
			//IL_032b: Expected O, but got Unknown
			//IL_0338: Unknown result type (might be due to invalid IL or missing references)
			//IL_033d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0341: Unknown result type (might be due to invalid IL or missing references)
			//IL_0348: Unknown result type (might be due to invalid IL or missing references)
			//IL_0364: Unknown result type (might be due to invalid IL or missing references)
			//IL_0396: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d5: Unknown result type (might be due to invalid IL or missing references)
			if (!ModConfig.HudVisible.Value || ((int)Event.current.type != 7 && (int)Event.current.type != 8))
			{
				return;
			}
			Player val = GameState.LocalBuilder();
			if (!((Object)(object)val == (Object)null) && ((Character)val).InPlaceMode() && !Hud.IsPieceSelectionVisible() && !Menu.IsVisible())
			{
				EnsureStyles();
				Sb.Clear();
				Piece selectedPiece = val.GetSelectedPiece();
				GameObject placementGhost = val.m_placementGhost;
				string value = (((Object)(object)selectedPiece != (Object)null) ? Localize(selectedPiece.m_name) : "-");
				Sb.Append("<b>Builder Toolkit</b>\n");
				Sb.Append("Piece: ").Append(value).Append('\n');
				if ((Object)(object)placementGhost != (Object)null && placementGhost.activeSelf)
				{
					Vector3 position = placementGhost.transform.position;
					Quaternion rotation = placementGhost.transform.rotation;
					Vector3 eulerAngles = ((Quaternion)(ref rotation)).eulerAngles;
					Sb.AppendFormat("Pos: {0:0.00}  {1:0.00}  {2:0.00}\n", position.x, position.y, position.z);
					Sb.AppendFormat("Rot: {0:0.#}°  (pitch {1:0.#}°, roll {2:0.#}°)\n", eulerAngles.y, Wrap(eulerAngles.x), Wrap(eulerAngles.z));
					Sb.Append("Status: ").Append(StatusText(val)).Append('\n');
					Sb.AppendFormat("Reach: {0:0.0} / {1:0.0} m\n", Vector3.Distance(((Character)val).m_eye.position, position), BuilderCam.EffectiveReach(val));
				}
				float gridSize = PlacementTweaks.GridSize;
				Sb.Append("Grid: ").Append((gridSize > 0f) ? (gridSize.ToString("0.##") + " m") : "off");
				Sb.Append("   Height lock: ").Append(PlacementTweaks.HeightLocked ? PlacementTweaks.LockedHeight.ToString("0.00") : "off").Append('\n');
				Vector3 nudgeOffset = PlacementTweaks.NudgeOffset;
				Sb.AppendFormat("Nudge: {0:0.00}  {1:0.00}  {2:0.00}   Fine yaw: {3:0.#}°\n", nudgeOffset.x, nudgeOffset.y, nudgeOffset.z, PlacementTweaks.YawOffset);
				if (BuilderCam.Active)
				{
					Sb.AppendFormat("<color=#8fd3ff>Builder cam: {0:0}/{1:0} m   reach +{2:0.#} m</color>\n", BuilderCam.DistanceFromPlayer, ModConfig.CamMaxDistance.Value, BuilderCam.ReachBonus);
				}
				string text = Sb.ToString().TrimEnd(new char[1] { '\n' });
				string text2 = (ModConfig.HudShowKeys.Value ? KeyHelp() : null);
				float num = _label.CalcHeight(new GUIContent(text), 324f);
				float num2 = ((text2 != null) ? (_dim.CalcHeight(new GUIContent(text2), 324f) + 6f) : 0f);
				Vector2 value2 = ModConfig.HudPosition.Value;
				Rect val2 = default(Rect);
				((Rect)(ref val2))..ctor(value2.x, value2.y, 340f, num + num2 + 16f);
				GUI.Box(val2, GUIContent.none, _box);
				GUI.Label(new Rect(((Rect)(ref val2)).x + 8f, ((Rect)(ref val2)).y + 8f, 324f, num), text, _label);
				if (text2 != null)
				{
					GUI.Label(new Rect(((Rect)(ref val2)).x + 8f, ((Rect)(ref val2)).y + 8f + num + 6f, 324f, num2), text2, _dim);
				}
			}
		}

		private static string StatusText(Player player)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			if (PlacementTweaks.LastBlockReason != null)
			{
				return "<color=#ff7a7a>" + PlacementTweaks.LastBlockReason + "</color>";
			}
			if ((int)player.m_placementStatus != 0)
			{
				return "<color=#ff7a7a>" + ((object)Unsafe.As<PlacementStatus, PlacementStatus>(ref player.m_placementStatus)/*cast due to .constrained prefix*/).ToString() + "</color>";
			}
			return "<color=#9cff9c>OK</color>";
		}

		private static string KeyHelp()
		{
			return K(ModConfig.KeyNudgeForward) + "/" + K(ModConfig.KeyNudgeBack) + "/" + K(ModConfig.KeyNudgeLeft) + "/" + K(ModConfig.KeyNudgeRight) + " nudge   " + K(ModConfig.KeyNudgeUp) + "/" + K(ModConfig.KeyNudgeDown) + " up/down\n" + K(ModConfig.KeyRotateLeft) + "/" + K(ModConfig.KeyRotateRight) + " fine rotate   hold " + K(ModConfig.KeyFineModifier) + " = fine\n" + K(ModConfig.KeyGridCycle) + " grid   " + K(ModConfig.KeyHeightLock) + " height lock   " + K(ModConfig.KeyMatchRotation) + " match rot\n" + K(ModConfig.KeyResetOffsets) + " reset   " + K(ModConfig.KeyBuilderCam) + " builder cam   " + K(ModConfig.KeyToggleHud) + " hide HUD";
		}

		private static string K(ConfigEntry<KeyCode> e)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Invalid comparison between Unknown and I4
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Invalid comparison between Unknown and I4
			//IL_0011: 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_0041: Expected I4, but got Unknown
			//IL_0074: 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)
			KeyCode value = e.Value;
			if ((int)value != 44)
			{
				if ((int)value != 46)
				{
					return (value - 273) switch
					{
						0 => "↑", 
						1 => "↓", 
						3 => "←", 
						2 => "→", 
						7 => "PgUp", 
						8 => "PgDn", 
						_ => ((object)e.Value/*cast due to .constrained prefix*/).ToString(), 
					};
				}
				return ".";
			}
			return ",";
		}

		private static float Wrap(float a)
		{
			if (!(a > 180f))
			{
				return a;
			}
			return a - 360f;
		}

		private static string Localize(string token)
		{
			if (Localization.instance == null)
			{
				return token;
			}
			return Localization.instance.Localize(token);
		}

		private static void EnsureStyles()
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			//IL_0027: 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_0057: Expected O, but got Unknown
			//IL_0061: 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_006d: 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_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Expected O, but got Unknown
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: 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_00d6: Expected O, but got Unknown
			if (_box == null)
			{
				Texture2D val = new Texture2D(1, 1);
				val.SetPixel(0, 0, new Color(0.06f, 0.05f, 0.04f, 0.78f));
				val.Apply();
				GUIStyle val2 = new GUIStyle(GUI.skin.box);
				val2.normal.background = val;
				_box = val2;
				GUIStyle val3 = new GUIStyle(GUI.skin.label)
				{
					richText = true,
					fontSize = 14,
					wordWrap = true
				};
				val3.normal.textColor = new Color(0.95f, 0.9f, 0.8f);
				_label = val3;
				GUIStyle val4 = new GUIStyle(_label)
				{
					fontSize = 12
				};
				val4.normal.textColor = new Color(0.75f, 0.72f, 0.65f);
				_dim = val4;
			}
		}
	}
	internal static class GameState
	{
		public static bool UiBlocksInput()
		{
			if ((!((Object)(object)Chat.instance != (Object)null) || !Chat.instance.HasFocus()) && !Console.IsVisible() && !Menu.IsVisible() && !TextInput.IsVisible() && !InventoryGui.IsVisible() && !Minimap.IsOpen() && !StoreGui.IsVisible())
			{
				if ((Object)(object)Hud.instance != (Object)null)
				{
					return Hud.IsPieceSelectionVisible();
				}
				return false;
			}
			return true;
		}

		public static bool KeyDown(KeyCode key)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			if ((int)key != 0)
			{
				return ZInput.GetKeyDown(key, false);
			}
			return false;
		}

		public static bool KeyHeld(KeyCode key)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			if ((int)key != 0)
			{
				return ZInput.GetKey(key, false);
			}
			return false;
		}

		public static Player LocalBuilder()
		{
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null || ((Character)localPlayer).IsDead() || ((Character)localPlayer).InCutscene() || ((Character)localPlayer).IsTeleporting())
			{
				return null;
			}
			return localPlayer;
		}
	}
	internal static class ModConfig
	{
		public static ConfigEntry<bool> Enabled;

		public static ConfigEntry<float> NudgeStep;

		public static ConfigEntry<float> FineNudgeMultiplier;

		public static ConfigEntry<float> FineRotationStep;

		public static ConfigEntry<string> GridSizes;

		public static ConfigEntry<bool> GridSnapsHeight;

		public static ConfigEntry<bool> ResetOffsetsOnPieceChange;

		public static ConfigEntry<float> CamMaxDistance;

		public static ConfigEntry<float> CamReachBonus;

		public static ConfigEntry<float> CamSpeed;

		public static ConfigEntry<float> CamFastMultiplier;

		public static ConfigEntry<float> CamSensitivity;

		public static ConfigEntry<bool> CamRequireBuildMode;

		public static ConfigEntry<bool> CamCollision;

		public static ConfigEntry<float> CamEnemyCheckRange;

		public static ConfigEntry<bool> CamExitOnDamage;

		public static ConfigEntry<bool> HudVisible;

		public static ConfigEntry<bool> HudShowKeys;

		public static ConfigEntry<Vector2> HudPosition;

		public static ConfigEntry<KeyCode> KeyNudgeForward;

		public static ConfigEntry<KeyCode> KeyNudgeBack;

		public static ConfigEntry<KeyCode> KeyNudgeLeft;

		public static ConfigEntry<KeyCode> KeyNudgeRight;

		public static ConfigEntry<KeyCode> KeyNudgeUp;

		public static ConfigEntry<KeyCode> KeyNudgeDown;

		public static ConfigEntry<KeyCode> KeyFineModifier;

		public static ConfigEntry<KeyCode> KeyRotateLeft;

		public static ConfigEntry<KeyCode> KeyRotateRight;

		public static ConfigEntry<KeyCode> KeyResetOffsets;

		public static ConfigEntry<KeyCode> KeyGridCycle;

		public static ConfigEntry<KeyCode> KeyHeightLock;

		public static ConfigEntry<KeyCode> KeyMatchRotation;

		public static ConfigEntry<KeyCode> KeyBuilderCam;

		public static ConfigEntry<KeyCode> KeyCamUp;

		public static ConfigEntry<KeyCode> KeyCamDown;

		public static ConfigEntry<KeyCode> KeyCamFast;

		public static ConfigEntry<KeyCode> KeyToggleHud;

		public static void Bind(ConfigFile cfg)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Expected O, but got Unknown
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Expected O, but got Unknown
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Expected O, but got Unknown
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Expected O, but got Unknown
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Expected O, but got Unknown
			//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Expected O, but got Unknown
			//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f3: Expected O, but got Unknown
			//IL_0221: Unknown result type (might be due to invalid IL or missing references)
			//IL_022b: Expected O, but got Unknown
			//IL_028f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0299: Expected O, but got Unknown
			//IL_0304: Unknown result type (might be due to invalid IL or missing references)
			Enabled = cfg.Bind<bool>("1 - General", "Enabled", true, "Master switch for the whole mod.");
			NudgeStep = cfg.Bind<float>("2 - Placement", "NudgeStep", 0.1f, new ConfigDescription("Meters moved per nudge key press.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.01f, 2f), Array.Empty<object>()));
			FineNudgeMultiplier = cfg.Bind<float>("2 - Placement", "FineMultiplier", 0.1f, new ConfigDescription("Nudge/rotation step multiplier while holding the fine modifier key.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.01f, 1f), Array.Empty<object>()));
			FineRotationStep = cfg.Bind<float>("2 - Placement", "FineRotationStep", 5f, new ConfigDescription("Degrees added per fine-rotate key press (on top of vanilla scroll rotation).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 90f), Array.Empty<object>()));
			GridSizes = cfg.Bind<string>("2 - Placement", "GridSizes", "0.25,0.5,1,2,4", "Comma separated grid sizes in meters. The grid key cycles Off -> each size -> Off.");
			GridSnapsHeight = cfg.Bind<bool>("2 - Placement", "GridSnapsHeight", false, "Also snap the vertical position to the grid.");
			ResetOffsetsOnPieceChange = cfg.Bind<bool>("2 - Placement", "ResetOffsetsOnPieceChange", true, "Clear nudge/rotation offsets when you select a different piece.");
			CamMaxDistance = cfg.Bind<float>("3 - Builder Cam", "MaxDistance", 30f, new ConfigDescription("How far the builder cam may fly from your character (meters).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(5f, 64f), Array.Empty<object>()));
			CamReachBonus = cfg.Bind<float>("3 - Builder Cam", "ReachBonus", 6f, new ConfigDescription("Extra build/remove reach (meters, measured from your character) while the builder cam is on. Vanilla reach is about 8 m.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 16f), Array.Empty<object>()));
			CamSpeed = cfg.Bind<float>("3 - Builder Cam", "Speed", 8f, new ConfigDescription("Fly speed in meters per second.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 30f), Array.Empty<object>()));
			CamFastMultiplier = cfg.Bind<float>("3 - Builder Cam", "FastMultiplier", 2.5f, new ConfigDescription("Speed multiplier while holding the fast key.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 5f), Array.Empty<object>()));
			CamSensitivity = cfg.Bind<float>("3 - Builder Cam", "MouseSensitivity", 1f, new ConfigDescription("Mouse look multiplier.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 5f), Array.Empty<object>()));
			CamRequireBuildMode = cfg.Bind<bool>("3 - Builder Cam", "RequireBuildMode", true, "Only allow the builder cam while a build tool (hammer, hoe, cultivator) is in place mode.");
			CamCollision = cfg.Bind<bool>("3 - Builder Cam", "Collision", true, "Stop the camera from passing through terrain, rocks and building pieces.");
			CamEnemyCheckRange = cfg.Bind<float>("3 - Builder Cam", "EnemyCheckRange", 25f, new ConfigDescription("Builder cam refuses to start / exits if an enemy is this close to your character.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 60f), Array.Empty<object>()));
			CamExitOnDamage = cfg.Bind<bool>("3 - Builder Cam", "ExitOnDamage", true, "Snap back to your character the moment it takes damage.");
			HudVisible = cfg.Bind<bool>("4 - HUD", "Visible", true, "Show the build info panel while in build mode.");
			HudShowKeys = cfg.Bind<bool>("4 - HUD", "ShowKeybinds", true, "Show the keybind cheat sheet under the info panel.");
			HudPosition = cfg.Bind<Vector2>("4 - HUD", "Position", new Vector2(20f, 220f), "Top-left corner of the HUD panel in screen pixels.");
			KeyNudgeForward = cfg.Bind<KeyCode>("5 - Keys", "NudgeForward", (KeyCode)273, "Nudge ghost away from the camera (snapped to the nearest world axis).");
			KeyNudgeBack = cfg.Bind<KeyCode>("5 - Keys", "NudgeBack", (KeyCode)274, "Nudge ghost toward the camera.");
			KeyNudgeLeft = cfg.Bind<KeyCode>("5 - Keys", "NudgeLeft", (KeyCode)276, "Nudge ghost left.");
			KeyNudgeRight = cfg.Bind<KeyCode>("5 - Keys", "NudgeRight", (KeyCode)275, "Nudge ghost right.");
			KeyNudgeUp = cfg.Bind<KeyCode>("5 - Keys", "NudgeUp", (KeyCode)280, "Nudge ghost up.");
			KeyNudgeDown = cfg.Bind<KeyCode>("5 - Keys", "NudgeDown", (KeyCode)281, "Nudge ghost down.");
			KeyFineModifier = cfg.Bind<KeyCode>("5 - Keys", "FineModifier", (KeyCode)303, "Hold for smaller nudge/rotation steps.");
			KeyRotateLeft = cfg.Bind<KeyCode>("5 - Keys", "FineRotateLeft", (KeyCode)44, "Fine rotate counter-clockwise.");
			KeyRotateRight = cfg.Bind<KeyCode>("5 - Keys", "FineRotateRight", (KeyCode)46, "Fine rotate clockwise.");
			KeyResetOffsets = cfg.Bind<KeyCode>("5 - Keys", "ResetOffsets", (KeyCode)278, "Clear nudge offset, fine rotation and height lock.");
			KeyGridCycle = cfg.Bind<KeyCode>("5 - Keys", "GridCycle", (KeyCode)103, "Cycle grid snapping size.");
			KeyHeightLock = cfg.Bind<KeyCode>("5 - Keys", "HeightLock", (KeyCode)104, "Lock the ghost to its current height (great for floors and roofs).");
			KeyMatchRotation = cfg.Bind<KeyCode>("5 - Keys", "MatchRotation", (KeyCode)116, "Match the rotation of the building piece under the crosshair.");
			KeyBuilderCam = cfg.Bind<KeyCode>("5 - Keys", "BuilderCam", (KeyCode)287, "Toggle the limited builder cam.");
			KeyCamUp = cfg.Bind<KeyCode>("5 - Keys", "CamUp", (KeyCode)32, "Builder cam: fly up.");
			KeyCamDown = cfg.Bind<KeyCode>("5 - Keys", "CamDown", (KeyCode)306, "Builder cam: fly down.");
			KeyCamFast = cfg.Bind<KeyCode>("5 - Keys", "CamFast", (KeyCode)308, "Builder cam: hold to fly faster.");
			KeyToggleHud = cfg.Bind<KeyCode>("5 - Keys", "ToggleHud", (KeyCode)288, "Show/hide the HUD panel.");
		}

		public static float[] ParseGridSizes()
		{
			string[] array = GridSizes.Value.Split(new char[1] { ',' });
			List<float> list = new List<float>();
			string[] array2 = array;
			for (int i = 0; i < array2.Length; i++)
			{
				if (float.TryParse(array2[i].Trim(), NumberStyles.Float, CultureInfo.InvariantCulture, out var result) && result > 0.01f)
				{
					list.Add(result);
				}
			}
			if (list.Count <= 0)
			{
				return new float[3] { 0.5f, 1f, 2f };
			}
			return list.ToArray();
		}
	}
	[HarmonyPatch]
	internal static class PlacementTweaks
	{
		public static Vector3 NudgeOffset;

		public static float YawOffset;

		public static bool HeightLocked;

		public static float LockedHeight;

		public static int GridIndex = -1;

		public static string LastBlockReason;

		private static float[] _gridSizes;

		private static string _lastPieceName;

		public static float GridSize
		{
			get
			{
				if (_gridSizes == null)
				{
					_gridSizes = ModConfig.ParseGridSizes();
				}
				if (GridIndex < 0 || GridIndex >= _gridSizes.Length)
				{
					return 0f;
				}
				return _gridSizes[GridIndex];
			}
		}

		public static bool HasOffsets
		{
			get
			{
				//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)
				if (!(NudgeOffset != Vector3.zero) && !(Mathf.Abs(YawOffset) > 0.001f))
				{
					return HeightLocked;
				}
				return true;
			}
		}

		public static void ResetOffsets()
		{
			//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)
			NudgeOffset = Vector3.zero;
			YawOffset = 0f;
			HeightLocked = false;
		}

		public static void HandleInput()
		{
			//IL_002b: 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_005b: 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_006b: 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_00a5: 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_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: 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_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: 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_00de: 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_00e6: 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_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: 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)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_024a: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_028c: Unknown result type (might be due to invalid IL or missing references)
			Player val = GameState.LocalBuilder();
			if ((Object)(object)val == (Object)null || !((Character)val).InPlaceMode() || GameState.UiBlocksInput())
			{
				return;
			}
			GameObject placementGhost = val.m_placementGhost;
			float num = (GameState.KeyHeld(ModConfig.KeyFineModifier.Value) ? ModConfig.FineNudgeMultiplier.Value : 1f);
			float num2 = ModConfig.NudgeStep.Value * num;
			Vector3 val2 = CameraAxisForward();
			Vector3 val3 = default(Vector3);
			((Vector3)(ref val3))..ctor(val2.z, 0f, 0f - val2.x);
			if (GameState.KeyDown(ModConfig.KeyNudgeForward.Value))
			{
				NudgeOffset += val2 * num2;
			}
			if (GameState.KeyDown(ModConfig.KeyNudgeBack.Value))
			{
				NudgeOffset -= val2 * num2;
			}
			if (GameState.KeyDown(ModConfig.KeyNudgeRight.Value))
			{
				NudgeOffset += val3 * num2;
			}
			if (GameState.KeyDown(ModConfig.KeyNudgeLeft.Value))
			{
				NudgeOffset -= val3 * num2;
			}
			if (GameState.KeyDown(ModConfig.KeyNudgeUp.Value))
			{
				NudgeOffset += Vector3.up * num2;
			}
			if (GameState.KeyDown(ModConfig.KeyNudgeDown.Value))
			{
				NudgeOffset -= Vector3.up * num2;
			}
			float num3 = ModConfig.FineRotationStep.Value * num;
			if (GameState.KeyDown(ModConfig.KeyRotateLeft.Value))
			{
				YawOffset = Mathf.Repeat(YawOffset - num3, 360f);
			}
			if (GameState.KeyDown(ModConfig.KeyRotateRight.Value))
			{
				YawOffset = Mathf.Repeat(YawOffset + num3, 360f);
			}
			if (GameState.KeyDown(ModConfig.KeyResetOffsets.Value))
			{
				ResetOffsets();
			}
			if (GameState.KeyDown(ModConfig.KeyGridCycle.Value))
			{
				_gridSizes = ModConfig.ParseGridSizes();
				GridIndex++;
				if (GridIndex >= _gridSizes.Length)
				{
					GridIndex = -1;
				}
				ShowMessage((GridIndex < 0) ? "Grid snap: off" : $"Grid snap: {GridSize:0.##} m");
			}
			if (GameState.KeyDown(ModConfig.KeyHeightLock.Value))
			{
				if (HeightLocked)
				{
					HeightLocked = false;
					ShowMessage("Height lock: off");
				}
				else if ((Object)(object)placementGhost != (Object)null && placementGhost.activeSelf)
				{
					HeightLocked = true;
					LockedHeight = placementGhost.transform.position.y;
					ShowMessage($"Height lock: {LockedHeight:0.00} m");
				}
			}
			if (GameState.KeyDown(ModConfig.KeyMatchRotation.Value) && (Object)(object)placementGhost != (Object)null)
			{
				MatchRotationUnderCrosshair(val, placementGhost);
			}
		}

		[HarmonyPatch(typeof(Player), "UpdatePlacementGhost")]
		[HarmonyPostfix]
		private static void UpdatePlacementGhost_Postfix(Player __instance)
		{
			//IL_008b: 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_0092: 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_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: 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_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: 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_0139: 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_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			if (!ModConfig.Enabled.Value || (Object)(object)__instance != (Object)(object)Player.m_localPlayer)
			{
				return;
			}
			GameObject placementGhost = __instance.m_placementGhost;
			if ((Object)(object)placementGhost == (Object)null || !placementGhost.activeSelf)
			{
				return;
			}
			if (ModConfig.ResetOffsetsOnPieceChange.Value && ((Object)placementGhost).name != _lastPieceName)
			{
				if (_lastPieceName != null)
				{
					ResetOffsets();
				}
				_lastPieceName = ((Object)placementGhost).name;
			}
			float gridSize = GridSize;
			if (gridSize <= 0f && !HasOffsets)
			{
				LastBlockReason = null;
				return;
			}
			Transform transform = placementGhost.transform;
			Vector3 position = transform.position;
			Quaternion val = transform.rotation;
			if (Mathf.Abs(YawOffset) > 0.001f)
			{
				val = Quaternion.Euler(0f, YawOffset, 0f) * val;
			}
			if (gridSize > 0f)
			{
				position.x = Mathf.Round(position.x / gridSize) * gridSize;
				position.z = Mathf.Round(position.z / gridSize) * gridSize;
				if (ModConfig.GridSnapsHeight.Value)
				{
					position.y = Mathf.Round(position.y / gridSize) * gridSize;
				}
			}
			if (HeightLocked)
			{
				position.y = LockedHeight;
			}
			position += NudgeOffset;
			transform.SetPositionAndRotation(position, val);
			Revalidate(__instance, position);
		}

		private static void Revalidate(Player player, Vector3 pos)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: 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_002b: 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_0041: 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_005e: 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_006e: Unknown result type (might be due to invalid IL or missing references)
			LastBlockReason = null;
			if ((int)player.m_placementStatus == 0)
			{
				PlacementStatus val = (PlacementStatus)0;
				if (Vector3.Distance(((Character)player).m_eye.position, pos) > player.m_maxPlaceDistance)
				{
					val = (PlacementStatus)1;
					LastBlockReason = "Out of reach";
				}
				else if (Location.IsInsideNoBuildLocation(pos))
				{
					val = (PlacementStatus)3;
					LastBlockReason = "No-build zone";
				}
				else if (!PrivateArea.CheckAccess(pos, 0f, false, false))
				{
					val = (PlacementStatus)4;
					LastBlockReason = "Protected by a ward";
				}
				if ((int)val != 0)
				{
					player.m_placementStatus = val;
					player.SetPlacementGhostValid(false);
				}
			}
		}

		private static void MatchRotationUnderCrosshair(Player player, GameObject ghost)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0076: 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_0093: 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_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			GameCamera instance = GameCamera.instance;
			if ((Object)(object)instance == (Object)null)
			{
				return;
			}
			Transform transform = ((Component)instance).transform;
			RaycastHit val = default(RaycastHit);
			if (Physics.Raycast(transform.position, transform.forward, ref val, 50f, player.m_placeRayMask))
			{
				Piece componentInParent = ((Component)((RaycastHit)(ref val)).collider).GetComponentInParent<Piece>();
				if ((Object)(object)componentInParent == (Object)null || (Object)(object)((Component)componentInParent).gameObject == (Object)(object)ghost)
				{
					ShowMessage("Look at a building piece to match its rotation");
					return;
				}
				Quaternion rotation = ghost.transform.rotation;
				float num = ((Quaternion)(ref rotation)).eulerAngles.y - YawOffset;
				rotation = ((Component)componentInParent).transform.rotation;
				YawOffset = Mathf.Repeat(((Quaternion)(ref rotation)).eulerAngles.y - num, 360f);
				rotation = ((Component)componentInParent).transform.rotation;
				ShowMessage($"Matched rotation: {((Quaternion)(ref rotation)).eulerAngles.y:0.#}°");
			}
		}

		private static Vector3 CameraAxisForward()
		{
			//IL_001c: 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_0021: 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_0039: 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_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: 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)
			GameCamera instance = GameCamera.instance;
			Vector3 val = (((Object)(object)instance != (Object)null) ? ((Component)instance).transform.forward : Vector3.forward);
			val.y = 0f;
			if (Mathf.Abs(val.x) > Mathf.Abs(val.z))
			{
				return new Vector3(Mathf.Sign(val.x), 0f, 0f);
			}
			return new Vector3(0f, 0f, Mathf.Sign((val.z == 0f) ? 1f : val.z));
		}

		internal static void ShowMessage(string text)
		{
			MessageHud instance = MessageHud.instance;
			if (instance != null)
			{
				instance.ShowMessage((MessageType)1, text, 0, (Sprite)null, false, true);
			}
		}
	}
	[BepInPlugin("com.buildertoolkit.valheim", "Builder Toolkit", "0.1.1")]
	[BepInProcess("valheim.exe")]
	public class Plugin : BaseUnityPlugin
	{
		public const string ModGuid = "com.buildertoolkit.valheim";

		public const string ModName = "Builder Toolkit";

		public const string ModVersion = "0.1.1";

		internal static ManualLogSource Log;

		private Harmony _harmony;

		private void Awake()
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			ModConfig.Bind(((BaseUnityPlugin)this).Config);
			_harmony = new Harmony("com.buildertoolkit.valheim");
			_harmony.PatchAll(typeof(Plugin).Assembly);
			Log.LogInfo((object)"Builder Toolkit 0.1.1 loaded (client-side only).");
		}

		private void Update()
		{
			if (!ModConfig.Enabled.Value)
			{
				BuilderCam.Exit(null);
				return;
			}
			PlacementTweaks.HandleInput();
			BuilderCam.HandleInput();
			BuildHud.HandleInput();
		}

		private void OnGUI()
		{
			if (ModConfig.Enabled.Value)
			{
				BuildHud.Draw();
			}
		}

		private void OnDestroy()
		{
			BuilderCam.Exit(null);
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}