Decompiled source of ValheimTerrainTools v0.6.4

ValheimTerrainTools.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
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.Bootstrap;
using BepInEx.Configuration;
using HarmonyLib;
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(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("ValheimTerrainTools")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.6.4.0")]
[assembly: AssemblyInformationalVersion("0.6.4")]
[assembly: AssemblyProduct("ValheimTerrainTools")]
[assembly: AssemblyTitle("ValheimTerrainTools")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.6.4.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace ValheimTerrainTools
{
	internal sealed class BrushAim
	{
		private float _distance = 10f;

		internal void Reset()
		{
			_distance = 10f;
		}

		internal bool Resolve(Player player, GameObject ghost, float cameraReach, out Vector3 point)
		{
			//IL_0002: 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_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: 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_006f: 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_0076: 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_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: 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_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d0: 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_0190: Unknown result type (might be due to invalid IL or missing references)
			point = default(Vector3);
			if (!Object.op_Implicit((Object)(object)GameCamera.instance) || !Object.op_Implicit((Object)(object)player))
			{
				return false;
			}
			Transform transform = ((Component)GameCamera.instance).transform;
			Vector3 position = transform.position;
			Vector3 forward = transform.forward;
			float num = 0f;
			float num2 = cameraReach;
			if (cameraReach <= 0f)
			{
				float num3 = player.m_maxPlaceDistance + (float)(Object.op_Implicit((Object)(object)ghost) ? (ghost.GetComponent<Piece>()?.m_extraPlacementDistance ?? 0) : 0);
				Vector3 val = position - ((Character)player).GetEyePoint();
				float num4 = Vector3.Dot(val, forward);
				float num5 = num4 * num4 - ((Vector3)(ref val)).sqrMagnitude + num3 * num3;
				if (num3 <= 0f || num5 < 0f)
				{
					return false;
				}
				float num6 = Mathf.Sqrt(num5);
				num = Mathf.Max(0f, 0f - num4 - num6);
				num2 = Mathf.Min(50f, 0f - num4 + num6);
				if (num2 < num || num2 <= 0f)
				{
					return false;
				}
			}
			RaycastHit[] array = Physics.RaycastAll(position, forward, num2, Native.PlaceRayMask(player), (QueryTriggerInteraction)1);
			Array.Sort(array, (RaycastHit a, RaycastHit b) => ((RaycastHit)(ref a)).distance.CompareTo(((RaycastHit)(ref b)).distance));
			RaycastHit[] array2 = array;
			for (int num7 = 0; num7 < array2.Length; num7++)
			{
				RaycastHit val2 = array2[num7];
				if (Object.op_Implicit((Object)(object)((RaycastHit)(ref val2)).collider) && !((Component)((RaycastHit)(ref val2)).collider).transform.IsChildOf(((Component)player).transform) && (!Object.op_Implicit((Object)(object)ghost) || !((Component)((RaycastHit)(ref val2)).collider).transform.IsChildOf(ghost.transform)))
				{
					if (((RaycastHit)(ref val2)).distance < num)
					{
						return false;
					}
					point = ((RaycastHit)(ref val2)).point;
					_distance = ((RaycastHit)(ref val2)).distance;
					return true;
				}
			}
			point = position + forward * Mathf.Clamp(_distance, num, num2);
			return true;
		}
	}
	internal sealed class BrushController
	{
		private Player _player;

		private Piece _piece;

		private GameObject _ghost;

		private BrushPreview _preview;

		private readonly WheelGate _wheel = new WheelGate();

		private readonly BrushAim _aim = new BrushAim();

		private readonly RemovalHighlight _highlight = new RemovalHighlight();

		private Vector3 _aimPoint;

		private bool _hasAim;

		private float _buildHeight = 10f;

		private float _radius = 2f;

		private float _nativeRadius = 2f;

		private float _target;

		private float _yaw;

		private bool _hasTarget;

		private BrushMode _mode;

		private ObjectRemoval.Selection _removal;

		private float _scanTime;

		private float _scanRadius;

		private float _scanHeight;

		private float _scanYaw;

		private BrushShape _scanShape;

		private Vector3 _scanCenter;

		private SlopePlane _slope;

		private Settings _settings;

		private BrushCosts _costs;

		private string _problem = "";

		private bool _valid;

		private float _pressed = -9999f;

		private readonly BrushPanel _panel = new BrushPanel();

		private static bool Shift
		{
			get
			{
				if (!ZInput.GetKey((KeyCode)304, true))
				{
					return ZInput.GetKey((KeyCode)303, true);
				}
				return true;
			}
		}

		private static bool Control
		{
			get
			{
				if (!ZInput.GetKey((KeyCode)306, true))
				{
					return ZInput.GetKey((KeyCode)305, true);
				}
				return true;
			}
		}

		private static bool Alt
		{
			get
			{
				if (!ZInput.GetKey((KeyCode)308, true))
				{
					return ZInput.GetKey((KeyCode)307, true);
				}
				return true;
			}
		}

		private static bool ShapeShortcutDown
		{
			get
			{
				//IL_000a: Unknown result type (might be due to invalid IL or missing references)
				//IL_000f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0012: 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_0032: Unknown result type (might be due to invalid IL or missing references)
				KeyboardShortcut value = Plugin.Instance.ShapeShortcut.Value;
				if ((int)((KeyboardShortcut)(ref value)).MainKey != 0 && ShapeModifiersHeld())
				{
					value = Plugin.Instance.ShapeShortcut.Value;
					return ZInput.GetKeyDown(((KeyboardShortcut)(ref value)).MainKey, true);
				}
				return false;
			}
		}

		private static string ShapeKeyLabel
		{
			get
			{
				//IL_000a: Unknown result type (might be due to invalid IL or missing references)
				//IL_000f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0012: 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_004d: 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_0078: Unknown result type (might be due to invalid IL or missing references)
				KeyboardShortcut value = Plugin.Instance.ShapeShortcut.Value;
				if ((int)((KeyboardShortcut)(ref value)).MainKey == 0)
				{
					return ((object)Plugin.Instance.ShapeKey.Value/*cast due to .constrained prefix*/).ToString();
				}
				List<string> list = new List<string>();
				foreach (KeyCode modifier in ((KeyboardShortcut)(ref value)).Modifiers)
				{
					list.Add(Label(modifier));
				}
				list.Add(Label(((KeyboardShortcut)(ref value)).MainKey));
				return string.Join(" + ", list);
				unsafe static string Label(KeyCode key)
				{
					//IL_0000: Unknown result type (might be due to invalid IL or missing references)
					//IL_0006: Invalid comparison between Unknown and I4
					//IL_0008: Unknown result type (might be due to invalid IL or missing references)
					//IL_000e: Invalid comparison between Unknown and I4
					//IL_0010: Unknown result type (might be due to invalid IL or missing references)
					//IL_0016: Invalid comparison between Unknown and I4
					//IL_0018: Unknown result type (might be due to invalid IL or missing references)
					//IL_001e: Invalid comparison between Unknown and I4
					//IL_0020: Unknown result type (might be due to invalid IL or missing references)
					//IL_0026: Invalid comparison between Unknown and I4
					//IL_0028: Unknown result type (might be due to invalid IL or missing references)
					//IL_002e: Invalid comparison between Unknown and I4
					if ((int)key != 308 && (int)key != 307)
					{
						if ((int)key != 306 && (int)key != 305)
						{
							if ((int)key != 304 && (int)key != 303)
							{
								return ((object)(*(KeyCode*)(&key))/*cast due to .constrained prefix*/).ToString();
							}
							return "Shift";
						}
						return "Ctrl";
					}
					return "Alt";
				}
			}
		}

		private bool HasHeight => BrushMath.HasHeight(_mode);

		private bool FreeAim
		{
			get
			{
				if (_mode != BrushMode.Reset)
				{
					return BrushMath.IsRemoval(_mode);
				}
				return true;
			}
		}

		private bool HasCursor
		{
			get
			{
				if (!FreeAim)
				{
					return _ghost.activeSelf;
				}
				return _hasAim;
			}
		}

		private BrushShape Shape => Plugin.Instance.Shape.Value;

		private float MaximumRadius
		{
			get
			{
				if (!BrushMath.IsRemoval(_mode))
				{
					return Plugin.Instance.MaximumRadius.Value;
				}
				return Plugin.Instance.RemovalMaximumRadius.Value;
			}
		}

		private float Transition => BrushMath.Transition(_mode, Plugin.Instance.NaturalEdges.Value ? Plugin.Instance.TransitionWidth.Value : 0f);

		internal static bool Owns(Player player, Piece piece)
		{
			BrushMode mode;
			if (Object.op_Implicit((Object)(object)Plugin.Instance) && Plugin.Instance.Ready && Plugin.Instance.Enabled.Value && Object.op_Implicit((Object)(object)player) && (Object)(object)player == (Object)(object)Player.m_localPlayer && Object.op_Implicit((Object)(object)piece) && ((Character)player).InPlaceMode() && Native.RightItem((Humanoid)(object)player)?.m_shared.m_name == "$item_hoe")
			{
				return TryMode(piece, out mode);
			}
			return false;
		}

		private static bool TryMode(Piece piece, out BrushMode mode)
		{
			mode = BrushMode.Paint;
			if (!Object.op_Implicit((Object)(object)piece))
			{
				return false;
			}
			switch (Utils.GetPrefabName(((Object)((Component)piece).gameObject).name))
			{
			case "mud_road_v2":
				mode = BrushMode.Level;
				return true;
			case "raise_v2":
				mode = BrushMode.Raise;
				return true;
			case "path_v2":
			case "paved_road_v2":
				return true;
			case "vtt_smooth_ground":
				mode = BrushMode.Smooth;
				return true;
			case "vtt_move_ground":
				mode = BrushMode.Move;
				return true;
			default:
				return SmoothPiece.TryMode(Utils.GetPrefabName(((Object)((Component)piece).gameObject).name), out mode);
			}
		}

		private static bool InputReady(Player player)
		{
			if (Object.op_Implicit((Object)(object)player) && Native.TakeInput((Character)(object)player) && TerrainCamera.GameplayInput && !Plugin.Instance.FreeCamera.InputBlocked && !((Character)player).IsDead() && !((Character)player).IsTeleporting() && !((Character)player).InCutscene() && !GameCamera.InFreeFly() && !PlayerController.HasInputDelay && !Hud.IsPieceSelectionVisible() && !Hud.InRadial())
			{
				return !UnifiedPopup.IsVisible();
			}
			return false;
		}

		private static bool ShapeModifiersHeld()
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			KeyboardShortcut value = Plugin.Instance.ShapeShortcut.Value;
			foreach (KeyCode modifier in ((KeyboardShortcut)(ref value)).Modifiers)
			{
				if (!ZInput.GetKey(modifier, false))
				{
					return false;
				}
			}
			return true;
		}

		internal static bool IsShapeShortcutKey(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)
			//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_0024: 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)
			if ((int)key != 0)
			{
				KeyboardShortcut value = Plugin.Instance.ShapeShortcut.Value;
				if (key != ((KeyboardShortcut)(ref value)).MainKey || !ShapeModifiersHeld())
				{
					return key == Plugin.Instance.ShapeKey.Value;
				}
				return true;
			}
			return false;
		}

		private bool Ensure(Player player)
		{
			//IL_00e9: 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)
			Piece val = (Object.op_Implicit((Object)(object)player) ? player.GetSelectedPiece() : null);
			if (!Owns(player, val) || !Object.op_Implicit((Object)(object)Native.Ghost(player)))
			{
				return false;
			}
			if ((Object)(object)_piece != (Object)(object)val || (Object)(object)_player != (Object)(object)player || (Object)(object)_ghost != (Object)(object)Native.Ghost(player))
			{
				bool num = (Object)(object)_piece == (Object)(object)val && (Object)(object)_player == (Object)(object)player;
				bool num2 = (Object)(object)_player == (Object)(object)player;
				_preview?.Dispose();
				_highlight.Clear();
				_player = player;
				_piece = val;
				_ghost = Native.Ghost(player);
				TryMode(val, out _mode);
				_removal = null;
				_settings = (Settings)(((object)((Component)val).GetComponent<TerrainOp>()?.m_settings) ?? ((object)new Settings
				{
					m_paintCleared = false
				}));
				_nativeRadius = (SmoothPiece.TryMode(Utils.GetPrefabName(((Object)((Component)val).gameObject).name), out var _) ? SmoothPiece.Radius : ((Component)val).GetComponent<TerrainOp>().GetRadius());
				if (!num2)
				{
					_radius = _nativeRadius;
					_aim.Reset();
				}
				if (!num)
				{
					_hasTarget = false;
				}
				_preview = new BrushPreview(_ghost);
				_pressed = -9999f;
			}
			_radius = BrushMath.Clamp(_radius, 0.5f, MaximumRadius);
			return true;
		}

		internal void Reset()
		{
			_preview?.Dispose();
			_preview = null;
			_highlight.Clear();
			_panel.Hide();
			_player = null;
			_piece = null;
			_ghost = null;
			_costs = null;
			_hasTarget = false;
			_yaw = 0f;
			_pressed = -9999f;
			_removal = null;
			_hasAim = false;
			_aim.Reset();
		}

		internal void Dispose()
		{
			Reset();
			_panel.Dispose();
		}

		internal void CancelInput()
		{
			_pressed = -9999f;
			_highlight.Clear();
		}

		internal void Tick()
		{
			//IL_0064: 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_00b8: 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)
			if (!Ensure(Player.m_localPlayer))
			{
				Reset();
				return;
			}
			if (!InputReady(_player))
			{
				_pressed = -9999f;
				_highlight.Clear();
				return;
			}
			if (Shift || Control || Alt)
			{
				ZInput.GetMouseScrollWheel();
			}
			if (ShapeShortcutDown || ((int)Plugin.Instance.ShapeKey.Value != 0 && ZInput.GetKeyDown(Plugin.Instance.ShapeKey.Value, true)))
			{
				Plugin.Instance.Shape.Value = ((Plugin.Instance.Shape.Value == BrushShape.Circle) ? BrushShape.Square : BrushShape.Circle);
			}
			if (HasHeight && ZInput.GetKeyDown(Plugin.Instance.TransitionKey.Value, true))
			{
				Plugin.Instance.NaturalEdges.Value = !Plugin.Instance.NaturalEdges.Value;
			}
			if (HasHeight && ZInput.GetKeyDown(Plugin.Instance.ResetHeightKey.Value, true))
			{
				_hasTarget = _mode == BrushMode.Move;
				_target = 0f;
			}
		}

		internal bool ConsumeWheel(float wheel)
		{
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: 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_0173: 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_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01de: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			if (!InputReady(localPlayer) || !Ensure(localPlayer))
			{
				return false;
			}
			BrushWheelAction brushWheelAction = BrushControls.Wheel(Shift, Control, Alt, Shape, _mode);
			if (brushWheelAction == BrushWheelAction.None)
			{
				return false;
			}
			int num = _wheel.Step(Time.frameCount, wheel);
			if (num != 0)
			{
				switch (brushWheelAction)
				{
				case BrushWheelAction.Radius:
					_radius = BrushMath.Clamp(_radius + (float)num * Plugin.Instance.RadiusStep.Value, 0.5f, MaximumRadius);
					break;
				case BrushWheelAction.SelectionHeight:
					_buildHeight = BrushMath.Clamp(_buildHeight + (float)num * 1f, 1f, 100f);
					break;
				case BrushWheelAction.Rotation:
					_yaw = BrushGeometry.NormalizeYaw(_yaw + (float)num * Plugin.Instance.RotationStep.Value);
					if (BrushMath.IsSlope(_mode) && _hasTarget)
					{
						Vector3 val2 = GroundCenter();
						_slope = _slope.RotateAt(val2.x, val2.z, _yaw);
					}
					break;
				case BrushWheelAction.Height:
					if (_ghost.activeSelf)
					{
						EstablishHeight();
						float num2 = Plugin.Instance.HeightStep.Value * ((_mode == BrushMode.Raise) ? 1f : 0.5f);
						Vector3 val = GroundCenter();
						float num3 = ((_mode == BrushMode.Move) ? 0f : _ghost.transform.position.y);
						_target = BrushMath.Clamp(TargetAt(val) + (float)num * num2, num3 - 16f, num3 + 16f);
						if (BrushMath.IsSlope(_mode))
						{
							_slope = new SlopePlane(_mode, val.x, val.z, _target, _yaw);
						}
					}
					break;
				}
			}
			return true;
		}

		private Vector3 GroundCenter()
		{
			//IL_001b: 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_0020: 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_002b: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = (FreeAim ? _aimPoint : _ghost.transform.position);
			float y = default(float);
			if (_mode != BrushMode.RemoveBuilds && Heightmap.GetHeight(val, ref y))
			{
				val.y = y;
			}
			return val;
		}

		private void EstablishHeight()
		{
			//IL_001e: 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_005d: 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)
			if (!_hasTarget && HasHeight)
			{
				_target = ((_mode == BrushMode.Move) ? 0.25f : (GroundCenter().y + ((_mode == BrushMode.Raise) ? 2f : 0f)));
				if (BrushMath.IsSlope(_mode))
				{
					Vector3 val = GroundCenter();
					_slope = new SlopePlane(_mode, val.x, val.z, _target, _yaw);
				}
				_hasTarget = true;
			}
		}

		private float TargetAt(Vector3 center)
		{
			//IL_001a: 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)
			if (!BrushMath.IsSlope(_mode))
			{
				return _target;
			}
			return _slope.At(center.x, center.z);
		}

		private void Evaluate()
		{
			//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0211: Unknown result type (might be due to invalid IL or missing references)
			//IL_0246: Unknown result type (might be due to invalid IL or missing references)
			//IL_0247: Unknown result type (might be due to invalid IL or missing references)
			if (FreeAim)
			{
				_hasAim = _aim.Resolve(_player, _ghost, Plugin.Instance.FreeCamera.For(_player) ? Plugin.Instance.FreeCamera.Reach : 0f, out _aimPoint);
			}
			if (_ghost.activeSelf)
			{
				EstablishHeight();
			}
			_costs = new BrushCosts(_player, _piece, _radius + Transition, _nativeRadius, Shape);
			bool flag = BrushMath.IsRemoval(_mode);
			_valid = (FreeAim ? _hasAim : (_ghost.activeSelf && (int)Native.Status(_player) == 0));
			_problem = (_valid ? "" : (FreeAim ? "Aim within Hoe reach, or use the free camera." : (Plugin.Instance.FreeCamera.Active ? "Aim at loaded ground within camera reach." : "Aim at ground within Hoe reach.")));
			if (_valid)
			{
				_valid = (flag ? TerrainEditor.CheckObjectFootprint(GroundCenter(), _radius, out _problem, Shape, _yaw) : TerrainEditor.CheckFootprint(GroundCenter(), _radius, Shape, flash: false, out _problem, _yaw, Transition)) && _costs.Validate(out _problem);
			}
			if (_valid && flag)
			{
				Vector3 val = GroundCenter();
				bool flag2 = !((Vector3)(ref val)).Equals(_scanCenter);
				if (_removal == null || flag2 || Time.unscaledTime - _scanTime >= 0.2f || _scanRadius != _radius || _scanHeight != _buildHeight || _scanShape != Shape || _scanYaw != _yaw)
				{
					_removal = ObjectRemoval.Scan(val, _radius, _mode, _buildHeight, Shape, _yaw);
					_scanTime = Time.unscaledTime;
					_scanCenter = val;
					_scanRadius = _radius;
					_scanHeight = _buildHeight;
					_scanShape = Shape;
					_scanYaw = _yaw;
				}
			}
		}

		internal void DrawPreview()
		{
			//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_005e: 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)
			if (!Ensure(Player.m_localPlayer))
			{
				Reset();
				return;
			}
			if (!InputReady(_player))
			{
				_preview.Hide();
				_panel.Hide();
				_highlight.Clear();
				return;
			}
			Evaluate();
			if (HasCursor)
			{
				Vector3 center = GroundCenter();
				_preview.Show(center, _radius, Shape, _mode, TargetAt(center), _valid, _yaw, Transition, _buildHeight);
			}
			else
			{
				_preview.Hide();
			}
			if (_valid && BrushMath.IsRemoval(_mode))
			{
				_highlight.Show(_removal);
			}
			else
			{
				_highlight.Clear();
			}
			UpdatePanel();
		}

		internal bool HandleInput(Player player, bool takeInput)
		{
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: 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_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_02be: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0305: Unknown result type (might be due to invalid IL or missing references)
			//IL_030b: Unknown result type (might be due to invalid IL or missing references)
			if (!Ensure(player))
			{
				return false;
			}
			Native.PlacePressed(player) = -9999f;
			if (!takeInput || !InputReady(player) || ZInput.GetButtonDown("BuildMenu") || ZInput.GetKeyDown((KeyCode)27, true))
			{
				_pressed = -9999f;
				return false;
			}
			if (ZInput.GetButtonDown("Attack") || ZInput.GetButtonDown("JoyPlace"))
			{
				_pressed = Time.time;
			}
			if (Time.time - _pressed >= 0.2f)
			{
				return false;
			}
			if (Time.time - Native.LastToolUse(player) <= player.m_placeDelay)
			{
				return true;
			}
			_pressed = -9999f;
			if (ZInput.GetButton("JoyAltKeys"))
			{
				return true;
			}
			Native.UpdateGhost(player, arg2: true);
			if (!Ensure(player))
			{
				return true;
			}
			Evaluate();
			if (!_valid)
			{
				((Character)player).Message((MessageType)2, _problem, 0, (Sprite)null, false);
				return true;
			}
			Vector3 val = GroundCenter();
			BrushCosts costs = _costs;
			int num = 0;
			bool flag;
			try
			{
				string problem;
				Func<bool> stillValid = () => InputReady(player) && Owns(player, _piece) && costs.Validate(out problem);
				if (BrushMath.IsRemoval(_mode))
				{
					_highlight.Clear();
					num = ObjectRemoval.Apply(val, _radius, _mode, stillValid, _buildHeight, Shape, _yaw);
					flag = num > 0;
					_removal = null;
				}
				else
				{
					flag = TerrainEditor.Apply(val, _radius, Shape, _mode, TargetAt(val), _settings, stillValid, _yaw, Transition);
				}
			}
			catch (InvalidOperationException ex)
			{
				((Character)player).Message((MessageType)2, ex.Message, 0, (Sprite)null, false);
				return true;
			}
			if (!flag)
			{
				((Character)player).Message((MessageType)1, BrushMath.IsRemoval(_mode) ? "No removable objects. Active Wards and protected objects are skipped. Nothing consumed." : ((_mode == BrushMode.Reset) ? "Terrain is already original. Nothing consumed." : "No terrain change: already at the target or terrain limit. Nothing consumed."), 0, (Sprite)null, false);
				return true;
			}
			costs.Pay();
			Native.LastToolUse(player) = Time.time;
			if (num > 0)
			{
				((Character)player).Message((MessageType)1, "Removed " + num + " objects. No drops or materials returned.", 0, (Sprite)null, false);
			}
			player.FaceLookDirection();
			Native.Animation((Character)(object)player).SetTrigger(costs.Tool.m_shared.m_attack.m_attackAnimation);
			costs.Tool.m_shared.m_buildEffect.Create(((Component)player).transform.position, Quaternion.identity, (Transform)null, 1f, -1, ((Character)player).GetZDOID());
			TerrainOp component = ((Component)_piece).GetComponent<TerrainOp>();
			if (component != null)
			{
				component.m_onPlacedEffect.Create(val, Quaternion.identity, (Transform)null, 1f, -1, default(ZDOID));
			}
			if (Object.op_Implicit((Object)(object)Hud.instance))
			{
				Hud.instance.m_buildUi.AddRecentPiece(_piece);
			}
			return true;
		}

		private void UpdatePanel()
		{
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: 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_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: 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)
			Plugin instance = Plugin.Instance;
			if (!instance.ShowPanel.Value)
			{
				_panel.Hide();
			}
			else
			{
				_panel.Show(_piece.m_icon, (_mode == BrushMode.Smooth) ? "Smooth ground" : Localization.instance.Localize(_piece.m_name), Shape, _radius, (HasHeight && _hasTarget) ? new float?(TargetAt(GroundCenter())) : ((float?)null), HasHeight, _costs.Free ? "Free building · no costs" : (BrushCosts.Number(_costs.Factor) + "× area costs"), _costs.Free ? "No materials, stamina or durability consumed." : _costs.Describe(), (!_valid) ? _problem : ((!BrushMath.IsRemoval(_mode)) ? ((_mode == BrushMode.Reset) ? "Restore height and ground cover inside the selection" : "Ready to apply") : (_removal?.Summary ?? "Checking objects")), _valid, ShapeKeyLabel, ((object)instance.ResetHeightKey.Value/*cast due to .constrained prefix*/).ToString(), instance.PanelScale.Value, _yaw, _mode == BrushMode.Move, Transition, ((object)instance.TransitionKey.Value/*cast due to .constrained prefix*/).ToString(), ((object)instance.CameraKey.Value/*cast due to .constrained prefix*/).ToString(), instance.FreeCamera.Hint, BrushMath.IsSlope(_mode), _mode == BrushMode.Reset, _mode == BrushMode.RemoveNature, _mode == BrushMode.RemoveBuilds, _buildHeight);
			}
		}

		internal void UpdateCostHud(Hud hud, Piece piece)
		{
			//IL_00f1: 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)
			if (!Owns(Player.m_localPlayer, piece) || !Ensure(Player.m_localPlayer))
			{
				return;
			}
			BrushCosts brushCosts = new BrushCosts(_player, piece, _radius + Transition, _nativeRadius, Shape);
			for (int i = 0; i < Math.Min(piece.m_resources.Length, hud.m_requirementItems.Length); i++)
			{
				Requirement val = piece.m_resources[i];
				if (!((Object)(object)val?.m_resItem == (Object)null))
				{
					GameObject obj = hud.m_requirementItems[i];
					object obj2;
					if (obj == null)
					{
						obj2 = null;
					}
					else
					{
						Transform obj3 = obj.transform.Find("res_amount");
						obj2 = ((obj3 != null) ? ((Component)obj3).GetComponent<TMP_Text>() : null);
					}
					TMP_Text val2 = (TMP_Text)obj2;
					if (Object.op_Implicit((Object)(object)val2))
					{
						long num = BrushMath.MaterialCost(val.GetAmount(0), brushCosts.Factor);
						val2.text = num.ToString();
						((Graphic)val2).color = ((!brushCosts.Free && ((Humanoid)_player).GetInventory().CountItems(val.m_resItem.m_itemData.m_shared.m_name, -1, true) < num) ? Color.red : Color.white);
					}
				}
			}
		}
	}
	[HarmonyPatch(typeof(Hud), "SetupPieceInfo")]
	internal static class CostHudPatch
	{
		private static void Postfix(Hud __instance, Piece piece)
		{
			Plugin.Instance?.Brush.UpdateCostHud(__instance, piece);
		}
	}
	internal sealed class BrushCosts
	{
		internal readonly Player Player;

		internal readonly Piece Piece;

		internal readonly ItemData Tool;

		internal readonly bool Free;

		internal readonly double Factor;

		internal readonly float Stamina;

		internal readonly float Durability;

		internal readonly Dictionary<string, long> Materials = new Dictionary<string, long>(StringComparer.Ordinal);

		internal BrushCosts(Player player, Piece piece, float radius, float nativeRadius, BrushShape shape)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			Player = player;
			Piece = piece;
			Tool = Native.RightItem((Humanoid)(object)player);
			Free = player.NoCostCheat() || ZoneSystem.instance.GetGlobalKey(piece.FreeBuildKey());
			Factor = (Plugin.Instance.ScaleCosts.Value ? BrushMath.AreaFactor(radius, nativeRadius, shape) : 1.0);
			Requirement[] resources = piece.m_resources;
			foreach (Requirement val in resources)
			{
				if (!((Object)(object)val?.m_resItem == (Object)null))
				{
					string name = val.m_resItem.m_itemData.m_shared.m_name;
					Materials.TryGetValue(name, out var value);
					Materials[name] = checked(value + BrushMath.MaterialCost(val.GetAmount(0), Factor));
				}
			}
			Stamina = (Free ? 0f : ((float)((double)Math.Max(0f, Native.BuildStamina(player)) * Factor)));
			Durability = ((Free || !Tool.m_shared.m_useDurability) ? 0f : ((float)((double)Math.Max(0f, Native.PlaceDurability(player, Tool) * Game.m_durabilityRate) * Factor)));
		}

		internal bool Validate(out string problem)
		{
			//IL_006b: 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)
			problem = "";
			if (!Object.op_Implicit((Object)(object)Player) || Native.RightItem((Humanoid)(object)Player) != Tool || (Object)(object)Player.GetSelectedPiece() != (Object)(object)Piece)
			{
				problem = "The selected tool changed.";
				return false;
			}
			if (Free != (Player.NoCostCheat() || ZoneSystem.instance.GetGlobalKey(Piece.FreeBuildKey())))
			{
				problem = "Free building changed. Try again.";
				return false;
			}
			if (!Player.NoCostCheat() && Object.op_Implicit((Object)(object)Piece.m_craftingStation) && !Object.op_Implicit((Object)(object)CraftingStation.HaveBuildStationInRange(Piece.m_craftingStation.m_name, ((Component)Player).transform.position)) && !ZoneSystem.instance.GetGlobalKey((GlobalKeys)27))
			{
				problem = "A nearby crafting station is required.";
				return false;
			}
			if (!string.IsNullOrEmpty(Piece.m_dlc) && !DLCMan.instance.IsDLCInstalled(Piece.m_dlc))
			{
				problem = "This terrain tool requires its DLC.";
				return false;
			}
			if (Free)
			{
				return true;
			}
			if (!BrushMath.Finite(Stamina) || !BrushMath.Finite(Durability))
			{
				problem = "Invalid Hoe costs.";
				return false;
			}
			foreach (KeyValuePair<string, long> material in Materials)
			{
				if (((Humanoid)Player).GetInventory().CountItems(material.Key, -1, true) < material.Value)
				{
					problem = "Not enough materials. Reduce the brush size.";
					return false;
				}
			}
			if (Player.GetStamina() + 0.001f < Stamina)
			{
				problem = "Not enough stamina. Reduce the brush size or wait.";
				return false;
			}
			if (Tool.m_shared.m_useDurability && (Tool.m_durability <= 0f || Tool.m_durability + 0.001f < Durability))
			{
				problem = "Not enough Hoe durability. Reduce the brush size or repair.";
				return false;
			}
			return true;
		}

		internal void Pay()
		{
			if (Free)
			{
				return;
			}
			foreach (KeyValuePair<string, long> material in Materials)
			{
				if (material.Value > 0)
				{
					((Humanoid)Player).GetInventory().RemoveItem(material.Key, checked((int)material.Value), -1, true);
				}
			}
			if (Stamina > 0f)
			{
				((Character)Player).UseStamina(Stamina);
			}
			if (Tool.m_shared.m_useDurability)
			{
				Tool.m_durability = Mathf.Max(0f, Tool.m_durability - Durability);
			}
		}

		internal string Describe()
		{
			if (Free)
			{
				return "Free building: no materials, stamina or durability consumed.";
			}
			StringBuilder stringBuilder = new StringBuilder();
			foreach (KeyValuePair<string, long> material in Materials)
			{
				if (material.Value > 0)
				{
					stringBuilder.Append(Localization.instance.Localize(material.Key)).Append(": ").Append(material.Value)
						.Append(" / ")
						.Append(((Humanoid)Player).GetInventory().CountItems(material.Key, -1, true))
						.Append("   ");
				}
			}
			if (stringBuilder.Length > 0)
			{
				stringBuilder.Append('\n');
			}
			stringBuilder.Append("Stamina: ").Append(Number(Stamina)).Append(" / ")
				.Append(Number(Player.GetStamina()));
			if (Tool.m_shared.m_useDurability)
			{
				stringBuilder.Append("   Durability: ").Append(Number(Durability)).Append(" / ")
					.Append(Number(Tool.m_durability));
			}
			return stringBuilder.ToString();
		}

		internal static string Number(double value)
		{
			return value.ToString("0.##", CultureInfo.InvariantCulture);
		}
	}
	internal readonly struct BrushGeometry
	{
		internal readonly float Radius;

		internal readonly float Yaw;

		internal readonly BrushShape Shape;

		private readonly float _sin;

		private readonly float _cos;

		internal float Extent => ExtentAt(Radius);

		internal float BoundingRadius
		{
			get
			{
				if (Shape != BrushShape.Square)
				{
					return Radius;
				}
				return Radius * 1.414214f;
			}
		}

		internal BrushGeometry(float radius, BrushShape shape, float yaw = 0f)
		{
			Radius = radius;
			Shape = shape;
			Yaw = NormalizeYaw(yaw);
			double num = (double)Yaw * Math.PI / 180.0;
			_sin = (float)Math.Sin(num);
			_cos = (float)Math.Cos(num);
		}

		internal static float NormalizeYaw(float yaw)
		{
			if (!BrushMath.Finite(yaw))
			{
				throw new ArgumentException("Invalid brush rotation.");
			}
			float num = yaw % 360f;
			if (!(num < 0f))
			{
				return num;
			}
			return num + 360f;
		}

		internal float ExtentAt(float radius)
		{
			if (Shape != BrushShape.Square)
			{
				return radius;
			}
			return radius * (Math.Abs(_cos) + Math.Abs(_sin));
		}

		internal void ToWorld(float localX, float localZ, out float worldX, out float worldZ)
		{
			worldX = localX * _cos + localZ * _sin;
			worldZ = (0f - localX) * _sin + localZ * _cos;
		}

		internal void ToLocal(float worldX, float worldZ, out float localX, out float localZ)
		{
			localX = worldX * _cos - worldZ * _sin;
			localZ = worldX * _sin + worldZ * _cos;
		}

		internal float Distance(float dx, float dz)
		{
			if (Shape == BrushShape.Circle)
			{
				return BrushMath.Distance(dx, dz, Shape);
			}
			ToLocal(dx, dz, out var localX, out var localZ);
			return BrushMath.Distance(localX, localZ, Shape);
		}

		internal bool Inside(float dx, float dz)
		{
			return Distance(dx, dz) <= Radius + 0.0001f;
		}

		internal float Weight(float dx, float dz)
		{
			if (Shape == BrushShape.Circle)
			{
				return BrushMath.Weight(dx, dz, Radius, Shape);
			}
			ToLocal(dx, dz, out var localX, out var localZ);
			return BrushMath.Weight(localX, localZ, Radius, Shape);
		}
	}
	internal readonly struct SlopePlane
	{
		private readonly BrushMode _mode;

		private readonly float _x;

		private readonly float _z;

		private readonly float _height;

		private readonly BrushGeometry _direction;

		internal SlopePlane(BrushMode mode, float x, float z, float height, float yaw)
		{
			_mode = mode;
			_x = x;
			_z = z;
			_height = height;
			_direction = new BrushGeometry(1f, BrushShape.Circle, yaw);
		}

		internal float At(float x, float z)
		{
			return _height + BrushMath.SlopeRise(_mode, _direction, x - _x, z - _z);
		}

		internal SlopePlane RotateAt(float x, float z, float yaw)
		{
			return new SlopePlane(_mode, x, z, At(x, z), yaw);
		}
	}
	internal readonly struct TerrainBounds
	{
		internal readonly int MinX;

		internal readonly int MinZ;

		internal readonly int MaxX;

		internal readonly int MaxZ;

		internal int Width => MaxX - MinX + 1;

		internal int Height => MaxZ - MinZ + 1;

		internal TerrainBounds(int minX, int minZ, int maxX, int maxZ)
		{
			MinX = minX;
			MinZ = minZ;
			MaxX = maxX;
			MaxZ = maxZ;
		}

		internal static TerrainBounds ForBrush(float x, float z, BrushGeometry brush)
		{
			float num = brush.ExtentAt(brush.Radius + 2f);
			return new TerrainBounds((int)Math.Floor(x - num) - 1, (int)Math.Floor(z - num) - 1, (int)Math.Ceiling(x + num) + 1, (int)Math.Ceiling(z + num) + 1);
		}
	}
	internal enum BrushWheelAction
	{
		None,
		Radius,
		Height,
		Rotation,
		SelectionHeight
	}
	internal static class BrushControls
	{
		internal static BrushWheelAction Wheel(bool shift, bool control, bool alt, BrushShape shape, BrushMode mode)
		{
			if (shift)
			{
				return BrushWheelAction.Radius;
			}
			if (control && mode == BrushMode.RemoveBuilds)
			{
				return BrushWheelAction.SelectionHeight;
			}
			if (control && BrushMath.HasHeight(mode))
			{
				return BrushWheelAction.Height;
			}
			if (alt && (shape == BrushShape.Square || BrushMath.IsSlope(mode)))
			{
				return BrushWheelAction.Rotation;
			}
			return BrushWheelAction.None;
		}
	}
	public enum BrushShape
	{
		Circle,
		Square
	}
	internal enum BrushMode
	{
		Level,
		Raise,
		Smooth,
		Paint,
		Move,
		Slope26,
		Slope45,
		Slope67,
		Reset,
		RemoveNature,
		RemoveBuilds
	}
	internal static class BrushMath
	{
		internal const float TerrainLimit = 8f;

		internal const float MaximumTransition = 10f;

		internal const float MaximumRemovalRadius = 50f;

		internal static bool IsRemoval(BrushMode mode)
		{
			if (mode != BrushMode.RemoveNature)
			{
				return mode == BrushMode.RemoveBuilds;
			}
			return true;
		}

		internal static int SlopeAngle(BrushMode mode)
		{
			return mode switch
			{
				BrushMode.Slope67 => 67, 
				BrushMode.Slope45 => 45, 
				BrushMode.Slope26 => 26, 
				_ => 0, 
			};
		}

		internal static bool IsSlope(BrushMode mode)
		{
			return SlopeAngle(mode) != 0;
		}

		internal static bool HasHeight(BrushMode mode)
		{
			if (mode != BrushMode.Level && mode != BrushMode.Raise && mode != BrushMode.Move)
			{
				return IsSlope(mode);
			}
			return true;
		}

		internal static float SlopeRise(BrushMode mode, BrushGeometry brush, float dx, float dz)
		{
			brush.ToLocal(dx, dz, out var _, out var localZ);
			return localZ * (float)Math.Tan((double)SlopeAngle(mode) * Math.PI / 180.0);
		}

		internal static float Transition(BrushMode mode, float width)
		{
			if (!HasHeight(mode))
			{
				return 0f;
			}
			return width;
		}

		internal static float TransitionWeight(float distance, float radius, float width)
		{
			if (!(distance <= radius))
			{
				if (!(width > 0f))
				{
					return 0f;
				}
				return 1f - Ease((distance - radius) / width);
			}
			return 1f;
		}

		internal static float Desired(float current, float edge, float target, BrushMode mode, BrushGeometry brush, float dx, float dz, float transition)
		{
			float num = TransitionWeight(brush.Distance(dx, dz), brush.Radius, transition);
			switch (mode)
			{
			case BrushMode.Move:
				return current + target * num;
			case BrushMode.Level:
				return current + (target - current) * num;
			default:
				if (IsSlope(mode))
				{
					return current + (target + SlopeRise(mode, brush, dx, dz) - current) * num;
				}
				if (mode == BrushMode.Raise)
				{
					return Raise(current, edge, target, new BrushGeometry(brush.Radius + transition, brush.Shape, brush.Yaw).Weight(dx, dz));
				}
				return current;
			}
		}

		internal static bool Finite(float n)
		{
			if (!float.IsNaN(n))
			{
				return !float.IsInfinity(n);
			}
			return false;
		}

		internal static float Clamp(float n, float lo, float hi)
		{
			return Math.Max(lo, Math.Min(hi, n));
		}

		internal static float Distance(float x, float z, BrushShape shape)
		{
			if (shape != BrushShape.Square)
			{
				return (float)Math.Sqrt(x * x + z * z);
			}
			return Math.Max(Math.Abs(x), Math.Abs(z));
		}

		internal static bool Inside(float x, float z, float radius, BrushShape shape)
		{
			return Distance(x, z, shape) <= radius + 0.0001f;
		}

		internal static float Ease(float x)
		{
			x = Clamp(x, 0f, 1f);
			return x * x * x * (x * (x * 6f - 15f) + 10f);
		}

		internal static float Weight(float x, float z, float radius, BrushShape shape)
		{
			if (shape == BrushShape.Square)
			{
				return (1f - Ease(Math.Abs(x) / radius)) * (1f - Ease(Math.Abs(z) / radius));
			}
			return 1f - Ease(Distance(x, z, shape) / radius);
		}

		internal static float Raise(float oldHeight, float edgeHeight, float target, float weight)
		{
			if (weight <= 0f)
			{
				return oldHeight;
			}
			float val = edgeHeight + (target - edgeHeight) * weight;
			return Math.Max(oldHeight, Math.Min(target, val));
		}

		internal static float Limit(float desired, float baseHeight)
		{
			return Clamp(desired, baseHeight - 8f, baseHeight + 8f);
		}

		internal static float Delta(float desired, float beforeCompiler, float baseHeight)
		{
			return Limit(desired, baseHeight) - beforeCompiler;
		}

		internal static double AreaFactor(float radius, float nativeRadius, BrushShape shape)
		{
			if (!(radius >= 0.5f) || !(radius <= 50f) || !(nativeRadius >= 0.5f) || !(nativeRadius <= 20f))
			{
				throw new ArgumentOutOfRangeException("radius");
			}
			decimal num = (decimal)radius / (decimal)nativeRadius;
			return (double)(num * num) * ((shape == BrushShape.Square) ? (4.0 / Math.PI) : 1.0);
		}

		internal static long MaterialCost(int native, double factor)
		{
			if (native > 0)
			{
				return (long)decimal.Ceiling((decimal)native * (decimal)factor);
			}
			return 0L;
		}

		internal static float[] Smooth(float[] original, int width, int height, float originX, float originZ, float step, float centerX, float centerZ, float radius, BrushShape shape, float strength, int passes, float yaw = 0f)
		{
			BrushGeometry brushGeometry = new BrushGeometry(radius, shape, yaw);
			float[] array = (float[])original.Clone();
			float[] array2 = (float[])original.Clone();
			int[] array3 = new int[5] { 1, 4, 6, 4, 1 };
			for (int i = 0; i < passes; i++)
			{
				for (int j = 2; j < height - 2; j++)
				{
					for (int k = 2; k < width - 2; k++)
					{
						float num = brushGeometry.Distance(originX + (float)k * step - centerX, originZ + (float)j * step - centerZ);
						if (num >= radius)
						{
							continue;
						}
						double num2 = 0.0;
						for (int l = -2; l <= 2; l++)
						{
							for (int m = -2; m <= 2; m++)
							{
								num2 += (double)(array[(j + l) * width + k + m] * (float)array3[l + 2] * (float)array3[m + 2]);
							}
						}
						float num3 = 1f - Ease((num / radius - 0.7f) / 0.3f);
						int num4 = j * width + k;
						array2[num4] = array[num4] + ((float)(num2 / 256.0) - array[num4]) * strength * num3;
					}
				}
				float[] array4 = array;
				array = array2;
				array2 = array4;
			}
			return array;
		}
	}
	internal sealed class WheelGate
	{
		private int _frame = -1;

		internal int Step(int frame, float wheel)
		{
			if (_frame == frame || !BrushMath.Finite(wheel) || wheel == 0f)
			{
				return 0;
			}
			_frame = frame;
			return Math.Sign(wheel);
		}
	}
	internal sealed class BrushPanel : IDisposable
	{
		private static readonly Color Gold = new Color(1f, 0.76f, 0.38f);

		private static readonly Color Ivory = new Color(0.94f, 0.91f, 0.82f);

		private static readonly Color Muted = new Color(0.69f, 0.68f, 0.61f);

		private const float Width = 410f;

		private const float Inner = 374f;

		private Hud _hud;

		private RectTransform _root;

		private RectTransform _canvas;

		private Image _icon;

		private Image _bottom;

		private Image _statusBar;

		private TMP_Text _title;

		private TMP_Text _shape;

		private TMP_Text _sizeCaption;

		private TMP_Text _size;

		private TMP_Text _heightCaption;

		private TMP_Text _height;

		private TMP_Text _cameraHint;

		private TMP_Text _costTitle;

		private TMP_Text _costs;

		private TMP_Text _status;

		private TMP_Text _warning;

		private readonly TMP_Text[] _keys = (TMP_Text[])(object)new TMP_Text[8];

		private readonly TMP_Text[] _actions = (TMP_Text[])(object)new TMP_Text[8];

		private readonly Image[] _keyCaps = (Image[])(object)new Image[8];

		private bool Ensure()
		{
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Expected O, but got Unknown
			//IL_00e5: 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_013a: 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)
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_0214: Unknown result type (might be due to invalid IL or missing references)
			//IL_025d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0287: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0323: Unknown result type (might be due to invalid IL or missing references)
			//IL_0355: Unknown result type (might be due to invalid IL or missing references)
			//IL_0387: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0429: Unknown result type (might be due to invalid IL or missing references)
			//IL_0462: Unknown result type (might be due to invalid IL or missing references)
			//IL_04bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0500: Unknown result type (might be due to invalid IL or missing references)
			//IL_058a: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_060b: Unknown result type (might be due to invalid IL or missing references)
			//IL_063d: Unknown result type (might be due to invalid IL or missing references)
			//IL_066f: Unknown result type (might be due to invalid IL or missing references)
			//IL_069a: Unknown result type (might be due to invalid IL or missing references)
			//IL_06cb: Unknown result type (might be due to invalid IL or missing references)
			Hud instance = Hud.instance;
			if (!Object.op_Implicit((Object)(object)instance) || !Object.op_Implicit((Object)(object)instance.m_buildHud) || !Object.op_Implicit((Object)(object)instance.m_buildSelection) || !Object.op_Implicit((Object)(object)instance.m_pieceDescription) || !Object.op_Implicit((Object)(object)instance.m_buildSelection.font) || !Object.op_Implicit((Object)(object)instance.m_pieceDescription.font))
			{
				return false;
			}
			Canvas componentInParent = instance.m_buildHud.GetComponentInParent<Canvas>();
			if (!Object.op_Implicit((Object)(object)componentInParent))
			{
				return false;
			}
			if (Object.op_Implicit((Object)(object)_root) && (Object)(object)_hud == (Object)(object)instance && (Object)(object)_canvas == (Object)(object)((Component)componentInParent).transform)
			{
				return true;
			}
			Dispose();
			_hud = instance;
			_canvas = (RectTransform)((Component)componentInParent).transform;
			_root = new GameObject("VTT brush panel", new Type[2]
			{
				typeof(RectTransform),
				typeof(CanvasGroup)
			}).GetComponent<RectTransform>();
			((Component)_root).gameObject.SetActive(false);
			((Transform)_root).SetParent((Transform)(object)_canvas, false);
			RectTransform root = _root;
			RectTransform root2 = _root;
			Vector2 val = default(Vector2);
			((Vector2)(ref val))..ctor(1f, 0.48f);
			root2.anchorMax = val;
			root.anchorMin = val;
			_root.pivot = new Vector2(1f, 0.5f);
			_root.anchoredPosition = new Vector2(-24f, 0f);
			CanvasGroup component = ((Component)_root).GetComponent<CanvasGroup>();
			component.interactable = false;
			component.blocksRaycasts = false;
			Image obj = ((Component)_root).gameObject.AddComponent<Image>();
			((Graphic)obj).color = new Color(0.045f, 0.038f, 0.026f, 0.95f);
			((Graphic)obj).raycastTarget = false;
			Box("Header", 0f, 0f, 410f, 88f, new Color(0.16f, 0.12f, 0.065f, 0.7f));
			Box("Top edge", 0f, 0f, 410f, 2f, Gold);
			_bottom = Box("Bottom edge", 0f, 400f, 410f, 1f, new Color(Gold.r, Gold.g, Gold.b, 0.5f));
			_icon = Box("Tool", 18f, 25f, 46f, 46f, Color.white);
			_icon.preserveAspect = true;
			Label("Terrain tools", "TERRAIN TOOLS", 80f, 13f, 312f, 20f, 14, Muted);
			_title = Label("Action", "", 80f, 34f, 312f, 38f, 26, Gold, title: true);
			_shape = Label("Shape", "", 18f, 100f, 374f, 23f, 17, Ivory);
			_sizeCaption = Label("Size label", "", 18f, 133f, 174f, 20f, 14, Muted);
			_size = Label("Size", "", 18f, 155f, 174f, 35f, 28, Gold);
			_heightCaption = Label("Height label", "TARGET HEIGHT", 224f, 133f, 168f, 20f, 14, Muted);
			_height = Label("Height", "", 224f, 155f, 168f, 35f, 28, Gold);
			Box("Metric divider", 207f, 139f, 1f, 45f, new Color(0.4f, 0.32f, 0.19f, 0.7f));
			Box("Controls divider", 18f, 201f, 374f, 1f, new Color(0.4f, 0.32f, 0.19f, 0.7f));
			for (int i = 0; i < _keys.Length; i++)
			{
				_keyCaps[i] = Box("Key background " + i, 18f, 214 + i * 29, 136f, 24f, new Color(0.22f, 0.19f, 0.13f, 0.9f));
				_keys[i] = Label("Key " + i, "", 22f, 214 + i * 29, 128f, 24f, 15, Ivory);
				_keys[i].alignment = (TextAlignmentOptions)514;
				_keys[i].enableAutoSizing = true;
				_keys[i].fontSizeMin = 9f;
				_keys[i].fontSizeMax = 15f;
				_actions[i] = Label("Control " + i, "", 167f, 214 + i * 29, 225f, 24f, 17, Ivory);
			}
			_cameraHint = Label("Camera controls", "", 18f, 372f, 374f, 48f, 16, Muted);
			_warning = Label("Removal warning", "WARNING: NO MATERIALS RETURNED\nBuildings and chest contents are permanently deleted without drops.", 18f, 372f, 374f, 72f, 18, new Color(1f, 0.53f, 0.3f));
			_costTitle = Label("Cost title", "", 18f, 372f, 374f, 24f, 18, Gold);
			_costs = Label("Costs", "", 18f, 400f, 374f, 56f, 16, Muted);
			_statusBar = Box("Status accent", 18f, 466f, 3f, 24f, Gold);
			_status = Label("Status", "", 29f, 466f, 363f, 42f, 17, Ivory);
			((Component)_root).gameObject.SetActive(false);
			return true;
		}

		internal void Show(Sprite icon, string title, BrushShape shape, float radius, float? target, bool heightMode, string costTitle, string costs, string status, bool valid, string shapeKey, string resetKey, float userScale, float yaw = 0f, bool moveMode = false, float transition = 0f, string transitionKey = "F7", string cameraKey = "F3", string cameraHint = "", bool slopeMode = false, bool resetMode = false, bool removeNature = false, bool removeBuilds = false, float selectionHeight = 10f)
		{
			//IL_040f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0531: Unknown result type (might be due to invalid IL or missing references)
			//IL_0499: Unknown result type (might be due to invalid IL or missing references)
			//IL_059b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0585: Unknown result type (might be due to invalid IL or missing references)
			//IL_05a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_05bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_05bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_05be: Unknown result type (might be due to invalid IL or missing references)
			//IL_05c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_05e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0652: Unknown result type (might be due to invalid IL or missing references)
			//IL_068b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0690: Unknown result type (might be due to invalid IL or missing references)
			//IL_06ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_06b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_06d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_06e5: Unknown result type (might be due to invalid IL or missing references)
			if (Ensure())
			{
				((Component)_root).gameObject.SetActive(true);
				_icon.sprite = icon;
				((Behaviour)_icon).enabled = Object.op_Implicit((Object)(object)icon);
				_title.text = title;
				_shape.text = ((shape == BrushShape.Circle) ? "Circle selection" : ("Square selection · " + Number(BrushGeometry.NormalizeYaw(yaw)) + "°"));
				if (slopeMode)
				{
					_shape.text = ((shape == BrushShape.Circle) ? "Circle" : "Square") + " · uphill " + Number(BrushGeometry.NormalizeYaw(yaw)) + "°";
				}
				_sizeCaption.text = ((shape == BrushShape.Circle) ? "RADIUS" : "HALF-WIDTH");
				_size.text = Number(radius) + " m";
				_heightCaption.text = (resetMode ? "RESTORE" : (slopeMode ? "CENTRE HEIGHT" : (moveMode ? "CHANGE PER CLICK" : (heightMode ? "TARGET HEIGHT" : "SURFACE"))));
				_height.text = ((!heightMode) ? "Follow ground" : (target.HasValue ? (target.Value.ToString(moveMode ? "+0.###;-0.###;0" : "0.###", CultureInfo.InvariantCulture) + " m") : "Aim at ground"));
				_height.fontSize = ((heightMode && target.HasValue) ? 28 : 20);
				if (resetMode)
				{
					_height.text = "Original terrain";
				}
				bool flag = removeNature || removeBuilds;
				if (flag)
				{
					_heightCaption.text = "REMOVE";
					_height.text = (removeBuilds ? "Build pieces" : "Nature");
				}
				if (removeBuilds)
				{
					_shape.text = ((shape == BrushShape.Circle) ? "Cylinder · centred on aim point" : ("Box · " + Number(BrushGeometry.NormalizeYaw(yaw)) + "° · centred on aim point"));
					_heightCaption.text = "TOTAL HEIGHT";
					_height.text = Number(selectionHeight) + " m";
					_height.fontSize = 28f;
				}
				int num = 0;
				Key(num++, "Shift + scroll", "Resize selection");
				if (heightMode)
				{
					Key(num++, "Ctrl + scroll", "Adjust height");
				}
				else if (removeBuilds)
				{
					Key(num++, "Ctrl + scroll", "Resize height");
				}
				if (shape == BrushShape.Square || slopeMode)
				{
					Key(num++, "Alt + scroll", slopeMode ? "Rotate uphill direction" : "Rotate selection");
				}
				Key(num++, shapeKey, "Circle / square");
				if (heightMode)
				{
					Key(num++, resetKey, slopeMode ? "Start slope here" : (moveMode ? "Reset height change" : "Sample ground height"));
				}
				if (heightMode)
				{
					Key(num++, transitionKey, (transition > 0f) ? ("Natural edge: " + Number(transition) + " m") : "Natural edge: off");
				}
				Key(num++, cameraKey, string.IsNullOrEmpty(cameraHint) ? "Free camera" : "Return to player");
				Key(num++, "Mouse 1", flag ? "Remove objects" : (resetMode ? "Reset terrain" : "Apply terrain"));
				for (int i = num; i < _keys.Length; i++)
				{
					((Component)_keyCaps[i]).gameObject.SetActive(false);
					((Component)_keys[i]).gameObject.SetActive(false);
					((Component)_actions[i]).gameObject.SetActive(false);
				}
				float num2 = 224 + num * 29;
				((Component)_warning).gameObject.SetActive(removeBuilds);
				if (removeBuilds)
				{
					float num3 = Mathf.Ceil(_warning.GetPreferredValues(_warning.text, 374f, float.PositiveInfinity).y) + 4f;
					Move(_warning.rectTransform, 18f, num2, 374f, num3);
					num2 += num3 + 12f;
				}
				((Component)_cameraHint).gameObject.SetActive(!string.IsNullOrEmpty(cameraHint));
				if (((Component)_cameraHint).gameObject.activeSelf)
				{
					_cameraHint.text = cameraHint;
					float num4 = Mathf.Ceil(_cameraHint.GetPreferredValues(cameraHint, 374f, float.PositiveInfinity).y) + 2f;
					Move(_cameraHint.rectTransform, 18f, num2, 374f, num4);
					num2 += num4 + 10f;
				}
				_costTitle.text = costTitle;
				Move(_costTitle.rectTransform, 18f, num2, 374f, 24f);
				num2 += 27f;
				_costs.text = costs;
				float num5 = Mathf.Max(22f, Mathf.Ceil(_costs.GetPreferredValues(costs, 374f, float.PositiveInfinity).y) + 2f);
				Move(_costs.rectTransform, 18f, num2, 374f, num5);
				num2 += num5 + 14f;
				Color val = (valid ? new Color(0.65f, 0.85f, 0.48f) : new Color(1f, 0.56f, 0.36f));
				_status.text = status;
				TMP_Text status2 = _status;
				Color color = (((Graphic)_statusBar).color = val);
				((Graphic)status2).color = color;
				float num6 = Mathf.Max(24f, Mathf.Ceil(_status.GetPreferredValues(status, 363f, float.PositiveInfinity).y) + 2f);
				Move(_status.rectTransform, 29f, num2, 363f, num6);
				Move(((Graphic)_statusBar).rectTransform, 18f, num2, 3f, num6);
				float num7 = num2 + num6 + 18f;
				_root.sizeDelta = new Vector2(410f, num7);
				Move(((Graphic)_bottom).rectTransform, 0f, num7 - 1f, 410f, 1f);
				Rect rect = _canvas.rect;
				float num8 = (((Rect)(ref rect)).width - 48f) / 410f;
				rect = _canvas.rect;
				float num9 = Mathf.Min(userScale, Mathf.Min(num8, (((Rect)(ref rect)).height - 48f) / num7));
				((Transform)_root).localScale = Vector3.one * Mathf.Max(0.2f, num9);
				((Component)_root).gameObject.SetActive(true);
			}
		}

		private void Key(int row, string key, string action)
		{
			((Component)_keyCaps[row]).gameObject.SetActive(true);
			((Component)_keys[row]).gameObject.SetActive(true);
			((Component)_actions[row]).gameObject.SetActive(true);
			_keys[row].text = key;
			_actions[row].text = action;
		}

		private Image Box(string name, float x, float y, float width, float height, Color color)
		{
			//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_003e: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name, new Type[2]
			{
				typeof(RectTransform),
				typeof(Image)
			});
			val.transform.SetParent((Transform)(object)_root, false);
			Image component = val.GetComponent<Image>();
			((Graphic)component).color = color;
			((Graphic)component).raycastTarget = false;
			Move(((Graphic)component).rectTransform, x, y, width, height);
			return component;
		}

		private TMP_Text Label(string name, string text, float x, float y, float width, float height, int size, Color color, bool title = false)
		{
			//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_0089: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) });
			val.transform.SetParent((Transform)(object)_root, false);
			TextMeshProUGUI obj = val.AddComponent<TextMeshProUGUI>();
			TMP_Text val2 = (title ? _hud.m_buildSelection : _hud.m_pieceDescription);
			((TMP_Text)obj).font = val2.font;
			((TMP_Text)obj).fontSharedMaterial = (Object.op_Implicit((Object)(object)val2.fontSharedMaterial) ? val2.fontSharedMaterial : ((TMP_Asset)val2.font).material);
			((TMP_Text)obj).fontSize = size;
			((Graphic)obj).color = color;
			((TMP_Text)obj).text = text;
			((TMP_Text)obj).richText = false;
			((Graphic)obj).raycastTarget = false;
			((TMP_Text)obj).textWrappingMode = (TextWrappingModes)1;
			((TMP_Text)obj).alignment = (TextAlignmentOptions)513;
			((TMP_Text)obj).overflowMode = (TextOverflowModes)1;
			Move(((TMP_Text)obj).rectTransform, x, y, width, height);
			return (TMP_Text)(object)obj;
		}

		private static void Move(RectTransform rect, float x, float y, float width, float height)
		{
			//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_002a: 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_0046: Unknown result type (might be due to invalid IL or missing references)
			Vector2 val = default(Vector2);
			((Vector2)(ref val))..ctor(0f, 1f);
			rect.anchorMax = val;
			rect.anchorMin = val;
			rect.pivot = new Vector2(0f, 1f);
			rect.anchoredPosition = new Vector2(x, 0f - y);
			rect.sizeDelta = new Vector2(width, height);
		}

		private static string Number(float value)
		{
			return value.ToString("0.##", CultureInfo.InvariantCulture);
		}

		internal void Hide()
		{
			if (Object.op_Implicit((Object)(object)_root))
			{
				((Component)_root).gameObject.SetActive(false);
			}
		}

		public void Dispose()
		{
			if (Object.op_Implicit((Object)(object)_root))
			{
				((Component)_root).gameObject.SetActive(false);
				Object.Destroy((Object)(object)((Component)_root).gameObject);
			}
			_root = null;
			_hud = null;
			_canvas = null;
		}
	}
	internal sealed class BrushPreview : IDisposable
	{
		private readonly GameObject _root;

		private readonly Transform _native;

		private readonly bool _nativeActive;

		private readonly Material _material;

		private readonly LineRenderer _outline;

		private readonly LineRenderer _surface;

		private readonly LineRenderer _border;

		private readonly LineRenderer _crossX;

		private readonly LineRenderer _crossZ;

		private readonly LineRenderer _height;

		private readonly LineRenderer _uphill;

		private readonly LineRenderer _groundOutline;

		private readonly LineRenderer[] _sides = (LineRenderer[])(object)new LineRenderer[4];

		internal BrushPreview(GameObject ghost)
		{
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Expected O, but got Unknown
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Expected O, but got Unknown
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			_native = ghost.transform.Find("_GhostOnly");
			if (Object.op_Implicit((Object)(object)_native))
			{
				_nativeActive = ((Component)_native).gameObject.activeSelf;
			}
			Shader val = Shader.Find("Hidden/Internal-Colored");
			if (!Object.op_Implicit((Object)(object)val) || !val.isSupported)
			{
				val = Shader.Find("Sprites/Default");
			}
			if (!Object.op_Implicit((Object)(object)val) || !val.isSupported)
			{
				throw new InvalidOperationException("Could not load the terrain preview shader.");
			}
			_root = new GameObject("VTT terrain selection");
			_root.SetActive(false);
			_material = new Material(val)
			{
				renderQueue = 4000
			};
			if (_material.HasProperty("_Color"))
			{
				_material.SetColor("_Color", Color.white);
			}
			_material.SetInt("_SrcBlend", 5);
			_material.SetInt("_DstBlend", 10);
			_material.SetInt("_Cull", 0);
			_material.SetInt("_ZWrite", 0);
			_material.SetInt("_ZTest", 8);
			_outline = Line("Selected height", loop: true, 0.055f);
			_surface = Line("Ground footprint", loop: true, 0.035f);
			_border = Line("Natural transition boundary", loop: true, 0.045f);
			_crossX = Line("Profile X", loop: false, 0.035f);
			_crossZ = Line("Profile Z", loop: false, 0.035f);
			_height = Line("Height guide", loop: false, 0.03f);
			_uphill = Line("Uphill direction", loop: false, 0.075f);
			_groundOutline = Line("Terrain selection boundary", loop: true, 0.055f);
			for (int i = 0; i < _sides.Length; i++)
			{
				_sides[i] = Line("Selection side " + i, loop: false, 0.035f);
			}
		}

		private LineRenderer Line(string name, bool loop, float width)
		{
			//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)
			GameObject val = new GameObject(name);
			val.transform.SetParent(_root.transform, false);
			LineRenderer obj = val.AddComponent<LineRenderer>();
			((Renderer)obj).sharedMaterial = _material;
			obj.useWorldSpace = true;
			obj.loop = loop;
			obj.widthMultiplier = width;
			((Renderer)obj).shadowCastingMode = (ShadowCastingMode)0;
			((Renderer)obj).receiveShadows = false;
			obj.numCornerVertices = 3;
			obj.numCapVertices = 2;
			return obj;
		}

		internal void Hide()
		{
			if (Object.op_Implicit((Object)(object)_root))
			{
				_root.SetActive(false);
			}
			if (Object.op_Implicit((Object)(object)_native))
			{
				((Component)_native).gameObject.SetActive(_nativeActive);
			}
		}

		internal void Show(Vector3 center, float radius, BrushShape shape, BrushMode mode, float target, bool valid, float yaw = 0f, float transition = 0f, float selectionHeight = 10f)
		{
			//IL_000a: 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_0079: 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_007e: 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_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: 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)
			//IL_0151: 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_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01be: 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_01c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01da: Unknown result type (might be due to invalid IL or missing references)
			//IL_01db: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0210: Unknown result type (might be due to invalid IL or missing references)
			//IL_0217: 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_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02db: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0301: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_04eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_04fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0503: Unknown result type (might be due to invalid IL or missing references)
			//IL_0516: Unknown result type (might be due to invalid IL or missing references)
			//IL_051b: Unknown result type (might be due to invalid IL or missing references)
			//IL_052e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0533: Unknown result type (might be due to invalid IL or missing references)
			//IL_0388: Unknown result type (might be due to invalid IL or missing references)
			//IL_038a: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_0553: Unknown result type (might be due to invalid IL or missing references)
			//IL_0558: Unknown result type (might be due to invalid IL or missing references)
			//IL_0562: Unknown result type (might be due to invalid IL or missing references)
			//IL_0567: Unknown result type (might be due to invalid IL or missing references)
			//IL_056c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0574: Unknown result type (might be due to invalid IL or missing references)
			//IL_0595: Unknown result type (might be due to invalid IL or missing references)
			//IL_05a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_05b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_05b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_05c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_05f2: Unknown result type (might be due to invalid IL or missing references)
			BrushGeometry brush = new BrushGeometry(radius, shape, yaw);
			transition = BrushMath.Transition(mode, transition);
			Color val = (valid ? new Color(1f, 0.79f, 0.27f, 0.92f) : new Color(1f, 0.25f, 0.18f, 0.92f));
			LineRenderer[] sides = _sides;
			for (int i = 0; i < sides.Length; i++)
			{
				((Renderer)sides[i]).enabled = mode == BrushMode.RemoveBuilds;
			}
			((Renderer)_groundOutline).enabled = mode == BrushMode.RemoveBuilds;
			if (mode == BrushMode.RemoveBuilds)
			{
				ShowVolume(center, brush, selectionHeight, val);
				_root.SetActive(true);
				if (Object.op_Implicit((Object)(object)_native))
				{
					((Component)_native).gameObject.SetActive(false);
				}
				return;
			}
			Color val2 = default(Color);
			((Color)(ref val2))..ctor(0.3f, 0.8f, 1f, 0.5f);
			Color val3 = (_outline.startColor = (_outline.endColor = val));
			val3 = (_surface.startColor = (_surface.endColor = val2));
			LineRenderer border = _border;
			LineRenderer border2 = _border;
			((Color)(ref val3))..ctor(0.5f, 1f, 0.55f, 0.8f);
			border2.endColor = val3;
			border.startColor = val3;
			val3 = (_crossX.startColor = (_crossX.endColor = val));
			val3 = (_crossZ.startColor = (_crossZ.endColor = val));
			val3 = (_height.startColor = (_height.endColor = val2));
			LineRenderer uphill = _uphill;
			LineRenderer uphill2 = _uphill;
			((Color)(ref val3))..ctor(1f, 0.95f, 0.7f, 1f);
			uphill2.endColor = val3;
			uphill.startColor = val3;
			int num = Mathf.Max(64, Mathf.CeilToInt((radius + transition) * 16f));
			num = (num + 7) / 8 * 8;
			Vector3[] array = (Vector3[])(object)new Vector3[num];
			Vector3[] array2 = (Vector3[])(object)new Vector3[num];
			Vector3[] array3 = (Vector3[])(object)new Vector3[num];
			for (int j = 0; j < num; j++)
			{
				float num2 = (float)j * MathF.PI * 2f / (float)num;
				float num3 = Mathf.Cos(num2);
				float num4 = Mathf.Sin(num2);
				if (shape == BrushShape.Square)
				{
					float num5 = Mathf.Max(Mathf.Abs(num3), Mathf.Abs(num4));
					num3 /= num5;
					num4 /= num5;
				}
				brush.ToWorld(num3 * radius, num4 * radius, out var worldX, out var worldZ);
				Vector3 val14 = center + new Vector3(worldX, 0f, worldZ);
				val14.y = Surface(val14) + 0.06f;
				array2[j] = val14;
				if (mode == BrushMode.Level || mode == BrushMode.Raise)
				{
					val14.y = target + 0.08f;
				}
				else if (mode == BrushMode.Move)
				{
					val14.y += target + 0.02f;
				}
				else if (BrushMath.IsSlope(mode))
				{
					val14.y = target + BrushMath.SlopeRise(mode, brush, worldX, worldZ) + 0.08f;
				}
				array[j] = val14;
				brush.ToWorld(num3 * (radius + transition), num4 * (radius + transition), out worldX, out worldZ);
				val14 = center + new Vector3(worldX, 0f, worldZ);
				val14.y = Surface(val14) + 0.08f;
				array3[j] = val14;
			}
			Set(_outline, array);
			Set(_surface, array2);
			((Renderer)_border).enabled = transition > 0f;
			if (((Renderer)_border).enabled)
			{
				Set(_border, array3);
			}
			bool flag = BrushMath.HasHeight(mode);
			((Renderer)_surface).enabled = flag;
			LineRenderer crossX = _crossX;
			LineRenderer crossZ = _crossZ;
			bool flag2 = (((Renderer)_height).enabled = flag);
			bool enabled = (((Renderer)crossZ).enabled = flag2);
			((Renderer)crossX).enabled = enabled;
			((Renderer)_uphill).enabled = BrushMath.IsSlope(mode);
			if (((Renderer)_uphill).enabled)
			{
				Set(_uphill, (Vector3[])(object)new Vector3[5]
				{
					At(0f, -0.7f),
					At(0f, 0.7f),
					At(-0.2f, 0.4f),
					At(0f, 0.7f),
					At(0.2f, 0.4f)
				});
			}
			if (flag)
			{
				Set(_height, (Vector3[])(object)new Vector3[2]
				{
					center + Vector3.up * 0.08f,
					new Vector3(center.x, target + ((mode == BrushMode.Move) ? center.y : 0f) + 0.08f, center.z)
				});
				Set(_crossX, Profile(center, brush, mode, target, xAxis: true, transition));
				Set(_crossZ, Profile(center, brush, mode, target, xAxis: false, transition));
			}
			_root.SetActive(true);
			if (Object.op_Implicit((Object)(object)_native))
			{
				((Component)_native).gameObject.SetActive(false);
			}
			Vector3 At(float x, float z)
			{
				//IL_0059: Unknown result type (might be due to invalid IL or missing references)
				brush.ToWorld(x * radius, z * radius, out var worldX2, out var worldZ2);
				return new Vector3(center.x + worldX2, target + BrushMath.SlopeRise(mode, brush, worldX2, worldZ2) + 0.13f, center.z + worldZ2);
			}
		}

		private void ShowVolume(Vector3 center, BrushGeometry brush, float height, Color color)
		{
			//IL_000a: 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_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)
			//IL_0094: 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_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: 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_00b4: 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_00c2: 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_00cc: 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_012d: 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_0147: 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_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_0188: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: 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_01b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01be: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01df: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f3: 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_01fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_026e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0270: Unknown result type (might be due to invalid IL or missing references)
			//IL_0271: Unknown result type (might be due to invalid IL or missing references)
			//IL_0278: Unknown result type (might be due to invalid IL or missing references)
			//IL_027a: Unknown result type (might be due to invalid IL or missing references)
			//IL_027b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0282: Unknown result type (might be due to invalid IL or missing references)
			//IL_0284: Unknown result type (might be due to invalid IL or missing references)
			//IL_0285: 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)
			//IL_02a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02af: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0303: Unknown result type (might be due to invalid IL or missing references)
			//IL_030d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0312: Unknown result type (might be due to invalid IL or missing references)
			//IL_0317: Unknown result type (might be due to invalid IL or missing references)
			//IL_0330: Unknown result type (might be due to invalid IL or missing references)
			//IL_0335: Unknown result type (might be due to invalid IL or missing references)
			//IL_033f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0344: Unknown result type (might be due to invalid IL or missing references)
			//IL_0349: Unknown result type (might be due to invalid IL or missing references)
			//IL_0351: Unknown result type (might be due to invalid IL or missing references)
			//IL_0356: Unknown result type (might be due to invalid IL or missing references)
			//IL_0360: Unknown result type (might be due to invalid IL or missing references)
			//IL_0365: Unknown result type (might be due to invalid IL or missing references)
			//IL_036a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0383: Unknown result type (might be due to invalid IL or missing references)
			//IL_0388: Unknown result type (might be due to invalid IL or missing references)
			//IL_0394: Unknown result type (might be due to invalid IL or missing references)
			//IL_0399: Unknown result type (might be due to invalid IL or missing references)
			//IL_039e: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0412: Unknown result type (might be due to invalid IL or missing references)
			//IL_0414: Unknown result type (might be due to invalid IL or missing references)
			//IL_0415: Unknown result type (might be due to invalid IL or missing references)
			//IL_041c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0434: Unknown result type (might be due to invalid IL or missing references)
			//IL_0436: Unknown result type (might be due to invalid IL or missing references)
			//IL_0442: Unknown result type (might be due to invalid IL or missing references)
			//IL_0447: 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)
			//IL_0453: Unknown result type (might be due to invalid IL or missing references)
			//IL_0455: Unknown result type (might be due to invalid IL or missing references)
			//IL_0461: Unknown result type (might be due to invalid IL or missing references)
			//IL_0466: Unknown result type (might be due to invalid IL or missing references)
			//IL_046b: Unknown result type (might be due to invalid IL or missing references)
			bool square = brush.Shape == BrushShape.Square;
			int num = (square ? 4 : Mathf.Max(64, Mathf.CeilToInt(brush.Radius * 16f)));
			Vector3[] array = (Vector3[])(object)new Vector3[num];
			Vector3[] array2 = (Vector3[])(object)new Vector3[num];
			for (int i = 0; i < num; i++)
			{
				Vector3 val = Edge((float)i * MathF.PI * 2f / (float)num + (square ? (MathF.PI / 4f) : 0f));
				array[i] = val + Vector3.up * (height * 0.5f);
				array2[i] = val - Vector3.up * (height * 0.5f);
			}
			int num2 = Mathf.Max(64, Mathf.CeilToInt(brush.Radius * 16f));
			num2 = (num2 + 7) / 8 * 8;
			Vector3[] array3 = (Vector3[])(object)new Vector3[num2];
			for (int j = 0; j < num2; j++)
			{
				Vector3 val2 = Edge((float)j * MathF.PI * 2f / (float)num2);
				val2.y = Surface(val2) + 0.06f;
				array3[j] = val2;
			}
			Set(_outline, array);
			Set(_surface, array2);
			Set(_groundOutline, array3);
			Color val3 = default(Color);
			((Color)(ref val3))..ctor(color.r, color.g, color.b, color.a * 0.45f);
			Color val4 = (_groundOutline.startColor = (_groundOutline.endColor = color));
			LineRenderer outline = _outline;
			LineRenderer outline2 = _outline;
			LineRenderer surface = _surface;
			Color val7 = (_surface.endColor = val3);
			Color val9 = (surface.startColor = val7);
			val4 = (outline.startColor = (outline2.endColor = val9));
			((Renderer)_surface).enabled = true;
			LineRenderer border = _border;
			bool enabled = (((Renderer)_uphill).enabled = false);
			((Renderer)border).enabled = enabled;
			LineRenderer crossX = _crossX;
			LineRenderer crossZ = _crossZ;
			bool flag2 = (((Renderer)_height).enabled = true);
			enabled = (((Renderer)crossZ).enabled = flag2);
			((Renderer)crossX).enabled = enabled;
			LineRenderer crossX2 = _crossX;
			LineRenderer crossX3 = _crossX;
			LineRenderer crossZ2 = _crossZ;
			val7 = (_crossZ.endColor = color);
			val9 = (crossZ2.startColor = val7);
			val4 = (crossX2.startColor = (crossX3.endColor = val9));
			LineRenderer height2 = _height;
			LineRenderer height3 = _height;
			((Color)(ref val4))..ctor(color.r, color.g, color.b, 0.35f);
			height3.endColor = val4;
			height2.startColor = val4;
			Set(_crossX, (Vector3[])(object)new Vector3[2]
			{
				center - Vector3.right * 0.25f,
				center + Vector3.right * 0.25f
			});
			Set(_crossZ, (Vector3[])(object)new Vector3[2]
			{
				center - Vector3.forward * 0.25f,
				center + Vector3.forward * 0.25f
			});
			Set(_height, (Vector3[])(object)new Vector3[2]
			{
				center - Vector3.up * (height * 0.5f),
				center + Vector3.up * (height * 0.5f)
			});
			for (int k = 0; k < _sides.Length; k++)
			{
				Vector3 val17 = Edge((float)k * MathF.PI * 0.5f + (square ? (MathF.PI / 4f) : 0f));
				val4 = (_sides[k].startColor = (_sides[k].endColor = val3));
				Set(_sides[k], (Vector3[])(object)new Vector3[2]
				{
					val17 - Vector3.up * (height * 0.5f),
					val17 + Vector3.up * (height * 0.5f)
				});
			}
			Vector3 Edge(float angle)
			{
				//IL_005d: 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_006e: Unknown result type (might be due to invalid IL or missing references)
				float num3 = Mathf.Cos(angle);
				float num4 = Mathf.Sin(angle);
				if (square)
				{
					float num5 = Mathf.Max(Mathf.Abs(num3), Mathf.Abs(num4));
					num3 /= num5;
					num4 /= num5;
				}
				brush.ToWorld(num3 * brush.Radius, num4 * brush.Radius, out var worldX, out var worldZ);
				return center + new Vector3(worldX, 0f, worldZ);
			}
		}

		private static Vector3[] Profile(Vector3 center, BrushGeometry brush, BrushMode mode, float target, bool xAxis, float transition)
		{
			//IL_0054: 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_0058: 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_0062: 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_0065: 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_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_008b: 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_009f: 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_00cc: Unknown result type (might be due to invalid IL or missing references)
			Vector3[] array = (Vector3[])(object)new Vector3[65];
			Vector3 val = default(Vector3);
			for (int i = 0; i < array.Length; i++)
			{
				float num = ((float)i / 64f * 2f - 1f) * (brush.Radius + transition);
				brush.ToWorld(xAxis ? 1 : 0, (!xAxis) ? 1 : 0, out var worldX, out var worldZ);
				((Vector3)(ref val))..ctor(worldX, 0f, worldZ);
				Vector3 val2 = center + val * num;
				Vector3 point = center + val * Mathf.Sign(num) * (brush.Radius + transition + 2f);
				float num2 = BrushMath.Desired(Surface(val2), (mode == BrushMode.Raise) ? Surface(point) : 0f, target, mode, brush, worldX * num, worldZ * num, transition);
				val2.y = num2 + 0.08f;
				array[i] = val2;
			}
			return array;
		}

		private static float Surface(Vector3 point)
		{
			//IL_0000: 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_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)
			//IL_0039: 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_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			int num = Mathf.FloorToInt(point.x);
			int num2 = Mathf.FloorToInt(point.z);
			float num3 = At(num, num2, point.y);
			float num4 = At(num + 1, num2, point.y);
			float num5 = At(num, num2 + 1, point.y);
			float num6 = At(num + 1, num2 + 1, point.y);
			return Mathf.Lerp(Mathf.Lerp(num3, num4, point.x - (float)num), Mathf.Lerp(num5, num6, point.x - (float)num), point.z - (float)num2);
		}

		private static float At(int x, int z, float fallback)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			float result = default(float);
			if (!Heightmap.GetHeight(new Vector3((float)x, 0f, (float)z), ref result))
			{
				return fallback;
			}
			return result;
		}

		private static void Set(LineRenderer line, Vector3[] points)
		{
			line.positionCount = points.Length;
			line.SetPositions(points);
		}

		public void Dispose()
		{
			if (Object.op_Implicit((Object)(object)_native))
			{
				((Component)_native).gameObject.SetActive(_nativeActive);
			}
			if (Object.op_Implicit((Object)(object)_root))
			{
				Object.Destroy((Object)(object)_root);
			}
			if (Object.op_Implicit((Object)(object)_material))
			{
				Object.Destroy((Object)(object)_material);
			}
		}
	}
	internal sealed class FocusResumeGate
	{
		private int _neutralFrame = -1;

		internal bool Waiting { get; private set; }

		internal void Suspend()
		{
			Waiting = true;
		}

		internal bool Blocks(int frame)
		{
			if (!Waiting)
			{
				return _neutralFrame == frame;
			}
			return true;
		}

		internal bool Consume(bool inputReady, bool busy, int frame)
		{
			if (Waiting && inputReady && !busy)
			{
				Waiting = false;
				_neutralFrame = frame;
			}
			return Blocks(frame);
		}
	}
	internal static class Native
	{
		private static readonly FieldRef<ZNetScene, Dictionary<ZDO, ZNetView>> _SceneObjects = AccessTools.FieldRefAccess<ZNetScene, Dictionary<ZDO, ZNetView>>("m_instances");

		internal static readonly List<PrivateArea> Wards = (List<PrivateArea>)AccessTools.Field(typeof(PrivateArea), "m_allAreas").GetValue(null);

		private static readonly FieldRef<Player, int> _PlaceRayMask = AccessTools.FieldRefAccess<Player, int>("m_placeRayMask");

		private static readonly FieldRef<Player, GameObject> _Ghost = AccessTools.FieldRefAccess<Player, GameObject>("m_placementGhost");

		private static readonly FieldRef<Player, PlacementStatus> _Status = AccessTools.FieldRefAccess<Player, PlacementStatus>("m_placementStatus");

		private static readonly FieldRef<Player, float> _PlacePressed = AccessTools.FieldRefAccess<Player, float>("m_placePressedTime");

		private static readonly FieldRef<Player, float> _LastToolUse = AccessTools.FieldRefAccess<Player, float>("m_lastToolUseTime");

		private static readonly FieldRef<Character, ZSyncAnimation> _Animation = AccessTools.FieldRefAccess<Character, ZSyncAnimation>("m_zanim");

		private static readonly FieldRef<Heightmap, bool> _Distant = AccessTools.FieldRefAccess<Heightmap, bool>("m_isDistantLod");

		private static readonly FieldRef<Heightmap, List<float>> _Heights = AccessTools.FieldRefAccess<Heightmap, List<float>>("m_heights");

		private static readonly FieldRef<TerrainComp, bool> _Initialized = AccessTools.FieldRefAccess<TerrainComp, bool>("m_initialized");

		private static readonly FieldRef<TerrainComp, ZNetView> _View = AccessTools.FieldRefAccess<TerrainComp, ZNetView>("m_nview");

		private static readonly FieldRef<TerrainComp, Color[]> _PaintMask = AccessTools.FieldRefAccess<TerrainComp, Color[]>("m_paintMask");

		private static readonly FieldRef<TerrainComp, float[]> _Level = AccessTools.FieldRefAccess<TerrainComp, float[]>("m_levelDelta");

		private static readonly FieldRef<TerrainComp, float[]> _Smooth = AccessTools.FieldRefAccess<TerrainComp, float[]>("m_smoothDelta");

		private static readonly FieldRef<TerrainComp, bool[]> _ModifiedHeight = AccessTools.FieldRefAccess<TerrainComp, bool[]>("m_modifiedHeight");

		private static readonly FieldRef<TerrainComp, bool[]> _ModifiedPaint = AccessTools.FieldRefAccess<TerrainComp, bool[]>("m_modifiedPaint");

		private static readonly FieldRef<TerrainComp, int> _Operations = AccessTools.FieldRefAccess<TerrainComp, int>("m_operations");

		private static readonly FieldRef<TerrainComp, Vector3> _LastPoint = AccessTools.FieldRefAccess<TerrainComp, Vector3>("m_lastOpPoint");

		private static readonly FieldRef<TerrainComp, float> _LastRadius = AccessTools.FieldRefAccess<TerrainComp, float>("m_lastOpRadius");

		private static readonly FieldRef<TerrainComp, Heightmap> _Heightmap = AccessTools.FieldRefAccess<TerrainComp, Heightmap>("m_hmap");

		internal static readonly Func<Humanoid, ItemData> RightItem = AccessTools.MethodDelegate<Func<Humanoid, ItemData>>(AccessTools.Method(typeof(Humanoid), "GetRightItem", (Type[])null, (Type[])null), (object)null, true);

		internal static readonly Func<Character, bool> TakeInput = AccessTools.MethodDelegate<Func<Character, bool>>(AccessTools.Method(typeof(Character), "TakeInput", (Type[])null, (Type[])null), (object)null, true);

		internal static readonly Func<Player, float> BuildStamina = AccessTools.MethodDelegate<Func<Player, float>>(AccessTools.Method(typeof(Player), "GetBuildStamina", (Type[])null, (Type[])null), (object)null, true);

		internal static readonly Func<Player, ItemData, float> PlaceDurability = AccessTools.MethodDelegate<Func<Player, ItemData, float>>(AccessTools.Method(typeof(Player), "GetPlaceDurability", (Type[])null, (Type[])null), (object)null, true);

		internal static readonly Action<Player, bool> UpdateGhost = AccessTools.MethodDelegate<Action<Player, bool>>(AccessTools.Method(typeof(Player), "UpdatePlacementGhost", (Type[])null, (Type[])null), (object)null, true);

		internal static readonly Action<TerrainComp> CheckLoad = AccessTools.MethodDelegate<Action<TerrainComp>>(AccessTools.Method(typeof(TerrainComp), "CheckLoad", (Type[])null, (Type[])null), (object)null, true);

		internal static readonly Action<TerrainComp, bool> Save = AccessTools.MethodDelegate<Action<TerrainComp, bool>>(AccessTools.Method(typeof(TerrainComp), "Save", (Type[])null, (Type[])null), (object)null, true);

		internal static readonly List<Location> Locations = (List<Location>)AccessTools.Field(typeof(Location), "s_allLocations").GetValue(null);

		internal static Dictionary<ZDO, ZNetView> SceneObjects(ZNetScene scene)
		{
			return _SceneObjects.Invoke(scene);
		}

		internal static ref int PlaceRayMask(Player instance)
		{
			return ref _PlaceRayMask.Invoke(instance);
		}

		internal static ref GameObject Ghost(Player instance)
		{
			return ref _Ghost.Invoke(instance);
		}

		internal static ref PlacementStatus Status(Player instance)
		{
			return ref _Status.Invoke(instance);
		}

		internal static ref float PlacePressed(Player instance)
		{
			return ref _PlacePressed.Invoke(instance);
		}

		internal static ref float LastToolUse(Player instance)
		{
			return ref _LastToolUse.Invoke(instance);
		}

		internal static ref ZSyncAnimation Animation(Character instance)
		{
			return ref _Animation.I