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
{
}
}
}