Decompiled source of LC Fov v1.1.1

LC_Fov.dll

Decompiled 2 months ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using Unity.Netcode;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("fov")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("fov")]
[assembly: AssemblyCopyright("Copyright ©  2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("7ac834db-85a7-474e-b917-0007ede04ca2")]
[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 LC_Fov;

[BepInPlugin("DSL.LC_Fov", "LC Fov", "1.0.0")]
public class LCFovBase : BaseUnityPlugin
{
	public const string ModGuid = "DSL.LC_Fov";

	public const string ModName = "LC Fov";

	public const string ModVer = "1.0.0";

	private readonly Harmony _harmony = new Harmony("DSL.LC_Fov");

	private static LCFovBase _instance;

	public static ManualLogSource Log;

	public static ConfigEntry<float> CfgFov;

	public static ConfigEntry<float> CfgSprintFov;

	public static ConfigEntry<bool> CfgHideVisor;

	private void Awake()
	{
		if ((Object)(object)_instance == (Object)null)
		{
			_instance = this;
		}
		Log = ((BaseUnityPlugin)this).Logger;
		Log.LogInfo((object)"Starting LC FOV…");
		CfgFov = ((BaseUnityPlugin)this).Config.Bind<float>("General", "fov", 90f, "Vertical FOV. Clamped 66–130.");
		CfgSprintFov = ((BaseUnityPlugin)this).Config.Bind<float>("General", "sprintFov", 1.25f, "Sprint FOV multiplier. Clamped 1.0–1.5.");
		CfgHideVisor = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "hideVisor", true, "If true, hides the first-person visor.");
		PlayerControllerBPatches.newTargetFovBase = Mathf.Clamp(CfgFov.Value, 66f, 130f);
		PlayerControllerBPatches.sprintFovMultiplier = Mathf.Clamp(CfgSprintFov.Value, 1f, 1.5f);
		PlayerControllerBPatches.hideVisor = CfgHideVisor.Value;
		PlayerControllerBPatches.RecalculateVisorScale();
		_harmony.PatchAll(typeof(PlayerControllerBPatches));
		_harmony.PatchAll(typeof(HUDManagerPatches));
		Log.LogInfo((object)"LC FOV loaded.");
	}

	public static void SetHideVisor(bool value)
	{
		PlayerControllerBPatches.hideVisor = value;
		_instance.ConfigHideVisorAndSave(value);
		PlayerControllerBPatches.RecalculateVisorScale();
	}

	public static void SetFov(float v)
	{
		float value = (PlayerControllerBPatches.newTargetFovBase = Mathf.Clamp(v, 66f, 130f));
		_instance.ConfigSetFovAndSave(value);
		PlayerControllerBPatches.snapFovChange = true;
		PlayerControllerBPatches.RecalculateVisorScale();
	}

	private void ConfigHideVisorAndSave(bool value)
	{
		CfgHideVisor.Value = value;
		((BaseUnityPlugin)this).Config.Save();
	}

	private void ConfigSetFovAndSave(float value)
	{
		CfgFov.Value = value;
		((BaseUnityPlugin)this).Config.Save();
	}
}
public static class PlayerControllerBPatches
{
	public static float newTargetFovBase = 90f;

	public static float sprintFovMultiplier = 1.25f;

	public static bool snapFovChange = false;

	public static bool hideVisor = true;

	private static Vector3 visorScale;

	private static float lastAppliedFovForScale = -999f;

	private static readonly Vector3 VisorScaleBottom = new Vector3(0.68f, 0.8f, 0.95f);

	private static readonly Vector3 VisorScaleTop = new Vector3(0.68f, 0.35f, 0.99f);

	private const float TopRefFov = 130f;

	private const float LerpCurveMix = 0.6f;

	private static float _prefixCamFov = 0f;

	[HarmonyPatch(typeof(PlayerControllerB), "Awake")]
	[HarmonyPostfix]
	private static void PlayerAwake_Postfix(PlayerControllerB __instance)
	{
		//IL_0023: Unknown result type (might be due to invalid IL or missing references)
		if (!FilterOut(__instance) && (Object)(object)__instance.localVisor != (Object)null)
		{
			__instance.localVisor.localScale = visorScale;
		}
	}

	[HarmonyPatch(typeof(PlayerControllerB), "Update")]
	[HarmonyPrefix]
	[HarmonyPriority(500)]
	private static void Update_Prefix(PlayerControllerB __instance)
	{
		//IL_0046: 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_0062: Unknown result type (might be due to invalid IL or missing references)
		if (!FilterOut(__instance))
		{
			_prefixCamFov = (((Object)(object)__instance.gameplayCamera != (Object)null) ? __instance.gameplayCamera.fieldOfView : newTargetFovBase);
			if ((Object)(object)__instance.localVisor != (Object)null && __instance.localVisor.localScale != visorScale)
			{
				__instance.localVisor.localScale = visorScale;
			}
		}
	}

	[HarmonyPatch(typeof(PlayerControllerB), "Update")]
	[HarmonyPostfix]
	[HarmonyPriority(300)]
	private static void Update_Postfix(PlayerControllerB __instance)
	{
		if (FilterOut(__instance))
		{
			return;
		}
		float num = newTargetFovBase;
		if (__instance.inTerminalMenu)
		{
			num = 60f;
		}
		else if (__instance.IsInspectingItem)
		{
			num = 46f;
		}
		else if (__instance.isSprinting)
		{
			num *= sprintFovMultiplier;
		}
		if ((Object)(object)__instance.gameplayCamera != (Object)null)
		{
			__instance.gameplayCamera.fieldOfView = Mathf.Lerp(_prefixCamFov, num, 8f * Time.deltaTime);
			if (snapFovChange)
			{
				__instance.gameplayCamera.fieldOfView = num;
				_prefixCamFov = num;
				snapFovChange = false;
			}
		}
	}

	[HarmonyPatch(typeof(PlayerControllerB), "LateUpdate")]
	[HarmonyPostfix]
	[HarmonyPriority(300)]
	private static void LateUpdate_Postfix(PlayerControllerB __instance)
	{
		//IL_0036: Unknown result type (might be due to invalid IL or missing references)
		//IL_0041: Unknown result type (might be due to invalid IL or missing references)
		//IL_0055: Unknown result type (might be due to invalid IL or missing references)
		//IL_005a: 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)
		if (!FilterOut(__instance) && !((Object)(object)__instance.localVisor == (Object)null) && newTargetFovBase > 66f)
		{
			Transform localVisor = __instance.localVisor;
			localVisor.position += __instance.localVisor.rotation * new Vector3(0f, 0f, -0.06f);
		}
	}

	public static void RecalculateVisorScale()
	{
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c6: 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)
		if (hideVisor)
		{
			visorScale = Vector3.zero;
			lastAppliedFovForScale = newTargetFovBase;
		}
		else if (!(Math.Abs(newTargetFovBase - lastAppliedFovForScale) < 0.01f))
		{
			lastAppliedFovForScale = newTargetFovBase;
			if (newTargetFovBase <= 66f)
			{
				visorScale = new Vector3(0.36f, 0.49f, 0.49f);
				return;
			}
			float num = Mathf.InverseLerp(66f, 130f, newTargetFovBase);
			float num2 = Mathf.Sin(num * (float)Math.PI * 0.5f);
			float num3 = Mathf.Lerp(num, num2, 0.6f);
			visorScale = Vector3.LerpUnclamped(VisorScaleBottom, VisorScaleTop, num3);
		}
	}

	private static bool FilterOut(PlayerControllerB p)
	{
		return (Object)(object)p == (Object)null || !((NetworkBehaviour)p).IsOwner || !p.isPlayerControlled || (((NetworkBehaviour)p).IsServer && !p.isHostPlayerObject && !p.isTestingPlayer);
	}
}
public static class HUDManagerPatches
{
	[HarmonyPatch(typeof(HUDManager), "SubmitChat_performed")]
	[HarmonyPrefix]
	public static bool SubmitChat_Prefix(HUDManager __instance)
	{
		string text = __instance.chatTextField.text?.Trim() ?? string.Empty;
		if (string.IsNullOrEmpty(text))
		{
			return true;
		}
		if (text.StartsWith("/fov", StringComparison.OrdinalIgnoreCase))
		{
			string[] array = text.Split(new char[1] { ' ' });
			if (array.Length > 1 && float.TryParse(array[1], out var result) && !float.IsNaN(result))
			{
				LCFovBase.SetFov(result);
				AddChat(__instance, $"FOV set to {Mathf.Clamp(result, 66f, 130f):0.#}");
			}
			else
			{
				AddChat(__instance, "Usage: /fov <66–130>");
			}
			ClearChatBox(__instance);
			return false;
		}
		if (text.StartsWith("/visor", StringComparison.OrdinalIgnoreCase))
		{
			string text2 = ((text.Length > 6) ? text.Substring(6).Trim().ToLowerInvariant() : "toggle");
			bool? flag = null;
			switch (text2)
			{
			case "on":
				flag = true;
				break;
			case "off":
				flag = false;
				break;
			default:
				AddChat(__instance, "Usage: /visor on | off | toggle");
				ClearChatBox(__instance);
				return false;
			case "toggle":
				break;
			}
			if (flag.HasValue)
			{
				LCFovBase.SetHideVisor(!flag.Value);
				AddChat(__instance, flag.Value ? "Visor: ON (visible)" : "Visor: OFF (hidden)");
			}
			else
			{
				bool hideVisor = PlayerControllerBPatches.hideVisor;
				LCFovBase.SetHideVisor(!hideVisor);
				AddChat(__instance, (!hideVisor) ? "Visor: OFF (hidden)" : "Visor: ON (visible)");
			}
			ClearChatBox(__instance);
			return false;
		}
		return true;
	}

	private static void AddChat(HUDManager hud, string msg)
	{
		try
		{
			Traverse.Create((object)hud).Method("AddChatMessage", new object[2] { msg, "" }).GetValue();
		}
		catch
		{
			ManualLogSource log = LCFovBase.Log;
			if (log != null)
			{
				log.LogMessage((object)msg);
			}
		}
	}

	private static void ClearChatBox(HUDManager hud)
	{
		hud.localPlayer = GameNetworkManager.Instance.localPlayerController;
		hud.localPlayer.isTypingChat = false;
		hud.chatTextField.text = "";
		if ((Object)(object)hud.typingIndicator != (Object)null)
		{
			((Behaviour)hud.typingIndicator).enabled = false;
		}
	}
}