Decompiled source of GeosBeltTweaks v0.2.0

GeosBeltTweaks.dll

Decompiled 2 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Rendering;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("GeosBeltTweaks")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Geo's belt tweaks for Dyson Sphere Program")]
[assembly: AssemblyFileVersion("0.2.0.0")]
[assembly: AssemblyInformationalVersion("0.2.0+f652a7157560e04adc67b7f3d716f6a3db85a77f")]
[assembly: AssemblyProduct("Geo's Belt Tweaks")]
[assembly: AssemblyTitle("GeosBeltTweaks")]
[assembly: AssemblyVersion("0.2.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace GeosBeltTweaks
{
	[HarmonyPatch]
	internal static class BeltPreviewTiltPatch
	{
		private sealed class CapRenderer : IDisposable
		{
			internal readonly ConnGizmoRenderer Renderer;

			internal readonly CapBatch Major;

			internal readonly CapBatch Minor;

			internal bool Enabled;

			internal CapRenderer(ConnGizmoRenderer renderer, Mesh major, Mesh minor, Material majorMat, Material minorMat)
			{
				Renderer = renderer;
				Major = new CapBatch(major, majorMat);
				try
				{
					Minor = new CapBatch(minor, minorMat);
				}
				catch
				{
					Major.Dispose();
					throw;
				}
			}

			public void Dispose()
			{
				Major.Dispose();
				Minor.Dispose();
			}
		}

		private sealed class CapBatch : IDisposable
		{
			internal readonly Mesh OriginalMesh;

			internal Mesh GuideMesh;

			internal ConnGizmoObj[] CapInstances = Array.Empty<ConnGizmoObj>();

			private Mesh _capMesh;

			private Material _capMaterial;

			private ComputeBuffer? _instanceBuffer;

			private ComputeBuffer? _drawArgsBuffer;

			private readonly uint[] _drawArgs = new uint[5];

			private int _instanceCount;

			internal CapBatch(Mesh original, Material material)
			{
				//IL_0132: 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_0172: Unknown result type (might be due to invalid IL or missing references)
				//IL_02c8: Unknown result type (might be due to invalid IL or missing references)
				//IL_02d2: Expected O, but got Unknown
				//IL_02da: Unknown result type (might be due to invalid IL or missing references)
				//IL_02e4: Expected O, but got Unknown
				//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
				//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
				//IL_01d7: 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_01f8: Unknown result type (might be due to invalid IL or missing references)
				//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
				//IL_0201: Unknown result type (might be due to invalid IL or missing references)
				//IL_0210: Unknown result type (might be due to invalid IL or missing references)
				//IL_0227: Unknown result type (might be due to invalid IL or missing references)
				OriginalMesh = original;
				try
				{
					Vector3[] vertices = original.vertices;
					int[] triangles = original.triangles;
					List<int> list = new List<int>();
					List<int> list2 = new List<int>();
					for (int i = 0; i < triangles.Length; i += 3)
					{
						List<int> obj = ((vertices[triangles[i]].y >= -0.001f && vertices[triangles[i + 1]].y >= -0.001f && vertices[triangles[i + 2]].y >= -0.001f) ? list : list2);
						obj.Add(triangles[i]);
						obj.Add(triangles[i + 1]);
						obj.Add(triangles[i + 2]);
					}
					if (list.Count == 0 || list2.Count == 0)
					{
						throw new InvalidOperationException("GeosBeltTweaks: belt preview mesh has no separate cap and stem.");
					}
					_capMesh = Object.Instantiate<Mesh>(original);
					List<Vector3> list3 = new List<Vector3>(vertices);
					List<Vector3> list4 = new List<Vector3>(original.normals);
					List<Vector4> list5 = new List<Vector4>(original.tangents);
					List<Color32> list6 = new List<Color32>(original.colors32);
					Dictionary<int, int> dictionary = new Dictionary<int, int>();
					int count = list.Count;
					for (int j = 0; j < count; j += 3)
					{
						if (list4[list[j]].y < 0.99f || list4[list[j + 1]].y < 0.99f || list4[list[j + 2]].y < 0.99f)
						{
							continue;
						}
						for (int num = 2; num >= 0; num--)
						{
							int num2 = list[j + num];
							if (!dictionary.TryGetValue(num2, out var value))
							{
								value = list3.Count;
								dictionary.Add(num2, value);
								Vector3 item = vertices[num2];
								item.y = 0f;
								list3.Add(item);
								list4.Add(Vector3.down);
								if (list5.Count > 0)
								{
									Vector4 val = list5[num2];
									val.w = 0f - val.w;
									list5.Add(val);
								}
								if (list6.Count > 0)
								{
									list6.Add(list6[num2]);
								}
							}
							list.Add(value);
						}
					}
					_capMesh.SetVertices(list3);
					_capMesh.SetNormals(list4);
					if (list5.Count > 0)
					{
						_capMesh.SetTangents(list5);
					}
					if (list6.Count > 0)
					{
						_capMesh.SetColors(list6);
					}
					_capMesh.SetTriangles(list, 0, false);
					GuideMesh = Object.Instantiate<Mesh>(original);
					GuideMesh.SetTriangles(list2, 0, false);
					_capMaterial = new Material(material);
					_drawArgsBuffer = new ComputeBuffer(5, 4, (ComputeBufferType)256);
					_drawArgs[0] = _capMesh.GetIndexCount(0);
					_drawArgs[2] = _capMesh.GetIndexStart(0);
					_drawArgs[3] = _capMesh.GetBaseVertex(0);
				}
				catch
				{
					Dispose();
					throw;
				}
			}

			internal void CopyWithQueuedRotations(List<ConnGizmoObj> source)
			{
				//IL_006f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0074: Unknown result type (might be due to invalid IL or missing references)
				//IL_007a: Unknown result type (might be due to invalid IL or missing references)
				//IL_007b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0049: Unknown result type (might be due to invalid IL or missing references)
				//IL_0053: Expected O, but got Unknown
				//IL_0098: Unknown result type (might be due to invalid IL or missing references)
				//IL_0099: Unknown result type (might be due to invalid IL or missing references)
				//IL_008b: Unknown result type (might be due to invalid IL or missing references)
				//IL_008c: Unknown result type (might be due to invalid IL or missing references)
				_instanceCount = source.Count;
				if (_instanceCount > CapInstances.Length)
				{
					int num = Mathf.NextPowerOfTwo(_instanceCount);
					CapInstances = (ConnGizmoObj[])(object)new ConnGizmoObj[num];
					ComputeBuffer? instanceBuffer = _instanceBuffer;
					if (instanceBuffer != null)
					{
						instanceBuffer.Release();
					}
					_instanceBuffer = new ComputeBuffer(num, 36);
					_capMaterial.SetBuffer("_ObjBuffer", _instanceBuffer);
				}
				for (int i = 0; i < _instanceCount; i++)
				{
					ConnGizmoObj val = source[i];
					if (QueuedCapRotations.TryGetValue(val.pos, out var value))
					{
						val.rot = value;
					}
					CapInstances[i] = val;
				}
			}

			internal void UploadCaps()
			{
				if (_instanceCount != 0)
				{
					_instanceBuffer.SetData((Array)CapInstances, 0, 0, _instanceCount);
					if (_drawArgs[1] != (uint)_instanceCount)
					{
						_drawArgs[1] = (uint)_instanceCount;
						_drawArgsBuffer.SetData((Array)_drawArgs);
					}
				}
			}

			internal void DrawCaps()
			{
				//IL_0016: 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)
				if (_instanceCount > 0)
				{
					Graphics.DrawMeshInstancedIndirect(_capMesh, 0, _capMaterial, new Bounds(Vector3.zero, new Vector3(10000f, 10000f, 10000f)), _drawArgsBuffer, 0, (MaterialPropertyBlock)null, (ShadowCastingMode)0, false, 0, (Camera)null, (LightProbeUsage)1);
				}
			}

			public void Dispose()
			{
				ComputeBuffer? instanceBuffer = _instanceBuffer;
				if (instanceBuffer != null)
				{
					instanceBuffer.Release();
				}
				ComputeBuffer? drawArgsBuffer = _drawArgsBuffer;
				if (drawArgsBuffer != null)
				{
					drawArgsBuffer.Release();
				}
				Object.Destroy((Object)(object)_capMesh);
				Object.Destroy((Object)(object)GuideMesh);
				Object.Destroy((Object)(object)_capMaterial);
			}
		}

		private static CapRenderer? _capRenderer;

		private static bool _initializationFailed;

		private static ConnGizmoRenderer? _queuedRotationOwner;

		private static readonly Dictionary<Vector3, Quaternion> QueuedCapRotations = new Dictionary<Vector3, Quaternion>();

		[HarmonyPrefix]
		[HarmonyPatch(typeof(ConnGizmoRenderer), "Update")]
		private static void BeginMarkerUpdate(ConnGizmoRenderer __instance, out bool __state)
		{
			__state = false;
			if (!Plugin.ShowBeltPreviewTilt.Value || _initializationFailed || __instance.factory == null || (Object)(object)__instance.factoryModel == (Object)null || GameMain.localPlanet?.factory != __instance.factory)
			{
				if (_queuedRotationOwner == __instance)
				{
					_queuedRotationOwner = null;
					QueuedCapRotations.Clear();
				}
				return;
			}
			if (_queuedRotationOwner != __instance)
			{
				_queuedRotationOwner = __instance;
				__instance.factoryModel.needRefreshConnGizmo012 = true;
			}
			__state = __instance.factoryModel.needRefreshConnGizmo012 || __instance.cursorGizmoGraph.pointCount > 0;
			if (__state)
			{
				QueuedCapRotations.Clear();
			}
		}

		[HarmonyTranspiler]
		[HarmonyPatch(typeof(ConnGizmoRenderer), "Update")]
		private static IEnumerable<CodeInstruction> InjectQueuedRotationCapture(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Expected O, but got Unknown
			List<CodeInstruction> list = new List<CodeInstruction>(instructions);
			FieldInfo fieldInfo = AccessTools.Field(typeof(PrebuildData), "rot");
			FieldInfo fieldInfo2 = AccessTools.Field(typeof(ConnGizmoObj), "rot");
			int num = -1;
			for (int i = 1; i + 1 < list.Count; i++)
			{
				if (list[i - 1].opcode == OpCodes.Ldelema && object.Equals(list[i - 1].operand, typeof(PrebuildData)) && CodeInstructionExtensions.LoadsField(list[i], fieldInfo, false) && CodeInstructionExtensions.StoresField(list[i + 1], fieldInfo2))
				{
					if (num >= 0)
					{
						throw new InvalidOperationException("GeosBeltTweaks queued belt tilt: multiple marker rotation assignments in ConnGizmoRenderer.Update.");
					}
					num = i;
				}
			}
			if (num < 0)
			{
				throw new InvalidOperationException("GeosBeltTweaks queued belt tilt: marker rotation assignment not found in ConnGizmoRenderer.Update.");
			}
			list[num].opcode = OpCodes.Ldarg_0;
			list[num].operand = null;
			list.Insert(num + 1, new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(BeltPreviewTiltPatch), "CaptureQueuedCapRotation", (Type[])null, (Type[])null)));
			return list;
		}

		private static Quaternion CaptureQueuedCapRotation(ref PrebuildData belt, ConnGizmoRenderer renderer)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: 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_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			if (_queuedRotationOwner != renderer)
			{
				return belt.rot;
			}
			PlanetFactory factory = renderer.factory;
			Vector3 forward = belt.rot * Vector3.forward;
			bool flag = default(bool);
			int num = default(int);
			int num2 = default(int);
			for (int i = 0; i < 4; i++)
			{
				factory.ReadObjectConn(-belt.id, i, ref flag, ref num, ref num2);
				if (num != 0)
				{
					Vector3 val = ((num > 0) ? factory.entityPool[num].pos : factory.prebuildPool[-num].pos);
					forward = (flag ? (val - belt.pos) : (belt.pos - val));
					break;
				}
			}
			QueuedCapRotations[belt.pos] = CalculateCapRotation(belt.rot, belt.pos, forward, belt.tilt);
			return belt.rot;
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(ConnGizmoRenderer), "Update")]
		private static void UpdateCapBatches(ConnGizmoRenderer __instance, List<ConnGizmoObj> ___objs_0, List<ConnGizmoObj> ___objs_1, Mesh ___mesh_0, Mesh ___mesh_1, Material ___mat_0, Material ___mat_1, bool __state)
		{
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_021d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0222: Unknown result type (might be due to invalid IL or missing references)
			//IL_0273: 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_027c: Unknown result type (might be due to invalid IL or missing references)
			//IL_027e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0286: Unknown result type (might be due to invalid IL or missing references)
			//IL_028b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0299: Unknown result type (might be due to invalid IL or missing references)
			//IL_029b: Unknown result type (might be due to invalid IL or missing references)
			if (!__state && _queuedRotationOwner == __instance && _capRenderer?.Renderer == __instance)
			{
				return;
			}
			if (_capRenderer?.Renderer == __instance)
			{
				_capRenderer.Enabled = false;
			}
			if (!Plugin.ShowBeltPreviewTilt.Value || _initializationFailed || _queuedRotationOwner != __instance)
			{
				return;
			}
			Player mainPlayer = GameMain.mainPlayer;
			PlayerAction_Build val = ((mainPlayer == null) ? null : mainPlayer.controller?.actionBuild);
			BuildTool_Path val2 = val?.pathTool;
			ConnGizmoGraph cursorGizmoGraph = __instance.cursorGizmoGraph;
			int num = ((val != null && val.active && val2 != null && ((BuildTool)val2).active && val.model.connRenderer == __instance && ((BuildTool)val2).buildPreviews.Count == cursorGizmoGraph.pointCount) ? cursorGizmoGraph.pointCount : 0);
			int num2 = 0;
			int num3 = 0;
			for (int i = 0; i < num; i++)
			{
				BuildPreview val3 = ((BuildTool)val2).buildPreviews[i];
				if (!val3.isConnNode || val3.desc == null || !val3.desc.isBelt)
				{
					return;
				}
				if (!(cursorGizmoGraph.pointsCurrent[i] == Vector3.zero))
				{
					if (i == 0 || i == cursorGizmoGraph.pointCount - 1)
					{
						num2++;
					}
					else
					{
						num3++;
					}
				}
			}
			if (___objs_0.Count + ___objs_1.Count == 0 || num2 > ___objs_0.Count || num3 > ___objs_1.Count)
			{
				return;
			}
			if (_capRenderer?.Renderer != __instance)
			{
				_capRenderer?.Dispose();
				_capRenderer = null;
				try
				{
					_capRenderer = new CapRenderer(__instance, ___mesh_0, ___mesh_1, ___mat_0, ___mat_1);
				}
				catch (Exception arg)
				{
					_initializationFailed = true;
					Plugin.Log.LogError((object)$"Belt preview tilt disabled until restart: could not split the marker meshes. {arg}");
					return;
				}
			}
			CapRenderer capRenderer = _capRenderer;
			capRenderer.Major.CopyWithQueuedRotations(___objs_0);
			capRenderer.Minor.CopyWithQueuedRotations(___objs_1);
			int num4 = ___objs_0.Count - num2;
			int num5 = ___objs_1.Count - num3;
			for (int j = 0; j < num; j++)
			{
				if (cursorGizmoGraph.pointsCurrent[j] == Vector3.zero)
				{
					continue;
				}
				int num6;
				CapBatch capBatch;
				if (j != 0)
				{
					num6 = ((j == cursorGizmoGraph.pointCount - 1) ? 1 : 0);
					if (num6 == 0)
					{
						capBatch = capRenderer.Minor;
						goto IL_0254;
					}
				}
				else
				{
					num6 = 1;
				}
				capBatch = capRenderer.Major;
				goto IL_0254;
				IL_0254:
				CapBatch capBatch2 = capBatch;
				int num7 = ((num6 != 0) ? num4++ : num5++);
				ConnGizmoObj val4 = capBatch2.CapInstances[num7];
				val4.rot = CursorCapRotation(val4.rot, val2, j);
				capBatch2.CapInstances[num7] = val4;
			}
			capRenderer.Major.UploadCaps();
			capRenderer.Minor.UploadCaps();
			capRenderer.Enabled = true;
		}

		private static Quaternion CursorCapRotation(Quaternion rotation, BuildTool_Path tool, int index)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: 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_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			BuildPreview val = ((BuildTool)tool).buildPreviews[index];
			Vector3 forward;
			if (index + 1 < ((BuildTool)tool).buildPreviews.Count)
			{
				forward = ((BuildTool)tool).buildPreviews[index + 1].lpos - val.lpos;
			}
			else if (index > 0)
			{
				forward = val.lpos - ((BuildTool)tool).buildPreviews[index - 1].lpos;
			}
			else
			{
				if (val.tilt == 0f)
				{
					return rotation;
				}
				forward = rotation * Vector3.forward;
			}
			return CalculateCapRotation(rotation, val.lpos, forward, val.tilt);
		}

		private static Quaternion CalculateCapRotation(Quaternion rotation, Vector3 position, Vector3 forward, float tilt)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: 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_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = Vector3.ProjectOnPlane(position, forward);
			if (Vector3.Dot(forward, forward) < 1E-08f || ((Vector3)(ref val)).sqrMagnitude < 1E-08f)
			{
				return rotation;
			}
			Quaternion val2 = Quaternion.LookRotation(forward, val);
			if (tilt != 0f)
			{
				return Quaternion.AngleAxis(tilt, forward) * val2;
			}
			return val2;
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(ConnGizmoRenderer), "Draw")]
		private static void UseGuideMeshes(ConnGizmoRenderer __instance, ref Mesh ___mesh_0, ref Mesh ___mesh_1, out CapRenderer? __state)
		{
			__state = _capRenderer;
			if (__state == null || !__state.Enabled || __state.Renderer != __instance)
			{
				__state = null;
				return;
			}
			___mesh_0 = __state.Major.GuideMesh;
			___mesh_1 = __state.Minor.GuideMesh;
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(ConnGizmoRenderer), "Draw")]
		private static void DrawRotatedCaps(ref Mesh ___mesh_0, ref Mesh ___mesh_1, CapRenderer? __state)
		{
			if (__state != null)
			{
				___mesh_0 = __state.Major.OriginalMesh;
				___mesh_1 = __state.Minor.OriginalMesh;
				__state.Major.DrawCaps();
				__state.Minor.DrawCaps();
			}
		}

		[HarmonyFinalizer]
		[HarmonyPatch(typeof(ConnGizmoRenderer), "Draw")]
		private static void RestoreMeshes(ref Mesh ___mesh_0, ref Mesh ___mesh_1, CapRenderer? __state)
		{
			if (__state != null)
			{
				___mesh_0 = __state.Major.OriginalMesh;
				___mesh_1 = __state.Minor.OriginalMesh;
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(ConnGizmoRenderer), "Destroy")]
		private static void ReleaseRenderer(ConnGizmoRenderer __instance)
		{
			if (_capRenderer?.Renderer == __instance || _queuedRotationOwner == __instance)
			{
				Release();
			}
		}

		internal static void Release()
		{
			_capRenderer?.Dispose();
			_capRenderer = null;
			_initializationFailed = false;
			_queuedRotationOwner = null;
			QueuedCapRotations.Clear();
		}
	}
	[HarmonyPatch(typeof(BuildTool_Path), "ConfirmOperation")]
	internal static class MatchStartingBeltPatch
	{
		[HarmonyPrefix]
		private static void Prefix(BuildTool_Path __instance, out int __state)
		{
			__state = ((BuildTool)__instance).controller.cmd.stage;
		}

		[HarmonyPostfix]
		private static void Postfix(BuildTool_Path __instance, int __state)
		{
			if (__state != 0 || ((BuildTool)__instance).controller.cmd.stage != 1)
			{
				return;
			}
			ItemProto itemProto = ((BuildTool)__instance).GetItemProto(__instance.startObjectId);
			if (itemProto != null && (itemProto.prefabDesc.isBelt || itemProto.prefabDesc.isSplitter))
			{
				if (Plugin.MatchStartingBeltHeight.Value)
				{
					float num = ((Vector3)(ref __instance.startTarget)).magnitude - ((BuildTool)__instance).planet.realRadius - 0.2f;
					__instance.altitude = Mathf.Clamp(Mathf.RoundToInt(num / 1.3333333f), 0, 60);
				}
				if (itemProto.prefabDesc.isBelt && Plugin.MatchStartingBeltTier.Value && ((Proto)itemProto).ID != ((BuildTool)__instance).controller.cmd.refId)
				{
					((BuildTool)__instance).player.SetHandItems(((Proto)itemProto).ID, 0, 0);
					((BuildTool)__instance).controller.cmd.refId = ((Proto)itemProto).ID;
					__instance.UpdateHandItem();
				}
			}
		}
	}
	[BepInPlugin("com.geostyx.dsp.geosbelttweaks", "Geo's Belt Tweaks", "0.2.0")]
	public class Plugin : BaseUnityPlugin
	{
		private Harmony? _harmony;

		internal static ManualLogSource Log;

		internal static ConfigEntry<bool> MatchStartingBeltTier;

		internal static ConfigEntry<bool> MatchStartingBeltHeight;

		internal static ConfigEntry<bool> ShowBeltPreviewTilt;

		internal static ConfigEntry<bool> ToggleBeltSurfaceHeight;

		internal static ConfigEntry<bool> RememberBeltFreeAngleMode;

		private void Awake()
		{
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			MatchStartingBeltHeight = ((BaseUnityPlugin)this).Config.Bind<bool>("Building", "MatchStartingBeltHeight", true, "Match the height of the belt or splitter you start from, rounded to the nearest build level. Applies to the next belt you start.");
			MatchStartingBeltTier = ((BaseUnityPlugin)this).Config.Bind<bool>("Building", "MatchStartingBeltTier", true, "Use the starting belt's tier when extending it. Applies to the next belt you start.");
			ShowBeltPreviewTilt = ((BaseUnityPlugin)this).Config.Bind<bool>("Building", "ShowBeltPreviewTilt", true, "Show the belt's slope and tilt in belt previews. Applies immediately.");
			ToggleBeltSurfaceHeight = ((BaseUnityPlugin)this).Config.Bind<bool>("Building", "ToggleBeltSurfaceHeight", true, "Toggle between the surface and the previous belt height with the reset-height hotkey (numpad 0 by default). Applies immediately.");
			RememberBeltFreeAngleMode = ((BaseUnityPlugin)this).Config.Bind<bool>("Building", "RememberBeltFreeAngleMode", true, "Keep free-angle mode selected when reopening the belt tool.");
			_harmony = new Harmony("com.geostyx.dsp.geosbelttweaks");
			try
			{
				_harmony.PatchAll(typeof(Plugin).Assembly);
			}
			catch
			{
				_harmony.UnpatchSelf();
				_harmony = null;
				throw;
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Geo's Belt Tweaks 0.2.0 loaded");
		}

		private void OnDestroy()
		{
			Harmony? harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
			_harmony = null;
			BeltPreviewTiltPatch.Release();
			ToggleBeltSurfaceHeightPatch.ClearSavedHeight();
		}
	}
	[HarmonyPatch(typeof(BuildTool_Path), "_OnOpen")]
	internal static class RememberBeltFreeAngleModePatch
	{
		[HarmonyPrefix]
		private static void Prefix(BuildTool_Path __instance, out bool __state)
		{
			__state = Plugin.RememberBeltFreeAngleMode.Value && __instance.geodesic;
		}

		[HarmonyPostfix]
		private static void Postfix(BuildTool_Path __instance, bool __state)
		{
			if (__state)
			{
				__instance.geodesic = true;
			}
		}
	}
	[HarmonyPatch]
	internal static class ToggleBeltSurfaceHeightPatch
	{
		private static int _savedAltitude;

		[HarmonyTranspiler]
		[HarmonyPatch(typeof(BuildTool_Path), "DeterminePreviews")]
		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Expected O, but got Unknown
			List<CodeInstruction> list = new List<CodeInstruction>(instructions);
			MethodInfo methodInfo = AccessTools.PropertyGetter(typeof(VFInput), "_beltsZeroKey");
			FieldInfo fieldInfo = AccessTools.Field(typeof(BuildTool_Path), "altitude");
			int num = -1;
			for (int i = 0; i + 4 < list.Count; i++)
			{
				if (CodeInstructionExtensions.Calls(list[i], methodInfo) && (list[i + 1].opcode == OpCodes.Brfalse || list[i + 1].opcode == OpCodes.Brfalse_S) && list[i + 2].opcode == OpCodes.Ldarg_0 && CodeInstructionExtensions.LoadsConstant(list[i + 3], 0L) && CodeInstructionExtensions.StoresField(list[i + 4], fieldInfo))
				{
					if (num >= 0)
					{
						throw new InvalidOperationException("GeosBeltTweaks belt surface toggle: multiple reset-height assignments in BuildTool_Path.DeterminePreviews.");
					}
					num = i + 3;
				}
			}
			if (num < 0)
			{
				throw new InvalidOperationException("GeosBeltTweaks belt surface toggle: reset-height assignment not found in BuildTool_Path.DeterminePreviews.");
			}
			list[num].opcode = OpCodes.Ldarg_0;
			list[num].operand = null;
			list.Insert(num + 1, new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(ToggleBeltSurfaceHeightPatch), "GetResetHeight", (Type[])null, (Type[])null)));
			return list;
		}

		private static int GetResetHeight(BuildTool_Path tool)
		{
			if (!Plugin.ToggleBeltSurfaceHeight.Value)
			{
				_savedAltitude = 0;
				return 0;
			}
			if (tool.altitude == 0)
			{
				return _savedAltitude;
			}
			_savedAltitude = Math.Max(0, Math.Min(60, tool.altitude));
			return 0;
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(BuildTool_Path), "_OnOpen")]
		private static void OnOpen()
		{
			_savedAltitude = 0;
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(BuildTool_Path), "_OnClose")]
		internal static void ClearSavedHeight()
		{
			_savedAltitude = 0;
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "com.geostyx.dsp.geosbelttweaks";

		public const string PLUGIN_NAME = "Geo's Belt Tweaks";

		public const string PLUGIN_VERSION = "0.2.0";
	}
}