Decompiled source of BuildModeNoAutoZoom v1.0.2

plugins/noautozoom.dll

Decompiled 3 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("squarepatchmod")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("squarepatchmod")]
[assembly: AssemblyCopyright("Copyright ©  2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("0a889f29-f468-4803-b8f9-663f72777b5c")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace BuildModeNoAutoZoom;

[BepInPlugin("nekogod.dsp.buildmode.noautozoom", "DSP Build Mode No AutoZoom", "1.0.2")]
public class BuildModeNoAutoZoomPlugin : BaseUnityPlugin
{
	public const string PluginGuid = "nekogod.dsp.buildmode.noautozoom";

	public const string PluginName = "DSP Build Mode No AutoZoom";

	public const string PluginVersion = "1.0.2";

	internal static ConfigEntry<bool> Enabled;

	internal static ConfigEntry<float> ExtraMaxZoomOut;

	internal static ConfigEntry<int> ShiftClickPinFrames;

	private void Awake()
	{
		//IL_0069: Unknown result type (might be due to invalid IL or missing references)
		//IL_006f: Expected O, but got Unknown
		//IL_009f: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a5: Expected O, but got Unknown
		Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Enable mod.");
		ExtraMaxZoomOut = ((BaseUnityPlugin)this).Config.Bind<float>("General", "ExtraMaxZoomOut", 2f, "Permanent extra max zoom-out distance (meters). 0 disables.");
		ShiftClickPinFrames = ((BaseUnityPlugin)this).Config.Bind<int>("General", "ShiftClickPinFrames", 8, "How many frames to enforce the non-build camera pose after Shift+LMB (covers shift-click entry path). -Shouldn't need changing, but increase if you still see auto zooming when shift+clicking.");
		Harmony val = new Harmony("nekogod.dsp.buildmode.noautozoom");
		MethodInfo methodInfo = AccessTools.Method(typeof(CameraPoseBlender), "Calculate", (Type[])null, (Type[])null);
		if (methodInfo != null)
		{
			HarmonyMethod val2 = new HarmonyMethod(typeof(BlenderPinPatches), "CameraPoseBlender_Calculate_Prefix", (Type[])null);
			val.Patch((MethodBase)methodInfo, val2, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		}
		PatchPoserByExactTypeNameFromAssemblyCSharp(val, "RTSPoser");
		PatchPoserByExactTypeNameFromAssemblyCSharp(val, "PRTSPoser");
	}

	private void Update()
	{
		if (!Enabled.Value)
		{
			return;
		}
		try
		{
			if (Input.GetMouseButtonDown(0) && (Input.GetKey((KeyCode)304) || Input.GetKey((KeyCode)303)) && !BlenderPinPatches.IsBlueprintToolActive_Public())
			{
				BlenderPinPatches.OnShiftClick_Public();
			}
		}
		catch
		{
		}
	}

	private static void PatchPoserByExactTypeNameFromAssemblyCSharp(Harmony h, string typeName)
	{
		//IL_0120: Unknown result type (might be due to invalid IL or missing references)
		//IL_0127: Expected O, but got Unknown
		try
		{
			Assembly assembly = FindAssembly("Assembly-CSharp");
			if (assembly == null)
			{
				return;
			}
			Type type = assembly.GetType(typeName, throwOnError: false);
			if (type == null)
			{
				return;
			}
			MethodInfo methodInfo = AccessTools.Method(type, "Calculate", (Type[])null, (Type[])null);
			if (!(methodInfo == null))
			{
				FieldInfo fieldInfo = AccessTools.Field(type, "distMax");
				FieldInfo fieldInfo2 = AccessTools.Field(type, "distMin");
				FieldInfo fieldInfo3 = AccessTools.Field(type, "dist");
				FieldInfo fieldInfo4 = AccessTools.Field(type, "distCoef");
				if (!(fieldInfo == null) && !(fieldInfo.FieldType != typeof(float)) && !(fieldInfo2 == null) && !(fieldInfo2.FieldType != typeof(float)) && !(fieldInfo3 == null) && !(fieldInfo3.FieldType != typeof(float)) && !(fieldInfo4 == null) && !(fieldInfo4.FieldType != typeof(float)))
				{
					HarmonyMethod val = new HarmonyMethod(typeof(PermanentZoomPatches), "Calculate_Prefix", (Type[])null);
					h.Patch((MethodBase)methodInfo, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				}
			}
		}
		catch
		{
		}
	}

	private static Assembly FindAssembly(string simpleName)
	{
		try
		{
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			foreach (Assembly assembly in assemblies)
			{
				if (!(assembly == null) && string.Equals(assembly.GetName().Name, simpleName, StringComparison.OrdinalIgnoreCase))
				{
					return assembly;
				}
			}
		}
		catch
		{
		}
		return null;
	}
}
internal static class BlenderPinPatches
{
	private sealed class RefEq<T> : IEqualityComparer<T> where T : class
	{
		public static readonly RefEq<T> Instance = new RefEq<T>();

		public bool Equals(T x, T y)
		{
			return x == y;
		}

		public int GetHashCode(T obj)
		{
			return RuntimeHelpers.GetHashCode(obj);
		}
	}

	private sealed class BlenderState
	{
		public FieldInfo IndexField;

		public int LastNonBuildIndex;

		public bool HasNonBuild;

		public int Baseline;

		public bool PinActive;
	}

	private static readonly Dictionary<CameraPoseBlender, BlenderState> _states = new Dictionary<CameraPoseBlender, BlenderState>(RefEq<CameraPoseBlender>.Instance);

	private static bool _lastBuildActive;

	private static int _forcedPinFrames = 0;

	internal static void OnShiftClick_Public()
	{
		SnapshotAllBlendersAsNonBuild();
		ArmPinningFromSnapshots();
		_forcedPinFrames = Math.Max(1, BuildModeNoAutoZoomPlugin.ShiftClickPinFrames.Value);
	}

	internal static bool IsBlueprintToolActive_Public()
	{
		return IsBlueprintToolActive();
	}

	private static void SnapshotAllBlendersAsNonBuild()
	{
		try
		{
			CameraPoseBlender[] array = Resources.FindObjectsOfTypeAll<CameraPoseBlender>();
			if (array == null)
			{
				return;
			}
			foreach (CameraPoseBlender val in array)
			{
				if (!((Object)(object)val == (Object)null))
				{
					if (!_states.TryGetValue(val, out var value))
					{
						value = new BlenderState();
						value.IndexField = ((object)val).GetType().GetField("index", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
						_states[val] = value;
					}
					if (!(value.IndexField == null))
					{
						int lastNonBuildIndex = (int)value.IndexField.GetValue(val);
						value.LastNonBuildIndex = lastNonBuildIndex;
						value.HasNonBuild = true;
					}
				}
			}
		}
		catch
		{
		}
	}

	private static void ArmPinningFromSnapshots()
	{
		foreach (KeyValuePair<CameraPoseBlender, BlenderState> state in _states)
		{
			BlenderState value = state.Value;
			if (value != null && !(value.IndexField == null))
			{
				if (value.HasNonBuild)
				{
					value.Baseline = value.LastNonBuildIndex;
				}
				value.PinActive = true;
			}
		}
	}

	private static void DisarmPinning()
	{
		foreach (KeyValuePair<CameraPoseBlender, BlenderState> state in _states)
		{
			state.Value.PinActive = false;
		}
	}

	public static void CameraPoseBlender_Calculate_Prefix(CameraPoseBlender __instance)
	{
		if (!BuildModeNoAutoZoomPlugin.Enabled.Value)
		{
			return;
		}
		try
		{
			bool flag = IsBuild();
			if (flag != _lastBuildActive)
			{
				if (flag)
				{
					foreach (KeyValuePair<CameraPoseBlender, BlenderState> state in _states)
					{
						BlenderState value = state.Value;
						if (!(value.IndexField == null))
						{
							value.Baseline = (value.HasNonBuild ? value.LastNonBuildIndex : ((int)value.IndexField.GetValue(state.Key)));
							value.PinActive = true;
						}
					}
				}
				else
				{
					DisarmPinning();
				}
				_lastBuildActive = flag;
			}
			if ((Object)(object)__instance == (Object)null)
			{
				return;
			}
			if (!_states.TryGetValue(__instance, out var value2))
			{
				value2 = new BlenderState();
				value2.IndexField = ((object)__instance).GetType().GetField("index", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				_states[__instance] = value2;
			}
			if (value2.IndexField == null)
			{
				return;
			}
			int num = (int)value2.IndexField.GetValue(__instance);
			if (!flag && _forcedPinFrames <= 0)
			{
				value2.LastNonBuildIndex = num;
				value2.HasNonBuild = true;
				return;
			}
			if ((flag || _forcedPinFrames > 0) && IsBlueprintToolActive())
			{
				if (_forcedPinFrames > 0)
				{
					_forcedPinFrames--;
				}
				return;
			}
			if ((flag || _forcedPinFrames > 0) && value2.PinActive && num != value2.Baseline)
			{
				value2.IndexField.SetValue(__instance, value2.Baseline);
			}
			if (_forcedPinFrames > 0)
			{
				_forcedPinFrames--;
			}
			if (_forcedPinFrames <= 0 && !flag)
			{
				DisarmPinning();
			}
		}
		catch
		{
		}
	}

	private static bool IsBuild()
	{
		try
		{
			Player mainPlayer = GameMain.mainPlayer;
			PlayerAction_Build val = ((mainPlayer == null) ? null : mainPlayer.controller?.actionBuild);
			return val != null && val.active;
		}
		catch
		{
			return false;
		}
	}

	private static bool IsBlueprintToolActive()
	{
		try
		{
			Player mainPlayer = GameMain.mainPlayer;
			PlayerAction_Build obj = ((mainPlayer == null) ? null : mainPlayer.controller?.actionBuild);
			BuildTool val = ((obj != null) ? obj.activeTool : null);
			if (val == null)
			{
				return false;
			}
			return ((object)val).GetType().Name.IndexOf("Blueprint", StringComparison.OrdinalIgnoreCase) >= 0;
		}
		catch
		{
			return false;
		}
	}
}
internal static class PermanentZoomPatches
{
	private sealed class RefEq<T> : IEqualityComparer<T> where T : class
	{
		public static readonly RefEq<T> Instance = new RefEq<T>();

		public bool Equals(T x, T y)
		{
			return x == y;
		}

		public int GetHashCode(T obj)
		{
			return RuntimeHelpers.GetHashCode(obj);
		}
	}

	private static readonly HashSet<object> Done = new HashSet<object>(RefEq<object>.Instance);

	[HarmonyPrefix]
	public static void Calculate_Prefix(object __instance)
	{
		if (!BuildModeNoAutoZoomPlugin.Enabled.Value)
		{
			return;
		}
		float value = BuildModeNoAutoZoomPlugin.ExtraMaxZoomOut.Value;
		if (value <= 0.0001f || !Done.Add(__instance))
		{
			return;
		}
		try
		{
			Type type = __instance.GetType();
			FieldInfo fieldInfo = AccessTools.Field(type, "distMin");
			FieldInfo fieldInfo2 = AccessTools.Field(type, "distMax");
			FieldInfo fieldInfo3 = AccessTools.Field(type, "dist");
			FieldInfo fieldInfo4 = AccessTools.Field(type, "distCoef");
			FieldInfo fieldInfo5 = AccessTools.Field(type, "distCoefWanted");
			FieldInfo fieldInfo6 = AccessTools.Field(type, "distCoefBegin");
			if (fieldInfo == null || fieldInfo2 == null || fieldInfo3 == null || fieldInfo4 == null)
			{
				return;
			}
			float num = (float)fieldInfo.GetValue(__instance);
			float num2 = (float)fieldInfo2.GetValue(__instance);
			float num3 = (float)fieldInfo3.GetValue(__instance);
			float num4 = num2 + value;
			fieldInfo2.SetValue(__instance, num4);
			float num5 = num4 - num;
			if (!(num5 <= 0.0001f))
			{
				float num6 = (num3 - num) / num5;
				if (num6 < 0f)
				{
					num6 = 0f;
				}
				else if (num6 > 1f)
				{
					num6 = 1f;
				}
				fieldInfo4.SetValue(__instance, num6);
				if (fieldInfo5 != null && fieldInfo5.FieldType == typeof(float))
				{
					fieldInfo5.SetValue(__instance, num6);
				}
				if (fieldInfo6 != null && fieldInfo6.FieldType == typeof(float))
				{
					fieldInfo6.SetValue(__instance, num6);
				}
			}
		}
		catch
		{
		}
	}
}