using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using CommonAPI;
using CommonAPI.Systems.ModLocalization;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Rendering;
using crecheng.DSPModSave;
[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.7.0.0")]
[assembly: AssemblyInformationalVersion("0.7.0+954ea16393523eea94c036482e9024018f25f01f")]
[assembly: AssemblyProduct("Geo's Belt Tweaks")]
[assembly: AssemblyTitle("GeosBeltTweaks")]
[assembly: AssemblyVersion("0.7.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]
internal static class ChainUpgradeAcrossTiersPatch
{
[HarmonyTranspiler]
[HarmonyPatch(typeof(BuildTool_Upgrade), "DetermineMoreChainTargets")]
private static IEnumerable<CodeInstruction> ChainTargetsTranspiler(IEnumerable<CodeInstruction> instructions)
{
//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
//IL_00ad: Expected O, but got Unknown
List<CodeInstruction> list = new List<CodeInstruction>(instructions);
FieldInfo fieldInfo = AccessTools.Field(typeof(PrefabDesc), "beltSpeed");
MethodInfo methodInfo = AccessTools.Method(typeof(ChainUpgradeAcrossTiersPatch), "StopsChain", (Type[])null, (Type[])null);
int num = 0;
for (int i = 0; i + 1 < list.Count; i++)
{
if (CodeInstructionExtensions.LoadsField(list[i], fieldInfo, false) && (list[i + 1].opcode == OpCodes.Bne_Un || list[i + 1].opcode == OpCodes.Bne_Un_S))
{
list[i + 1].opcode = OpCodes.Brtrue;
list.Insert(++i, new CodeInstruction(OpCodes.Call, (object)methodInfo));
num++;
}
}
if (num != 1)
{
throw new InvalidOperationException($"GeosBeltTweaks chain upgrade across tiers: expected 1 belt speed comparison in BuildTool_Upgrade.DetermineMoreChainTargets, found {num}.");
}
return list;
}
private static bool StopsChain(int hoveredBeltSpeed, int beltSpeed)
{
if (!Plugin.ChainUpgradeAcrossTiers.Value)
{
return hoveredBeltSpeed != beltSpeed;
}
return false;
}
[HarmonyTranspiler]
[HarmonyPatch(typeof(BuildTool_Upgrade), "UpgradeAction")]
private static IEnumerable<CodeInstruction> UpgradeActionTranspiler(IEnumerable<CodeInstruction> instructions)
{
//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
//IL_00e1: Expected O, but got Unknown
List<CodeInstruction> list = new List<CodeInstruction>(instructions);
FieldInfo fieldInfo = AccessTools.Field(typeof(BuildPreview), "objId");
FieldInfo fieldInfo2 = AccessTools.Field(typeof(BuildTool_Upgrade), "upgradeLevel");
MethodInfo methodInfo = AccessTools.Method(typeof(ChainUpgradeAcrossTiersPatch), "GetChainGrade", (Type[])null, (Type[])null);
int num = 0;
for (int i = 0; i + 3 < list.Count; i++)
{
if (CodeInstructionExtensions.LoadsField(list[i], fieldInfo, false) && CodeInstructionExtensions.LoadsConstant(list[i + 1], 0L) && list[i + 2].opcode == OpCodes.Ldarg_0 && CodeInstructionExtensions.LoadsField(list[i + 3], fieldInfo2, false))
{
list[i + 1].opcode = OpCodes.Ldarg_0;
list[i + 1].operand = null;
list.Insert(i + 2, new CodeInstruction(OpCodes.Call, (object)methodInfo));
num++;
}
}
if (num != 2)
{
throw new InvalidOperationException($"GeosBeltTweaks chain upgrade across tiers: expected 2 DoUpgradeObject grade arguments in BuildTool_Upgrade.UpgradeAction, found {num}.");
}
return list;
}
private static int GetChainGrade(BuildTool_Upgrade tool)
{
if (!Plugin.ChainUpgradeAcrossTiers.Value || !tool.chainReaction || tool.cursorType != 0)
{
return 0;
}
BuildPreview val = ((BuildTool)tool).buildPreviews[0];
if (!val.desc.isBelt)
{
return 0;
}
return Math.Max(1, val.item.Grade + tool.upgradeLevel);
}
}
[HarmonyPatch]
internal static class HalfGridBeltSnapPatch
{
private const float TwoPi = (float)Math.PI * 2f;
internal static bool Enabled;
internal static bool HalfStep;
[HarmonyTranspiler]
[HarmonyPatch(typeof(BuildTool_Path), "UpdateRaycast")]
private static IEnumerable<CodeInstruction> SnapCursor(IEnumerable<CodeInstruction> instructions)
{
List<CodeInstruction> list = new List<CodeInstruction>(instructions);
MethodInfo methodInfo = AccessTools.Method(typeof(PlanetAuxData), "Snap", new Type[2]
{
typeof(Vector3),
typeof(bool)
}, (Type[])null);
List<int> list2 = new List<int>();
List<int> list3 = new List<int>();
for (int i = 0; i < list.Count; i++)
{
if (CodeInstructionExtensions.Calls(list[i], methodInfo))
{
list2.Add(i);
}
else if (list[i].opcode == OpCodes.Ldc_R4 && object.Equals(list[i].operand, 0.6f))
{
list3.Add(i);
}
}
if (list2.Count != 2 || list3.Count != 2)
{
throw new InvalidOperationException($"GeosBeltTweaks half-grid snapping: expected 2 PlanetAuxData.Snap calls and 2 object snap radii in BuildTool_Path.UpdateRaycast, found {list2.Count} and {list3.Count}.");
}
foreach (int item in list2)
{
list[item].opcode = OpCodes.Call;
list[item].operand = AccessTools.Method(typeof(HalfGridBeltSnapPatch), "Snap", (Type[])null, (Type[])null);
}
foreach (int item2 in list3)
{
list[item2].opcode = OpCodes.Call;
list[item2].operand = AccessTools.Method(typeof(HalfGridBeltSnapPatch), "GetObjectSnapRadius", (Type[])null, (Type[])null);
}
return list;
}
private static Vector3 Snap(PlanetAuxData aux, Vector3 pos, bool onTerrain)
{
//IL_0001: 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_0008: 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_001e: Unknown result type (might be due to invalid IL or missing references)
//IL_0023: Unknown result type (might be due to invalid IL or missing references)
//IL_002b: 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_005f: Unknown result type (might be due to invalid IL or missing references)
//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
Vector3 result = aux.Snap(pos, onTerrain);
PlanetGrid activeGrid = aux.activeGrid;
if (!Enabled || activeGrid == null)
{
return result;
}
Vector3 normalized = ((Vector3)(ref pos)).normalized;
int segment = activeGrid.segment;
float row = Mathf.Round(Mathf.Asin(normalized.y) / ((float)Math.PI * 2f) * (float)segment * 10f) / 10f;
float columnCount = GetColumnCount(row, segment);
float column = Mathf.Round(Mathf.Atan2(normalized.x, 0f - normalized.z) / ((float)Math.PI * 2f) * columnCount * 10f) / 10f;
float num = ((Vector3)(ref result)).magnitude + (HalfStep ? 0.6666666f : 0f);
return GetDirection(row, column, segment, columnCount) * num;
}
private static float GetObjectSnapRadius()
{
if (!Enabled)
{
return 0.6f;
}
return 0.3f;
}
[HarmonyPrefix]
[HarmonyPatch(typeof(PlanetGrid), "SnapLineNonAlloc")]
private static bool SnapLine(PlanetGrid __instance, Vector3 begin, Vector3 end, int path, Vector3[] snaps, out int swerveIndex, ref int __result)
{
//IL_004e: Unknown result type (might be due to invalid IL or missing references)
//IL_0053: Unknown result type (might be due to invalid IL or missing references)
//IL_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_005c: Unknown result type (might be due to invalid IL or missing references)
//IL_0068: Unknown result type (might be due to invalid IL or missing references)
//IL_006e: 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_0089: 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_009d: Unknown result type (might be due to invalid IL or missing references)
//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
//IL_00de: Unknown result type (might be due to invalid IL or missing references)
//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
//IL_010c: Unknown result type (might be due to invalid IL or missing references)
//IL_0112: Unknown result type (might be due to invalid IL or missing references)
//IL_012c: Unknown result type (might be due to invalid IL or missing references)
//IL_014a: Unknown result type (might be due to invalid IL or missing references)
//IL_014f: Unknown result type (might be due to invalid IL or missing references)
swerveIndex = 0;
if (!Enabled)
{
return true;
}
int segment = __instance.segment;
int capacity = snaps.Length - 10;
int count = 0;
__result = 0;
if (capacity <= 0)
{
return false;
}
Vector3 normalized = ((Vector3)(ref begin)).normalized;
Vector3 normalized2 = ((Vector3)(ref end)).normalized;
float num = Mathf.Asin(normalized.y);
float num2 = Mathf.Atan2(normalized.x, 0f - normalized.z);
float num3 = Mathf.Asin(normalized2.y);
float num4 = Mathf.Atan2(normalized2.x, 0f - normalized2.z);
bool flag = (normalized.x * normalized.x + normalized.z * normalized.z) * (float)segment * (float)segment < 1f;
bool flag2 = (normalized2.x * normalized2.x + normalized2.z * normalized2.z) * (float)segment * (float)segment < 1f;
if (flag && flag2 && normalized.y * normalized2.y >= 0f)
{
snaps[0] = new Vector3(0f, (normalized.y >= 0f) ? 1f : (-1f), 0f);
__result = 1;
return false;
}
if (flag && flag2)
{
num2 = (num4 = 0f);
num = Mathf.Sign(num) * (float)Math.PI * 0.5f;
num3 = Mathf.Sign(num3) * (float)Math.PI * 0.5f;
}
else if (flag)
{
num2 = num4;
num = Mathf.Sign(num) * (float)Math.PI * 0.5f;
}
else if (flag2)
{
num4 = num2;
num3 = Mathf.Sign(num3) * (float)Math.PI * 0.5f;
}
float num5 = Mathf.Repeat(num4 - num2, (float)Math.PI * 2f);
if (num5 > (float)Math.PI)
{
num5 -= (float)Math.PI * 2f;
}
if (num5 > 2f || num5 < -2f)
{
num5 -= Mathf.Sign(num5) * (float)Math.PI;
num3 = ((num3 >= 0f) ? ((float)Math.PI) : (-(float)Math.PI)) - num3;
}
num4 = num2 + num5;
int num6 = Mathf.RoundToInt(num / ((float)Math.PI * 2f) * (float)segment * 10f);
int num7 = Mathf.RoundToInt(num3 / ((float)Math.PI * 2f) * (float)segment * 10f);
float row;
float columns;
int num8 = Mathf.RoundToInt(GetHalfColumn(num6, num2, out row, out columns)) & 1;
int num9 = Mathf.RoundToInt(GetHalfColumn(num7, num4, out columns, out row)) & 1;
if (path == 1)
{
AddParallel(num6, num2, num8, num4, num9);
swerveIndex = count;
AddMeridian(num4, num9, num6, num7);
}
else
{
AddMeridian(num2, num8, num6, num7);
swerveIndex = count;
AddParallel(num7, num2, num8, num4, num9);
}
__result = count;
return false;
void Add(Vector3 point)
{
//IL_0061: Unknown result type (might be due to invalid IL or missing references)
//IL_0062: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
//IL_0033: Unknown result type (might be due to invalid IL or missing references)
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
//IL_003d: Unknown result type (might be due to invalid IL or missing references)
float num10 = 0.25f / (float)segment;
if (count < capacity)
{
if (count != 0)
{
Vector3 val = point - snaps[count - 1];
if (!(((Vector3)(ref val)).sqrMagnitude > num10 * num10))
{
return;
}
}
snaps[count++] = point;
}
}
void AddMeridian(float longitude, int parity, int fromHalfRow, int toHalfRow)
{
int num10 = ((toHalfRow >= fromHalfRow) ? 2 : (-2));
for (int i = fromHalfRow; (toHalfRow - i) * num10 > 0; i += num10)
{
if (count >= capacity)
{
break;
}
AddOnMeridian(i, longitude, parity);
}
AddOnMeridian(toHalfRow, longitude, parity);
}
void AddOnMeridian(int halfRow, float longitude, int parity)
{
//IL_0023: Unknown result type (might be due to invalid IL or missing references)
float row2;
float columns2;
int num10 = Align(GetHalfColumn(halfRow, longitude, out row2, out columns2), parity);
Add(GetDirection(row2, (float)num10 / 10f, segment, columns2));
}
void AddParallel(int halfRow, float fromLongitude, int fromParity, float toLongitude, int toParity)
{
//IL_0089: 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)
float row2;
float columns2;
int num10 = Align(GetHalfColumn(halfRow, fromLongitude, out row2, out columns2), fromParity);
float row3;
float columns3;
int num11 = Align(GetHalfColumn(halfRow, toLongitude, out row3, out columns3), toParity);
int num12 = ((num11 >= num10) ? 2 : (-2));
for (int i = num10; (num11 - i) * num12 > 0; i += num12)
{
if (count >= capacity)
{
break;
}
Add(GetDirection(row2, (float)i / 10f, segment, columns2));
}
Add(GetDirection(row2, (float)num11 / 10f, segment, columns2));
}
static int Align(float halfColumn, int parity)
{
return parity + 2 * Mathf.RoundToInt((halfColumn - (float)parity) / 2f);
}
float GetHalfColumn(int halfRow, float longitude, out float reference, out float reference2)
{
reference = (float)halfRow / 10f;
if (Mathf.Abs(reference) > (float)segment / 4f)
{
reference = Mathf.Sign(reference) * (float)segment / 2f - reference;
longitude += (float)Math.PI;
}
reference2 = GetColumnCount(reference, segment);
return longitude / ((float)Math.PI * 2f) * reference2 * 10f;
}
}
private static float GetColumnCount(float row, int segment)
{
return PlanetGrid.DetermineLongitudeSegmentCount(Mathf.FloorToInt(Mathf.Max(0f, Mathf.Abs(row) - 0.05f)), segment);
}
private static Vector3 GetDirection(float row, float column, int segment, float columns)
{
//IL_0033: Unknown result type (might be due to invalid IL or missing references)
float num = row / (float)segment * ((float)Math.PI * 2f);
float num2 = column / columns * ((float)Math.PI * 2f);
float num3 = Mathf.Cos(num);
return new Vector3(num3 * Mathf.Sin(num2), Mathf.Sin(num), (0f - num3) * Mathf.Cos(num2));
}
[HarmonyPrefix]
[HarmonyPatch(typeof(BuildTool_Path), "DeterminePreviews")]
private static void StepHalfHeight(BuildTool_Path __instance)
{
if (!Enabled)
{
return;
}
if (VFInput._notSnapBuild)
{
if (VFInput._liftBeltsHeight)
{
HalfStep &= __instance.altitude + 2 < 60;
__instance.altitude -= 3;
}
if (VFInput._reduceBeltsHeight)
{
HalfStep &= __instance.altitude >= 2;
__instance.altitude += 3;
}
return;
}
if (VFInput._liftBeltsHeight)
{
if (HalfStep)
{
HalfStep = false;
}
else if (__instance.altitude < 60)
{
HalfStep = true;
__instance.altitude--;
}
}
if (VFInput._reduceBeltsHeight)
{
if (HalfStep)
{
HalfStep = false;
__instance.altitude++;
}
else if (__instance.altitude > 0)
{
HalfStep = true;
}
}
}
[HarmonyPostfix]
[HarmonyPatch(typeof(BuildTool_Path), "_OnClose")]
private static void ClearHalfStep()
{
HalfStep = false;
}
[HarmonyPostfix]
[HarmonyPatch(typeof(UIBuildingGrid), "Update")]
private static void RaiseAltitudeGrid(UIBuildingGrid __instance)
{
//IL_006b: Unknown result type (might be due to invalid IL or missing references)
PlanetData localPlanet = GameMain.localPlanet;
Player mainPlayer = GameMain.mainPlayer;
if (HalfStep && __instance.altGridRnd.enabled && localPlanet != null && mainPlayer != null)
{
float num = (localPlanet.realRadius + 0.2f + ((float)mainPlayer.controller.actionBuild.pathTool.altitude + 0.5f) * 1.3333333f) * 2f;
((Component)__instance.altGridRnd).transform.localScale = new Vector3(num, num, num);
}
}
}
[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))
{
return;
}
if (Plugin.MatchStartingBeltHeight.Value)
{
float num = ((Vector3)(ref __instance.startTarget)).magnitude - ((BuildTool)__instance).planet.realRadius - 0.2f;
if (HalfGridBeltSnapPatch.Enabled)
{
int num2 = Mathf.Clamp(Mathf.RoundToInt(num / 0.6666666f), 0, 120);
__instance.altitude = num2 / 2;
HalfGridBeltSnapPatch.HalfStep = num2 % 2 == 1;
}
else
{
__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();
}
}
}
[HarmonyPatch]
internal static class PauseBattleBaseBuildingPatch
{
internal static bool Enabled;
private static PlanetFactory? _pausedFactory;
private static IEnumerable<MethodBase> TargetMethods()
{
yield return AccessTools.Method(typeof(ConstructionModuleComponent), "GameTick", (Type[])null, (Type[])null);
yield return AccessTools.Method(typeof(ConstructionModuleComponent), "PlaceItems", (Type[])null, (Type[])null);
yield return AccessTools.Method(typeof(ConstructionModuleComponent), "SearchBuildTargets", (Type[])null, (Type[])null);
yield return AccessTools.Method(typeof(ConstructionSystem), "UpdateDrones", (Type[])null, (Type[])null);
yield return AccessTools.Method(typeof(ConstructionSystem), "AddBuildTargetToModules", (Type[])null, (Type[])null);
}
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions, MethodBase original)
{
List<CodeInstruction> list = new List<CodeInstruction>(instructions);
FieldInfo fieldInfo = AccessTools.Field(typeof(ConstructionModuleComponent), "droneConstructEnabled");
MethodInfo operand = AccessTools.Method(typeof(PauseBattleBaseBuildingPatch), "CanBuild", (Type[])null, (Type[])null);
bool flag = false;
foreach (CodeInstruction item in list)
{
if (CodeInstructionExtensions.LoadsField(item, fieldInfo, false))
{
item.opcode = OpCodes.Call;
item.operand = operand;
flag = true;
}
}
if (!flag)
{
throw new InvalidOperationException("GeosBeltTweaks BAB building pause: droneConstructEnabled not read in " + original.DeclaringType.Name + "." + original.Name + ".");
}
return list;
}
private static bool CanBuild(ConstructionModuleComponent module)
{
ConstructionModuleComponent[] array = _pausedFactory?.constructionSystem.constructionModules.buffer;
if (module.droneConstructEnabled)
{
if (array != null && module.id < array.Length)
{
return array[module.id] != module;
}
return true;
}
return false;
}
internal static void Update()
{
Player mainPlayer = GameMain.mainPlayer;
PlanetFactory val = ((Enabled && ((mainPlayer != null) ? mainPlayer.controller.actionBuild.activeTool : null) is BuildTool_Path) ? mainPlayer.factory : null);
if (val == _pausedFactory)
{
return;
}
PlanetFactory pausedFactory = _pausedFactory;
_pausedFactory = val;
if (mainPlayer != null)
{
if (pausedFactory != null && pausedFactory.gameData == GameMain.data)
{
SearchBuildTargets(pausedFactory, mainPlayer);
}
if (val != null)
{
SearchBuildTargets(val, mainPlayer);
}
}
}
private static void SearchBuildTargets(PlanetFactory factory, Player player)
{
ObjectPool<ConstructionModuleComponent> constructionModules = factory.constructionSystem.constructionModules;
for (int i = 1; i < constructionModules.cursor; i++)
{
ConstructionModuleComponent val = constructionModules.buffer[i];
if (val != null && val.id == i && val.entityId > 0 && factory.entityPool[val.entityId].id == val.entityId)
{
val.SearchBuildTargets(factory, player, true);
}
}
}
}
[BepInPlugin("com.geostyx.dsp.geosbelttweaks", "Geo's Belt Tweaks", "0.7.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[CommonAPISubmoduleDependency(new string[] { "LocalizationModule" })]
public class Plugin : BaseUnityPlugin, IModCanSave
{
private const int SaveVersion = 2;
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;
internal static ConfigEntry<bool> UnlimitedChainUpgradeRange;
internal static ConfigEntry<bool> ChainUpgradeAcrossTiers;
internal static ConfigEntry<KeyboardShortcut> ToggleHalfGridSnapKey;
internal static ConfigEntry<KeyboardShortcut> ToggleSlopeFromStartKey;
internal static ConfigEntry<KeyboardShortcut> ToggleBattleBaseConstructionKey;
private void Awake()
{
//IL_0102: Unknown result type (might be due to invalid IL or missing references)
//IL_0130: Unknown result type (might be due to invalid IL or missing references)
//IL_015e: 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_0284: Expected O, but got Unknown
Log = ((BaseUnityPlugin)this).Logger;
MatchStartingBeltHeight = ((BaseUnityPlugin)this).Config.Bind<bool>("Building", "MatchStartingBeltHeight", true, "Start new belts at the height of the belt or splitter you drag from.");
MatchStartingBeltTier = ((BaseUnityPlugin)this).Config.Bind<bool>("Building", "MatchStartingBeltTier", true, "Select the starting belt's tier when extending it.");
ShowBeltPreviewTilt = ((BaseUnityPlugin)this).Config.Bind<bool>("Building", "ShowBeltPreviewTilt", true, "Show slope and tilt in belt previews.");
ToggleBeltSurfaceHeight = ((BaseUnityPlugin)this).Config.Bind<bool>("Building", "ToggleBeltSurfaceHeight", true, "The reset-height key toggles between the surface and the previous height.");
RememberBeltFreeAngleMode = ((BaseUnityPlugin)this).Config.Bind<bool>("Building", "RememberBeltFreeAngleMode", true, "Keep free-angle mode on when reopening the belt tool.");
UnlimitedChainUpgradeRange = ((BaseUnityPlugin)this).Config.Bind<bool>("Building", "UnlimitedChainUpgradeRange", true, "Chain upgrades reach the whole belt, ignoring build range.");
ChainUpgradeAcrossTiers = ((BaseUnityPlugin)this).Config.Bind<bool>("Building", "ChainUpgradeAcrossTiers", true, "Chain upgrades continue through tier changes.");
ToggleHalfGridSnapKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Building", "ToggleHalfGridSnapKey", new KeyboardShortcut((KeyCode)96, Array.Empty<KeyCode>()), "Toggles half-grid snapping in the belt tool.");
ToggleSlopeFromStartKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Building", "ToggleSlopeFromStartKey", new KeyboardShortcut((KeyCode)257, Array.Empty<KeyCode>()), "Toggles sloping from the first segment in the belt tool.");
ToggleBattleBaseConstructionKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Building", "ToggleBattleBaseConstructionKey", new KeyboardShortcut((KeyCode)258, Array.Empty<KeyCode>()), "Toggles building by Battlefield Analysis Bases on the planet while the belt tool is open.");
ToggleHalfGridSnapKey.SettingChanged += ToggleKeyTip.HalfGrid.OnKeyChanged;
ToggleSlopeFromStartKey.SettingChanged += ToggleKeyTip.SlopeFromStart.OnKeyChanged;
ToggleBattleBaseConstructionKey.SettingChanged += ToggleKeyTip.BattleBaseConstruction.OnKeyChanged;
LocalizationModule.RegisterTranslation(ToggleKeyTip.HalfGrid.OnText, "Half-grid: on", "半格:开", "");
LocalizationModule.RegisterTranslation(ToggleKeyTip.HalfGrid.OffText, "Half-grid: off", "半格:关", "");
LocalizationModule.RegisterTranslation(ToggleKeyTip.SlopeFromStart.OnText, "Slope from start: on", "起点起坡:开", "");
LocalizationModule.RegisterTranslation(ToggleKeyTip.SlopeFromStart.OffText, "Slope from start: off", "起点起坡:关", "");
LocalizationModule.RegisterTranslation(ToggleKeyTip.BattleBaseConstruction.OnText, "BAB construction: on", "战场分析基站建设:开", "");
LocalizationModule.RegisterTranslation(ToggleKeyTip.BattleBaseConstruction.OffText, "BAB construction: off", "战场分析基站建设:关", "");
_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.7.0 loaded");
}
private void Update()
{
//IL_0034: Unknown result type (might be due to invalid IL or missing references)
//IL_0039: Unknown result type (might be due to invalid IL or missing references)
//IL_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_007c: Unknown result type (might be due to invalid IL or missing references)
//IL_0081: Unknown result type (might be due to invalid IL or missing references)
PauseBattleBaseBuildingPatch.Update();
if (VFInput.inputing)
{
return;
}
Player mainPlayer = GameMain.mainPlayer;
if (((mainPlayer != null) ? mainPlayer.controller.actionBuild.activeTool : null) is BuildTool_Path)
{
KeyboardShortcut value = ToggleHalfGridSnapKey.Value;
if (((KeyboardShortcut)(ref value)).IsDown())
{
HalfGridBeltSnapPatch.Enabled = !HalfGridBeltSnapPatch.Enabled;
HalfGridBeltSnapPatch.HalfStep = false;
}
value = ToggleSlopeFromStartKey.Value;
if (((KeyboardShortcut)(ref value)).IsDown())
{
SlopeFromStartPatch.Enabled = !SlopeFromStartPatch.Enabled;
}
value = ToggleBattleBaseConstructionKey.Value;
if (((KeyboardShortcut)(ref value)).IsDown())
{
PauseBattleBaseBuildingPatch.Enabled = !PauseBattleBaseBuildingPatch.Enabled;
}
}
}
private void OnDestroy()
{
ToggleHalfGridSnapKey.SettingChanged -= ToggleKeyTip.HalfGrid.OnKeyChanged;
ToggleSlopeFromStartKey.SettingChanged -= ToggleKeyTip.SlopeFromStart.OnKeyChanged;
ToggleBattleBaseConstructionKey.SettingChanged -= ToggleKeyTip.BattleBaseConstruction.OnKeyChanged;
Harmony? harmony = _harmony;
if (harmony != null)
{
harmony.UnpatchSelf();
}
_harmony = null;
BeltPreviewTiltPatch.Release();
ToggleBeltSurfaceHeightPatch.ClearSavedHeight();
ToggleKeyTip.HalfGrid.Destroy();
ToggleKeyTip.SlopeFromStart.Destroy();
ToggleKeyTip.BattleBaseConstruction.Destroy();
}
public void Export(BinaryWriter w)
{
w.Write(2);
w.Write(HalfGridBeltSnapPatch.Enabled);
w.Write(SlopeFromStartPatch.Enabled);
Player mainPlayer = GameMain.mainPlayer;
w.Write(mainPlayer != null && mainPlayer.controller.actionBuild.pathTool.geodesic);
w.Write(PauseBattleBaseBuildingPatch.Enabled);
}
public void Import(BinaryReader r)
{
int num = r.ReadInt32();
if (num > 2)
{
Log.LogWarning((object)$"Ignoring belt tool modes saved by a newer version (save data version {num})");
IntoOtherSave();
return;
}
HalfGridBeltSnapPatch.Enabled = r.ReadBoolean();
HalfGridBeltSnapPatch.HalfStep = false;
SlopeFromStartPatch.Enabled = r.ReadBoolean();
bool geodesic = r.ReadBoolean();
PauseBattleBaseBuildingPatch.Enabled = num >= 2 && r.ReadBoolean();
if (GameMain.mainPlayer != null)
{
GameMain.mainPlayer.controller.actionBuild.pathTool.geodesic = geodesic;
}
}
public void IntoOtherSave()
{
HalfGridBeltSnapPatch.Enabled = false;
HalfGridBeltSnapPatch.HalfStep = false;
SlopeFromStartPatch.Enabled = false;
PauseBattleBaseBuildingPatch.Enabled = false;
}
}
[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(typeof(PlanetAuxData), "SnapLineNonAlloc")]
internal static class SlopeFromStartPatch
{
internal static bool Enabled;
private static bool _snappingFlatStart;
[HarmonyPrefix]
private static void Prefix(ref bool begin_flat, out bool __state)
{
__state = begin_flat && Enabled && !_snappingFlatStart;
begin_flat &= !__state;
}
[HarmonyPostfix]
private static void Postfix(PlanetAuxData __instance, Vector3 begin, Vector3 end, int path, bool geodesic, Vector3[] snaps, bool forceVertical, ref float maxGridSlope, bool useOldPath, ref int __result, bool __state)
{
//IL_000a: 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_00e8: 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_0037: Unknown result type (might be due to invalid IL or missing references)
//IL_003c: Unknown result type (might be due to invalid IL or missing references)
//IL_003f: Unknown result type (might be due to invalid IL or missing references)
//IL_004c: Unknown result type (might be due to invalid IL or missing references)
//IL_0056: Unknown result type (might be due to invalid IL or missing references)
//IL_0062: Unknown result type (might be due to invalid IL or missing references)
//IL_0067: Unknown result type (might be due to invalid IL or missing references)
//IL_0068: 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_006a: 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_0091: Unknown result type (might be due to invalid IL or missing references)
//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
if (!__state || __result < 2 || CanSlopeFromStart(begin, snaps[1]))
{
return;
}
if (HalfGridBeltSnapPatch.Enabled && __result < snaps.Length - 10)
{
Vector3 val = snaps[0];
Vector3 val2 = Vector3.Slerp(((Vector3)(ref val)).normalized, ((Vector3)(ref snaps[1])).normalized, 0.5f) * ((Vector3)(ref val)).magnitude;
Vector3 val3 = val2 - val;
if (((Vector3)(ref val3)).sqrMagnitude >= 0.28f)
{
for (int num = __result; num >= 2; num--)
{
snaps[num] = ((Vector3)(ref snaps[num - 1])).normalized * ((((Vector3)(ref snaps[num - 1])).magnitude + ((Vector3)(ref snaps[num - 2])).magnitude) / 2f);
}
snaps[1] = val2;
__result++;
return;
}
}
_snappingFlatStart = true;
try
{
__result = __instance.SnapLineNonAlloc(begin, end, path, geodesic, true, snaps, forceVertical, ref maxGridSlope, useOldPath);
}
finally
{
_snappingFlatStart = false;
}
}
private static bool CanSlopeFromStart(Vector3 start, Vector3 next)
{
//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_0097: Unknown result type (might be due to invalid IL or missing references)
//IL_0084: Unknown result type (might be due to invalid IL or missing references)
//IL_009c: Unknown result type (might be due to invalid IL or missing references)
//IL_009e: Unknown result type (might be due to invalid IL or missing references)
//IL_009f: Unknown result type (might be due to invalid IL or missing references)
//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
if (Mathf.Abs(Maths.SphericalSlopeRatio(start, next)) <= 0.1f)
{
return true;
}
Player mainPlayer = GameMain.mainPlayer;
BuildTool_Path val = ((mainPlayer == null) ? null : mainPlayer.controller?.actionBuild?.pathTool);
if (val == null || !((BuildTool)val).ObjectIsBelt(val.startObjectId))
{
return false;
}
PlanetFactory factory = ((BuildTool)val).factory;
bool flag = default(bool);
int num = default(int);
int num2 = default(int);
for (int i = 1; i < 4; i++)
{
factory.ReadObjectConn(val.startObjectId, i, ref flag, ref num, ref num2);
if (num != 0)
{
Vector3 val2 = ((num > 0) ? factory.entityPool[num].pos : factory.prebuildPool[-num].pos);
if (Maths.SphericalAngleAOBInRAD(start, next, val2) >= 2.5f)
{
return true;
}
}
}
return false;
}
}
[HarmonyPatch]
internal static class ToggleBeltSurfaceHeightPatch
{
private static int _savedAltitude;
private static bool _savedHalfStep;
[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;
_savedHalfStep = false;
HalfGridBeltSnapPatch.HalfStep = false;
return 0;
}
if (tool.altitude == 0 && !HalfGridBeltSnapPatch.HalfStep)
{
HalfGridBeltSnapPatch.HalfStep = _savedHalfStep && HalfGridBeltSnapPatch.Enabled;
return _savedAltitude;
}
_savedAltitude = Math.Max(0, Math.Min(60, tool.altitude));
_savedHalfStep = HalfGridBeltSnapPatch.HalfStep && _savedAltitude < 60;
HalfGridBeltSnapPatch.HalfStep = false;
return 0;
}
[HarmonyPostfix]
[HarmonyPatch(typeof(BuildTool_Path), "_OnOpen")]
private static void OnOpen()
{
_savedAltitude = 0;
_savedHalfStep = false;
}
[HarmonyPostfix]
[HarmonyPatch(typeof(BuildTool_Path), "_OnClose")]
internal static void ClearSavedHeight()
{
_savedAltitude = 0;
_savedHalfStep = false;
}
}
[HarmonyPatch]
internal sealed class ToggleKeyTip(string onText, string offText)
{
internal static readonly ToggleKeyTip HalfGrid = new ToggleKeyTip("GeosBeltTweaks half-grid snapping on", "GeosBeltTweaks half-grid snapping off");
internal static readonly ToggleKeyTip SlopeFromStart = new ToggleKeyTip("GeosBeltTweaks slope from start on", "GeosBeltTweaks slope from start off");
internal static readonly ToggleKeyTip BattleBaseConstruction = new ToggleKeyTip("GeosBeltTweaks battle base construction on", "GeosBeltTweaks battle base construction off");
internal readonly string OnText = onText;
internal readonly string OffText = offText;
private UIKeyTipNode? _keyTip;
private string _onTip = "";
private string _offTip = "";
private bool _keyLabelStale;
private bool _hasKey;
[HarmonyPostfix]
[HarmonyPatch(typeof(UIKeyTips), "RegisterAllTips")]
private static void RegisterKeyTips(UIKeyTips __instance)
{
HalfGrid.Register(__instance);
SlopeFromStart.Register(__instance);
BattleBaseConstruction.Register(__instance);
}
[HarmonyPostfix]
[HarmonyPatch(typeof(UIKeyTips), "UpdateTipDesiredState")]
private static void UpdateKeyTips(UIKeyTips __instance)
{
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
//IL_003f: Unknown result type (might be due to invalid IL or missing references)
HalfGrid.Update(__instance, Plugin.ToggleHalfGridSnapKey.Value, HalfGridBeltSnapPatch.Enabled);
SlopeFromStart.Update(__instance, Plugin.ToggleSlopeFromStartKey.Value, SlopeFromStartPatch.Enabled);
BattleBaseConstruction.Update(__instance, Plugin.ToggleBattleBaseConstructionKey.Value, !PauseBattleBaseBuildingPatch.Enabled);
}
private void Register(UIKeyTips tips)
{
_onTip = Localization.Translate(onText);
_offTip = Localization.Translate(offText);
_keyTip = tips.RegisterTip("", _offTip);
_keyLabelStale = true;
}
private void Update(UIKeyTips tips, KeyboardShortcut shortcut, bool on)
{
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
//IL_002a: Invalid comparison between Unknown and I4
//IL_0043: Unknown result type (might be due to invalid IL or missing references)
//IL_0048: Unknown result type (might be due to invalid IL or missing references)
//IL_004b: Unknown result type (might be due to invalid IL or missing references)
//IL_0051: Unknown result type (might be due to invalid IL or missing references)
//IL_006f: Expected I4, but got Unknown
//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
//IL_00b2: Expected I4, but got Unknown
//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)
if ((Object)(object)_keyTip == (Object)null)
{
return;
}
if (_keyLabelStale)
{
_keyLabelStale = false;
_hasKey = (int)((KeyboardShortcut)(ref shortcut)).MainKey > 0;
byte b = 0;
foreach (KeyCode modifier in ((KeyboardShortcut)(ref shortcut)).Modifiers)
{
int num = b;
int num2;
switch (modifier - 303)
{
case 0:
case 1:
num2 = 1;
break;
case 2:
case 3:
num2 = 2;
break;
case 4:
case 5:
num2 = 4;
break;
default:
num2 = 0;
break;
}
b = (byte)(num | num2);
}
UIKeyTipNode? keyTip = _keyTip;
CombineKey val = new CombineKey((int)((KeyboardShortcut)(ref shortcut)).MainKey, b, (ECombineKeyAction)0, false);
keyTip.SetKeyTip(((CombineKey)(ref val)).ToTokenString(0), _offTip);
}
_keyTip.desired = _hasKey && tips.zeroKeyInBuildMode2.desired;
_keyTip.tipTextComp.text = (on ? _onTip : _offTip);
}
internal void OnKeyChanged(object sender, EventArgs e)
{
_keyLabelStale = true;
}
internal void Destroy()
{
if ((Object)(object)_keyTip != (Object)null)
{
((ManualBehaviour)_keyTip)._Destroy();
}
_keyTip = null;
}
}
[HarmonyPatch(typeof(BuildTool_Upgrade), "DetermineMoreChainTargets")]
internal static class UnlimitedChainUpgradeRangePatch
{
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
{
//IL_0059: Unknown result type (might be due to invalid IL or missing references)
//IL_0063: Expected O, but got Unknown
List<CodeInstruction> list = new List<CodeInstruction>(instructions);
FieldInfo fieldInfo = AccessTools.Field(typeof(Mecha), "buildArea");
MethodInfo methodInfo = AccessTools.Method(typeof(UnlimitedChainUpgradeRangePatch), "GetChainBuildArea", (Type[])null, (Type[])null);
int num = 0;
for (int i = 0; i < list.Count; i++)
{
if (CodeInstructionExtensions.LoadsField(list[i], fieldInfo, false))
{
list.Insert(++i, new CodeInstruction(OpCodes.Call, (object)methodInfo));
num++;
}
}
if (num != 2)
{
throw new InvalidOperationException($"GeosBeltTweaks unlimited chain upgrade range: expected 2 build area reads in BuildTool_Upgrade.DetermineMoreChainTargets, found {num}.");
}
return list;
}
private static float GetChainBuildArea(float buildArea)
{
if (!Plugin.UnlimitedChainUpgradeRange.Value)
{
return buildArea;
}
return float.PositiveInfinity;
}
}
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.7.0";
}
}