using System;
using System.Collections;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
using UnityEngine.SceneManagement;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("M4GMaRFirstPersonCamera")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("M4GMaRFirstPersonCamera")]
[assembly: AssemblyCopyright("Copyright © 2024")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("c03b480e-ea29-4d74-80a9-f836145f9834")]
[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 FirstPersonCamera;
[BepInPlugin("com.m4gmar.firstPersonCamera", "First Person Camera Mod", "1.1.2")]
public class FirstPersonCamera : BaseUnityPlugin
{
[Tooltip("Mouse X sensitivity multiplier")]
[SerializeField]
private float sensitivityX = 1f;
[Tooltip("Mouse Y sensitivity multiplier")]
[SerializeField]
private float sensitivityY = 1f;
public bool useFirstPersonMod = true;
public bool usePaniniProjection = true;
public bool useDynamicPanini = true;
public float paniniMultiplier = 1f;
public float FOV = 100f;
private ConfigEntry<bool> configUsePaniniProjection;
private ConfigEntry<bool> configUseDynamicPanini;
private ConfigEntry<float> configPaniniMultiplier;
private ConfigEntry<float> configFOV;
private bool initializationRequested = false;
private Camera mainCamera;
private GameObject primaryCharacter;
private GameObject secondaryCharacter;
private Transform primaryHeadTransform;
private Transform secondaryHeadTransform;
private PlayerHealth primaryCharacterHealth;
private Quaternion lastHeadRotation = Quaternion.identity;
private float pitch = 0f;
private float yaw = 0f;
private PaniniProjection panini;
private PlayerOptionsManager POM;
private Coroutine secondaryCharacterUpdaterCoroutine;
private InputAction toggleMenuAction;
private bool showMenu = false;
private void Awake()
{
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
//IL_0039: Expected O, but got Unknown
//IL_005b: Unknown result type (might be due to invalid IL or missing references)
//IL_0065: Expected O, but got Unknown
//IL_008b: Unknown result type (might be due to invalid IL or missing references)
//IL_0095: Expected O, but got Unknown
//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
//IL_00c5: Expected O, but got Unknown
//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
//IL_00fc: Expected O, but got Unknown
((BaseUnityPlugin)this).Logger.LogInfo((object)"AWAKE: Hooking into SceneManager.sceneLoaded");
configUsePaniniProjection = ((BaseUnityPlugin)this).Config.Bind<bool>("Panini", "UsePaniniProjection", true, new ConfigDescription("If true, Panini projection (lens correction) will be created and applied at runtime.", (AcceptableValueBase)null, Array.Empty<object>()));
configUseDynamicPanini = ((BaseUnityPlugin)this).Config.Bind<bool>("Panini", "UseDynamicPanini", true, new ConfigDescription("If true, Panini distance will be updated dynamically based on camera vertical direction.", (AcceptableValueBase)null, Array.Empty<object>()));
configPaniniMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Panini", "PaniniMultiplier", 1f, new ConfigDescription("Base multiplier for the Panini projection distance.", (AcceptableValueBase)null, Array.Empty<object>()));
configFOV = ((BaseUnityPlugin)this).Config.Bind<float>("Panini", "FOV", 100f, new ConfigDescription("Base FOV for the camera.", (AcceptableValueBase)null, Array.Empty<object>()));
LoadConfig();
SceneManager.sceneLoaded += OnSceneLoaded;
toggleMenuAction = new InputAction("ToggleMenu", (InputActionType)1, "<Keyboard>/f8", (string)null, (string)null, (string)null);
toggleMenuAction.performed += delegate
{
showMenu = !showMenu;
};
toggleMenuAction.Enable();
}
private void OnDestroy()
{
SceneManager.sceneLoaded -= OnSceneLoaded;
if (secondaryCharacterUpdaterCoroutine != null)
{
((MonoBehaviour)this).StopCoroutine(secondaryCharacterUpdaterCoroutine);
secondaryCharacterUpdaterCoroutine = null;
}
if (toggleMenuAction == null)
{
return;
}
toggleMenuAction.Disable();
try
{
toggleMenuAction.performed -= delegate
{
showMenu = !showMenu;
};
}
catch
{
}
toggleMenuAction.Dispose();
toggleMenuAction = null;
}
private void LoadConfig()
{
usePaniniProjection = configUsePaniniProjection.Value;
useDynamicPanini = configUseDynamicPanini.Value;
paniniMultiplier = configPaniniMultiplier.Value;
FOV = configFOV.Value;
ApplyPaniniSettings();
}
private void SaveConfig()
{
configUsePaniniProjection.Value = usePaniniProjection;
configUseDynamicPanini.Value = useDynamicPanini;
configPaniniMultiplier.Value = paniniMultiplier;
configFOV.Value = FOV;
((BaseUnityPlugin)this).Config.Save();
((BaseUnityPlugin)this).Logger.LogInfo((object)$"Config saved: usePaniniProjection={usePaniniProjection} useDynamicPanini={useDynamicPanini} paniniMultiplier={paniniMultiplier}");
ApplyPaniniSettings();
}
private void ApplyPaniniSettings()
{
if ((Object)(object)panini != (Object)null)
{
((VolumeComponent)panini).active = usePaniniProjection;
((VolumeParameter)panini.distance).overrideState = true;
((VolumeParameter<float>)(object)panini.distance).value = paniniMultiplier;
((VolumeParameter)panini.cropToFit).overrideState = true;
((VolumeParameter<float>)(object)panini.cropToFit).value = 1f;
}
}
private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
{
((BaseUnityPlugin)this).Logger.LogInfo((object)("SCENE LOADED: " + ((Scene)(ref scene)).name));
if (((Scene)(ref scene)).name.Contains("map") && useFirstPersonMod)
{
initializationRequested = true;
}
}
private void LateUpdate()
{
//IL_0092: 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_0135: Unknown result type (might be due to invalid IL or missing references)
//IL_0137: Unknown result type (might be due to invalid IL or missing references)
if (initializationRequested)
{
initializationRequested = false;
((MonoBehaviour)this).StartCoroutine(InitializeCharacterReferencesAsync());
}
if ((Object)(object)mainCamera != (Object)null && (Object)(object)primaryHeadTransform != (Object)null && (Object)(object)primaryCharacterHealth != (Object)null && primaryCharacterHealth.alive)
{
UpdateCameraRotation();
UpdateCameraPosition();
PlayerInputManager val = Object.FindFirstObjectByType<PlayerInputManager>();
if ((Object)(object)val != (Object)null)
{
val.rotatePlayer.targetRotation = ((Component)mainCamera).transform.eulerAngles.y;
}
if ((Object)(object)POM == (Object)null)
{
POM = Object.FindFirstObjectByType<PlayerOptionsManager>();
}
if ((Object)(object)POM != (Object)null)
{
mainCamera.fieldOfView = POM.cameraFOV.value;
FOV = POM.cameraFOV.value;
}
if ((Object)(object)panini != (Object)null && useDynamicPanini)
{
Vector3 forward = ((Component)mainCamera).transform.forward;
float y = forward.y;
((VolumeParameter<float>)(object)panini.distance).value = Mathf.Clamp01(1f - Mathf.Abs(y)) * paniniMultiplier;
}
if ((Object)(object)panini != (Object)null && !useDynamicPanini)
{
((VolumeParameter<float>)(object)panini.distance).value = paniniMultiplier;
}
if ((Object)(object)panini != (Object)null && !usePaniniProjection)
{
((VolumeParameter<float>)(object)panini.distance).value = 0f;
}
}
if (!((Object)(object)primaryCharacterHealth != (Object)null) || primaryCharacterHealth.alive || !((Object)(object)primaryHeadTransform != (Object)null))
{
return;
}
MeshRenderer[] componentsInChildren = ((Component)primaryHeadTransform).gameObject.GetComponentsInChildren<MeshRenderer>();
MeshRenderer[] array = componentsInChildren;
foreach (MeshRenderer val2 in array)
{
if (!((Renderer)val2).enabled)
{
((Renderer)val2).enabled = true;
}
}
}
private IEnumerator InitializeCharacterReferencesAsync()
{
yield return (object)new WaitForSeconds(1f);
CacheMainCameraAndPrimaryCharacter();
if ((Object)(object)mainCamera != (Object)null)
{
mainCamera.targetTexture = null;
}
if (secondaryCharacterUpdaterCoroutine != null)
{
((MonoBehaviour)this).StopCoroutine(secondaryCharacterUpdaterCoroutine);
}
secondaryCharacterUpdaterCoroutine = ((MonoBehaviour)this).StartCoroutine(PeriodicSecondaryCharacterSearch());
POM = Object.FindFirstObjectByType<PlayerOptionsManager>((FindObjectsInactive)1);
if (usePaniniProjection)
{
GameObject volumeGO = new GameObject("Runtime Panini+Lens Volume");
Volume volume = volumeGO.AddComponent<Volume>();
volume.isGlobal = true;
VolumeProfile profile = (volume.profile = ScriptableObject.CreateInstance<VolumeProfile>());
PaniniProjection panini = default(PaniniProjection);
if (!profile.TryGet<PaniniProjection>(ref panini))
{
panini = profile.Add<PaniniProjection>(true);
}
((VolumeComponent)panini).active = usePaniniProjection;
((VolumeParameter)panini.distance).overrideState = true;
((VolumeParameter<float>)(object)panini.distance).value = paniniMultiplier;
((VolumeParameter)panini.cropToFit).overrideState = true;
((VolumeParameter<float>)(object)panini.cropToFit).value = 1f;
this.panini = panini;
}
}
private void CacheMainCameraAndPrimaryCharacter()
{
//IL_00d2: 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)
mainCamera = Camera.main;
if ((Object)(object)mainCamera == (Object)null)
{
((BaseUnityPlugin)this).Logger.LogInfo((object)"No main camera found.");
return;
}
mainCamera.fieldOfView = FOV;
primaryCharacter = FindClosestCharacterToCamera();
if ((Object)(object)primaryCharacter == (Object)null)
{
((BaseUnityPlugin)this).Logger.LogInfo((object)"No characters found in the scene.");
return;
}
primaryHeadTransform = FindHeadTransformInChildren(primaryCharacter);
if ((Object)(object)primaryHeadTransform != (Object)null)
{
((BaseUnityPlugin)this).Logger.LogInfo((object)("Cached " + ((Object)primaryCharacter).name + "'s head transform."));
DestroyCameraSmoothFollowComponents();
lastHeadRotation = primaryHeadTransform.rotation;
primaryCharacterHealth = primaryCharacter.GetComponent<PlayerHealth>();
MeshRenderer[] componentsInChildren = ((Component)primaryHeadTransform).gameObject.GetComponentsInChildren<MeshRenderer>();
MeshRenderer[] array = componentsInChildren;
foreach (MeshRenderer val in array)
{
((Renderer)val).enabled = false;
}
}
else
{
((BaseUnityPlugin)this).Logger.LogInfo((object)("No 'head' (neck) component found in " + ((Object)primaryCharacter).name + "."));
}
}
private GameObject FindClosestCharacterToCamera()
{
//IL_0046: Unknown result type (might be due to invalid IL or missing references)
//IL_0052: Unknown result type (might be due to invalid IL or missing references)
GameObject[] array = Object.FindObjectsByType<GameObject>((FindObjectsSortMode)0);
GameObject val = null;
float num = float.MaxValue;
GameObject[] array2 = array;
foreach (GameObject val2 in array2)
{
if (((Object)val2).name.Contains("Character"))
{
float num2 = Vector3.Distance(((Component)mainCamera).transform.position, val2.transform.position);
if (num2 < num)
{
num = num2;
val = val2;
}
}
}
if ((Object)(object)val != (Object)null)
{
((BaseUnityPlugin)this).Logger.LogInfo((object)("Closest character cached: " + ((Object)val).name));
primaryCharacterHealth = val.GetComponent<PlayerHealth>();
}
return val;
}
private Transform FindHeadTransformInChildren(GameObject character)
{
if ((Object)(object)character == (Object)null)
{
return null;
}
Transform[] componentsInChildren = character.GetComponentsInChildren<Transform>(true);
Transform[] array = componentsInChildren;
foreach (Transform val in array)
{
if (((Object)val).name.IndexOf("neck", StringComparison.OrdinalIgnoreCase) >= 0)
{
return val;
}
}
return null;
}
private void DestroyCameraSmoothFollowComponents()
{
CameraSmoothFollow[] array = Object.FindObjectsByType<CameraSmoothFollow>((FindObjectsSortMode)0);
CameraSmoothFollow[] array2 = array;
foreach (CameraSmoothFollow val in array2)
{
((BaseUnityPlugin)this).Logger.LogInfo((object)("Found CameraSmoothFollow in " + ((Object)((Component)val).gameObject).name + " ...DESTROYING IT and relocating Camera"));
Object.Destroy((Object)(object)val);
}
}
private void UpdateCameraPosition()
{
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
((Component)mainCamera).gameObject.transform.position = primaryHeadTransform.TransformPoint(0f, 0.12f, 0.04f);
mainCamera.nearClipPlane = 0.06f;
}
private IEnumerator PeriodicSecondaryCharacterSearch()
{
while (true)
{
if ((Object)(object)primaryCharacter != (Object)null)
{
secondaryCharacter = FindSecondClosestLivingCharacter();
if ((Object)(object)secondaryCharacter != (Object)null)
{
secondaryHeadTransform = FindHeadTransformInChildren(secondaryCharacter);
if ((Object)(object)secondaryHeadTransform != (Object)null)
{
((BaseUnityPlugin)this).Logger.LogInfo((object)("Second closest character's head cached: " + ((Object)secondaryHeadTransform).name));
}
else
{
((BaseUnityPlugin)this).Logger.LogInfo((object)("No 'head' (neck) component found in " + ((Object)secondaryCharacter).name + "."));
}
}
}
yield return (object)new WaitForSeconds(2f);
}
}
private GameObject FindSecondClosestLivingCharacter()
{
//IL_0058: Unknown result type (might be due to invalid IL or missing references)
//IL_0064: Unknown result type (might be due to invalid IL or missing references)
GameObject[] array = Object.FindObjectsByType<GameObject>((FindObjectsSortMode)0);
GameObject val = null;
float num = float.MaxValue;
GameObject[] array2 = array;
foreach (GameObject val2 in array2)
{
if (!((Object)val2).name.Contains("Character") || (Object)(object)val2 == (Object)(object)primaryCharacter)
{
continue;
}
float num2 = Vector3.Distance(((Component)mainCamera).transform.position, val2.transform.position);
if (num2 < num)
{
PlayerHealth component = val2.GetComponent<PlayerHealth>();
if ((Object)(object)component != (Object)null && component.alive)
{
num = num2;
val = val2;
}
}
}
if ((Object)(object)val != (Object)null)
{
((BaseUnityPlugin)this).Logger.LogInfo((object)("Second closest character cached: " + ((Object)val).name));
}
return val;
}
private void UpdateCameraRotation()
{
//IL_0041: Unknown result type (might be due to invalid IL or missing references)
//IL_0046: Unknown result type (might be due to invalid IL or missing references)
//IL_004d: Unknown result type (might be due to invalid IL or missing references)
//IL_0061: Unknown result type (might be due to invalid IL or missing references)
//IL_0066: Unknown result type (might be due to invalid IL or missing references)
//IL_006b: 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_01cc: Unknown result type (might be due to invalid IL or missing references)
//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
//IL_01dd: Unknown result type (might be due to invalid IL or missing references)
//IL_0158: Unknown result type (might be due to invalid IL or missing references)
//IL_0168: Unknown result type (might be due to invalid IL or missing references)
//IL_016d: 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_0176: Unknown result type (might be due to invalid IL or missing references)
//IL_017b: Unknown result type (might be due to invalid IL or missing references)
//IL_017d: Unknown result type (might be due to invalid IL or missing references)
//IL_017e: Unknown result type (might be due to invalid IL or missing references)
//IL_02e3: Unknown result type (might be due to invalid IL or missing references)
//IL_02e8: Unknown result type (might be due to invalid IL or missing references)
//IL_02f4: Unknown result type (might be due to invalid IL or missing references)
//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
//IL_0208: Unknown result type (might be due to invalid IL or missing references)
//IL_0223: Unknown result type (might be due to invalid IL or missing references)
//IL_02af: Unknown result type (might be due to invalid IL or missing references)
//IL_02c1: Unknown result type (might be due to invalid IL or missing references)
//IL_02c6: Unknown result type (might be due to invalid IL or missing references)
//IL_02cb: Unknown result type (might be due to invalid IL or missing references)
//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
//IL_019a: Unknown result type (might be due to invalid IL or missing references)
//IL_019b: Unknown result type (might be due to invalid IL or missing references)
//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)primaryCharacter == (Object)null || (Object)(object)primaryHeadTransform == (Object)null)
{
((BaseUnityPlugin)this).Logger.LogInfo((object)"Character or Head transform is missing.");
return;
}
Vector3 forward = primaryHeadTransform.forward;
Quaternion val = primaryHeadTransform.rotation * Quaternion.Euler(10f, 0f, 0f);
float num = 4000f;
float num2 = 4000f;
Vector3 zero = Vector3.zero;
if (Keyboard.current != null)
{
if (((ButtonControl)Keyboard.current.eKey).isPressed)
{
zero.y += num * Time.deltaTime;
}
if (((ButtonControl)Keyboard.current.qKey).isPressed)
{
zero.y -= num * Time.deltaTime;
}
if (((ButtonControl)Keyboard.current.rKey).isPressed)
{
zero.x -= num2 * Time.deltaTime;
}
if (((ButtonControl)Keyboard.current.fKey).isPressed)
{
zero.x += num2 * Time.deltaTime;
}
}
if ((Object)(object)secondaryCharacter != (Object)null && (Object)(object)secondaryHeadTransform != (Object)null)
{
Vector3 val2 = secondaryHeadTransform.position - ((Component)mainCamera).transform.position;
Vector3 normalized = ((Vector3)(ref val2)).normalized;
float num3 = Vector3.Angle(forward, normalized);
if (num3 <= 100f)
{
val2 = Vector3.Lerp(forward, normalized, 0.32f);
Vector3 normalized2 = ((Vector3)(ref val2)).normalized;
val = Quaternion.LookRotation(normalized2);
}
else
{
val = primaryHeadTransform.rotation;
}
}
Quaternion val3 = Quaternion.Euler(zero);
val *= val3;
if (Mouse.current != null)
{
Vector2 val4 = ((InputControl<Vector2>)(object)((Pointer)Mouse.current).delta).ReadValue();
yaw += val4.x * sensitivityX;
pitch -= val4.y * sensitivityY;
pitch = Mathf.Clamp(pitch, -64f, 64f);
yaw = Mathf.Clamp(yaw, -64f, 64f);
yaw = Mathf.Lerp(yaw, 0f, 1f * Time.deltaTime);
pitch = Mathf.Lerp(pitch, 0f, 1f * Time.deltaTime);
val *= Quaternion.Euler(pitch, yaw, 0f);
}
((Component)mainCamera).transform.rotation = Quaternion.Slerp(((Component)mainCamera).transform.rotation, val, 2f * Time.deltaTime);
}
private void OnGUI()
{
//IL_004a: Unknown result type (might be due to invalid IL or missing references)
//IL_0077: Unknown result type (might be due to invalid IL or missing references)
//IL_009b: Unknown result type (might be due to invalid IL or missing references)
//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
//IL_0100: Unknown result type (might be due to invalid IL or missing references)
//IL_0141: Unknown result type (might be due to invalid IL or missing references)
//IL_0165: Unknown result type (might be due to invalid IL or missing references)
//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
//IL_01da: Unknown result type (might be due to invalid IL or missing references)
//IL_0212: Unknown result type (might be due to invalid IL or missing references)
//IL_025e: Unknown result type (might be due to invalid IL or missing references)
//IL_0292: Unknown result type (might be due to invalid IL or missing references)
//IL_02df: Unknown result type (might be due to invalid IL or missing references)
if (showMenu)
{
int num = 800;
int num2 = 400;
int num3 = 420;
int num4 = 200;
GUI.Box(new Rect((float)num - 10f, (float)num2 - 10f, (float)(num3 + 20), (float)(num4 + 160)), "First Person Camera Config");
int num5 = num;
int num6 = num2;
num6 += 50;
GUI.Label(new Rect((float)num5, (float)num6, 380f, 20f), "Enable First Person");
useFirstPersonMod = GUI.Toggle(new Rect((float)num5, (float)(num6 + 20), 380f, 20f), useFirstPersonMod, $"{useFirstPersonMod}");
num6 += 50;
GUI.Label(new Rect((float)num5, (float)num6, 380f, 20f), "Use Panini Projection");
usePaniniProjection = GUI.Toggle(new Rect((float)num5, (float)(num6 + 20), 380f, 20f), usePaniniProjection, $"{usePaniniProjection}");
num6 += 50;
GUI.Label(new Rect((float)num5, (float)num6, 380f, 20f), "Use Dynamic Panini");
useDynamicPanini = GUI.Toggle(new Rect((float)num5, (float)(num6 + 20), 380f, 20f), useDynamicPanini, $"{useDynamicPanini}");
num6 += 50;
GUI.Label(new Rect((float)num5, (float)num6, 380f, 20f), $"Panini Multiplier: {paniniMultiplier:F2}");
paniniMultiplier = GUI.HorizontalSlider(new Rect((float)num5, (float)(num6 + 20), 260f, 20f), paniniMultiplier, 0f, 1f);
string s = GUI.TextField(new Rect((float)(num5 + 270), (float)(num6 + 18), 90f, 22f), paniniMultiplier.ToString("F2"));
if (float.TryParse(s, out var result))
{
paniniMultiplier = result;
}
num6 += 60;
if (GUI.Button(new Rect((float)num5, (float)num6, 130f, 32f), "Apply & Save"))
{
SaveConfig();
}
if (GUI.Button(new Rect((float)(num5 + 150), (float)num6, 140f, 32f), "Reset to Default"))
{
usePaniniProjection = true;
useDynamicPanini = true;
paniniMultiplier = 1f;
SaveConfig();
}
if (GUI.Button(new Rect((float)(num5 + 305), (float)num6, 120f, 32f), "Restore Config"))
{
LoadConfig();
}
}
}
}