using System; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = "")] [assembly: AssemblyCompany("ThirdPersonSelfCam")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.1.0")] [assembly: AssemblyInformationalVersion("1.0.1")] [assembly: AssemblyProduct("ThirdPersonSelfCam")] [assembly: AssemblyTitle("ThirdPersonSelfCam")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.1.0")] [module: UnverifiableCode] namespace ThirdPersonSelfCam { [BepInPlugin("com.sleepylemon.thirdpersonselfcam", "ThirdPersonSelfCam", "1.0.1")] public class Plugin : BaseUnityPlugin { internal static Plugin Instance; internal static ManualLogSource Log; public static ConfigEntry ToggleKey; public static ConfigEntry Distance; public static ConfigEntry Height; public static ConfigEntry Shoulder; public static ConfigEntry Smoothing; public static ConfigEntry CollisionRadius; public static ConfigEntry CollisionBuffer; public static ConfigEntry AllowScrollZoom; public static ConfigEntry MinDistance; public static ConfigEntry MaxDistance; public static ConfigEntry StartInThirdPerson; private ThirdPersonCamera cam; private void Awake() { //IL_01a2: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Unknown result type (might be due to invalid IL or missing references) Instance = this; Log = ((BaseUnityPlugin)this).Logger; ToggleKey = ((BaseUnityPlugin)this).Config.Bind("Hotkey", "ToggleKey", (KeyCode)118, "Key used to switch between first and third person."); Distance = ((BaseUnityPlugin)this).Config.Bind("Camera", "Distance", 2.5f, "How far behind the player the camera sits."); Height = ((BaseUnityPlugin)this).Config.Bind("Camera", "Height", 0.2f, "Vertical offset from the eye point."); Shoulder = ((BaseUnityPlugin)this).Config.Bind("Camera", "Shoulder", 0f, "Sideways (over the shoulder) offset. 0 = centred."); Smoothing = ((BaseUnityPlugin)this).Config.Bind("Camera", "Smoothing", 12f, "How quickly the camera moves between first and third person."); CollisionRadius = ((BaseUnityPlugin)this).Config.Bind("Collision", "Radius", 0.2f, "Radius of the sphere cast used to keep the camera out of walls."); CollisionBuffer = ((BaseUnityPlugin)this).Config.Bind("Collision", "Buffer", 0.15f, "Gap kept between the camera and any wall it hits."); AllowScrollZoom = ((BaseUnityPlugin)this).Config.Bind("Camera", "AllowScrollZoom", false, "Allow the mouse scroll wheel to change the camera distance while in third person."); MinDistance = ((BaseUnityPlugin)this).Config.Bind("Camera", "MinDistance", 1f, "Minimum distance when scroll zoom is enabled."); MaxDistance = ((BaseUnityPlugin)this).Config.Bind("Camera", "MaxDistance", 6f, "Maximum distance when scroll zoom is enabled."); StartInThirdPerson = ((BaseUnityPlugin)this).Config.Bind("Camera", "StartInThirdPerson", false, "If enabled, third person is active as soon as you spawn."); cam = new ThirdPersonCamera(); new Harmony("com.sleepylemon.thirdpersonselfcam").PatchAll(); Log.LogInfo((object)string.Format("{0} {1} loaded. Toggle key: {2}.", "ThirdPersonSelfCam", "1.0.1", ToggleKey.Value)); } internal void DriveTick() { cam?.Tick(); } private void OnDestroy() { cam?.RestoreFirstPerson(); } } [HarmonyPatch(typeof(CameraAim), "Update")] internal static class CameraAimUpdatePatch { private static void Postfix() { Plugin.Instance?.DriveTick(); } } internal static class PluginInfo { public const string Guid = "com.sleepylemon.thirdpersonselfcam"; public const string Name = "ThirdPersonSelfCam"; public const string Version = "1.0.1"; } public class ThirdPersonCamera { public static ThirdPersonCamera Instance; private bool thirdPersonEnabled; private bool visualsApplied; private bool startApplied; private Camera mainCamera; private static FieldInfo menuManagerCurrentMenuPageField; public ThirdPersonCamera() { Instance = this; if (menuManagerCurrentMenuPageField == null) { menuManagerCurrentMenuPageField = typeof(MenuManager).GetField("currentMenuPage", BindingFlags.Instance | BindingFlags.NonPublic); if (menuManagerCurrentMenuPageField == null) { Plugin.Log.LogWarning((object)"Could not find MenuManager.currentMenuPage field via reflection. Menu checks will be skipped."); } } } private MenuPage GetCurrentMenuPage() { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown if (!Object.op_Implicit((Object)(object)MenuManager.instance)) { return null; } if (menuManagerCurrentMenuPageField != null) { return (MenuPage)menuManagerCurrentMenuPageField.GetValue(MenuManager.instance); } return null; } public void Tick() { //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Invalid comparison between Unknown and I4 try { if (!Object.op_Implicit((Object)(object)mainCamera) && Object.op_Implicit((Object)(object)GameDirector.instance)) { mainCamera = GameDirector.instance.MainCamera; } if (!Object.op_Implicit((Object)(object)mainCamera) || (Object)(object)((Component)mainCamera).transform.parent == (Object)null) { return; } if (Object.op_Implicit((Object)(object)SpectateCamera.instance)) { visualsApplied = false; return; } PlayerAvatar instance = PlayerAvatar.instance; bool num = Object.op_Implicit((Object)(object)GameDirector.instance) && (int)GameDirector.instance.currentState >= 2; bool flag = Object.op_Implicit((Object)(object)instance) && !instance.isDisabled; bool flag2 = !SemiFunc.MenuLevel(); bool flag3 = num && flag && flag2; if (flag3 && !startApplied) { startApplied = true; if (Plugin.StartInThirdPerson.Value) { thirdPersonEnabled = true; } } HandleToggleInput(flag3); if (thirdPersonEnabled && flag3) { ApplyThirdPerson(instance); } else { ApplyFirstPerson(instance); } } catch (Exception arg) { Plugin.Log.LogError((object)$"Exception in LateUpdate: {arg}"); } } private void HandleToggleInput(bool canSpectateSelf) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) if (canSpectateSelf && !Object.op_Implicit((Object)(object)GetCurrentMenuPage()) && Input.GetKeyDown(Plugin.ToggleKey.Value)) { thirdPersonEnabled = !thirdPersonEnabled; } } private void ApplyThirdPerson(PlayerAvatar localPlayer) { //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0095: 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_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) Transform parent = ((Component)mainCamera).transform.parent; float num = Plugin.Distance.Value; float value = Plugin.Height.Value; float value2 = Plugin.Shoulder.Value; if (Plugin.AllowScrollZoom.Value) { float num2 = SemiFunc.InputScrollY(); if (num2 != 0f) { num = Mathf.Clamp(num - num2 * 0.0025f, Plugin.MinDistance.Value, Plugin.MaxDistance.Value); Plugin.Distance.Value = num; } } Vector3 val = parent.position + parent.up * value + parent.right * value2; Vector3 val2 = -parent.forward; float num3 = num; RaycastHit val3 = default(RaycastHit); if (Physics.SphereCast(val, Plugin.CollisionRadius.Value, val2, ref val3, num, LayerMask.op_Implicit(SemiFunc.LayerMaskGetVisionObstruct()), (QueryTriggerInteraction)1)) { num3 = Mathf.Max(0f, ((RaycastHit)(ref val3)).distance - Plugin.CollisionBuffer.Value); } Vector3 val4 = default(Vector3); ((Vector3)(ref val4))..ctor(value2, value, 0f - num3); ((Component)mainCamera).transform.localPosition = Vector3.Lerp(((Component)mainCamera).transform.localPosition, val4, Plugin.Smoothing.Value * Time.deltaTime); SetThirdPersonVisuals(localPlayer, state: true); if (Object.op_Implicit((Object)(object)localPlayer.playerAvatarVisuals)) { localPlayer.playerAvatarVisuals.ShowSelfOverride(0.5f); } } private void ApplyFirstPerson(PlayerAvatar localPlayer) { //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_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: 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_0074: Unknown result type (might be due to invalid IL or missing references) Vector3 localPosition = ((Component)mainCamera).transform.localPosition; if (((Vector3)(ref localPosition)).sqrMagnitude > 0.0001f) { ((Component)mainCamera).transform.localPosition = Vector3.Lerp(localPosition, Vector3.zero, Plugin.Smoothing.Value * Time.deltaTime); Vector3 localPosition2 = ((Component)mainCamera).transform.localPosition; if (((Vector3)(ref localPosition2)).sqrMagnitude < 0.0001f) { ((Component)mainCamera).transform.localPosition = Vector3.zero; } } SetThirdPersonVisuals(localPlayer, state: false); } private void SetThirdPersonVisuals(PlayerAvatar localPlayer, bool state) { if (visualsApplied == state) { return; } if (Object.op_Implicit((Object)(object)localPlayer)) { PhysGrabber physGrabber = localPlayer.physGrabber; if (physGrabber != null) { physGrabber.SetThirdPerson(state); } FlashlightController flashlightController = localPlayer.flashlightController; if (flashlightController != null) { flashlightController.SetThirdPerson(state); } } visualsApplied = state; } public void RestoreFirstPerson() { //IL_0018: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)mainCamera)) { ((Component)mainCamera).transform.localPosition = Vector3.zero; } } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } }