using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Core.Logging.Interpolation; using BepInEx.Logging; using BepInEx.Unity.IL2CPP; using HarmonyLib; using Il2CppInterop.Runtime; using Il2CppInterop.Runtime.Injection; using Il2CppInterop.Runtime.InteropTypes; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Microsoft.CodeAnalysis; using Mirror; using UnityEngine; using UnityEngine.Rendering; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("ThirdPerson")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("Third-person, front-facing and free camera views for Big Walk")] [assembly: AssemblyFileVersion("1.3.1.0")] [assembly: AssemblyInformationalVersion("1.3.1")] [assembly: AssemblyProduct("ThirdPerson")] [assembly: AssemblyTitle("ThirdPerson")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.3.1.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace ThirdPerson { internal static class Freecam { private struct Shift { public Transform Transform; public Vector3 Delta; public Quaternion Rotation; } private struct Pin { public Transform Transform; public Vector3 LocalPosition; public Quaternion LocalRotation; public Vector3 Position; public Quaternion Rotation; } private static readonly List Shifts = new List(); private static readonly List Pins = new List(); private static readonly List HeldChildren = new List(); private static Transform _heldOwner; private static int _heldCount = -1; private static bool _active; private static bool _seedPending; private static Vector3 _position; private static float _yaw; private static float _pitch; private static Vector3 _fromEye; private static ViewMode _chosen; private const ViewMode Borrowed = ViewMode.Behind; public static ViewMode ChosenMode { get { if (!_active) { return Plugin.Mode.Value; } return _chosen; } set { if (_active) { _chosen = value; } else { Plugin.Mode.Value = value; } } } public static Vector3 Position => _position; public static float Yaw => _yaw; public static float Pitch => _pitch; public static bool Active => _active; public static Quaternion Rotation => Quaternion.Euler(_pitch, _yaw, 0f); public static void Toggle() { SetActive(!_active); } public static void SetActive(bool active) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Expected O, but got Unknown //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Expected O, but got Unknown if (active == _active) { return; } bool flag = default(bool); if (active) { _chosen = Plugin.Mode.Value; _active = true; Plugin.Mode.Value = ViewMode.Behind; _seedPending = true; ManualLogSource log = Plugin.Log; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(95, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("freecam on, taking the camera off your head (view stays "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(_chosen); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" "); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("for you, borrowing "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ViewMode.Behind); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" to draw your body)"); } log.LogInfo(val); } else { _active = false; Restore(); Plugin.Mode.Value = _chosen; if (_chosen == ViewMode.FirstPerson) { ThirdPersonCamera.Reset(); } ManualLogSource log2 = Plugin.Log; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(52, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("freecam off, camera back on your head, view back to "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(_chosen); } log2.LogInfo(val); } } public static void Restore() { //IL_0049: 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_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) if (Shifts.Count == 0 && Pins.Count == 0) { return; } for (int num = Shifts.Count - 1; num >= 0; num--) { Shift shift = Shifts[num]; if (!((Object)(object)shift.Transform == (Object)null)) { shift.Transform.rotation = shift.Rotation; Transform transform = shift.Transform; transform.position -= shift.Delta; } } Shifts.Clear(); for (int num2 = Pins.Count - 1; num2 >= 0; num2--) { Pin pin = Pins[num2]; if (!((Object)(object)pin.Transform == (Object)null)) { pin.Transform.localPosition = pin.LocalPosition; pin.Transform.localRotation = pin.LocalRotation; } } Pins.Clear(); } public static void Apply(PlayerCharacter pc) { //IL_004c: 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) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0065: 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_0070: 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) //IL_008f: 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_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) Restore(); if (!_active && !Hud.Wanted) { return; } Transform ui; Camera camera; Camera uiCamera; Transform val = CameraTransform(pc, out ui, out camera, out uiCamera); Hud.Tick(camera, uiCamera); if (_active && !((Object)(object)val == (Object)null)) { if (_seedPending) { _seedPending = false; Seed(val); } Vector3 delta = (_fromEye = _position - val.position); Quaternion spin = Rotation * Quaternion.Inverse(val.rotation); if (Plugin.PinCameraChildren.Value) { Hold(val); } Move(val, delta, spin); if ((Object)(object)ui != (Object)null && !ui.IsChildOf(val)) { Move(ui, delta, spin); } Anchor(); } } private static void Seed(Transform main) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: 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) //IL_0058: Expected O, but got Unknown _position = main.position; Quaternion rotation = main.rotation; Vector3 eulerAngles = ((Quaternion)(ref rotation)).eulerAngles; _yaw = Wrap(eulerAngles.y); _pitch = Mathf.Clamp(Wrap(eulerAngles.x), 0f - Limit(), Limit()); ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(36, 4, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("freecam starting at ("); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(_position.x, "0.#"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(_position.y, "0.#"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(_position.z, "0.#"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("), facing "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(_yaw, "0"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("°"); } log.LogInfo(val); } public static void Steer(float forward, float strafe, float rise, float speed, float dt) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: 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) //IL_0064: 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_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: 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) if (_active && (forward != 0f || strafe != 0f || rise != 0f)) { Vector3 val = Rotation * new Vector3(strafe, 0f, forward); val += Vector3.up * rise; if (((Vector3)(ref val)).sqrMagnitude > 1f) { ((Vector3)(ref val)).Normalize(); } _position += val * speed * dt; } } public static void Look(float yaw, float pitch) { if (_active) { _yaw = Wrap(_yaw + yaw); _pitch = Mathf.Clamp(_pitch + pitch, 0f - Limit(), Limit()); } } public static void Level() { _pitch = 0f; } public static bool Teleport() { //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Expected O, but got Unknown //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: 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_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Expected O, but got Unknown //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) if (!_active) { return false; } PlayerCharacter local = ThirdPersonCamera.Local; if ((Object)(object)local == (Object)null) { return false; } bool flag = default(bool); try { Rigidbody rb = local.rb; Transform val = (((Object)(object)rb != (Object)null) ? ((Component)rb).transform : (((Object)(object)local.kernal != (Object)null) ? local.kernal : ((Component)local).transform)); if ((Object)(object)val == (Object)null) { Plugin.Log.LogWarning((object)"nothing on your character to move, so the teleport did nothing"); return false; } Vector3 val2 = val.position + _fromEye; if ((Object)(object)rb != (Object)null) { rb.velocity = Vector3.zero; rb.angularVelocity = Vector3.zero; rb.position = val2; } val.position = val2; PlayerMover mover = local.mover; if (mover != null) { mover.cachedKernalPos = val2; } ManualLogSource log = Plugin.Log; BepInExInfoLogInterpolatedStringHandler val3 = new BepInExInfoLogInterpolatedStringHandler(46, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("brought your character to the camera at "); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("("); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(val2.x, "0.#"); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(", "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(val2.y, "0.#"); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(", "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(val2.z, "0.#"); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(")"); } log.LogInfo(val3); return true; } catch (Exception ex) { ManualLogSource log2 = Plugin.Log; BepInExWarningLogInterpolatedStringHandler val4 = new BepInExWarningLogInterpolatedStringHandler(46, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("could not bring your character to the camera: "); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted(ex.Message); } log2.LogWarning(val4); return false; } } private static float Limit() { return Mathf.Clamp(Plugin.FreecamMaxPitch.Value, 0f, 89.9f); } private static float Wrap(float degrees) { degrees %= 360f; if (degrees > 180f) { degrees -= 360f; } else if (degrees < -180f) { degrees += 360f; } return degrees; } private static void Hold(Transform main) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) foreach (Transform item in Held(main)) { if (!((Object)(object)item == (Object)null)) { Pins.Add(new Pin { Transform = item, LocalPosition = item.localPosition, LocalRotation = item.localRotation, Position = item.position, Rotation = item.rotation }); } } } private static List Held(Transform main) { if ((Object)(object)_heldOwner == (Object)(object)main && _heldCount == main.childCount) { return HeldChildren; } _heldOwner = main; _heldCount = main.childCount; HeldChildren.Clear(); for (int i = 0; i < main.childCount; i++) { Transform child = main.GetChild(i); if (!((Object)(object)child == (Object)null)) { Il2CppReferenceArray componentsInChildren = ((Component)child).GetComponentsInChildren(Il2CppType.Of(), true); if (componentsInChildren == null || ((Il2CppArrayBase)(object)componentsInChildren).Length <= 0) { HeldChildren.Add(child); } } } return HeldChildren; } private static void Anchor() { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) foreach (Pin pin in Pins) { if (!((Object)(object)pin.Transform == (Object)null)) { pin.Transform.position = pin.Position; pin.Transform.rotation = pin.Rotation; } } } private static void Move(Transform t, Vector3 delta, Quaternion spin) { //IL_0017: 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_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) Shifts.Add(new Shift { Transform = t, Delta = delta, Rotation = t.rotation }); t.position += delta; t.rotation = spin * t.rotation; } private static Transform CameraTransform(PlayerCharacter pc, out Transform ui, out Camera camera, out Camera uiCamera) { ui = null; camera = null; uiCamera = null; PlayerCameraMinder cameraMinder = pc.cameraMinder; PlayerCameraReferences val = ((cameraMinder != null) ? cameraMinder.playerCameraReferences : null); if ((Object)(object)val != (Object)null) { uiCamera = val.playerUICamera; if ((Object)(object)uiCamera != (Object)null) { ui = ((Component)uiCamera).transform; } camera = val.playerCamera; if ((Object)(object)camera != (Object)null) { return ((Component)camera).transform; } } Transform cameraTransform = pc.cameraTransform; if (!((Object)(object)cameraTransform != (Object)null)) { return null; } return cameraTransform; } } [HarmonyPatch] internal static class FreecamPatches { [HarmonyPrefix] [HarmonyPriority(800)] [HarmonyPatch(typeof(PlayerCharacter), "FixedUpdate")] private static void BeforeFixedUpdate() { Safely(Freecam.Restore); } [HarmonyPrefix] [HarmonyPriority(800)] [HarmonyPatch(typeof(PlayerCharacter), "Update")] private static void BeforeUpdate() { Safely(Freecam.Restore); } [HarmonyPrefix] [HarmonyPriority(800)] [HarmonyPatch(typeof(PlayerCharacter), "LateUpdate")] private static void BeforeLateUpdate() { Safely(Freecam.Restore); } [HarmonyPostfix] [HarmonyPriority(0)] [HarmonyPatch(typeof(PlayerCharacter), "LateUpdate")] private static void AfterLateUpdate(PlayerCharacter __instance) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown try { if (ThirdPersonCamera.IsLocal(__instance)) { Freecam.Apply(__instance); } } catch (Exception ex) { ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(34, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("freecam failed, switching it off: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex); } log.LogError(val); Safely(delegate { Freecam.SetActive(active: false); }); Safely(Hud.Restore); } } private static void Safely(Action action) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Expected O, but got Unknown try { action(); } catch (Exception ex) { ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(24, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("freecam restore failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex); } log.LogError(val); } } } internal enum HudPiece { Crosshair, Backpack, Belt } internal static class FreecamPanel { private static HudPiece _piece; public static HudPiece Piece => _piece; public static void Body() { State(); GUILayout.Space(8f); PanelWidgets.Section("Flight", delegate { PanelWidgets.ResetAll("flight", Plugin.FreecamSpeed, Plugin.FreecamFastMultiplier, Plugin.FreecamSlowMultiplier); }); PanelWidgets.Slider(Plugin.FreecamSpeed, "Speed", 0.5f, 50f, "m/s", 1); PanelWidgets.Slider(Plugin.FreecamFastMultiplier, "Fast key", 1f, 20f, "x", 1); PanelWidgets.Slider(Plugin.FreecamSlowMultiplier, "Slow key", 0.02f, 1f, "x", 2); GUILayout.Space(8f); PanelWidgets.Section("Aim", delegate { PanelWidgets.ResetAll("aim", Plugin.FreecamLookSpeed, Plugin.FreecamMaxPitch); }); PanelWidgets.Slider(Plugin.FreecamLookSpeed, "Mouse speed", 0.1f, 20f, "°", 1); PanelWidgets.Slider(Plugin.FreecamMaxPitch, "Pitch limit", 0f, 89.9f, "°", 1); PanelWidgets.Toggle(Plugin.FreecamInvertPitch, "Invert up and down"); if (GUILayout.Button("Level the camera", (Il2CppReferenceArray)null)) { Freecam.Level(); PanelWidgets.Status = "levelled"; } GUILayout.Space(8f); PanelWidgets.Section("While flying"); PanelWidgets.Toggle(Plugin.FreecamFreezePlayer, "Freeze your character"); } private static void State() { //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) GUILayout.Label("— Freecam: " + (Freecam.Active ? "flying" : "off") + " —", (Il2CppReferenceArray)null); if (GUILayout.Button(Freecam.Active ? "[Land the camera]" : "Take the camera", (Il2CppReferenceArray)null)) { Freecam.Toggle(); PanelWidgets.Status = (Freecam.Active ? "flying" : "camera back on your head"); } if (Panels.FlyingShown) { Vector3 position = Freecam.Position; GUILayout.Label($"at ({position.x:0.#}, {position.y:0.#}, {position.z:0.#}) " + $"facing {Freecam.Yaw:0}°, {Freecam.Pitch:0}° up", (Il2CppReferenceArray)null); if (GUILayout.Button("Bring your character here", (Il2CppReferenceArray)null)) { PanelWidgets.Status = (Freecam.Teleport() ? "your character is here now" : "could not move you"); } GUILayout.Label(" (!) single player - this really moves you, and others would see it", (Il2CppReferenceArray)null); } } public static void HudBody() { PanelWidgets.Section("Everything"); PanelWidgets.Toggle(Plugin.HideHud, "Hide the whole HUD"); GUILayout.Space(8f); GUILayout.BeginHorizontal((Il2CppReferenceArray)null); Pick(HudPiece.Crosshair, "Crosshair", HudStyle.Crosshair); Pick(HudPiece.Backpack, "Backpack", HudStyle.Backpack); Pick(HudPiece.Belt, "Belt", HudStyle.Belt); GUILayout.EndHorizontal(); switch (Panels.PieceShown) { case HudPiece.Backpack: Draw("Backpack", HudStyle.Backpack); break; case HudPiece.Belt: Draw("Belt", HudStyle.Belt); break; default: Draw("Crosshair", HudStyle.Crosshair); break; } } private static void Pick(HudPiece piece, string label, HudElement element) { if (element.Overridden) { label += " •"; } bool flag = _piece == piece; if (!(!GUILayout.Button(flag ? ("[" + label + "]") : label, (Il2CppReferenceArray)null) || flag)) { _piece = piece; PanelWidgets.Status = ""; } } private static void Draw(string label, HudElement element) { GUILayout.Space(4f); PanelWidgets.Section(label, delegate { Reset(label, element); }); if (element == HudStyle.Crosshair && HudStyle.CrosshairTaken) { GUILayout.Label("Crosshair Resizer owns this. Delete CrosshairResizer.dll to use it here.", (Il2CppReferenceArray)null); return; } PanelWidgets.Toggle(element.Hide, "Hide it"); GUI.enabled = !element.Hide.Value; PanelWidgets.Slider(element.Scale, "Size", 0.1f, 3f, "x", 2); PanelWidgets.Slider(element.Opacity, "Opacity", 0f, 1f, "", 2); PanelWidgets.Toggle(element.Tint, "Recolour it"); GUI.enabled = !element.Hide.Value && element.Tint.Value; PanelWidgets.Slider(element.Red, "Red", 0f, 1f, "", 2); PanelWidgets.Slider(element.Green, "Green", 0f, 1f, "", 2); PanelWidgets.Slider(element.Blue, "Blue", 0f, 1f, "", 2); GUILayout.BeginHorizontal((Il2CppReferenceArray)null); Colour(element, "White", 1f, 1f, 1f); Colour(element, "Red", 1f, 0.15f, 0.15f); Colour(element, "Green", 0.2f, 1f, 0.2f); Colour(element, "Cyan", 0.2f, 1f, 1f); Colour(element, "Magenta", 1f, 0.2f, 1f); GUILayout.EndHorizontal(); GUI.enabled = true; if (Panels.MissingShown(Panels.PieceShown)) { GUILayout.Label("(not on screen yet — this applies once you are in a game)", (Il2CppReferenceArray)null); } } private static void Colour(HudElement element, string label, float r, float g, float b) { if (GUILayout.Button(label, (Il2CppReferenceArray)null)) { element.Red.Value = r; element.Green.Value = g; element.Blue.Value = b; PanelWidgets.Status = element.Name + ": " + label.ToLowerInvariant(); } } private static void Reset(string label, HudElement element) { element.Hide.Value = false; element.Tint.Value = false; PanelWidgets.ResetAll(label.ToLowerInvariant(), element.Scale, element.Opacity, element.Red, element.Green, element.Blue); } } public class FreecamRuntime : MonoBehaviour { private bool _inputDead; private bool _axesDead; private bool _styleDead; private bool _lookHeld; private bool _lookWas; private bool _lookWarned; private bool _playerHeld; private bool _playerUpdateWas; private bool _playerFixedWas; public FreecamRuntime(IntPtr ptr) : base(ptr) { } private void Update() { Style(); if (_inputDead) { return; } try { if (KeyList.AnyDown(Plugin.HudKeys.Value)) { Plugin.HideHud.Value = !Plugin.HideHud.Value; } if (KeyList.AnyDown(Plugin.FreecamKeys.Value)) { Freecam.Toggle(); } Latch(Freecam.Active); if (Freecam.Active) { if (KeyList.AnyDown(Plugin.FreecamTeleportKeys.Value)) { Freecam.Teleport(); } Fly(); } } catch (Exception arg) { _inputDead = true; Latch(held: false); Plugin.Log.LogError((object)("keyboard input is unavailable, so the freecam cannot be flown. " + $"Reason: {arg}")); } } private void Style() { //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Expected O, but got Unknown //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown if (_styleDead) { return; } try { HudStyle.Tick(); } catch (Exception ex) { _styleDead = true; ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(41, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("the HUD styling threw, switching it off: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex); } log.LogError(val); try { HudStyle.Restore(); } catch (Exception ex2) { ManualLogSource log2 = Plugin.Log; BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(28, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("could not put the HUD back: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex2.Message); } log2.LogWarning(val2); } } } private void Fly() { float num = 0f; float num2 = 0f; float num3 = 0f; if (KeyList.AnyHeld(Plugin.FreecamForwardKeys.Value)) { num += 1f; } if (KeyList.AnyHeld(Plugin.FreecamBackKeys.Value)) { num -= 1f; } if (KeyList.AnyHeld(Plugin.FreecamRightKeys.Value)) { num2 += 1f; } if (KeyList.AnyHeld(Plugin.FreecamLeftKeys.Value)) { num2 -= 1f; } if (KeyList.AnyHeld(Plugin.FreecamUpKeys.Value)) { num3 += 1f; } if (KeyList.AnyHeld(Plugin.FreecamDownKeys.Value)) { num3 -= 1f; } float num4 = Plugin.FreecamSpeed.Value; if (KeyList.AnyHeld(Plugin.FreecamFastKeys.Value)) { num4 *= Plugin.FreecamFastMultiplier.Value; } if (KeyList.AnyHeld(Plugin.FreecamSlowKeys.Value)) { num4 *= Plugin.FreecamSlowMultiplier.Value; } Freecam.Steer(num, num2, num3, num4, Time.unscaledDeltaTime); float value = Plugin.FreecamLookSpeed.Value; float num5 = MouseAxis("Mouse Y") * value; Freecam.Look(MouseAxis("Mouse X") * value, Plugin.FreecamInvertPitch.Value ? num5 : (0f - num5)); } private void Latch(bool held) { HoldLook(held); HoldPlayer(held && Plugin.FreecamFreezePlayer.Value); } private void HoldLook(bool held) { //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Expected O, but got Unknown try { PlayerCharacter local = ThirdPersonCamera.Local; PlayerHead val = ((local != null) ? local.head : null); if (val == null) { if (held && !_lookWarned) { _lookWarned = true; Plugin.Log.LogWarning((object)"no PlayerHead to freeze yet, so the mouse will turn you as well as the freecam"); } return; } _lookWarned = false; if (held) { if (!_lookHeld) { _lookHeld = true; _lookWas = val.bypassUpdate; } val.bypassUpdate = true; } else if (_lookHeld) { _lookHeld = false; val.bypassUpdate = _lookWas; } } catch (Exception ex) { ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(34, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("could not freeze the game's look: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex.Message); } log.LogWarning(val2); } } private void HoldPlayer(bool held) { //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Expected O, but got Unknown try { PlayerCharacter local = ThirdPersonCamera.Local; if ((Object)(object)local == (Object)null) { _playerHeld = false; } else if (held) { if (!_playerHeld) { _playerHeld = true; _playerUpdateWas = local.bypassUpdate; _playerFixedWas = local.bypassFixedUpdate; Plugin.Log.LogInfo((object)"freecam: your character is frozen while you fly"); } local.bypassUpdate = true; local.bypassFixedUpdate = true; } else if (_playerHeld) { _playerHeld = false; local.bypassUpdate = _playerUpdateWas; local.bypassFixedUpdate = _playerFixedWas; } } catch (Exception ex) { ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(33, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("could not freeze your character: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } log.LogWarning(val); } } private float MouseAxis(string axis) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown if (_axesDead) { return 0f; } try { return Input.GetAxisRaw(axis); } catch (Exception ex) { _axesDead = true; ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(82, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("this build has no '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(axis); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' axis, so the freecam cannot be aimed "); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("with the mouse. Reason: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } log.LogWarning(val); return 0f; } } private void OnDisable() { Release(); } private void OnDestroy() { Release(); } private void Release() { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Expected O, but got Unknown //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Expected O, but got Unknown Latch(held: false); bool flag = default(bool); try { Hud.Restore(); } catch (Exception ex) { ManualLogSource log = Plugin.Log; BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(28, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("could not put the HUD back: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } log.LogWarning(val); } try { HudStyle.Restore(); } catch (Exception ex2) { ManualLogSource log2 = Plugin.Log; BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(32, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("could not restyle the HUD back: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex2.Message); } log2.LogWarning(val); } } } internal static class Hud { private static Camera _masked; private static IntPtr _maskedPtr = IntPtr.Zero; private static int _hiddenBits; private static string _layerSource; private static int _layerMask; private static readonly List Canvases = new List(); private static bool _scanned; private static bool _dumped; private static bool _reported; public static bool Wanted { get { if (!Plugin.HideHud.Value && !_reported && !((Object)(object)_masked != (Object)null) && Canvases.Count <= 0) { if (Plugin.DumpCanvases.Value) { return !_dumped; } return false; } return true; } } public static void Tick(Camera main, Camera ui) { if (Plugin.DumpCanvases.Value && !_dumped) { _dumped = true; DumpCanvases(main, ui); } if (!Plugin.HideHud.Value) { Restore(); return; } if (!_reported) { _reported = true; Plugin.Log.LogInfo((object)("hiding the HUD: layers [" + Plugin.HudLayers.Value + "]" + (Plugin.HudHideCanvases.Value ? ", canvases" : ""))); } Mask(main); if (Plugin.HudHideCanvases.Value) { HideCanvases(); } else { RestoreCanvases(); } } public static void Restore() { if (_reported) { _reported = false; Plugin.Log.LogInfo((object)"HUD is back"); } if ((Object)(object)_masked != (Object)null && _hiddenBits != 0) { Camera masked = _masked; masked.cullingMask |= _hiddenBits; } _masked = null; _maskedPtr = IntPtr.Zero; _hiddenBits = 0; RestoreCanvases(); } private static void HideCanvases() { if (!_scanned) { _scanned = true; Collect(); } for (int i = 0; i < Canvases.Count; i++) { Canvas val = Canvases[i]; if ((Object)(object)val != (Object)null && ((Behaviour)val).enabled) { ((Behaviour)val).enabled = false; } } } private static void Collect() { //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Expected O, but got Unknown //IL_00a7: Unknown result type (might be due to invalid IL or missing references) Canvases.Clear(); try { int num = LayerMask(); Il2CppReferenceArray val = Resources.FindObjectsOfTypeAll(Il2CppType.Of()); if (val == null) { return; } int num2 = 0; for (int i = 0; i < ((Il2CppArrayBase)(object)val).Length; i++) { Object obj = ((Il2CppArrayBase)(object)val)[i]; Canvas val2 = ((obj != null) ? ((Il2CppObjectBase)obj).TryCast() : null); if ((Object)(object)val2 == (Object)null) { continue; } GameObject gameObject = ((Component)val2).gameObject; if (gameObject.activeInHierarchy && ((Behaviour)val2).enabled) { int layer = gameObject.layer; bool flag = num == 0 || (num & (1 << layer)) != 0; Plugin.Log.LogInfo((object)($"canvas '{((Object)gameObject).name}': {val2.renderMode}, layer {layer} " + "'" + LayerMask.LayerToName(layer) + "' — " + (flag ? "hiding" : "left alone, not in HudLayers"))); if (!flag) { num2++; continue; } ((Behaviour)val2).enabled = false; Canvases.Add(val2); } } Plugin.Log.LogInfo((object)($"HUD: switched off {Canvases.Count} canvases, left {num2} alone. " + "If something is still on screen, its canvas is named above — put its layer in HudLayers, or clear HudLayers to hide every canvas.")); } catch (Exception ex) { ManualLogSource log = Plugin.Log; bool flag2 = default(bool); BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(36, 1, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("could not collect the HUD canvases: "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(ex.Message); } log.LogWarning(val3); } } private static void RestoreCanvases() { for (int i = 0; i < Canvases.Count; i++) { Canvas val = Canvases[i]; if ((Object)(object)val != (Object)null) { ((Behaviour)val).enabled = true; } } Canvases.Clear(); _scanned = false; } private static void Mask(Camera main) { if ((Object)(object)main == (Object)null) { return; } if (_maskedPtr != IntPtr.Zero && ((Il2CppObjectBase)main).Pointer != _maskedPtr) { Restore(); } int num = LayerMask(); if (num != 0) { int num2 = num & main.cullingMask; if (num2 != 0) { main.cullingMask &= ~num2; _masked = main; _maskedPtr = ((Il2CppObjectBase)main).Pointer; _hiddenBits |= num2; } } } private static int LayerMask() { //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Expected O, but got Unknown string text = Plugin.HudLayers.Value ?? string.Empty; if (text == _layerSource) { return _layerMask; } _layerSource = text; int num = 0; string[] array = text.Split(','); bool flag = default(bool); for (int i = 0; i < array.Length; i++) { string text2 = array[i].Trim(); if (text2.Length == 0) { continue; } if (!int.TryParse(text2, out var result)) { result = LayerMask.NameToLayer(text2); } if (result >= 0 && result < 32) { num |= 1 << result; continue; } ManualLogSource log = Plugin.Log; BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(41, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("HudLayers: '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(text2); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' is not a layer, skipping it"); } log.LogWarning(val); } _layerMask = num; return num; } private static void DumpCanvases(Camera main, Camera ui) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown //IL_01e9: Unknown result type (might be due to invalid IL or missing references) //IL_01f0: Expected O, but got Unknown //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Expected O, but got Unknown //IL_012e: Unknown result type (might be due to invalid IL or missing references) bool flag = default(bool); try { ManualLogSource log = Plugin.Log; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(31, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("main camera mask 0x"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(((Object)(object)main != (Object)null) ? main.cullingMask : 0, "X8"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", "); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("UI camera "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(((Object)(object)ui != (Object)null) ? ((Object)ui).name : "none"); } log.LogInfo(val); Il2CppReferenceArray val2 = Resources.FindObjectsOfTypeAll(Il2CppType.Of()); if (val2 == null || ((Il2CppArrayBase)(object)val2).Length == 0) { Plugin.Log.LogInfo((object)"no canvases found at all"); return; } for (int i = 0; i < ((Il2CppArrayBase)(object)val2).Length; i++) { Object obj = ((Il2CppArrayBase)(object)val2)[i]; Canvas val3 = ((obj != null) ? ((Il2CppObjectBase)obj).TryCast() : null); if ((Object)(object)val3 == (Object)null) { continue; } GameObject gameObject = ((Component)val3).gameObject; if (gameObject.activeInHierarchy) { int layer = gameObject.layer; Camera worldCamera = val3.worldCamera; ManualLogSource log2 = Plugin.Log; val = new BepInExInfoLogInterpolatedStringHandler(39, 6, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("canvas '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(Path(((Component)val3).transform)); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("': "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(val3.renderMode); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", "); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("layer "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(layer); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(LayerMask.LayerToName(layer)); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("', "); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("camera "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(((Object)(object)worldCamera != (Object)null) ? ((Object)worldCamera).name : "none"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", "); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("order "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(val3.sortingOrder); } log2.LogInfo(val); } } } catch (Exception ex) { ManualLogSource log3 = Plugin.Log; BepInExWarningLogInterpolatedStringHandler val4 = new BepInExWarningLogInterpolatedStringHandler(29, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("could not list the canvases: "); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted(ex.Message); } log3.LogWarning(val4); } DumpCheatMover(); } private static void DumpCheatMover() { //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Expected O, but got Unknown //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Expected O, but got Unknown bool flag = default(bool); try { PlayerCharacter local = ThirdPersonCamera.Local; if ((Object)(object)local == (Object)null) { return; } PlayerCheater cheater = local.cheater; if (cheater == null) { Plugin.Log.LogInfo((object)"no PlayerCheater on the local player"); return; } CameraCheatMover cameraCheatMover = cheater.cameraCheatMover; if ((Object)(object)cameraCheatMover == (Object)null) { Plugin.Log.LogInfo((object)"PlayerCheater is present but has no CameraCheatMover"); return; } ManualLogSource log = Plugin.Log; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(86, 4, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("the game's own CameraCheatMover is present: detached "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(cameraCheatMover._detached); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", "); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("speed "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(cameraCheatMover.movingSpeed, "0.##"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", sensitivity "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(cameraCheatMover.sensitivity, "0.##"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", "); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("maxPitch "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(cameraCheatMover.maxPitch, "0.##"); } log.LogInfo(val); } catch (Exception ex) { ManualLogSource log2 = Plugin.Log; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(44, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("could not read the game's own camera cheat: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } log2.LogInfo(val); } } private static string Path(Transform t) { StringBuilder stringBuilder = new StringBuilder(((Object)t).name); Transform parent = t.parent; while ((Object)(object)parent != (Object)null) { stringBuilder.Insert(0, ((Object)parent).name + "/"); parent = parent.parent; } return stringBuilder.ToString(); } } internal sealed class HudElement { private struct Root { public Transform Transform; public Vector3 Scale; public CanvasGroup Group; public bool Added; public float Alpha; } private struct Tinted { public Graphic Graphic; public Color Original; } private static readonly List Scratch = new List(); public readonly string Name; public ConfigEntry Hide; public ConfigEntry Tint; public ConfigEntry Scale; public ConfigEntry Opacity; public ConfigEntry Red; public ConfigEntry Green; public ConfigEntry Blue; private readonly Func _owner; private readonly Action> _find; private readonly List _roots = new List(); private readonly List _tinted = new List(); private IntPtr _ownerPtr = IntPtr.Zero; private bool _touched; private bool _tinting; private bool _broken; private bool _reported; public bool Overridden { get { if (!Hide.Value && !Tint.Value && Scale.Value == 1f) { return Opacity.Value != 1f; } return true; } } public bool Found => _roots.Count > 0; public HudElement(string name, Func owner, Action> find) { Name = name; _owner = owner; _find = find; } public void Bind(ConfigFile cfg, string section, string what) { //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Expected O, but got Unknown //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Expected O, but got Unknown //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Expected O, but got Unknown //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Expected O, but got Unknown //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Expected O, but got Unknown Hide = cfg.Bind(section, "Hide", false, "Hide the " + what + " without hiding the rest of the HUD. This is the individual switch; the HUD keys hide everything at once."); Scale = cfg.Bind(section, "Scale", 1f, new ConfigDescription("Size of the " + what + ". 1 is the size the game draws it at, and the scale multiplies whatever the game set, so a widget that was never square keeps its shape.", (AcceptableValueBase)(object)new AcceptableValueRange(0.1f, 3f), Array.Empty())); Opacity = cfg.Bind(section, "Opacity", 1f, new ConfigDescription("How solid the " + what + " is. 1 is untouched and 0 is invisible. Applied through a CanvasGroup, so it multiplies the fades the game does rather than overriding them.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 1f), Array.Empty())); Tint = cfg.Bind(section, "Tint", false, "Override the colour of the " + what + ". Off means it keeps the colour it shipped with. Only the red, green and blue are replaced — the transparency stays the game's, since that is what it animates."); Red = cfg.Bind(section, "Red", 1f, new ConfigDescription("Red channel, 0-1. Only used when Tint is on.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 1f), Array.Empty())); Green = cfg.Bind(section, "Green", 1f, new ConfigDescription("Green channel, 0-1. Only used when Tint is on.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 1f), Array.Empty())); Blue = cfg.Bind(section, "Blue", 1f, new ConfigDescription("Blue channel, 0-1. Only used when Tint is on.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 1f), Array.Empty())); } public void Tick(bool resolve) { if (_broken) { return; } if (!Overridden) { if (_touched) { Restore(); } return; } if (resolve) { Resolve(); } if (_roots.Count != 0) { Apply(); } } private void Resolve() { IntPtr intPtr; try { intPtr = _owner(); } catch (Exception e) { Fail(e); return; } if (intPtr == IntPtr.Zero) { _roots.Clear(); _tinted.Clear(); _ownerPtr = IntPtr.Zero; _touched = false; _tinting = false; } else if (!(intPtr == _ownerPtr) || _roots.Count <= 0 || !((Object)(object)_roots[0].Transform != (Object)null)) { Collect(intPtr); } } private void Collect(IntPtr owner) { //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Expected O, but got Unknown Restore(); _roots.Clear(); _tinted.Clear(); _ownerPtr = owner; Scratch.Clear(); try { _find(Scratch); } catch (Exception e) { Scratch.Clear(); Fail(e); return; } for (int i = 0; i < Scratch.Count; i++) { Transform val = Scratch[i]; if (!((Object)(object)val == (Object)null)) { _roots.Add(new Root { Transform = val, Scale = val.localScale, Group = Group(val, out var added, out var alpha), Added = added, Alpha = alpha }); CollectGraphics(val); } } Scratch.Clear(); if (!_reported) { _reported = true; ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(19, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(Name); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(_roots.Count); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" parts, "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(_tinted.Count); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" graphics"); } log.LogInfo(val2); } } private void CollectGraphics(Transform root) { //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) Il2CppReferenceArray componentsInChildren = ((Component)root).GetComponentsInChildren(Il2CppType.Of(), true); if (componentsInChildren == null) { return; } for (int i = 0; i < ((Il2CppArrayBase)(object)componentsInChildren).Length; i++) { Component obj = ((Il2CppArrayBase)(object)componentsInChildren)[i]; Graphic val = ((obj != null) ? ((Il2CppObjectBase)obj).TryCast() : null); if (!((Object)(object)val == (Object)null)) { _tinted.Add(new Tinted { Graphic = val, Original = val.color }); } } } private static CanvasGroup Group(Transform root, out bool added, out float alpha) { added = false; alpha = 1f; Component component = ((Component)root).GetComponent(Il2CppType.Of()); CanvasGroup val = (((Object)(object)component != (Object)null) ? ((Il2CppObjectBase)component).TryCast() : null); if ((Object)(object)val != (Object)null) { alpha = val.alpha; return val; } Component val2 = ((Component)root).gameObject.AddComponent(Il2CppType.Of()); val = (((Object)(object)val2 != (Object)null) ? ((Il2CppObjectBase)val2).TryCast() : null); added = (Object)(object)val != (Object)null; return val; } private void Apply() { //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008c: 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_013c: 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_0143: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) float value = Scale.Value; float num = (Hide.Value ? 0f : Mathf.Clamp01(Opacity.Value)); bool flag = Tint.Value && !Hide.Value; for (int i = 0; i < _roots.Count; i++) { Root root = _roots[i]; if (!((Object)(object)root.Transform == (Object)null)) { Vector3 val = root.Scale * value; if (root.Transform.localScale != val) { root.Transform.localScale = val; } if ((Object)(object)root.Group != (Object)null && root.Group.alpha != num) { root.Group.alpha = num; } } } if (flag) { _tinting = true; float value2 = Red.Value; float value3 = Green.Value; float value4 = Blue.Value; for (int j = 0; j < _tinted.Count; j++) { Graphic graphic = _tinted[j].Graphic; if (!((Object)(object)graphic == (Object)null)) { Color color = graphic.color; if (color.r != value2 || color.g != value3 || color.b != value4) { graphic.color = new Color(value2, value3, value4, color.a); } } } } else { Untint(); } _touched = true; } public void Restore() { //IL_0036: Unknown result type (might be due to invalid IL or missing references) if (!_touched) { return; } _touched = false; for (int i = 0; i < _roots.Count; i++) { Root root = _roots[i]; if ((Object)(object)root.Transform != (Object)null) { root.Transform.localScale = root.Scale; } if ((Object)(object)root.Group != (Object)null) { root.Group.alpha = (root.Added ? 1f : root.Alpha); } } Untint(); } private void Untint() { //IL_003b: 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_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004e: 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_005f: Unknown result type (might be due to invalid IL or missing references) if (!_tinting) { return; } _tinting = false; for (int i = 0; i < _tinted.Count; i++) { Graphic graphic = _tinted[i].Graphic; if (!((Object)(object)graphic == (Object)null)) { Color original = _tinted[i].Original; graphic.color = new Color(original.r, original.g, original.b, graphic.color.a); } } } private void Fail(Exception e) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown _broken = true; ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(37, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("cannot reach the "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(Name); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", leaving it alone: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(e.Message); } log.LogWarning(val); } } internal static class HudStyle { private const float ResolveInterval = 1f; private const string ResizerGuid = "deck.bigwalk.crosshairresizer"; public static readonly HudElement Crosshair = new HudElement("crosshair", CrosshairOwner, CrosshairRoots); public static readonly HudElement Backpack = new HudElement("backpack indicator", ArmHudOwner, BackpackRoots); public static readonly HudElement Belt = new HudElement("belt indicator", ArmHudOwner, BeltRoots); private static float _nextResolve; private static bool _touched; private static bool _checkedResizer; private static bool _resizer; public static bool CrosshairTaken { get { //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Expected O, but got Unknown if (_checkedResizer) { return _resizer; } _checkedResizer = true; try { _resizer = ((BaseChainloader)(object)IL2CPPChainloader.Instance).Plugins.ContainsKey("deck.bigwalk.crosshairresizer"); if (_resizer) { Plugin.Log.LogWarning((object)"Crosshair Resizer is installed and writes the same crosshair scale and colour, so the crosshair controls here are switched off. Delete BepInEx/plugins/CrosshairResizer.dll to use them — everything it did is in this mod's HUD tab."); } } catch (Exception ex) { _resizer = false; ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(39, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("could not check for Crosshair Resizer: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } log.LogInfo(val); } return _resizer; } } public static void Bind(ConfigFile cfg) { Crosshair.Bind(cfg, "Crosshair", "crosshair"); Backpack.Bind(cfg, "Backpack", "backpack indicator"); Belt.Bind(cfg, "Belt", "belt indicator"); } public static void Tick() { bool flag = Crosshair.Overridden || Backpack.Overridden || Belt.Overridden; if (flag || _touched) { _touched = flag; bool resolve = false; float unscaledTime = Time.unscaledTime; if (unscaledTime >= _nextResolve) { _nextResolve = unscaledTime + 1f; resolve = true; } if (!CrosshairTaken) { Crosshair.Tick(resolve); } Backpack.Tick(resolve); Belt.Tick(resolve); } } public static void Restore() { Crosshair.Restore(); Backpack.Restore(); Belt.Restore(); _touched = false; } private static IntPtr CrosshairOwner() { Crosshair instance = Crosshair.instance; if (instance == null) { return IntPtr.Zero; } return ((Il2CppObjectBase)instance).Pointer; } private static void CrosshairRoots(List into) { Crosshair instance = Crosshair.instance; if (instance != null) { Add(into, instance.crosshairNormal); Add(into, instance.crosshairHolding); Add(into, (Transform)(object)instance.crosshairWindup); } } private static IntPtr ArmHudOwner() { ArmHud instance = ArmHud.instance; if (instance == null) { return IntPtr.Zero; } return ((Il2CppObjectBase)instance).Pointer; } private static void BackpackRoots(List into) { ArmHud instance = ArmHud.instance; if (instance != null) { Add(into, instance.backpackEmpty); Add(into, instance.backpackFull); } } private static void BeltRoots(List into) { ArmHud instance = ArmHud.instance; if (instance != null) { Add(into, instance.holsterEmpty); Add(into, instance.holsterFull); } } private static void Add(List into, Transform root) { if ((Object)(object)root != (Object)null) { into.Add(root); } } } internal enum PanelTab { View, Freecam, Hud, Setup } internal static class Panels { private const float PreferredWidth = 560f; private const float MinimumWidth = 320f; private const float Gap = 10f; public static bool Open; public static PanelTab Tab; private static Vector2 _scroll; private static bool _ready; private static PanelTab _tabShown; private static HudPiece _pieceShown; private static bool _flyingShown; private static bool _crosshairMissing; private static bool _backpackMissing; private static bool _beltMissing; public static PanelTab TabShown => _tabShown; public static HudPiece PieceShown => _pieceShown; public static bool FlyingShown => _flyingShown; public static float Scale { get { float num = Mathf.Max(0.5f, (float)Screen.width / 340f); return Mathf.Clamp(Plugin.PanelScale.Value, 0.5f, num); } } public static bool Clamped => Plugin.PanelScale.Value > Scale + 0.01f; public static bool MissingShown(HudPiece piece) { return piece switch { HudPiece.Belt => _beltMissing, HudPiece.Backpack => _backpackMissing, _ => _crosshairMissing, }; } private static void Snapshot() { _ready = true; _tabShown = Tab; _pieceShown = FreecamPanel.Piece; _flyingShown = Freecam.Active; _crosshairMissing = Missing(HudStyle.Crosshair); _backpackMissing = Missing(HudStyle.Backpack); _beltMissing = Missing(HudStyle.Belt); } private static bool Missing(HudElement element) { if (!element.Found) { return element.Overridden; } return false; } public static void Closed() { _ready = false; } private static Rect Area() { //IL_0049: Unknown result type (might be due to invalid IL or missing references) float scale = Scale; float num = Mathf.Clamp((float)Screen.width / scale - 20f, 320f, 560f); float num2 = Mathf.Max(140f, (float)Screen.height / scale - 20f); return new Rect(10f, 10f, num, num2); } public static void Draw() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Invalid comparison between Unknown and I4 //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_003c: 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_0042: 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) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) if ((int)Event.current.type == 8) { Snapshot(); } else if (!_ready) { return; } Matrix4x4 matrix = GUI.matrix; float scale = Scale; GUI.matrix = Matrix4x4.Scale(new Vector3(scale, scale, 1f)); Rect val = Area(); GUILayout.BeginArea(val, GUI.skin.box); GUILayout.Label("BIG PERSON VIEW — settings", (Il2CppReferenceArray)null); TabBar(); _scroll = GUILayout.BeginScrollView(_scroll, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(((Rect)(ref val)).height - 130f) }); switch (_tabShown) { case PanelTab.Freecam: FreecamPanel.Body(); break; case PanelTab.Hud: FreecamPanel.HudBody(); break; case PanelTab.Setup: SettingsPanel.SetupBody(); break; default: SettingsPanel.ViewBody(); break; } GUILayout.EndScrollView(); GUILayout.Space(4f); GUILayout.BeginHorizontal((Il2CppReferenceArray)null); if (GUILayout.Button("Save to file", (Il2CppReferenceArray)null)) { PanelWidgets.Save(); } if (GUILayout.Button("Reload file", (Il2CppReferenceArray)null)) { PanelWidgets.Reload(); } GUILayout.EndHorizontal(); GUILayout.Label((PanelWidgets.Status.Length > 0) ? PanelWidgets.Status : "changes apply now, and last the session", (Il2CppReferenceArray)null); GUILayout.EndArea(); GUI.matrix = matrix; } private static void TabBar() { GUILayout.BeginHorizontal((Il2CppReferenceArray)null); Pick(PanelTab.View, "View"); Pick(PanelTab.Freecam, "Freecam"); Pick(PanelTab.Hud, "HUD"); Pick(PanelTab.Setup, "Setup"); GUILayout.EndHorizontal(); } private static void Pick(PanelTab tab, string label) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) bool flag = Tab == tab; if (!(!GUILayout.Button(flag ? ("[" + label + "]") : label, (Il2CppReferenceArray)null) || flag)) { Tab = tab; _scroll = Vector2.zero; PanelWidgets.Status = ""; } } } internal static class PanelWidgets { public static string Status = ""; public static void Section(string title, Action reset = null) { GUILayout.BeginHorizontal((Il2CppReferenceArray)null); GUILayout.Label("— " + title + " —", (Il2CppReferenceArray)null); if (reset != null) { GUILayout.FlexibleSpace(); if (GUILayout.Button("reset section", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(110f) })) { reset(); } } GUILayout.EndHorizontal(); } public static void Slider(ConfigEntry entry, string label, float min, float max, string unit, int digits) { GUILayout.BeginHorizontal((Il2CppReferenceArray)null); GUILayout.Label(label + ": " + entry.Value.ToString("0." + new string('#', digits)) + unit, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(190f) }); float num = GUILayout.HorizontalSlider(entry.Value, min, max, Array.Empty()); float num2 = Mathf.Pow(10f, (float)digits); num = Mathf.Round(num * num2) / num2; if (!Mathf.Approximately(num, entry.Value)) { entry.Value = num; } float num3 = Default(entry); bool flag = !Mathf.Approximately(entry.Value, num3); if (GUILayout.Button(flag ? "↺" : "·", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(28f) }) && flag) { entry.Value = num3; Status = label + " back to " + num3.ToString("0." + new string('#', digits)) + unit; } GUILayout.EndHorizontal(); } public static void Toggle(ConfigEntry entry, string label) { bool flag = GUILayout.Toggle(entry.Value, " " + label, Array.Empty()); if (flag != entry.Value) { entry.Value = flag; } } public static void ResetAll(string what, params ConfigEntry[] entries) { foreach (ConfigEntry obj in entries) { obj.Value = Default(obj); } Status = what + " back to defaults"; } public static float Default(ConfigEntry entry) { try { return Convert.ToSingle(((ConfigEntryBase)entry).DefaultValue); } catch (Exception) { return entry.Value; } } public static void Save() { try { Plugin.Cfg.Save(); Status = "written to deck.bigwalk.thirdperson.cfg"; Plugin.Log.LogInfo((object)"settings saved from the panel"); } catch (Exception ex) { Status = "could not save: " + ex.Message; } } public static void Reload() { try { Plugin.Cfg.Reload(); Status = "reloaded from the file, losing this session's changes"; Plugin.Log.LogInfo((object)"settings reloaded from the file"); } catch (Exception ex) { Status = "could not reload: " + ex.Message; } } } internal static class PlayerBody { private struct Part { public Renderer Renderer; public bool Enabled; public bool ForcedOff; public ShadowCastingMode Shadows; public bool LodManaged; } private static readonly List Woken = new List(); private static readonly List Activated = new List(); private static PlayerCharacter _player; private static bool _active; private static bool _torsoOverridden; private static bool _savedHideTorso; private static float _nextSweep; private static int _refreshes; private static float _refreshWindow; private static bool _refreshStorm; public static void ShowFull(PlayerCharacter pc) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Invalid comparison between Unknown and I4 //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Expected O, but got Unknown PlayerLooks looks = pc.looks; if (looks == null) { return; } bool flag = !_active; _player = pc; _active = true; float unscaledTime = Time.unscaledTime; if (!_torsoOverridden) { _savedHideTorso = looks.hideLocalTorso; _torsoOverridden = true; looks.hideLocalTorso = false; } bool flag2 = false; if ((int)looks.currentLookType != 1) { looks.currentLookType = (LookType)1; looks.RefreshLook(); flag2 = !Counted(unscaledTime); } if (!(flag || flag2) && !(unscaledTime >= _nextSweep)) { return; } _nextSweep = unscaledTime + 0.5f; int num = Sweep(looks); if (flag) { ManualLogSource log = Plugin.Log; bool flag3 = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(42, 1, ref flag3); if (flag3) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("showing the full body, "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(num); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" renderers adjusted"); } log.LogInfo(val); } } private static bool Counted(float now) { _refreshes++; if (now < _refreshWindow) { return _refreshStorm; } _refreshWindow = now + 1f; bool flag = _refreshes > 10; if (flag != _refreshStorm) { _refreshStorm = flag; Plugin.Log.LogInfo((object)(flag ? ($"something in this scene is resetting your look about {_refreshes} times a " + "second. Re-asserting it every frame as before, but the full-body sweep is dropping back to twice a second so it does not cost you frames.") : "your look has settled — sweeping on every change again.")); } _refreshes = 0; return _refreshStorm; } public static void Restore() { //IL_0070: Unknown result type (might be due to invalid IL or missing references) if (!_active) { return; } _active = false; _refreshes = 0; _refreshWindow = 0f; _refreshStorm = false; foreach (Part item in Woken) { Renderer renderer = item.Renderer; if (!((Object)(object)renderer == (Object)null)) { if (!item.LodManaged) { renderer.enabled = item.Enabled; } renderer.forceRenderingOff = item.ForcedOff; renderer.shadowCastingMode = item.Shadows; } } Woken.Clear(); foreach (GameObject item2 in Activated) { if ((Object)(object)item2 != (Object)null) { item2.SetActive(false); } } Activated.Clear(); PlayerCharacter player = _player; _player = null; if ((Object)(object)player == (Object)null) { return; } PlayerLooks looks = player.looks; if (looks != null) { if (_torsoOverridden) { looks.hideLocalTorso = _savedHideTorso; _torsoOverridden = false; } looks.currentLookType = (LookType)0; looks.RefreshLook(); } } private static int Sweep(PlayerLooks looks) { return Wake(looks.headRenderers) + Wake(looks.torsoRenderers) + Wake(looks.legsRenderers); } private static int Wake(Il2CppReferenceArray parts) { //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Expected O, but got Unknown //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Invalid comparison between Unknown and I4 //IL_020e: Unknown result type (might be due to invalid IL or missing references) //IL_0214: Invalid comparison between Unknown and I4 //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Expected O, but got Unknown //IL_01d5: Unknown result type (might be due to invalid IL or missing references) if (parts == null) { return 0; } int num = 0; bool flag = default(bool); for (int i = 0; i < ((Il2CppArrayBase)(object)parts).Length; i++) { LooksRenderer val = ((Il2CppArrayBase)(object)parts)[i]; if (val == null) { continue; } Renderer renderer = val.renderer; if ((Object)(object)renderer == (Object)null) { continue; } if (val.local && !val.remote) { if (renderer.forceRenderingOff) { continue; } if (Remember(renderer, LodManaged(renderer)) && Plugin.DumpCameras.Value) { ManualLogSource log = Plugin.Log; BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(25, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("hiding first-person part "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(((Object)((Component)renderer).gameObject).name); } log.LogInfo(val2); } renderer.forceRenderingOff = true; num++; } else { if (!val.remote) { continue; } GameObject gameObject = ((Component)renderer).gameObject; if (PlayerExtras.Named(((Object)gameObject).name)) { continue; } if (!gameObject.activeSelf) { gameObject.SetActive(true); if (!Activated.Contains(gameObject)) { Activated.Add(gameObject); } num++; } bool flag2 = LodManaged(renderer); if ((renderer.enabled || flag2) && !renderer.forceRenderingOff && (int)renderer.shadowCastingMode != 3) { continue; } if (Remember(renderer, flag2) && Plugin.DumpCameras.Value) { ManualLogSource log2 = Plugin.Log; BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(53, 5, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("waking "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(((Object)gameObject).name); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(": enabled "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(renderer.enabled); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(", "); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("forceRenderingOff "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(renderer.forceRenderingOff); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(", "); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("shadows "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(renderer.shadowCastingMode); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(", lod "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(flag2); } log2.LogInfo(val2); } if (!flag2) { renderer.enabled = true; } renderer.forceRenderingOff = false; if ((int)renderer.shadowCastingMode == 3) { renderer.shadowCastingMode = (ShadowCastingMode)1; } num++; } } return num; } private static bool LodManaged(Renderer renderer) { try { Component componentInParent = ((Component)renderer).GetComponentInParent(Il2CppType.Of(), true); if ((Object)(object)componentInParent == (Object)null) { return false; } LODGroup val = ((Il2CppObjectBase)componentInParent).TryCast(); return (Object)(object)val == (Object)null || val.enabled; } catch (Exception) { return true; } } private static bool Remember(Renderer renderer, bool lodManaged) { //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) foreach (Part item in Woken) { if ((Object)(object)item.Renderer == (Object)(object)renderer) { return false; } } Woken.Add(new Part { Renderer = renderer, LodManaged = lodManaged, Enabled = renderer.enabled, ForcedOff = renderer.forceRenderingOff, Shadows = renderer.shadowCastingMode }); return true; } public static void Report(PlayerCharacter pc) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Expected O, but got Unknown //IL_003a: Unknown result type (might be due to invalid IL or missing references) PlayerLooks looks = pc.looks; if (looks == null) { Plugin.Log.LogWarning((object)"no PlayerLooks to report on"); return; } ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(25, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("look is "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(looks.currentLookType); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", hideLocalTorso "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(looks.hideLocalTorso); } log.LogInfo(val); Report("head", looks.headRenderers); Report("torso", looks.torsoRenderers); Report("legs", looks.legsRenderers); ReportLodGroups(pc); } private static void ReportLodGroups(PlayerCharacter pc) { //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Expected O, but got Unknown try { Il2CppReferenceArray componentsInChildren = ((Component)pc).GetComponentsInChildren(Il2CppType.Of(), true); if (componentsInChildren == null || ((Il2CppArrayBase)(object)componentsInChildren).Length == 0) { Plugin.Log.LogInfo((object)"no LODGroups on the character"); return; } StringBuilder stringBuilder = new StringBuilder("LODGroups:"); for (int i = 0; i < ((Il2CppArrayBase)(object)componentsInChildren).Length; i++) { Component obj = ((Il2CppArrayBase)(object)componentsInChildren)[i]; LODGroup val = ((obj != null) ? ((Il2CppObjectBase)obj).TryCast() : null); if (!((Object)(object)val == (Object)null)) { stringBuilder.Append(" " + ((Object)((Component)val).gameObject).name + "[" + (val.enabled ? "on" : "OFF") + " " + $"lods:{val.lodCount} size:{val.size:0.##}]"); } } Plugin.Log.LogInfo((object)stringBuilder.ToString()); } catch (Exception ex) { ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(26, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("could not read LODGroups: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex.Message); } log.LogWarning(val2); } } private static void Report(string part, Il2CppReferenceArray parts) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Invalid comparison between Unknown and I4 //IL_0179: 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_015d: 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) //IL_01ca: 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_01db: Unknown result type (might be due to invalid IL or missing references) //IL_01e7: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_0194: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Unknown result type (might be due to invalid IL or missing references) if (parts == null || ((Il2CppArrayBase)(object)parts).Length == 0) { ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(21, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(part); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": no renderers listed"); } log.LogInfo(val); return; } StringBuilder stringBuilder = new StringBuilder(part + ":"); for (int i = 0; i < ((Il2CppArrayBase)(object)parts).Length; i++) { LooksRenderer val2 = ((Il2CppArrayBase)(object)parts)[i]; if (val2 == null) { continue; } Renderer renderer = val2.renderer; if ((Object)(object)renderer == (Object)null) { stringBuilder.Append(" "); continue; } GameObject gameObject = ((Component)renderer).gameObject; stringBuilder.Append(" " + ((Object)gameObject).name + "[" + (val2.local ? "L" : "-") + (val2.remote ? "R" : "-")).Append(renderer.enabled ? " on" : " OFF").Append(gameObject.activeInHierarchy ? " active" : " INACTIVE") .Append(renderer.isVisible ? " seen" : " unseen"); if (renderer.forceRenderingOff) { stringBuilder.Append(" FORCED-OFF"); } if ((int)renderer.shadowCastingMode != 1) { stringBuilder.Append($" shadows:{renderer.shadowCastingMode}"); } Vector3 lossyScale = ((Component)renderer).transform.lossyScale; if (((Vector3)(ref lossyScale)).sqrMagnitude < 0.0001f) { stringBuilder.Append($" SCALE({lossyScale.x:0.###},{lossyScale.y:0.###},{lossyScale.z:0.###})"); } Bounds bounds = renderer.bounds; Vector3 size = ((Bounds)(ref bounds)).size; stringBuilder.Append($" size({size.x:0.##},{size.y:0.##},{size.z:0.##})"); Material sharedMaterial = renderer.sharedMaterial; if ((Object)(object)sharedMaterial == (Object)null) { stringBuilder.Append(" NO-MATERIAL"); } else { Shader shader = sharedMaterial.shader; stringBuilder.Append(" mat:" + ((Object)sharedMaterial).name + "/" + (((Object)(object)shader != (Object)null) ? ((Object)shader).name : "no shader")); } SkinnedMeshRenderer val3 = ((Il2CppObjectBase)renderer).TryCast(); if ((Object)(object)val3 != (Object)null) { Mesh sharedMesh = val3.sharedMesh; stringBuilder.Append(((Object)(object)sharedMesh == (Object)null) ? " NO-MESH" : $" mesh:{((Object)sharedMesh).name}({sharedMesh.vertexCount}v)"); } stringBuilder.Append(']'); } Plugin.Log.LogInfo((object)stringBuilder.ToString()); } } internal static class PlayerExtras { private struct Part { public Renderer Renderer; public bool Enabled; public bool ForcedOff; public ShadowCastingMode Shadows; } private static readonly List Hidden = new List(); private static readonly List Helpers = new List(); private static readonly HashSet Kit = new HashSet(); private static bool _kitUnknown; private static string _namesSource; private static string[] _names = new string[0]; private static bool _active; private static float _nextSweep; private static bool _reported; public static void Hide(PlayerCharacter pc) { //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Expected O, but got Unknown if ((Object)(object)pc == (Object)null) { return; } bool flag = !_active; _active = true; if (!flag && Time.unscaledTime < _nextSweep) { return; } _nextSweep = Time.unscaledTime + 0.5f; int num = Sweep(pc); if (flag && !_reported) { _reported = true; ManualLogSource log = Plugin.Log; bool flag2 = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(37, 1, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("hiding "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(num); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" stray parts on your character"); } log.LogInfo(val); } } public static void Restore() { //IL_004d: Unknown result type (might be due to invalid IL or missing references) if (!_active) { return; } _active = false; foreach (Part item in Hidden) { Renderer renderer = item.Renderer; if (!((Object)(object)renderer == (Object)null)) { renderer.enabled = item.Enabled; renderer.forceRenderingOff = item.ForcedOff; renderer.shadowCastingMode = item.Shadows; } } Hidden.Clear(); } private static int Sweep(PlayerCharacter pc) { int num = 0; if (Plugin.HideHelperParts.Value) { _kitUnknown = false; CollectKit(pc); if (!_kitUnknown) { Collect(pc); for (int i = 0; i < Helpers.Count; i++) { num += HideUnder(Helpers[i]); } } } string[] array = Names(); if (array.Length == 0) { return num; } Il2CppReferenceArray componentsInChildren = ((Component)pc).GetComponentsInChildren(Il2CppType.Of(), true); if (componentsInChildren == null) { return num; } for (int j = 0; j < ((Il2CppArrayBase)(object)componentsInChildren).Length; j++) { Component obj = ((Il2CppArrayBase)(object)componentsInChildren)[j]; Renderer val = ((obj != null) ? ((Il2CppObjectBase)obj).TryCast() : null); if (!((Object)(object)val == (Object)null) && Named(((Object)((Component)val).gameObject).name, array)) { num += Hide(val); } } return num; } private static void Collect(PlayerCharacter pc) { //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Expected O, but got Unknown Helpers.Clear(); try { PlayerHands hands = pc.hands; if (hands != null) { Add(hands.grasper); Add(hands.grasperGuide); } PlayerArms arms = pc.arms; if (arms != null) { Add(arms.holdRaisedGuide); Add(arms.stretchTranform); } } catch (Exception ex) { ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(39, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("could not read the arm helper objects: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } log.LogWarning(val); } } private static void Add(Transform helper) { if ((Object)(object)helper != (Object)null) { Helpers.Add(helper); } } private static int HideUnder(Transform root) { Il2CppReferenceArray componentsInChildren = ((Component)root).GetComponentsInChildren(Il2CppType.Of(), true); if (componentsInChildren == null) { return 0; } int num = 0; for (int i = 0; i < ((Il2CppArrayBase)(object)componentsInChildren).Length; i++) { Component obj = ((Il2CppArrayBase)(object)componentsInChildren)[i]; Renderer val = ((obj != null) ? ((Il2CppObjectBase)obj).TryCast() : null); if (!((Object)(object)val == (Object)null) && !Carried(val)) { num += Hide(val); } } return num; } private static bool Carried(Renderer renderer) { return Kit.Contains(((Il2CppObjectBase)renderer).Pointer); } private static void CollectKit(PlayerCharacter pc) { //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Expected O, but got Unknown Kit.Clear(); try { Il2CppReferenceArray componentsInChildren = ((Component)pc).GetComponentsInChildren(Il2CppType.Of(), true); if (componentsInChildren == null) { return; } for (int i = 0; i < ((Il2CppArrayBase)(object)componentsInChildren).Length; i++) { Component obj = ((Il2CppArrayBase)(object)componentsInChildren)[i]; Prop val = ((obj != null) ? ((Il2CppObjectBase)obj).TryCast() : null); if ((Object)(object)val == (Object)null) { continue; } Il2CppReferenceArray renderers = val.renderers; if (renderers != null) { for (int j = 0; j < ((Il2CppArrayBase)(object)renderers).Length; j++) { if ((Object)(object)((Il2CppArrayBase)(object)renderers)[j] != (Object)null) { Kit.Add(((Il2CppObjectBase)((Il2CppArrayBase)(object)renderers)[j]).Pointer); } } } Il2CppReferenceArray componentsInChildren2 = ((Component)val).GetComponentsInChildren(Il2CppType.Of(), true); if (componentsInChildren2 == null) { continue; } for (int k = 0; k < ((Il2CppArrayBase)(object)componentsInChildren2).Length; k++) { Component obj2 = ((Il2CppArrayBase)(object)componentsInChildren2)[k]; Renderer val2 = ((obj2 != null) ? ((Il2CppObjectBase)obj2).TryCast() : null); if ((Object)(object)val2 != (Object)null) { Kit.Add(((Il2CppObjectBase)val2).Pointer); } } } } catch (Exception ex) { ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(79, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("could not work out what you are carrying, so nothing will "); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("be hidden this pass: "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(ex.Message); } log.LogWarning(val3); _kitUnknown = true; } } private static int Hide(Renderer renderer) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected O, but got Unknown if ((Object)(object)renderer == (Object)null || renderer.forceRenderingOff) { return 0; } if (Remember(renderer)) { ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(28, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("hiding the stray '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(((Object)((Component)renderer).gameObject).name); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' "); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("(under "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(Owner(renderer)); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(")"); } log.LogInfo(val); } renderer.forceRenderingOff = true; return 1; } private static string Owner(Renderer renderer) { try { Transform parent = ((Component)renderer).transform.parent; return ((Object)(object)parent != (Object)null) ? ((Object)parent).name : "(no parent)"; } catch (Exception) { return "(unknown)"; } } private static bool Remember(Renderer renderer) { //IL_0070: 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) foreach (Part item in Hidden) { if ((Object)(object)item.Renderer == (Object)(object)renderer) { return false; } } Hidden.Add(new Part { Renderer = renderer, Enabled = renderer.enabled, ForcedOff = renderer.forceRenderingOff, Shadows = renderer.shadowCastingMode }); return true; } private static string[] Names() { string text = Plugin.HiddenParts.Value ?? string.Empty; if (text == _namesSource) { return _names; } _namesSource = text; List list = new List(); string[] array = text.Split(','); for (int i = 0; i < array.Length; i++) { string text2 = array[i].Trim(); if (text2.Length > 0) { list.Add(text2); } } _names = list.ToArray(); return _names; } private static bool Named(string name, string[] names) { for (int i = 0; i < names.Length; i++) { if (name.IndexOf(names[i], StringComparison.OrdinalIgnoreCase) >= 0) { return true; } } return false; } public static bool Named(string name) { return Named(name, Names()); } public static void Report(PlayerCharacter pc) { //IL_02bf: Unknown result type (might be due to invalid IL or missing references) //IL_02c6: Expected O, but got Unknown //IL_0153: 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_015c: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: 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_021d: Unknown result type (might be due to invalid IL or missing references) //IL_0229: Unknown result type (might be due to invalid IL or missing references) try { List list = new List(); PlayerLooks looks = pc.looks; if (looks != null) { Note(list, looks.headRenderers); Note(list, looks.torsoRenderers); Note(list, looks.legsRenderers); } Il2CppReferenceArray componentsInChildren = ((Component)pc).GetComponentsInChildren(Il2CppType.Of(), true); if (componentsInChildren != null) { for (int i = 0; i < ((Il2CppArrayBase)(object)componentsInChildren).Length; i++) { Component obj = ((Il2CppArrayBase)(object)componentsInChildren)[i]; Prop val = ((obj != null) ? ((Il2CppObjectBase)obj).TryCast() : null); if ((Object)(object)val == (Object)null) { continue; } Il2CppReferenceArray componentsInChildren2 = ((Component)val).GetComponentsInChildren(Il2CppType.Of(), true); if (componentsInChildren2 == null) { continue; } for (int j = 0; j < ((Il2CppArrayBase)(object)componentsInChildren2).Length; j++) { Component obj2 = ((Il2CppArrayBase)(object)componentsInChildren2)[j]; Renderer val2 = ((obj2 != null) ? ((Il2CppObjectBase)obj2).TryCast() : null); if ((Object)(object)val2 != (Object)null) { list.Add(((Il2CppObjectBase)val2).Pointer); } } } } Il2CppReferenceArray componentsInChildren3 = ((Component)pc).GetComponentsInChildren(Il2CppType.Of(), true); if (componentsInChildren3 == null || ((Il2CppArrayBase)(object)componentsInChildren3).Length == 0) { Plugin.Log.LogInfo((object)"no renderers on your character at all"); return; } int num = 0; for (int k = 0; k < ((Il2CppArrayBase)(object)componentsInChildren3).Length; k++) { Component obj3 = ((Il2CppArrayBase)(object)componentsInChildren3)[k]; Renderer val3 = ((obj3 != null) ? ((Il2CppObjectBase)obj3).TryCast() : null); if (!((Object)(object)val3 == (Object)null) && !list.Contains(((Il2CppObjectBase)val3).Pointer)) { num++; GameObject gameObject = ((Component)val3).gameObject; Bounds bounds = val3.bounds; Vector3 size = ((Bounds)(ref bounds)).size; Material sharedMaterial = val3.sharedMaterial; StringBuilder stringBuilder = new StringBuilder("stray '").Append(((Object)gameObject).name).Append("' at ").Append(Path(((Component)val3).transform, ((Component)pc).transform)) .Append(val3.enabled ? " on" : " OFF") .Append(gameObject.activeInHierarchy ? " active" : " INACTIVE") .Append(val3.forceRenderingOff ? " FORCED-OFF" : "") .Append($" shadows:{val3.shadowCastingMode}") .Append($" size({size.x:0.##},{size.y:0.##},{size.z:0.##})") .Append(((Object)(object)sharedMaterial == (Object)null) ? " NO-MATERIAL" : (" mat:" + ((Object)sharedMaterial).name)); Plugin.Log.LogInfo((object)stringBuilder.ToString()); } } Plugin.Log.LogInfo((object)($"{num} renderers on your character belong to neither the look " + "nor a prop. If one of those is what you can see, put a piece of its name in HiddenParts.")); } catch (Exception ex) { ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val4 = new BepInExWarningLogInterpolatedStringHandler(32, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("could not list the stray parts: "); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted(ex.Message); } log.LogWarning(val4); } } private static void Note(List known, Il2CppReferenceArray parts) { if (parts == null) { return; } for (int i = 0; i < ((Il2CppArrayBase)(object)parts).Length; i++) { LooksRenderer obj = ((Il2CppArrayBase)(object)parts)[i]; Renderer val = ((obj != null) ? obj.renderer : null); if ((Object)(object)val != (Object)null) { known.Add(((Il2CppObjectBase)val).Pointer); } } } private static string Path(Transform t, Transform stop) { string text = ((Object)t).name; Transform parent = t.parent; while ((Object)(object)parent != (Object)null && !((Object)(object)parent == (Object)(object)stop)) { text = ((Object)parent).name + "/" + text; parent = parent.parent; } return text; } } internal static class PlayerGear { private struct Home { public PropHome PropHome; public PlayerCharacter HiddenFor; } private struct Hidden { public Prop Prop; public PlayerCharacter HiddenFor; } private struct Part { public Renderer Renderer; public bool Enabled; public bool ForcedOff; public ShadowCastingMode Shadows; } private static readonly List Homes = new List(); private static readonly List Unhidden = new List(); private static readonly List Woken = new List(); private static PlayerCharacter _player; private static bool _active; private static float _nextSweep; private static IntPtr _lastHeld = IntPtr.Zero; private static Prop _reportHeld; private static float _reportHeldAt; public static void Show(PlayerCharacter pc) { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Expected O, but got Unknown if ((Object)(object)pc == (Object)null) { return; } bool flag = !_active; _player = pc; _active = true; if (!flag && Time.unscaledTime < _nextSweep) { return; } _nextSweep = Time.unscaledTime + 0.5f; int num = Sweep(pc); if (flag) { ManualLogSource log = Plugin.Log; bool flag2 = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(39, 1, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("showing what you are carrying, "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(num); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" changes"); } log.LogInfo(val); } } public static void Restore() { //IL_0052: Unknown result type (might be due to invalid IL or missing references) if (!_active) { return; } _active = false; foreach (Part item in Woken) { Renderer renderer = item.Renderer; if (!((Object)(object)renderer == (Object)null)) { renderer.enabled = item.Enabled; renderer.forceRenderingOff = item.ForcedOff; renderer.shadowCastingMode = item.Shadows; } } Woken.Clear(); foreach (Hidden item2 in Unhidden) { Prop prop = item2.Prop; if (!((Object)(object)prop == (Object)null) && StillOurs(prop)) { prop.locallyHiddenForPlayer = item2.HiddenFor; } } Unhidden.Clear(); foreach (Home home in Homes) { if ((Object)(object)home.PropHome != (Object)null) { home.PropHome.hideForLocalPlayer = home.HiddenFor; } } Homes.Clear(); PlayerCharacter player = _player; _player = null; if (!((Object)(object)player == (Object)null)) { PlayerLooks looks = player.looks; if (looks != null) { looks.RefreshAllRelevantProps(); } } } private static void ReportHeld(PlayerCharacter pc, Prop prop) { //IL_0532: Unknown result type (might be due to invalid IL or missing references) //IL_0539: Expected O, but got Unknown //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Expected O, but got Unknown //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Expected O, but got Unknown //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Expected O, but got Unknown //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0115: 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_0126: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Expected O, but got Unknown //IL_02c8: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Expected O, but got Unknown //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_02e4: 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_02f4: Unknown result type (might be due to invalid IL or missing references) //IL_02f6: Unknown result type (might be due to invalid IL or missing references) //IL_01cf: Unknown result type (might be due to invalid IL or missing references) //IL_030e: Unknown result type (might be due to invalid IL or missing references) //IL_0314: Expected O, but got Unknown //IL_01dd: Unknown result type (might be due to invalid IL or missing references) //IL_0232: Unknown result type (might be due to invalid IL or missing references) //IL_024f: Unknown result type (might be due to invalid IL or missing references) //IL_026c: Unknown result type (might be due to invalid IL or missing references) //IL_01eb: Unknown result type (might be due to invalid IL or missing references) //IL_03e3: Unknown result type (might be due to invalid IL or missing references) //IL_03e9: Expected O, but got Unknown //IL_01f9: Unknown result type (might be due to invalid IL or missing references) //IL_0461: Unknown result type (might be due to invalid IL or missing references) //IL_0207: Unknown result type (might be due to invalid IL or missing references) bool flag = default(bool); try { Camera val = Camera(pc); int num = (((Object)(object)val != (Object)null) ? val.cullingMask : (-1)); ManualLogSource log = Plugin.Log; BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(34, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("--- held prop '"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(((Object)prop).name); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("' one second on ---"); } log.LogInfo(val2); ManualLogSource log2 = Plugin.Log; val2 = new BepInExInfoLogInterpolatedStringHandler(5, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" at "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(Path(((Component)prop).transform)); } log2.LogInfo(val2); ManualLogSource log3 = Plugin.Log; val2 = new BepInExInfoLogInterpolatedStringHandler(35, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" hiddenForLocal: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(((Object)(object)prop.locallyHiddenForPlayer != (Object)null) ? "YES" : "no"); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(", object active: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(((Component)prop).gameObject.activeInHierarchy); } log3.LogInfo(val2); if ((Object)(object)val != (Object)null) { Vector3 position = ((Component)val).transform.position; Vector3 position2 = ((Component)prop).transform.position; Vector3 val3 = val.WorldToViewportPoint(position2); ManualLogSource log4 = Plugin.Log; val2 = new BepInExInfoLogInterpolatedStringHandler(33, 4, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" camera '"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(((Object)((Component)val).gameObject).name); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("' at "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(Fmt(position)); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(", prop at "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(Fmt(position2)); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(", "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(Vector3.Distance(position, position2), "0.##"); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("m away"); } log4.LogInfo(val2); ManualLogSource log5 = Plugin.Log; val2 = new BepInExInfoLogInterpolatedStringHandler(35, 4, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" on screen: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted((val3.z > 0f && val3.x > 0f && val3.x < 1f && val3.y > 0f && val3.y < 1f) ? "YES" : "NO"); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" (viewport "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(val3.x, "0.##"); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(", "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(val3.y, "0.##"); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(", depth "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(val3.z, "0.##"); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(")"); } log5.LogInfo(val2); } List list = Collect(prop); if (list.Count == 0) { Plugin.Log.LogInfo((object)" it has no renderers at all"); return; } Cameras(((Component)list[0]).gameObject.layer, ((Component)prop).transform.position); if ((Object)(object)val != (Object)null) { Vector3 position3 = ((Component)val).transform.position; Vector3 position4 = ((Component)prop).transform.position; RaycastHit val4 = default(RaycastHit); if (Physics.Linecast(position3, position4, ref val4)) { ManualLogSource log6 = Plugin.Log; val2 = new BepInExInfoLogInterpolatedStringHandler(43, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" line of sight blocked by '"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(((Object)((Component)((RaycastHit)(ref val4)).collider).gameObject).name); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("' "); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("at "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(((RaycastHit)(ref val4)).distance, "0.##"); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("m (layer "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(((Component)((RaycastHit)(ref val4)).collider).gameObject.layer); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(")"); } log6.LogInfo(val2); } else { Plugin.Log.LogInfo((object)" line of sight from the camera is clear"); } } foreach (Renderer item in list) { int layer = ((Component)item).gameObject.layer; bool flag2 = (num & (1 << layer)) == 0; ManualLogSource log7 = Plugin.Log; val2 = new BepInExInfoLogInterpolatedStringHandler(80, 9, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" renderer '"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(((Object)((Component)item).gameObject).name); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("': "); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("enabled "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(item.enabled); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(", forceOff "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(item.forceRenderingOff); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(", "); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("shadows "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(item.shadowCastingMode); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(", visible "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(item.isVisible); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(", "); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("objectActive "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(((Component)item).gameObject.activeInHierarchy); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(", "); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("layer "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(layer); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" '"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(LayerMask.LayerToName(layer)); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("'"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(flag2 ? " ** CULLED BY THIS CAMERA **" : ""); } log7.LogInfo(val2); } } catch (Exception ex) { ManualLogSource log8 = Plugin.Log; BepInExWarningLogInterpolatedStringHandler val5 = new BepInExWarningLogInterpolatedStringHandler(35, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val5).AppendLiteral("could not report on the held prop: "); ((BepInExLogInterpolatedStringHandler)val5).AppendFormatted(ex.Message); } log8.LogWarning(val5); } } private static void Cameras(int layer, Vector3 propAt) { //IL_01fd: Unknown result type (might be due to invalid IL or missing references) //IL_0204: Expected O, but got Unknown //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Expected O, but got Unknown //IL_00ba: 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_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Expected O, but got Unknown //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Unknown result type (might be due to invalid IL or missing references) bool flag = default(bool); try { Il2CppReferenceArray val = Object.FindObjectsOfType(Il2CppType.Of()); if (val == null || ((Il2CppArrayBase)(object)val).Length == 0) { Plugin.Log.LogInfo((object)" no cameras found at all"); return; } ManualLogSource log = Plugin.Log; BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(30, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" cameras that draw layer "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(layer); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" '"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(LayerMask.LayerToName(layer)); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("':"); } log.LogInfo(val2); for (int i = 0; i < ((Il2CppArrayBase)(object)val).Length; i++) { Object obj = ((Il2CppArrayBase)(object)val)[i]; Camera val3 = ((obj != null) ? ((Il2CppObjectBase)obj).TryCast() : null); if (!((Object)(object)val3 == (Object)null)) { bool flag2 = (val3.cullingMask & (1 << layer)) != 0; Vector3 position = ((Component)val3).transform.position; ManualLogSource log2 = Plugin.Log; val2 = new BepInExInfoLogInterpolatedStringHandler(72, 9, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" '"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(((Object)((Component)val3).gameObject).name); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("' "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(flag2 ? "DRAWS IT" : "does not"); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(", enabled "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(((Behaviour)val3).enabled); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(", active "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(((Component)val3).gameObject.activeInHierarchy); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(", depth "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(val3.depth); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(", clear "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(val3.clearFlags); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(", at "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(Fmt(position)); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" ("); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(Vector3.Distance(position, propAt), "0.##"); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("m from the prop)"); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(", near "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(val3.nearClipPlane, "0.###"); } log2.LogInfo(val2); } } } catch (Exception ex) { ManualLogSource log3 = Plugin.Log; BepInExWarningLogInterpolatedStringHandler val4 = new BepInExWarningLogInterpolatedStringHandler(30, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(" could not list the cameras: "); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted(ex.Message); } log3.LogWarning(val4); } } private static List Collect(Prop prop) { List list = new List(); Il2CppReferenceArray renderers = prop.renderers; if (renderers != null && ((Il2CppArrayBase)(object)renderers).Length > 0) { for (int i = 0; i < ((Il2CppArrayBase)(object)renderers).Length; i++) { if ((Object)(object)((Il2CppArrayBase)(object)renderers)[i] != (Object)null) { list.Add(((Il2CppArrayBase)(object)renderers)[i]); } } return list; } Il2CppReferenceArray componentsInChildren = ((Component)prop).GetComponentsInChildren(Il2CppType.Of(), true); if (componentsInChildren == null) { return list; } for (int j = 0; j < ((Il2CppArrayBase)(object)componentsInChildren).Length; j++) { Component obj = ((Il2CppArrayBase)(object)componentsInChildren)[j]; Renderer val = ((obj != null) ? ((Il2CppObjectBase)obj).TryCast() : null); if ((Object)(object)val != (Object)null) { list.Add(val); } } return list; } private static Camera Camera(PlayerCharacter pc) { PlayerCameraMinder cameraMinder = pc.cameraMinder; PlayerCameraReferences val = ((cameraMinder != null) ? cameraMinder.playerCameraReferences : null); if (!((Object)(object)val != (Object)null)) { return null; } return val.playerCamera; } private static string Fmt(Vector3 v) { //IL_0005: 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_001b: Unknown result type (might be due to invalid IL or missing references) return $"({v.x:0.#}, {v.y:0.#}, {v.z:0.#})"; } private static string Path(Transform t) { string text = ((Object)t).name; Transform parent = t.parent; while ((Object)(object)parent != (Object)null) { text = ((Object)parent).name + "/" + text; parent = parent.parent; } return text; } private static int Sweep(PlayerCharacter pc) { //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Expected O, but got Unknown //IL_01a2: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Expected O, but got Unknown int num = HideFirstPersonBelt(pc); bool flags = false; Prop val = Held(pc); int num2 = Show(val, ref flags); num += num2; bool flag = default(bool); if ((Object)(object)val != (Object)null && ((Il2CppObjectBase)val).Pointer != _lastHeld) { _lastHeld = ((Il2CppObjectBase)val).Pointer; if (Plugin.DumpCameras.Value) { ManualLogSource log = Plugin.Log; BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(40, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("showing what you picked up, '"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(((Object)val).name); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("', "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(num2); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" changes"); } log.LogInfo(val2); } _reportHeld = (Plugin.DumpCameras.Value ? val : null); _reportHeldAt = Time.unscaledTime + 1.5f; } else if ((Object)(object)val == (Object)null) { _lastHeld = IntPtr.Zero; _reportHeld = null; } if ((Object)(object)_reportHeld != (Object)null && Time.unscaledTime >= _reportHeldAt) { Prop reportHeld = _reportHeld; _reportHeld = null; ReportHeld(pc, reportHeld); } Il2CppReferenceArray componentsInChildren = ((Component)pc).GetComponentsInChildren(Il2CppType.Of(), true); if (componentsInChildren == null) { if (flags) { PlayerLooks looks = pc.looks; if (looks != null) { looks.RefreshAllRelevantProps(); } } return num; } for (int i = 0; i < ((Il2CppArrayBase)(object)componentsInChildren).Length; i++) { Component obj = ((Il2CppArrayBase)(object)componentsInChildren)[i]; PropHome val3 = ((obj != null) ? ((Il2CppObjectBase)obj).TryCast() : null); if ((Object)(object)val3 == (Object)null) { continue; } PlayerCharacter hideForLocalPlayer = val3.hideForLocalPlayer; if ((Object)(object)hideForLocalPlayer != (Object)null) { if (Remember(val3, hideForLocalPlayer) && Plugin.DumpCameras.Value) { ManualLogSource log2 = Plugin.Log; BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(20, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("unhiding the home '"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(((Object)val3).name); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("'"); } log2.LogInfo(val2); } val3.hideForLocalPlayer = null; num++; flags = true; } num += Show(val3.pinnedProp, ref flags); } if (flags) { PlayerLooks looks2 = pc.looks; if (looks2 != null) { looks2.RefreshAllRelevantProps(); } } return num; } private static int HideFirstPersonBelt(PlayerCharacter pc) { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Expected O, but got Unknown if (!Plugin.HideFirstPersonBelt.Value) { return 0; } PlayerRegistry registry = pc.registry; MeshRenderer val = ((registry != null) ? registry.fakeHolster : null); if ((Object)(object)val == (Object)null || !((Renderer)val).enabled) { return 0; } if (Remember((Renderer)(object)val) && Plugin.DumpCameras.Value) { ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(31, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("hiding the first-person belt '"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(((Object)((Component)val).gameObject).name); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("'"); } log.LogInfo(val2); } ((Renderer)val).enabled = false; return 1; } private static bool StillOurs(Prop prop) { //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Expected O, but got Unknown PlayerCharacter player = _player; if ((Object)(object)player == (Object)null) { return false; } try { if ((Object)(object)Held(player) == (Object)(object)prop) { return true; } Il2CppReferenceArray componentsInChildren = ((Component)player).GetComponentsInChildren(Il2CppType.Of(), true); if (componentsInChildren == null) { return false; } for (int i = 0; i < ((Il2CppArrayBase)(object)componentsInChildren).Length; i++) { Component obj = ((Il2CppArrayBase)(object)componentsInChildren)[i]; PropHome val = ((obj != null) ? ((Il2CppObjectBase)obj).TryCast() : null); if ((Object)(object)val != (Object)null && (Object)(object)val.pinnedProp == (Object)(object)prop) { return true; } } } catch (Exception ex) { ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(65, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("could not tell whether '"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(((Object)prop).name); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("' is still yours, so "); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("leaving it visible: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex.Message); } log.LogWarning(val2); } return false; } private static Prop Held(PlayerCharacter pc) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown try { PlayerHands hands = pc.hands; return (hands != null) ? hands.heldProp : null; } catch (Exception ex) { ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(37, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("could not read what you are holding: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } log.LogWarning(val); return null; } } private static int Show(Prop prop, ref bool flags) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Expected O, but got Unknown if ((Object)(object)prop == (Object)null) { return 0; } int num = 0; PlayerCharacter locallyHiddenForPlayer = prop.locallyHiddenForPlayer; if ((Object)(object)locallyHiddenForPlayer != (Object)null) { if (Remember(prop, locallyHiddenForPlayer) && Plugin.DumpCameras.Value) { ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(20, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("unhiding the prop '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(((Object)prop).name); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("'"); } log.LogInfo(val); } prop.locallyHiddenForPlayer = null; num++; flags = true; } Il2CppReferenceArray renderers = prop.renderers; if (renderers != null && ((Il2CppArrayBase)(object)renderers).Length > 0) { for (int i = 0; i < ((Il2CppArrayBase)(object)renderers).Length; i++) { num += Wake(((Il2CppArrayBase)(object)renderers)[i]); } return num; } Il2CppReferenceArray componentsInChildren = ((Component)prop).GetComponentsInChildren(Il2CppType.Of(), true); if (componentsInChildren == null) { return num; } for (int j = 0; j < ((Il2CppArrayBase)(object)componentsInChildren).Length; j++) { int num2 = num; Component obj = ((Il2CppArrayBase)(object)componentsInChildren)[j]; num = num2 + Wake((obj != null) ? ((Il2CppObjectBase)obj).TryCast() : null); } return num; } private static int Wake(Renderer renderer) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Invalid comparison between Unknown and I4 //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Invalid comparison between Unknown and I4 //IL_00a6: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)renderer == (Object)null) { return 0; } if (renderer.enabled && !renderer.forceRenderingOff && (int)renderer.shadowCastingMode != 3) { return 0; } if (Remember(renderer) && Plugin.DumpCameras.Value) { Plugin.Log.LogInfo((object)("waking the carried '" + ((Object)((Component)renderer).gameObject).name + "': " + $"enabled {renderer.enabled}, " + $"forceRenderingOff {renderer.forceRenderingOff}, " + $"shadows {renderer.shadowCastingMode}" + (((Component)renderer).gameObject.activeInHierarchy ? "" : ", on an INACTIVE object"))); } renderer.enabled = true; renderer.forceRenderingOff = false; if ((int)renderer.shadowCastingMode == 3) { renderer.shadowCastingMode = (ShadowCastingMode)1; } return 1; } private static bool Remember(Renderer renderer) { //IL_0070: 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) foreach (Part item in Woken) { if ((Object)(object)item.Renderer == (Object)(object)renderer) { return false; } } Woken.Add(new Part { Renderer = renderer, Enabled = renderer.enabled, ForcedOff = renderer.forceRenderingOff, Shadows = renderer.shadowCastingMode }); return true; } private static bool Remember(PropHome home, PlayerCharacter hiddenFor) { foreach (Home home2 in Homes) { if ((Object)(object)home2.PropHome == (Object)(object)home) { return false; } } Homes.Add(new Home { PropHome = home, HiddenFor = hiddenFor }); return true; } private static bool Remember(Prop prop, PlayerCharacter hiddenFor) { foreach (Hidden item in Unhidden) { if ((Object)(object)item.Prop == (Object)(object)prop) { return false; } } Unhidden.Add(new Hidden { Prop = prop, HiddenFor = hiddenFor }); return true; } public static void Report(PlayerCharacter pc, Transform camera) { //IL_0246: Unknown result type (might be due to invalid IL or missing references) //IL_024d: Expected O, but got Unknown //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_0170: 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_017a: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_018f: 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) try { PlayerRegistry registry = pc.registry; MeshRenderer val = ((registry != null) ? registry.fakeHolster : null); Plugin.Log.LogInfo((object)(((Object)(object)val == (Object)null) ? "no first-person belt (PlayerRegistry.fakeHolster) on this character" : ("first-person belt '" + ((Object)((Component)val).gameObject).name + "' at " + Path(((Component)val).transform, camera) + ", " + $"enabled {((Renderer)val).enabled}, active {((Component)val).gameObject.activeInHierarchy}"))); Il2CppReferenceArray componentsInChildren = ((Component)pc).GetComponentsInChildren(Il2CppType.Of(), true); if (componentsInChildren == null || ((Il2CppArrayBase)(object)componentsInChildren).Length == 0) { Plugin.Log.LogInfo((object)"no prop homes on your character"); return; } for (int i = 0; i < ((Il2CppArrayBase)(object)componentsInChildren).Length; i++) { Component obj = ((Il2CppArrayBase)(object)componentsInChildren)[i]; PropHome val2 = ((obj != null) ? ((Il2CppObjectBase)obj).TryCast() : null); if ((Object)(object)val2 == (Object)null) { continue; } Transform transform = ((Component)val2).transform; StringBuilder stringBuilder = new StringBuilder("home ").Append(Path(transform, camera)); if (val2.isInventory) { stringBuilder.Append(" inventory"); } if ((Object)(object)val2.hideForLocalPlayer != (Object)null) { stringBuilder.Append(" HIDDEN-FOR-LOCAL"); } if ((Object)(object)camera != (Object)null && transform.IsChildOf(camera)) { stringBuilder.Append(" UNDER-CAMERA"); } if ((Object)(object)camera != (Object)null) { Vector3 val3 = transform.position - camera.position; stringBuilder.Append($" fromCamera({val3.x:0.##},{val3.y:0.##},{val3.z:0.##})"); } Prop pinnedProp = val2.pinnedProp; if ((Object)(object)pinnedProp == (Object)null) { stringBuilder.Append(" empty"); } else { stringBuilder.Append(" holding '" + ((Object)pinnedProp).name + "'"); if ((Object)(object)pinnedProp.locallyHiddenForPlayer != (Object)null) { stringBuilder.Append(" LOCALLY-HIDDEN"); } Append(stringBuilder, pinnedProp); } Plugin.Log.LogInfo((object)stringBuilder.ToString()); } } catch (Exception ex) { ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val4 = new BepInExWarningLogInterpolatedStringHandler(38, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("could not list what you are carrying: "); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted(ex.Message); } log.LogWarning(val4); } } private static void Append(StringBuilder line, Prop prop) { //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Invalid comparison between Unknown and I4 //IL_00d9: Unknown result type (might be due to invalid IL or missing references) Il2CppReferenceArray renderers = prop.renderers; if (renderers == null || ((Il2CppArrayBase)(object)renderers).Length == 0) { line.Append(" [no renderers listed]"); return; } line.Append(" ["); for (int i = 0; i < ((Il2CppArrayBase)(object)renderers).Length; i++) { Renderer val = ((Il2CppArrayBase)(object)renderers)[i]; if (!((Object)(object)val == (Object)null)) { if (i > 0) { line.Append(' '); } line.Append(((Object)((Component)val).gameObject).name).Append(val.enabled ? " on" : " OFF").Append(((Component)val).gameObject.activeInHierarchy ? " active" : " INACTIVE") .Append(val.isVisible ? " seen" : " unseen"); if (val.forceRenderingOff) { line.Append(" FORCED-OFF"); } if ((int)val.shadowCastingMode != 1) { line.Append($" shadows:{val.shadowCastingMode}"); } line.Append(';'); } } line.Append(']'); } private static string Path(Transform t, Transform camera) { string text = ((Object)t).name; Transform parent = t.parent; while ((Object)(object)parent != (Object)null) { if ((Object)(object)parent == (Object)(object)camera) { return "[camera]/" + text; } text = ((Object)parent).name + "/" + text; parent = parent.parent; } return text; } } public enum ViewMode { FirstPerson, Behind, Front } [BepInPlugin("deck.bigwalk.thirdperson", "Third Person", "1.3.1")] public class Plugin : BasePlugin { public const string Guid = "deck.bigwalk.thirdperson"; public static ManualLogSource Log; public static ConfigEntry Mode; public static ConfigEntry Distance; public static ConfigEntry MinDistance; public static ConfigEntry Height; public static ConfigEntry Shoulder; public static ConfigEntry Collide; public static ConfigEntry CollisionRadius; public static ConfigEntry IgnoreLayers; public static ConfigEntry ShowBody; public static ConfigEntry ShowGear; public static ConfigEntry PinCameraChildren; public static ConfigEntry HideFirstPersonBelt; public static ConfigEntry HideHelperParts; public static ConfigEntry HiddenParts; public static ConfigEntry RevealLayers; public static ConfigEntry OrbitYaw; public static ConfigEntry OrbitPitch; public static ConfigEntry OrbitSpeed; public static ConfigEntry ToggleKeys; public static ConfigEntry CloserKeys; public static ConfigEntry FartherKeys; public static ConfigEntry OrbitLeftKeys; public static ConfigEntry OrbitRightKeys; public static ConfigEntry OrbitUpKeys; public static ConfigEntry OrbitDownKeys; public static ConfigEntry OrbitResetKeys; public static ConfigEntry CameraHoldKeys; public static ConfigEntry OrbitMouseSpeed; public static ConfigEntry FreezeLookWhileOrbiting; public static ConfigEntry ToggleChord; public static ConfigEntry ChordHold; public static ConfigEntry DistanceStep; public static ConfigEntry DumpCameras; public static ConfigEntry LogKeys; public static ConfigEntry PanelKeys; public static ConfigEntry PanelScale; public static ConfigEntry PanelFreeCursor; public static ConfigEntry FreecamKeys; public static ConfigEntry FreecamForwardKeys; public static ConfigEntry FreecamBackKeys; public static ConfigEntry FreecamLeftKeys; public static ConfigEntry FreecamRightKeys; public static ConfigEntry FreecamUpKeys; public static ConfigEntry FreecamDownKeys; public static ConfigEntry FreecamFastKeys; public static ConfigEntry FreecamSlowKeys; public static ConfigEntry FreecamSpeed; public static ConfigEntry FreecamFastMultiplier; public static ConfigEntry FreecamSlowMultiplier; public static ConfigEntry FreecamLookSpeed; public static ConfigEntry FreecamMaxPitch; public static ConfigEntry FreecamInvertPitch; public static ConfigEntry FreecamFreezePlayer; public static ConfigEntry FreecamTeleportKeys; public static ConfigEntry HideHud; public static ConfigEntry HudHideCanvases; public static ConfigEntry HudKeys; public static ConfigEntry HudLayers; public static ConfigEntry DumpCanvases; public static ConfigFile Cfg; public override void Load() { //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Expected O, but got Unknown //IL_01dd: Unknown result type (might be due to invalid IL or missing references) //IL_01e7: Expected O, but got Unknown //IL_021a: Unknown result type (might be due to invalid IL or missing references) //IL_0224: Expected O, but got Unknown //IL_0257: Unknown result type (might be due to invalid IL or missing references) //IL_0261: Expected O, but got Unknown //IL_0368: Unknown result type (might be due to invalid IL or missing references) //IL_0372: Expected O, but got Unknown //IL_0411: Unknown result type (might be due to invalid IL or missing references) //IL_041b: Expected O, but got Unknown //IL_0732: Unknown result type (might be due to invalid IL or missing references) //IL_073c: Expected O, but got Unknown //IL_076f: Unknown result type (might be due to invalid IL or missing references) //IL_0779: Expected O, but got Unknown //IL_07ac: Unknown result type (might be due to invalid IL or missing references) //IL_07b6: Expected O, but got Unknown //IL_07e9: Unknown result type (might be due to invalid IL or missing references) //IL_07f3: Expected O, but got Unknown //IL_0826: Unknown result type (might be due to invalid IL or missing references) //IL_0830: Expected O, but got Unknown //IL_0985: Unknown result type (might be due to invalid IL or missing references) //IL_098a: Unknown result type (might be due to invalid IL or missing references) //IL_0992: Unknown result type (might be due to invalid IL or missing references) //IL_0998: Expected O, but got Unknown //IL_09a8: Unknown result type (might be due to invalid IL or missing references) //IL_09ad: Unknown result type (might be due to invalid IL or missing references) //IL_09b5: Unknown result type (might be due to invalid IL or missing references) //IL_09bb: Expected O, but got Unknown //IL_09d9: Unknown result type (might be due to invalid IL or missing references) //IL_09df: Expected O, but got Unknown //IL_0aad: Unknown result type (might be due to invalid IL or missing references) //IL_0ab3: Expected O, but got Unknown Log = ((BasePlugin)this).Log; Cfg = ((BasePlugin)this).Config; ((BasePlugin)this).Config.SaveOnConfigSet = false; Mode = ((BasePlugin)this).Config.Bind("General", "Mode", ViewMode.FirstPerson, "The view to start in. FirstPerson is the game as shipped, Behind puts the camera over your shoulder, and Front puts it ahead of you looking back at yourself. The toggle keys cycle through all three in game; this is only where each session begins."); ShowBody = ((BasePlugin)this).Config.Bind("General", "ShowBody", true, "Switch your character to the full body other players see, so there is something to look at. Turn off if you would rather keep the first-person body."); ShowGear = ((BasePlugin)this).Config.Bind("General", "ShowGear", true, "Show your backpack, your belt and everything pinned to them. The game hides these from you in first person, since you would otherwise be wearing your own view. Turn off if un-hiding them causes trouble."); HideFirstPersonBelt = ((BasePlugin)this).Config.Bind("General", "HideFirstPersonBelt", true, "Hide the belt drawn for first person. It is a stand-in, hung where a camera inside your head can see it rather than on your hip, so from outside it is the wrong belt in the wrong place — the same reason the first-person arms and legs are hidden. What you have pinned to the belt is unaffected. Turn off if you would rather see it."); PinCameraChildren = ((BasePlugin)this).Config.Bind("General", "PinCameraChildren", true, "Keep anything parented to the camera where it was, instead of letting it travel with the camera. The belt is the one you notice: it hangs off the camera so you can see it when you look down, so without this it detaches and follows the view out behind you."); HideHelperParts = ((BasePlugin)this).Config.Bind("General", "HideHelperParts", false, "Hide the helper objects the game hangs off your arms and hands — the grasper, the grip guides and the stretch transform. They are where an arm is aimed rather than part of your body, and one of them may still have a mesh attached. Off by default: the grasper is also where things you pick up are held, and on the character this was built against the pass found no strays at all. Use HiddenParts to name a specific mesh instead — that is the one that fixes the green ball in the left arm."); HiddenParts = ((BasePlugin)this).Config.Bind("General", "HiddenParts", "", "Extra things on your character to leave undrawn in the third-person views, as comma-separated pieces of their object names — a partial match is enough and case does not matter. Empty by default. This is the escape hatch for a stray mesh the line above does not cover: set DumpCameras and the log names every renderer on you that is neither body nor carried kit, which is the short list it will be on."); RevealLayers = ((BasePlugin)this).Config.Bind("General", "RevealLayers", "", "Extra layers to let through the camera while in third person, by number or name. Empty by default because your whole character sits on layer 11 'Player', which the camera already renders — the game hides body parts by switching renderers off, not by culling a layer. Kept as a lever in case something you want to see turns out to be culled."); Distance = ((BasePlugin)this).Config.Bind("Camera", "Distance", 2.5f, new ConfigDescription("How far behind the head the camera sits, in metres.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 15f), Array.Empty())); Height = ((BasePlugin)this).Config.Bind("Camera", "Height", 0.35f, "How far above the head the camera sits, in metres."); Shoulder = ((BasePlugin)this).Config.Bind("Camera", "Shoulder", 0f, "Sideways offset, in metres. Positive is right. Leave at 0 to keep the crosshair lined up with what you actually interact with."); OrbitYaw = ((BasePlugin)this).Config.Bind("Camera", "OrbitYaw", 0f, new ConfigDescription("Swings the camera around you, in degrees. Positive is to your right. 0 is straight behind in Behind and dead-on in Front; something like 30 gets you a three-quarter view instead of face-on, which frames a face far better. The camera is aimed back at you as it swings, and the angle is relative to where you are looking, so it holds as you walk. Cycling the view resets it.", (AcceptableValueBase)(object)new AcceptableValueRange(-180f, 180f), Array.Empty())); OrbitPitch = ((BasePlugin)this).Config.Bind("Camera", "OrbitPitch", 0f, new ConfigDescription("Swings the camera up or down around you, in degrees. Positive looks down at you from above. Separate from Height, which slides the camera up without turning it. Cycling the view resets it.", (AcceptableValueBase)(object)new AcceptableValueRange(-85f, 85f), Array.Empty())); OrbitSpeed = ((BasePlugin)this).Config.Bind("Camera", "OrbitSpeed", 90f, new ConfigDescription("How fast the orbit keys swing the camera, in degrees per second while held.", (AcceptableValueBase)(object)new AcceptableValueRange(5f, 720f), Array.Empty())); Collide = ((BasePlugin)this).Config.Bind("Camera", "Collide", true, "Pull the camera in when a wall would otherwise be between it and your head."); CollisionRadius = ((BasePlugin)this).Config.Bind("Camera", "CollisionRadius", 0.25f, "Radius of the sphere swept back from your head to find walls."); MinDistance = ((BasePlugin)this).Config.Bind("Camera", "MinDistance", 0.4f, "Never pull the camera closer than this, even in tight spaces."); IgnoreLayers = ((BasePlugin)this).Config.Bind("Camera", "IgnoreLayers", "Player,Ignore Raycast,UI,Water,TransparentFX,PostProcessing", "Comma-separated layer names the wall check ignores. Names that do not exist are skipped."); ToggleKeys = ((BasePlugin)this).Config.Bind("Input", "ToggleKeys", "RightBracket", "Comma-separated keys that each cycle the view: first person, behind, front. This is one of four keys that sit together on the right of the keyboard: ; opens the panel, [ hides the HUD, ] cycles the view, \\ takes the camera. Ordinary keys, so they survive — Steam swallows the function keys before the game sees them on some setups. Add as many as you like and whichever arrives wins; any KeyCode name works, including JoystickButton0..19 for a pad. Turn on LogKeys to see exactly which presses reach the game."); ToggleChord = ((BasePlugin)this).Config.Bind("Input", "ToggleChord", "JoystickButton8,JoystickButton9", "Buttons that must be held together to cycle the view, for playing on the pad. Default is both stick clicks (L3+R3), which no single game action uses. A chord rather than one button because the game already owns every face and shoulder button. Set empty to disable. Xbox-style numbering: 0 A, 1 B, 2 X, 3 Y, 4 LB, 5 RB, 6 View, 7 Menu, 8 L3, 9 R3."); ChordHold = ((BasePlugin)this).Config.Bind("Input", "ChordHold", 0.25f, new ConfigDescription("How long the chord must be held before it fires, in seconds. Keeps a brush past both sticks from flipping the view. 0 fires the moment both are down.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 3f), Array.Empty())); CloserKeys = ((BasePlugin)this).Config.Bind("Input", "CloserKeys", "PageDown", "Comma-separated keys that move the camera closer. Kept alongside the wheel because a pad has no wheel: with these gone, changing distance on a handheld would mean opening the panel."); FartherKeys = ((BasePlugin)this).Config.Bind("Input", "FartherKeys", "PageUp", "Comma-separated keys that move the camera farther away."); CameraHoldKeys = ((BasePlugin)this).Config.Bind("Input", "CameraHoldKeys", "LeftAlt,Mouse2", "Comma-separated keys you hold to take hold of the camera. While one is down the mouse swings the camera around you instead of turning you, the wheel moves it closer and farther, and the arrow keys nudge it. The angle stays where you let go, and cycling the view puts it back to straight on. This is one gesture for the whole camera rather than a key per axis. Set empty to make the wheel work without a modifier — but the wheel is also the game's own zoom. On a handheld, map the right stick to the mouse in Steam's controller layout and this works on the pad."); OrbitMouseSpeed = ((BasePlugin)this).Config.Bind("Input", "OrbitMouseSpeed", 3f, new ConfigDescription("Degrees of swing per unit of mouse movement while an orbit-hold key is down. Set it negative to reverse both directions.", (AcceptableValueBase)(object)new AcceptableValueRange(-20f, 20f), Array.Empty())); FreezeLookWhileOrbiting = ((BasePlugin)this).Config.Bind("Input", "FreezeLookWhileOrbiting", true, "While an orbit-hold key is down, stop the game reading the mouse, so swinging the camera does not also turn your character and ruin the shot you are framing. Turn off if it causes trouble — the cost is that the mouse does both jobs at once."); OrbitLeftKeys = ((BasePlugin)this).Config.Bind("Input", "OrbitLeftKeys", "LeftArrow", "Comma-separated keys that swing the camera to your left. Held down rather than tapped: the camera moves for as long as you hold, at OrbitSpeed."); OrbitRightKeys = ((BasePlugin)this).Config.Bind("Input", "OrbitRightKeys", "RightArrow", "Comma-separated keys that swing the camera to your right."); OrbitUpKeys = ((BasePlugin)this).Config.Bind("Input", "OrbitUpKeys", "UpArrow", "Comma-separated keys that swing the camera up, to look down at yourself."); OrbitDownKeys = ((BasePlugin)this).Config.Bind("Input", "OrbitDownKeys", "DownArrow", "Comma-separated keys that swing the camera down, to look up at yourself."); OrbitResetKeys = ((BasePlugin)this).Config.Bind("Input", "OrbitResetKeys", "End", "Comma-separated keys that put the orbit back to straight-on without changing the view. Cycling the view with the toggle keys also resets it."); DistanceStep = ((BasePlugin)this).Config.Bind("Input", "DistanceStep", 0.25f, "Distance change per keypress or wheel notch, in metres."); PanelKeys = ((BasePlugin)this).Config.Bind("Panel", "PanelKeys", "Semicolon", "Comma-separated keys that open the settings panel, the first of the four keys along the right of the keyboard ([ hides the HUD, ] cycles the view, \\ takes the camera). Everything below can be dragged on a slider while you watch the result. Add more if the semicolon is awkward on your keyboard layout; the function keys are a poor choice, since Steam swallows them before the game sees them on some setups."); PanelScale = ((BasePlugin)this).Config.Bind("Panel", "Scale", 1.6f, "How much to magnify both panels. Unity's built-in debug UI draws at a fixed pixel size, which is unreadable on a handheld screen. Held back automatically if a larger size would not leave both panels on screen — the panels are laid out against the real screen width, so magnifying can never push one off the edge."); PanelFreeCursor = ((BasePlugin)this).Config.Bind("Panel", "FreeCursor", true, "Release the mouse cursor while the panels are open, so the sliders can be dragged. The game still reads the mouse for looking around, so expect the camera to turn while you aim at a control."); LogKeys = ((BasePlugin)this).Config.Bind("Debug", "LogKeys", false, "Log every key and pad button press. Turn on to find a binding this machine actually delivers — Steam eats the function keys here, so Semicolon is the one that works."); DumpCameras = ((BasePlugin)this).Config.Bind("Debug", "DumpCameras", false, "Log the camera hierarchy, layers, and the state of every body renderer a second after switching views. Turn on if a part of your character renders wrong — it names which flag is holding each part down."); FreecamKeys = ((BasePlugin)this).Config.Bind("Freecam", "FreecamKeys", "Backslash", "Comma-separated keys that take the camera off you entirely and let you fly it. It starts wherever you were looking from, so switching in never jumps the view. The camera is moved for rendering only — the game still runs everything else from your head, so this cannot reach through a wall or upset other players."); FreecamForwardKeys = ((BasePlugin)this).Config.Bind("Freecam", "ForwardKeys", "W", "Comma-separated keys that fly the camera forward. Shares the game's own movement keys by default, which works because FreezePlayer stops your character acting on them; rebind these if you turn that off."); FreecamBackKeys = ((BasePlugin)this).Config.Bind("Freecam", "BackKeys", "S", "Comma-separated keys that fly the camera backward."); FreecamLeftKeys = ((BasePlugin)this).Config.Bind("Freecam", "LeftKeys", "A", "Comma-separated keys that fly the camera left."); FreecamRightKeys = ((BasePlugin)this).Config.Bind("Freecam", "RightKeys", "D", "Comma-separated keys that fly the camera right."); FreecamUpKeys = ((BasePlugin)this).Config.Bind("Freecam", "UpKeys", "Space,E", "Comma-separated keys that fly the camera straight up. Up is world up rather than the camera's own, so looking down does not turn it into backwards."); FreecamDownKeys = ((BasePlugin)this).Config.Bind("Freecam", "DownKeys", "LeftControl,Q", "Comma-separated keys that fly the camera straight down."); FreecamFastKeys = ((BasePlugin)this).Config.Bind("Freecam", "FastKeys", "LeftShift", "Comma-separated keys you hold to fly faster, for crossing the map."); FreecamSlowKeys = ((BasePlugin)this).Config.Bind("Freecam", "SlowKeys", "Z", "Comma-separated keys you hold to fly slower, for creeping up on a shot. Not LeftAlt: that is the third-person camera hold key, and one key doing two jobs is how you end up fighting your own mod."); FreecamSpeed = ((BasePlugin)this).Config.Bind("Freecam", "Speed", 6f, new ConfigDescription("How fast the camera flies, in metres per second.", (AcceptableValueBase)(object)new AcceptableValueRange(0.5f, 50f), Array.Empty())); FreecamFastMultiplier = ((BasePlugin)this).Config.Bind("Freecam", "FastMultiplier", 4f, new ConfigDescription("How much the fast keys multiply the speed by.", (AcceptableValueBase)(object)new AcceptableValueRange(1f, 20f), Array.Empty())); FreecamSlowMultiplier = ((BasePlugin)this).Config.Bind("Freecam", "SlowMultiplier", 0.2f, new ConfigDescription("How much the slow keys multiply the speed by.", (AcceptableValueBase)(object)new AcceptableValueRange(0.02f, 1f), Array.Empty())); FreecamLookSpeed = ((BasePlugin)this).Config.Bind("Freecam", "LookSpeed", 3f, new ConfigDescription("Degrees of aim per unit of mouse movement while flying.", (AcceptableValueBase)(object)new AcceptableValueRange(0.1f, 20f), Array.Empty())); FreecamMaxPitch = ((BasePlugin)this).Config.Bind("Freecam", "MaxPitch", 89f, new ConfigDescription("How far up or down the camera can be aimed, in degrees. Short of 90 on purpose: straight down leaves no sensible heading to fly along.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 89.9f), Array.Empty())); FreecamInvertPitch = ((BasePlugin)this).Config.Bind("Freecam", "InvertPitch", false, "Invert the up and down aim, for anyone who flies the other way round."); FreecamTeleportKeys = ((BasePlugin)this).Config.Bind("Freecam", "TeleportKeys", "Home", "Comma-separated keys that bring your character to wherever the camera is flying. You arrive standing with your eyes where the camera was, keeping your speed at zero. There is a button for it on the Freecam tab as well. NOTE: this is the one thing in this mod that actually moves you — every view is otherwise render-only and cannot be seen by anyone else. Other players will see you arrive, and a host that disagrees about where you should be may put you back. Set empty to leave it on the panel button alone."); FreecamFreezePlayer = ((BasePlugin)this).Config.Bind("Freecam", "FreezePlayer", true, "Stop your character acting on input while the camera is flying. Legacy input cannot be intercepted, so without this the movement keys drive the camera and your legs at once and you walk off while lining up a shot. Turn off if it causes trouble — the cost is that you have to rebind the flight keys to something the game does not use."); HudKeys = ((BasePlugin)this).Config.Bind("Hud", "HudKeys", "LeftBracket", "Comma-separated keys that hide and show the HUD. Works in every view, not just the freecam — wanting a screenshot without a crosshair in it has nothing to do with where the camera is."); HideHud = ((BasePlugin)this).Config.Bind("Hud", "HideHud", false, "Whether the HUD starts hidden. The keys above toggle it in game; this is only where each session begins."); HudLayers = ((BasePlugin)this).Config.Bind("Hud", "HudLayers", "UI", "Comma-separated layers the HUD is drawn on, by number or name. Used twice: those layers are taken out of the camera while the HUD is hidden, and they pick which canvases HideCanvases switches off. Only the mask bits actually cleared are put back, so a mask the game changes meanwhile survives. Names that do not exist are skipped. Leave it EMPTY to hide every canvas, which is the thing to try if some of the HUD survives — the log names each canvas and the layer it is on."); HudHideCanvases = ((BasePlugin)this).Config.Bind("Hud", "HideCanvases", true, "Switch off the Canvas components the HUD is drawn on. This is the route that actually works everywhere: the layer route below only reaches canvases drawn through a camera, and a Screen Space - Overlay canvas is drawn by no camera at all. The canvases are collected once, when hiding starts, and only those are ever touched — so a pause menu opened afterwards still appears. The log names every canvas it found and every one it left alone, which is how you correct HudLayers if something stays on screen."); DumpCanvases = ((BasePlugin)this).Config.Bind("Debug", "DumpCanvases", false, "Log every live canvas with its render mode, layer and camera, once. This is the one thing worth knowing before tuning HudLayers, and it also reports whether the game's own CameraCheatMover is present."); HudStyle.Bind(((BasePlugin)this).Config); AdoptOldScrollModifier(); Harmony.CreateAndPatchAll(typeof(CameraPatches), "deck.bigwalk.thirdperson"); Harmony.CreateAndPatchAll(typeof(FreecamPatches), "deck.bigwalk.thirdperson"); ClassInjector.RegisterTypeInIl2Cpp(); GameObject val = new GameObject("ThirdPersonRuntime") { hideFlags = (HideFlags)61 }; Object.DontDestroyOnLoad((Object)val); val.AddComponent(); ClassInjector.RegisterTypeInIl2Cpp(); GameObject val2 = new GameObject("FreecamRuntime") { hideFlags = (HideFlags)61 }; Object.DontDestroyOnLoad((Object)val2); val2.AddComponent(); ((BasePlugin)this).Config.Save(); ManualLogSource log = Log; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val3 = new BepInExInfoLogInterpolatedStringHandler(134, 5, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("Third Person loaded. Hold ["); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(CameraHoldKeys.Value); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("] to take the camera. "); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("Any of ["); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(ToggleKeys.Value); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("] or the pad chord "); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("["); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(ToggleChord.Value); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("] cycles first person / behind / front. "); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("Starting in "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(Mode.Value); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" at "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(Distance.Value, "0.##"); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("m"); } log.LogInfo(val3); ManualLogSource log2 = Log; val3 = new BepInExInfoLogInterpolatedStringHandler(51, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("Freecam on ["); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(FreecamKeys.Value); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("], HUD on ["); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(HudKeys.Value); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("], "); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("the settings panel on ["); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(PanelKeys.Value); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("]."); } log2.LogInfo(val3); } private static void AdoptOldScrollModifier() { //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Expected O, but got Unknown //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Expected O, but got Unknown bool flag = default(bool); try { string configFilePath = Cfg.ConfigFilePath; if (string.IsNullOrEmpty(configFilePath) || !File.Exists(configFilePath)) { return; } string[] array = File.ReadAllLines(configFilePath); for (int i = 0; i < array.Length; i++) { string text = array[i].Trim(); if (!text.StartsWith("ScrollModifier", StringComparison.Ordinal)) { continue; } int num = text.IndexOf('='); if (num < 0) { continue; } string text2 = text.Substring(num + 1).Trim(); if (text2.Length == 0 || text2 == "None" || text2 == "LeftAlt") { break; } string text3 = CameraHoldKeys.Value ?? ""; if (text3.IndexOf(text2, StringComparison.OrdinalIgnoreCase) < 0) { CameraHoldKeys.Value = ((text3.Length == 0) ? text2 : (text3 + "," + text2)); ManualLogSource log = Log; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(78, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("kept your old ScrollModifier '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(text2); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' as a camera hold key. "); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("CameraHoldKeys is now ["); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(CameraHoldKeys.Value); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("]"); } log.LogInfo(val); } break; } } catch (Exception ex) { ManualLogSource log2 = Log; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(51, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("could not check for an old ScrollModifier setting: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } log2.LogInfo(val); } } } public class ThirdPersonRuntime : MonoBehaviour { private static KeyCode[] _allKeys; private bool _announced; private bool _inputDead; private ViewMode _lastMode; private float _chordSince = -1f; private bool _chordFired; private bool _orbiting; private bool _holding; private bool _lookWas; private bool _axesDead; private bool _cursorSaved; private CursorLockMode _lockWas; private bool _visibleWas; public ThirdPersonRuntime(IntPtr ptr) : base(ptr) { } private void Update() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Expected O, but got Unknown //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Expected O, but got Unknown //IL_0228: Unknown result type (might be due to invalid IL or missing references) //IL_028e: Unknown result type (might be due to invalid IL or missing references) //IL_0294: Expected O, but got Unknown bool flag = default(bool); if (!_announced) { _announced = true; _lastMode = Freecam.ChosenMode; ManualLogSource log = Plugin.Log; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(36, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("runtime active, in "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(_lastMode); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", watching for ["); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(Plugin.ToggleKeys.Value); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("]"); } log.LogInfo(val); } if (Freecam.ChosenMode != _lastMode) { _lastMode = Freecam.ChosenMode; ManualLogSource log2 = Plugin.Log; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(12, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("view is now "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(_lastMode); } log2.LogInfo(val); if (_lastMode == ViewMode.FirstPerson && !Freecam.Active) { ThirdPersonCamera.Reset(); } } if (_inputDead) { return; } try { if (Plugin.LogKeys.Value) { ReportKeys(); } if (KeyList.AnyDown(Plugin.PanelKeys.Value)) { Panels.Open = !Panels.Open; if (!Panels.Open) { RestoreCursor(); Panels.Closed(); } Plugin.Log.LogInfo((object)(Panels.Open ? "settings panels open" : "settings panels closed")); } if (KeyList.AnyDown(Plugin.ToggleKeys.Value) || ChordFired()) { ViewMode viewMode = (Freecam.ChosenMode = Next(Freecam.ChosenMode)); ResetOrbit(); Plugin.Log.LogInfo((object)((viewMode == ViewMode.FirstPerson) ? "view: first person" : $"view: {viewMode} ({Plugin.Distance.Value:0.##}m)")); if (viewMode == ViewMode.FirstPerson && !Freecam.Active) { ThirdPersonCamera.Reset(); } } if (Freecam.Active || Plugin.Mode.Value == ViewMode.FirstPerson) { Hold(held: false); return; } Orbit(); float num = 0f; if (KeyList.AnyDown(Plugin.FartherKeys.Value)) { num += Plugin.DistanceStep.Value; } if (KeyList.AnyDown(Plugin.CloserKeys.Value)) { num -= Plugin.DistanceStep.Value; } if (_holding || string.IsNullOrWhiteSpace(Plugin.CameraHoldKeys.Value)) { float y = Input.mouseScrollDelta.y; if (Mathf.Abs(y) > 0.01f) { num += Mathf.Sign(y) * Plugin.DistanceStep.Value; } } if (num != 0f) { Plugin.Distance.Value = Mathf.Clamp(Plugin.Distance.Value + num, 0f, 15f); ManualLogSource log3 = Plugin.Log; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(17, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("camera distance "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(Plugin.Distance.Value, "0.##"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("m"); } log3.LogInfo(val); } } catch (Exception arg) { _inputDead = true; Plugin.Log.LogError((object)("keyboard input is unavailable, so the toggle keys will not work. Set Mode in " + $"BepInEx/config/deck.bigwalk.thirdperson.cfg instead. Reason: {arg}")); } } private void OnGUI() { //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Expected O, but got Unknown //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) if (!Panels.Open) { return; } if (Plugin.PanelFreeCursor.Value) { if (!_cursorSaved) { _cursorSaved = true; _lockWas = Cursor.lockState; _visibleWas = Cursor.visible; } Cursor.lockState = (CursorLockMode)0; Cursor.visible = true; } try { Panels.Draw(); } catch (Exception ex) { Panels.Open = false; RestoreCursor(); Panels.Closed(); ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(38, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("the settings panel threw, closing it: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex); } log.LogError(val); } } private void RestoreCursor() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) if (_cursorSaved) { _cursorSaved = false; Cursor.lockState = _lockWas; Cursor.visible = _visibleWas; } } private void Orbit() { //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Expected O, but got Unknown if (KeyList.AnyDown(Plugin.OrbitResetKeys.Value)) { ResetOrbit(); Plugin.Log.LogInfo((object)"orbit: straight on"); return; } Hold(KeyList.AnyHeld(Plugin.CameraHoldKeys.Value)); if (_holding) { float value = Plugin.OrbitMouseSpeed.Value; AddYaw(MouseAxis("Mouse X") * value); AddPitch(MouseAxis("Mouse Y") * value); } float num = 0f; if (KeyList.AnyHeld(Plugin.OrbitRightKeys.Value)) { num += 1f; } if (KeyList.AnyHeld(Plugin.OrbitLeftKeys.Value)) { num -= 1f; } float num2 = 0f; if (KeyList.AnyHeld(Plugin.OrbitUpKeys.Value)) { num2 += 1f; } if (KeyList.AnyHeld(Plugin.OrbitDownKeys.Value)) { num2 -= 1f; } if (num == 0f && num2 == 0f) { if (_orbiting) { _orbiting = false; ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(21, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("orbit: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(Plugin.OrbitYaw.Value, "0"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("° across, "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(Plugin.OrbitPitch.Value, "0"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("° up"); } log.LogInfo(val); } } else { _orbiting = true; float num3 = Plugin.OrbitSpeed.Value * Time.unscaledDeltaTime; AddYaw(num * num3); AddPitch(num2 * num3); } } private void Hold(bool held) { if (held != _holding) { _holding = held; if (Plugin.FreezeLookWhileOrbiting.Value) { Freeze(held); } Plugin.Log.LogInfo((object)(held ? "orbit: mouse is on the camera, let go to lock it" : $"orbit locked at {Plugin.OrbitYaw.Value:0}° across, {Plugin.OrbitPitch.Value:0}° up")); } } private void Freeze(bool freeze) { //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Expected O, but got Unknown try { PlayerCharacter local = ThirdPersonCamera.Local; PlayerHead val = ((local != null) ? local.head : null); if (val == null) { if (freeze) { Plugin.Log.LogWarning((object)"no PlayerHead to freeze, so the mouse will turn you as well as the camera"); } return; } if (freeze) { _lookWas = val.bypassUpdate; } val.bypassUpdate = freeze || _lookWas; } catch (Exception ex) { ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(34, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("could not freeze the game's look: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex.Message); } log.LogWarning(val2); } } private float MouseAxis(string axis) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown if (_axesDead) { return 0f; } try { return Input.GetAxisRaw(axis); } catch (Exception ex) { _axesDead = true; ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(103, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("this build has no '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(axis); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' axis, so hold-to-orbit cannot read "); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("the mouse. Use the arrow keys instead. Reason: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } log.LogWarning(val); return 0f; } } private static void AddYaw(float degrees) { if (degrees != 0f) { float num = Plugin.OrbitYaw.Value + degrees; if (num > 180f) { num -= 360f; } else if (num < -180f) { num += 360f; } Plugin.OrbitYaw.Value = num; } } private static void AddPitch(float degrees) { if (degrees != 0f) { Plugin.OrbitPitch.Value = Mathf.Clamp(Plugin.OrbitPitch.Value + degrees, -85f, 85f); } } private static void ResetOrbit() { Plugin.OrbitYaw.Value = 0f; Plugin.OrbitPitch.Value = 0f; } private void OnDestroy() { Hold(held: false); } private void OnDisable() { Hold(held: false); } private bool ChordFired() { if (!KeyList.AllHeld(Plugin.ToggleChord.Value)) { _chordSince = -1f; _chordFired = false; return false; } if (_chordSince < 0f) { _chordSince = Time.unscaledTime; } if (_chordFired) { return false; } if (Time.unscaledTime - _chordSince < Plugin.ChordHold.Value) { return false; } _chordFired = true; return true; } private unsafe static void ReportKeys() { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Invalid comparison between Unknown and I4 //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Expected O, but got Unknown //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Invalid comparison between Unknown and I4 if (!Input.anyKeyDown) { return; } if (_allKeys == null) { _allKeys = (KeyCode[])Enum.GetValues(typeof(KeyCode)); } string text = null; KeyCode[] allKeys = _allKeys; for (int i = 0; i < allKeys.Length; i++) { KeyCode val = allKeys[i]; if ((int)val != 0 && ((int)val < 323 || (int)val > 329) && Input.GetKeyDown(val)) { text = ((text == null) ? ((object)(*(KeyCode*)(&val))/*cast due to .constrained prefix*/).ToString() : (text + ", " + ((object)(*(KeyCode*)(&val))/*cast due to .constrained prefix*/).ToString())); } } if (text != null) { ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(10, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("key down: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(text); } log.LogInfo(val2); } } private static ViewMode Next(ViewMode mode) { return mode switch { ViewMode.FirstPerson => ViewMode.Behind, ViewMode.Behind => ViewMode.Front, _ => ViewMode.FirstPerson, }; } } internal static class KeyList { private static readonly Dictionary Parsed = new Dictionary(); public static bool AnyDown(string spec) { KeyCode[] array = Parse(spec); for (int i = 0; i < array.Length; i++) { if (Input.GetKeyDown(array[i])) { return true; } } return false; } public static bool AnyHeld(string spec) { KeyCode[] array = Parse(spec); for (int i = 0; i < array.Length; i++) { if (Input.GetKey(array[i])) { return true; } } return false; } public static bool AllHeld(string spec) { KeyCode[] array = Parse(spec); if (array.Length == 0) { return false; } KeyCode[] array2 = array; for (int i = 0; i < array2.Length; i++) { if (!Input.GetKey(array2[i])) { return false; } } return true; } private static KeyCode[] Parse(string spec) { //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Expected O, but got Unknown //IL_0050: 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) if (spec == null) { spec = string.Empty; } if (Parsed.TryGetValue(spec, out var value)) { return value; } List list = new List(); string[] array = spec.Split(','); bool flag = default(bool); for (int i = 0; i < array.Length; i++) { string text = array[i].Trim(); if (text.Length == 0) { continue; } if (Enum.TryParse(text, ignoreCase: true, out KeyCode result) && (int)result != 0) { list.Add(result); continue; } ManualLogSource log = Plugin.Log; BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(33, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("'"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(text); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' is not a key name, ignoring it"); } log.LogWarning(val); } KeyCode[] array2 = list.ToArray(); Parsed[spec] = array2; return array2; } } internal static class SettingsPanel { public static void ViewBody() { View(); GUILayout.Space(8f); PanelWidgets.Section("Camera", delegate { PanelWidgets.ResetAll("camera", Plugin.Distance, Plugin.Height, Plugin.Shoulder); }); PanelWidgets.Slider(Plugin.Distance, "Distance", 0f, 15f, "m", 2); PanelWidgets.Slider(Plugin.Height, "Height above head", -1f, 2f, "m", 2); PanelWidgets.Slider(Plugin.Shoulder, "Shoulder offset", -2f, 2f, "m", 2); GUILayout.Space(8f); PanelWidgets.Section("Orbit — swing the camera around yourself", delegate { PanelWidgets.ResetAll("orbit", Plugin.OrbitYaw, Plugin.OrbitPitch, Plugin.OrbitSpeed, Plugin.OrbitMouseSpeed); }); GUILayout.Label("Hold [" + Plugin.CameraHoldKeys.Value + "] and move the mouse. Let go to lock it.", (Il2CppReferenceArray)null); PanelWidgets.Slider(Plugin.OrbitYaw, "Across", -180f, 180f, "°", 0); PanelWidgets.Slider(Plugin.OrbitPitch, "Up", -85f, 85f, "°", 0); PanelWidgets.Slider(Plugin.OrbitMouseSpeed, "Mouse speed", -20f, 20f, "°", 1); PanelWidgets.Slider(Plugin.OrbitSpeed, "Arrow key speed", 5f, 720f, "°/s", 0); PanelWidgets.Toggle(Plugin.FreezeLookWhileOrbiting, "Do not turn while orbiting"); GUILayout.Space(8f); PanelWidgets.Section("What is drawn"); PanelWidgets.Toggle(Plugin.ShowBody, "Your whole body, as others see it"); PanelWidgets.Toggle(Plugin.ShowGear, "Your backpack, belt and what is on them"); PanelWidgets.Toggle(Plugin.HideFirstPersonBelt, "Hide the first-person belt (a stand-in, wrongly placed)"); PanelWidgets.Toggle(Plugin.PinCameraChildren, "Leave camera-mounted things behind"); GUILayout.Space(8f); PanelWidgets.Section("Walls", delegate { PanelWidgets.ResetAll("wall settings", Plugin.CollisionRadius, Plugin.MinDistance); }); PanelWidgets.Toggle(Plugin.Collide, "Pull the camera in at walls"); PanelWidgets.Slider(Plugin.CollisionRadius, "Check radius", 0.05f, 1f, "m", 2); PanelWidgets.Slider(Plugin.MinDistance, "Never closer than", 0f, 3f, "m", 2); GUILayout.Space(8f); PanelWidgets.Section("Distance", delegate { PanelWidgets.ResetAll("distance step", Plugin.DistanceStep); }); PanelWidgets.Slider(Plugin.DistanceStep, "Per keypress or wheel notch", 0.05f, 1f, "m", 2); } public static void SetupBody() { PanelWidgets.Section("This panel", delegate { PanelWidgets.ResetAll("panel", Plugin.PanelScale); }); PanelWidgets.Slider(Plugin.PanelScale, "Size", 0.5f, 4f, "x", 2); if (Panels.Clamped) { GUILayout.Label("(held back to fit the screen)", (Il2CppReferenceArray)null); } PanelWidgets.Toggle(Plugin.PanelFreeCursor, "Free the cursor while open"); GUILayout.Space(8f); PanelWidgets.Section("Keys"); Key("Cycle the view", Plugin.ToggleKeys.Value); Key("This panel", Plugin.PanelKeys.Value); Key("Freecam", Plugin.FreecamKeys.Value); Key("Bring you to the camera", Plugin.FreecamTeleportKeys.Value); Key("HUD", Plugin.HudKeys.Value); Key("Hold the camera", Plugin.CameraHoldKeys.Value); Key("Orbit straight on", Plugin.OrbitResetKeys.Value); Key("Closer / farther", Plugin.CloserKeys.Value + " / " + Plugin.FartherKeys.Value); Key("Fly", Plugin.FreecamForwardKeys.Value + " " + Plugin.FreecamLeftKeys.Value + " " + Plugin.FreecamBackKeys.Value + " " + Plugin.FreecamRightKeys.Value); Key("Fly up / down", Plugin.FreecamUpKeys.Value + " / " + Plugin.FreecamDownKeys.Value); Key("Fly fast / slow", Plugin.FreecamFastKeys.Value + " / " + Plugin.FreecamSlowKeys.Value); Key("Pad cycle", Plugin.ToggleChord.Value); } private static void Key(string label, string keys) { GUILayout.BeginHorizontal((Il2CppReferenceArray)null); GUILayout.Label(label, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(170f) }); GUILayout.Label(keys, (Il2CppReferenceArray)null); GUILayout.EndHorizontal(); } private static void View() { GUILayout.Label($"— View: {Freecam.ChosenMode} —", (Il2CppReferenceArray)null); GUILayout.BeginHorizontal((Il2CppReferenceArray)null); Pick(ViewMode.FirstPerson, "First person"); Pick(ViewMode.Behind, "Behind"); Pick(ViewMode.Front, "Front"); GUILayout.EndHorizontal(); if (Panels.FlyingShown) { GUILayout.Label("(the freecam is flying — this is the view you land in)", (Il2CppReferenceArray)null); } } private static void Pick(ViewMode mode, string label) { bool flag = Freecam.ChosenMode == mode; if (!(!GUILayout.Button(flag ? ("[" + label + "]") : label, (Il2CppReferenceArray)null) || flag)) { Freecam.ChosenMode = mode; if (mode == ViewMode.FirstPerson && !Freecam.Active) { ThirdPersonCamera.Reset(); } PanelWidgets.Status = $"view: {mode}"; } } } internal static class ThirdPersonCamera { private struct Shift { public Transform Transform; public Vector3 Delta; public Quaternion Rotation; public bool Turned; } private struct Pin { public Transform Transform; public Vector3 LocalPosition; public Quaternion LocalRotation; public Vector3 Position; public Quaternion Rotation; } private static readonly List Shifts = new List(); private static readonly List Pins = new List(); private static readonly List HeldChildren = new List(); private static Transform _heldOwner; private static int _heldCount = -1; private static Il2CppStructArray _hits; private static string _maskSource; private static int _mask = -1; private static string _revealSource; private static int _revealMask; private static Camera _revealed; private static int _revealedBits; private static bool _dumped; private static ViewMode _reported = ViewMode.FirstPerson; private static float _reportBodyAt; public static PlayerCharacter Local { get; private set; } public static void Restore() { //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_revealed != (Object)null && _revealedBits != 0) { Camera revealed = _revealed; revealed.cullingMask &= ~_revealedBits; } _revealed = null; _revealedBits = 0; if (Shifts.Count == 0 && Pins.Count == 0) { return; } for (int num = Shifts.Count - 1; num >= 0; num--) { Shift shift = Shifts[num]; if (!((Object)(object)shift.Transform == (Object)null)) { if (shift.Turned) { shift.Transform.rotation = shift.Rotation; } Transform transform = shift.Transform; transform.position -= shift.Delta; } } Shifts.Clear(); for (int num2 = Pins.Count - 1; num2 >= 0; num2--) { Pin pin = Pins[num2]; if (!((Object)(object)pin.Transform == (Object)null)) { pin.Transform.localPosition = pin.LocalPosition; pin.Transform.localRotation = pin.LocalRotation; } } Pins.Clear(); } public static void Reset() { Restore(); PlayerBody.Restore(); PlayerGear.Restore(); PlayerExtras.Restore(); _reportBodyAt = 0f; } public static bool IsLocal(PlayerCharacter pc) { if ((Object)(object)pc == (Object)null) { return false; } try { if (((NetworkBehaviour)pc).isLocalPlayer) { return true; } } catch (Exception) { } PlayerCameraReferences val = References(pc); if ((Object)(object)val != (Object)null) { return (Object)(object)val.playerCamera != (Object)null; } return false; } public static void Apply(PlayerCharacter pc) { //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Expected O, but got Unknown //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Expected O, but got Unknown //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_011e: 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_0123: 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) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_019e: 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_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Unknown result type (might be due to invalid IL or missing references) //IL_01c6: Unknown result type (might be due to invalid IL or missing references) //IL_01c8: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: 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_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_01e2: Unknown result type (might be due to invalid IL or missing references) //IL_01e7: Unknown result type (might be due to invalid IL or missing references) //IL_018f: 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_01f5: Unknown result type (might be due to invalid IL or missing references) //IL_01f7: Unknown result type (might be due to invalid IL or missing references) //IL_01f9: Unknown result type (might be due to invalid IL or missing references) //IL_01fe: Unknown result type (might be due to invalid IL or missing references) //IL_0243: Unknown result type (might be due to invalid IL or missing references) //IL_0247: Unknown result type (might be due to invalid IL or missing references) //IL_020e: 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_0216: Unknown result type (might be due to invalid IL or missing references) //IL_021c: Unknown result type (might be due to invalid IL or missing references) //IL_0221: Unknown result type (might be due to invalid IL or missing references) //IL_0226: Unknown result type (might be due to invalid IL or missing references) //IL_022b: Unknown result type (might be due to invalid IL or missing references) //IL_0261: Unknown result type (might be due to invalid IL or missing references) //IL_0265: Unknown result type (might be due to invalid IL or missing references) Local = pc; Restore(); ViewMode value = Plugin.Mode.Value; if (value == ViewMode.FirstPerson) { _reported = value; _reportBodyAt = 0f; PlayerBody.Restore(); PlayerGear.Restore(); PlayerExtras.Restore(); return; } Transform ui; Camera camera; Transform val = CameraTransform(pc, out ui, out camera); bool flag = default(bool); if ((Object)(object)val == (Object)null) { if (_reported != value) { _reported = value; ManualLogSource log = Plugin.Log; BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(36, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(value); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(": found no player camera to move on "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(((Object)pc).name); } log.LogWarning(val2); } return; } if (_reported != value) { _reported = value; ManualLogSource log2 = Plugin.Log; BepInExInfoLogInterpolatedStringHandler val3 = new BepInExInfoLogInterpolatedStringHandler(24, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(value); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(": moving '"); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(((Object)val).name); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("' off the head"); } log2.LogInfo(val3); } if (Plugin.DumpCameras.Value && !_dumped) { _dumped = true; Dump(pc, val, ui, camera); } Reveal(camera); Vector3 position = val.position; Vector3 val4 = position + val.up * Plugin.Height.Value; Vector3 away = ((value == ViewMode.Front) ? val.forward : (-val.forward)); away = Orbit(away, val, out var orbiting); float num = Mathf.Max(0f, Plugin.Distance.Value); if (Plugin.Collide.Value && num > 0f) { num = ClampToGeometry(pc, val4, away, num); } Vector3 val5 = val4 + away * num + val.right * Plugin.Shoulder.Value; Vector3 delta = val5 - position; if (((Vector3)(ref delta)).sqrMagnitude < 1E-08f) { return; } Quaternion spin = Quaternion.identity; bool turn = false; if (value == ViewMode.Front || orbiting) { Vector3 val6 = val4 - val5; if (((Vector3)(ref val6)).sqrMagnitude > 1E-06f) { spin = Quaternion.LookRotation(val6, val.up) * Quaternion.Inverse(val.rotation); turn = true; } } if (Plugin.PinCameraChildren.Value) { Hold(val); } Move(val, delta, turn, spin); if ((Object)(object)ui != (Object)null && !ui.IsChildOf(val)) { Move(ui, delta, turn, spin); } Anchor(); if (Plugin.ShowBody.Value) { PlayerBody.ShowFull(pc); } else { PlayerBody.Restore(); } if (Plugin.ShowGear.Value) { PlayerGear.Show(pc); } else { PlayerGear.Restore(); } PlayerExtras.Hide(pc); if (Plugin.DumpCameras.Value && _reportBodyAt >= 0f) { if (_reportBodyAt == 0f) { _reportBodyAt = Time.unscaledTime + 1f; } else if (Time.unscaledTime >= _reportBodyAt) { _reportBodyAt = -1f; PlayerBody.Report(pc); PlayerGear.Report(pc, val); PlayerExtras.Report(pc); } } } private static Vector3 Orbit(Vector3 away, Transform main, out bool orbiting) { //IL_003c: 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_0046: 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_004c: 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_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) float value = Plugin.OrbitYaw.Value; float value2 = Plugin.OrbitPitch.Value; orbiting = Mathf.Abs(value) > 0.01f || Mathf.Abs(value2) > 0.01f; if (!orbiting) { return away; } Vector3 val = Quaternion.AngleAxis(value, Vector3.up) * away; Vector3 val2 = Vector3.Cross(val, Vector3.up); if (((Vector3)(ref val2)).sqrMagnitude < 1E-06f) { val2 = main.right; } return Quaternion.AngleAxis(value2, ((Vector3)(ref val2)).normalized) * val; } private static void Hold(Transform main) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) foreach (Transform item in Held(main)) { if (!((Object)(object)item == (Object)null)) { Pins.Add(new Pin { Transform = item, LocalPosition = item.localPosition, LocalRotation = item.localRotation, Position = item.position, Rotation = item.rotation }); } } } private static List Held(Transform main) { //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Expected O, but got Unknown if ((Object)(object)_heldOwner == (Object)(object)main && _heldCount == main.childCount) { return HeldChildren; } _heldOwner = main; _heldCount = main.childCount; HeldChildren.Clear(); bool flag = default(bool); for (int i = 0; i < main.childCount; i++) { Transform child = main.GetChild(i); if ((Object)(object)child == (Object)null) { continue; } Il2CppReferenceArray componentsInChildren = ((Component)child).GetComponentsInChildren(Il2CppType.Of(), true); if (componentsInChildren != null && ((Il2CppArrayBase)(object)componentsInChildren).Length > 0) { continue; } HeldChildren.Add(child); if (Plugin.DumpCameras.Value) { ManualLogSource log = Plugin.Log; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(19, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("holding '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(((Object)child).name); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' in place"); } log.LogInfo(val); } } return HeldChildren; } private static void Anchor() { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) foreach (Pin pin in Pins) { if (!((Object)(object)pin.Transform == (Object)null)) { pin.Transform.position = pin.Position; pin.Transform.rotation = pin.Rotation; } } } private static void Move(Transform t, Vector3 delta, bool turn, Quaternion spin) { //IL_0017: 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_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: 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_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0050: 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) Shifts.Add(new Shift { Transform = t, Delta = delta, Rotation = t.rotation, Turned = turn }); t.position += delta; if (turn) { t.rotation = spin * t.rotation; } } private static float ClampToGeometry(PlayerCharacter pc, Vector3 pivot, Vector3 away, float distance) { //IL_0029: 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_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) if (_hits == null) { _hits = new Il2CppStructArray(16L); } float num = Mathf.Max(0.01f, Plugin.CollisionRadius.Value); int num2 = Physics.SphereCastNonAlloc(pivot, num, away, _hits, distance, Mask(), (QueryTriggerInteraction)1); Transform root = ((Component)pc).transform.root; float num3 = distance; for (int i = 0; i < num2; i++) { RaycastHit val = ((Il2CppArrayBase)(object)_hits)[i]; if (!(((RaycastHit)(ref val)).distance <= 0f)) { Collider collider = ((RaycastHit)(ref val)).collider; if (!((Object)(object)collider == (Object)null) && !((Object)(object)((Component)collider).transform.root == (Object)(object)root) && ((RaycastHit)(ref val)).distance < num3) { num3 = ((RaycastHit)(ref val)).distance; } } } return Mathf.Max(Mathf.Min(Plugin.MinDistance.Value, distance), num3); } private static void Reveal(Camera camera) { if ((Object)(object)camera == (Object)null) { return; } int num = RevealMask(); if (num != 0) { int num2 = num & ~camera.cullingMask; if (num2 != 0) { camera.cullingMask |= num2; _revealed = camera; _revealedBits = num2; } } } private static int RevealMask() { //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Expected O, but got Unknown string text = Plugin.RevealLayers.Value ?? string.Empty; if (text == _revealSource) { return _revealMask; } _revealSource = text; int num = 0; string[] array = text.Split(','); bool flag = default(bool); for (int i = 0; i < array.Length; i++) { string text2 = array[i].Trim(); if (text2.Length == 0) { continue; } if (!int.TryParse(text2, out var result)) { result = LayerMask.NameToLayer(text2); } if (result >= 0 && result < 32) { num |= 1 << result; continue; } ManualLogSource log = Plugin.Log; BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(44, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("RevealLayers: '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(text2); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' is not a layer, skipping it"); } log.LogWarning(val); } _revealMask = num; return num; } private static int Mask() { //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Expected O, but got Unknown string text = Plugin.IgnoreLayers.Value ?? string.Empty; if (text == _maskSource) { return _mask; } _maskSource = text; int num = -1; string[] array = text.Split(','); bool flag = default(bool); for (int i = 0; i < array.Length; i++) { string text2 = array[i].Trim(); if (text2.Length == 0) { continue; } int num2 = LayerMask.NameToLayer(text2); if (num2 >= 0) { num &= ~(1 << num2); continue; } ManualLogSource log = Plugin.Log; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(58, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("IgnoreLayers: this game has no layer named '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(text2); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("', skipping it"); } log.LogInfo(val); } _mask = num; return num; } private static PlayerCameraReferences References(PlayerCharacter pc) { PlayerCameraMinder cameraMinder = pc.cameraMinder; if (cameraMinder == null) { return null; } PlayerCameraReferences playerCameraReferences = cameraMinder.playerCameraReferences; if (!((Object)(object)playerCameraReferences != (Object)null)) { return null; } return playerCameraReferences; } private static Transform CameraTransform(PlayerCharacter pc, out Transform ui, out Camera camera) { ui = null; camera = null; PlayerCameraReferences val = References(pc); if ((Object)(object)val != (Object)null) { Camera playerUICamera = val.playerUICamera; if ((Object)(object)playerUICamera != (Object)null) { ui = ((Component)playerUICamera).transform; } camera = val.playerCamera; if ((Object)(object)camera != (Object)null) { return ((Component)camera).transform; } } Transform cameraTransform = pc.cameraTransform; if (!((Object)(object)cameraTransform != (Object)null)) { return null; } return cameraTransform; } private static void Dump(PlayerCharacter pc, Transform main, Transform ui, Camera camera) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown //IL_02ef: Unknown result type (might be due to invalid IL or missing references) //IL_02f6: Expected O, but got Unknown //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Expected O, but got Unknown //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Expected O, but got Unknown //IL_0260: Unknown result type (might be due to invalid IL or missing references) //IL_0266: Expected O, but got Unknown ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(15, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("player camera: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(Path(main)); } log.LogInfo(val); Plugin.Log.LogInfo((object)(((Object)(object)ui != (Object)null) ? $"player UI camera: {Path(ui)} (child of player camera: {ui.IsChildOf(main)})" : "player UI camera: none")); List list = new List(); for (int i = 0; i < 32; i++) { string text = LayerMask.LayerToName(i); if (!string.IsNullOrEmpty(text)) { list.Add($"{i}:{text}"); } } ManualLogSource log2 = Plugin.Log; val = new BepInExInfoLogInterpolatedStringHandler(8, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("layers: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(string.Join(", ", list)); } log2.LogInfo(val); if ((Object)(object)camera != (Object)null) { ManualLogSource log3 = Plugin.Log; val = new BepInExInfoLogInterpolatedStringHandler(29, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("culling mask 0x"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(camera.cullingMask, "X8"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", "); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("revealing 0x"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(RevealMask(), "X8"); } log3.LogInfo(val); } try { Dictionary dictionary = new Dictionary(); Il2CppReferenceArray componentsInChildren = ((Component)pc).GetComponentsInChildren(Il2CppType.Of(), true); for (int j = 0; j < ((Il2CppArrayBase)(object)componentsInChildren).Length; j++) { Component obj = ((Il2CppArrayBase)(object)componentsInChildren)[j]; Renderer val2 = ((obj != null) ? ((Il2CppObjectBase)obj).TryCast() : null); if (!((Object)(object)val2 == (Object)null)) { int layer = ((Component)val2).gameObject.layer; string text2 = ((Object)((Component)val2).gameObject).name + (val2.enabled ? "" : "(off)") + (((Component)val2).gameObject.activeInHierarchy ? "" : "(inactive)"); dictionary[layer] = (dictionary.TryGetValue(layer, out var value) ? (value + ", " + text2) : text2); } } foreach (KeyValuePair item in dictionary) { string text3 = LayerMask.LayerToName(item.Key); string text4 = (((Object)(object)camera != (Object)null && (camera.cullingMask & (1 << item.Key)) == 0) ? " CULLED" : ""); ManualLogSource log4 = Plugin.Log; val = new BepInExInfoLogInterpolatedStringHandler(11, 4, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("layer "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(item.Key); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(text3); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("'"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(text4); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(item.Value); } log4.LogInfo(val); } } catch (Exception ex) { ManualLogSource log5 = Plugin.Log; BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(31, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("could not list your renderers: "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(ex.Message); } log5.LogWarning(val3); } } private static string Path(Transform t) { string text = ((Object)t).name; Transform parent = t.parent; while ((Object)(object)parent != (Object)null) { text = ((Object)parent).name + "/" + text; parent = parent.parent; } return text; } } [HarmonyPatch] internal static class CameraPatches { private static bool _hookLogged; [HarmonyPrefix] [HarmonyPatch(typeof(PlayerCharacter), "FixedUpdate")] private static void BeforeFixedUpdate() { Safely(ThirdPersonCamera.Restore); } [HarmonyPrefix] [HarmonyPatch(typeof(PlayerCharacter), "Update")] private static void BeforeUpdate() { Safely(ThirdPersonCamera.Restore); } [HarmonyPrefix] [HarmonyPatch(typeof(PlayerCharacter), "LateUpdate")] private static void BeforeLateUpdate() { Safely(ThirdPersonCamera.Restore); } [HarmonyPostfix] [HarmonyPatch(typeof(PlayerCharacter), "LateUpdate")] private static void AfterLateUpdate(PlayerCharacter __instance) { //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Expected O, but got Unknown //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown bool flag2 = default(bool); try { bool flag = ThirdPersonCamera.IsLocal(__instance); if (!_hookLogged) { _hookLogged = true; ManualLogSource log = Plugin.Log; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(41, 2, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("LateUpdate hook is running on '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(((Object)__instance).name); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("', local: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(flag); } log.LogInfo(val); } if (flag) { ThirdPersonCamera.Apply(__instance); } } catch (Exception ex) { ManualLogSource log2 = Plugin.Log; BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(56, 1, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("third person camera failed, going back to first person: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex); } log2.LogError(val2); Plugin.Mode.Value = ViewMode.FirstPerson; Safely(ThirdPersonCamera.Reset); } } private static void Safely(Action action) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Expected O, but got Unknown try { action(); } catch (Exception ex) { ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(29, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("third person restore failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex); } log.LogError(val); } } } }