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