Decompiled source of BetterBeastCam v1.1.17

Mods/BetterBeastCam.dll

Decompiled 7 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BetterBeastCam;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppSystem;
using Il2CppSystem.Reflection;
using MelonLoader;
using MelonLoader.Preferences;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(Mod), "BetterBeastCam", "1.1.17", "ImJoeO", null)]
[assembly: MelonGame("Boneloaf", "Gang Beasts")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("BetterBeastCam")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Integrated Third Person Camera for Gang Beasts")]
[assembly: AssemblyFileVersion("1.1.0.0")]
[assembly: AssemblyInformationalVersion("1.1.0")]
[assembly: AssemblyProduct("BetterBeastCam")]
[assembly: AssemblyTitle("BetterBeastCam")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.0.0")]
[module: UnverifiableCode]
namespace BetterBeastCam;

public class Mod : MelonMod
{
	private MelonPreferences_Category _category;

	private MelonPreferences_Entry<float> _mouseSensitivity;

	private MelonPreferences_Entry<float> _controllerSensitivity;

	private MelonPreferences_Entry<float> _distance;

	private float _yaw;

	private float _pitch;

	private bool _isMenuActive;

	private bool _isThirdPersonActive;

	private bool _f6WasPressed;

	private float _f6HoldTimer;

	private bool _f6HoldTriggered;

	private bool _stickWasPressed;

	private float _stickHoldTimer;

	private bool _stickHoldTriggered;

	private bool _dpadWasPressed;

	private int _menuSelection;

	private bool _hasFoundCamera;

	private float _currentDistance;

	private Transform _target;

	private Vector3 _smoothedCenter;

	private float _smoothingSpeed = 8f;

	private List<Behaviour> _suppressedComponents = new List<Behaviour>();

	private float _diagnosticTimer;

	private Vector3 _lastTargetPos;

	private float _staticTargetTimer;

	public override void OnInitializeMelon()
	{
		_category = MelonPreferences.CreateCategory("BetterBeastCam");
		_mouseSensitivity = _category.CreateEntry<float>("MouseSensitivity", 2f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
		_controllerSensitivity = _category.CreateEntry<float>("ControllerSensitivity", 50f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
		_distance = _category.CreateEntry<float>("CameraDistance", 5f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
		_currentDistance = _distance.Value;
		MelonLogger.Msg("BetterBeastCam v1.1.12 - Final Release.");
	}

	public override void OnUpdate()
	{
		try
		{
			HandleKeyboardInput();
			HandleControllerInput();
		}
		catch (Exception value)
		{
			MelonLogger.Error($"[OnUpdate Error] {value}");
		}
	}

	private void HandleKeyboardInput()
	{
		Keyboard current = Keyboard.current;
		if (current == null)
		{
			return;
		}
		bool isPressed = ((ButtonControl)current.f6Key).isPressed;
		if (isPressed)
		{
			_f6HoldTimer += Time.deltaTime;
			if (_f6HoldTimer > 0.6f && !_f6HoldTriggered)
			{
				ToggleMenu();
				_f6HoldTriggered = true;
			}
		}
		else if (_f6WasPressed)
		{
			if (!_f6HoldTriggered)
			{
				ToggleOrbit();
			}
			_f6HoldTimer = 0f;
			_f6HoldTriggered = false;
		}
		_f6WasPressed = isPressed;
	}

	private void HandleControllerInput()
	{
		//IL_008c: 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_00a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
		Gamepad current = Gamepad.current;
		if (current == null)
		{
			return;
		}
		bool isPressed = current.rightStickButton.isPressed;
		if (isPressed)
		{
			_stickHoldTimer += Time.deltaTime;
			if (_stickHoldTimer > 0.6f && !_stickHoldTriggered)
			{
				ToggleMenu();
				_stickHoldTriggered = true;
			}
		}
		else if (_stickWasPressed)
		{
			if (!_stickHoldTriggered)
			{
				ToggleOrbit();
			}
			_stickHoldTimer = 0f;
			_stickHoldTriggered = false;
		}
		_stickWasPressed = isPressed;
		if (!_isMenuActive)
		{
			return;
		}
		Vector2 val = ((InputControl<Vector2>)(object)current.dpad).ReadValue();
		if (((Vector2)(ref val)).sqrMagnitude > 0.1f)
		{
			if (!_dpadWasPressed)
			{
				if (val.y > 0.5f)
				{
					_menuSelection = (_menuSelection - 1 + 3) % 3;
				}
				else if (val.y < -0.5f)
				{
					_menuSelection = (_menuSelection + 1) % 3;
				}
				ModifyValue(val.x);
				_dpadWasPressed = true;
			}
		}
		else
		{
			_dpadWasPressed = false;
		}
	}

	private void ModifyValue(float horizontal)
	{
		if (!(Mathf.Abs(horizontal) < 0.5f))
		{
			float num = ((horizontal > 0f) ? 1f : (-1f));
			switch (_menuSelection)
			{
			case 0:
				_mouseSensitivity.Value = Mathf.Clamp(_mouseSensitivity.Value + num * 0.1f, 0.1f, 10f);
				break;
			case 1:
				_controllerSensitivity.Value = Mathf.Clamp(_controllerSensitivity.Value + num * 5f, 1f, 500f);
				break;
			case 2:
				_distance.Value = Mathf.Clamp(_distance.Value + num * 0.2f, 1f, 30f);
				break;
			}
		}
	}

	private void ToggleOrbit()
	{
		_isThirdPersonActive = !_isThirdPersonActive;
		MelonLogger.Msg("[DEBUG] Orbit Toggle: " + (_isThirdPersonActive ? "ENABLED" : "DISABLED"));
		if (!_isThirdPersonActive)
		{
			RestoreComponents();
		}
		_hasFoundCamera = false;
		_target = null;
		_staticTargetTimer = 0f;
	}

	private void ToggleMenu()
	{
		_isMenuActive = !_isMenuActive;
		if (!_isMenuActive && _category != null)
		{
			_category.SaveToFile(true);
			MelonLogger.Msg("Settings Auto-Saved!");
		}
		MelonLogger.Msg("[DEBUG] Menu Toggle: " + (_isMenuActive ? "OPEN" : "CLOSED"));
	}

	public override void OnLateUpdate()
	{
		if (_isThirdPersonActive)
		{
			UpdateOrbit();
		}
	}

	private void RestoreComponents()
	{
		foreach (Behaviour suppressedComponent in _suppressedComponents)
		{
			if ((Object)(object)suppressedComponent != (Object)null)
			{
				suppressedComponent.enabled = true;
			}
		}
		_suppressedComponents.Clear();
	}

	private void UpdateOrbit()
	{
		//IL_007c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0082: Unknown result type (might be due to invalid IL or missing references)
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		//IL_0047: 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_00be: Unknown result type (might be due to invalid IL or missing references)
		//IL_0104: Unknown result type (might be due to invalid IL or missing references)
		//IL_011a: 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_0175: Unknown result type (might be due to invalid IL or missing references)
		//IL_0191: 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_02ab: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b6: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_02cc: Unknown result type (might be due to invalid IL or missing references)
		//IL_02e2: Unknown result type (might be due to invalid IL or missing references)
		//IL_02e7: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ea: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ef: Unknown result type (might be due to invalid IL or missing references)
		//IL_02f9: Unknown result type (might be due to invalid IL or missing references)
		//IL_02fe: Unknown result type (might be due to invalid IL or missing references)
		//IL_0303: Unknown result type (might be due to invalid IL or missing references)
		//IL_030b: Unknown result type (might be due to invalid IL or missing references)
		//IL_030d: Unknown result type (might be due to invalid IL or missing references)
		//IL_030f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0314: Unknown result type (might be due to invalid IL or missing references)
		//IL_031f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0324: Unknown result type (might be due to invalid IL or missing references)
		//IL_0334: Unknown result type (might be due to invalid IL or missing references)
		//IL_020c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0211: Unknown result type (might be due to invalid IL or missing references)
		//IL_0214: Unknown result type (might be due to invalid IL or missing references)
		//IL_0230: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			Camera main = Camera.main;
			if ((Object)(object)main == (Object)null)
			{
				return;
			}
			if ((Object)(object)_target == (Object)null)
			{
				FindTarget();
				if ((Object)(object)_target == (Object)null)
				{
					return;
				}
				_smoothedCenter = _target.position;
			}
			_diagnosticTimer += Time.deltaTime;
			if (_diagnosticTimer > 1f)
			{
				_diagnosticTimer = 0f;
			}
			if (Vector3.Distance(_target.position, _lastTargetPos) < 0.001f)
			{
				_staticTargetTimer += Time.deltaTime;
			}
			else
			{
				_staticTargetTimer = 0f;
				_lastTargetPos = _target.position;
			}
			if (_staticTargetTimer > 3f)
			{
				_target = null;
				_hasFoundCamera = false;
				_staticTargetTimer = 0f;
				return;
			}
			if (!_hasFoundCamera)
			{
				SuppressComponents(main);
				_yaw = ((Component)main).transform.eulerAngles.y;
				_pitch = ((Component)main).transform.eulerAngles.x;
				if (_pitch > 180f)
				{
					_pitch -= 360f;
				}
				_hasFoundCamera = true;
			}
			float num = 0f;
			float num2 = 0f;
			Mouse current = Mouse.current;
			if (current != null)
			{
				Vector2 val = ((InputControl<Vector2>)(object)((Pointer)current).delta).ReadValue();
				num += val.x * (_mouseSensitivity.Value * 0.1f);
				num2 += val.y * (_mouseSensitivity.Value * 0.1f);
				float y = ((InputControl<Vector2>)(object)current.scroll).ReadValue().y;
				if (Mathf.Abs(y) > 0.1f)
				{
					_distance.Value = Mathf.Clamp(_distance.Value - y * 0.01f, 1f, 30f);
				}
			}
			Gamepad current2 = Gamepad.current;
			if (current2 != null)
			{
				Vector2 val2 = ((InputControl<Vector2>)(object)current2.rightStick).ReadValue();
				num += val2.x * (_controllerSensitivity.Value * Time.deltaTime);
				num2 += val2.y * (_controllerSensitivity.Value * Time.deltaTime);
			}
			_yaw += num;
			_pitch -= num2;
			_pitch = Mathf.Clamp(_pitch, -80f, 80f);
			_currentDistance = Mathf.Lerp(_currentDistance, _distance.Value, Time.deltaTime * 10f);
			_smoothedCenter = Vector3.Lerp(_smoothedCenter, _target.position, Time.deltaTime * _smoothingSpeed);
			Quaternion val3 = Quaternion.Euler(_pitch, _yaw, 0f);
			Vector3 val4 = _smoothedCenter + Vector3.up * 0.7f;
			((Component)main).transform.position = val4 + val3 * Vector3.back * _currentDistance;
			((Component)main).transform.rotation = val3;
		}
		catch (Exception value)
		{
			MelonLogger.Error($"[UpdateOrbit Error] {value}");
		}
	}

	private void SuppressComponents(Camera cam)
	{
		_suppressedComponents.Clear();
		foreach (Component component in ((Component)cam).GetComponents<Component>())
		{
			if ((Object)(object)component == (Object)null)
			{
				continue;
			}
			switch (((MemberInfo)((Object)component).GetIl2CppType()).Name)
			{
			case "CinemachineBrain":
			case "GlobalCamera":
			case "Fade":
			{
				Behaviour val = ((Il2CppObjectBase)component).TryCast<Behaviour>();
				if ((Object)(object)val != (Object)null && val.enabled)
				{
					val.enabled = false;
					_suppressedComponents.Add(val);
				}
				break;
			}
			}
		}
	}

	private void FindTarget()
	{
		foreach (Rigidbody item in Object.FindObjectsOfType<Rigidbody>())
		{
			if ((Object)(object)item == (Object)null || (Object)(object)((Component)item).gameObject == (Object)null)
			{
				continue;
			}
			string text = ((Object)((Component)item).gameObject).name.ToLower();
			if (!text.Contains("pelvis") && !text.Contains("hips") && !text.Contains("chest"))
			{
				continue;
			}
			Transform val = ((Component)item).transform;
			while ((Object)(object)val != (Object)null)
			{
				if (((Object)val).name.Contains("Actor") || ((Object)val).name.Contains("NetBeast"))
				{
					_target = ((Component)item).transform;
					return;
				}
				val = val.parent;
			}
		}
		foreach (GameObject item2 in Object.FindObjectsOfType<GameObject>())
		{
			if (!((Object)(object)item2 == (Object)null) && (((Object)item2).name.Contains("Actor") || ((Object)item2).name.Contains("NetBeast") || item2.tag == "Player"))
			{
				_target = item2.transform;
				break;
			}
		}
	}

	public override void OnGUI()
	{
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
		if (_isMenuActive)
		{
			Rect val = default(Rect);
			((Rect)(ref val))..ctor((float)(Screen.width / 2 - 125), (float)(Screen.height / 2 - 130), 250f, 260f);
			GUI.Box(val, "BetterBeastCam Settings");
			float num = ((Rect)(ref val)).x + 10f;
			float y = ((Rect)(ref val)).y + 35f;
			_mouseSensitivity.Value = DrawSetting(0, num, ref y, "Mouse Sens", _mouseSensitivity.Value, 0.1f, 10f);
			_controllerSensitivity.Value = DrawSetting(1, num, ref y, "Stick Sens", _controllerSensitivity.Value, 1f, 500f);
			_distance.Value = DrawSetting(2, num, ref y, "Orbit Distance", _distance.Value, 1f, 30f);
			y += 10f;
			GUI.Label(new Rect(num, y, 230f, 45f), "Press F6/RightStick: Orbit\nHold F6/RightStick: Menu\nD-Pad: Navigate Settings\n(Settings auto-save on close)");
		}
	}

	private float DrawSetting(int id, float x, ref float y, string label, float value, float min, float max)
	{
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0018: 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_009c: 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)
		bool flag = _isMenuActive && _menuSelection == id;
		GUI.color = (flag ? Color.yellow : Color.white);
		GUI.Label(new Rect(x, y, 230f, 20f), $"{(flag ? "> " : "")}{label}: {value:F1}");
		float result = GUI.HorizontalSlider(new Rect(x, y + 22f, 230f, 20f), value, min, max);
		y += 45f;
		GUI.color = Color.white;
		return result;
	}
}