using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using FirstPersonView.Compat; using GameNetcodeStuff; using HarmonyLib; using Microsoft.CodeAnalysis; using MoreCompany.Cosmetics; using TooManyEmotes; using TooManyEmotes.Patches; using Unity.Netcode; using UnityEngine; using UnityEngine.Rendering; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: IgnoresAccessChecksTo("AmazingAssets.TerrainToMesh")] [assembly: IgnoresAccessChecksTo("Assembly-CSharp-firstpass")] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: IgnoresAccessChecksTo("ClientNetworkTransform")] [assembly: IgnoresAccessChecksTo("com.olegknyazev.softmask")] [assembly: IgnoresAccessChecksTo("DissonanceVoip")] [assembly: IgnoresAccessChecksTo("DunGen")] [assembly: IgnoresAccessChecksTo("DunGen.Integration.ASPP")] [assembly: IgnoresAccessChecksTo("DunGen.Integration.UnityNav")] [assembly: IgnoresAccessChecksTo("EasyTextEffects")] [assembly: IgnoresAccessChecksTo("Facepunch Transport for Netcode for GameObjects")] [assembly: IgnoresAccessChecksTo("Facepunch.Steamworks.Win64")] [assembly: IgnoresAccessChecksTo("Unity.AI.Navigation")] [assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging")] [assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging.DocCodeExamples")] [assembly: IgnoresAccessChecksTo("Unity.Burst")] [assembly: IgnoresAccessChecksTo("Unity.Burst.Unsafe")] [assembly: IgnoresAccessChecksTo("Unity.Collections")] [assembly: IgnoresAccessChecksTo("Unity.Collections.LowLevel.ILSupport")] [assembly: IgnoresAccessChecksTo("Unity.InputSystem")] [assembly: IgnoresAccessChecksTo("Unity.InputSystem.ForUI")] [assembly: IgnoresAccessChecksTo("Unity.Jobs")] [assembly: IgnoresAccessChecksTo("Unity.Mathematics")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.Common")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.MetricTypes")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStats")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Component")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Configuration")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Implementation")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsReporting")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkProfiler.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkSolutionInterface")] [assembly: IgnoresAccessChecksTo("Unity.Netcode.Components")] [assembly: IgnoresAccessChecksTo("Unity.Netcode.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.Networking.Transport")] [assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Csg")] [assembly: IgnoresAccessChecksTo("Unity.ProBuilder")] [assembly: IgnoresAccessChecksTo("Unity.ProBuilder.KdTree")] [assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Poly2Tri")] [assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Stl")] [assembly: IgnoresAccessChecksTo("Unity.Profiling.Core")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.ShaderLibrary")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Config.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary")] [assembly: IgnoresAccessChecksTo("Unity.Services.Authentication")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Analytics")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Components")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Configuration")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Device")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments.Internal")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Internal")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Networking")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Registration")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Scheduler")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Telemetry")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Threading")] [assembly: IgnoresAccessChecksTo("Unity.Services.QoS")] [assembly: IgnoresAccessChecksTo("Unity.Services.Relay")] [assembly: IgnoresAccessChecksTo("Unity.TextMeshPro")] [assembly: IgnoresAccessChecksTo("Unity.Timeline")] [assembly: IgnoresAccessChecksTo("Unity.VisualEffectGraph.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.XR.CoreUtils")] [assembly: IgnoresAccessChecksTo("Unity.XR.Management")] [assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR")] [assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.ConformanceAutomation")] [assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.MetaQuestSupport")] [assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.MockRuntime")] [assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.OculusQuestSupport")] [assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.RuntimeDebugger")] [assembly: IgnoresAccessChecksTo("UnityEngine.ARModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.NVIDIAModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.SpatialTracking")] [assembly: IgnoresAccessChecksTo("UnityEngine.UI")] [assembly: IgnoresAccessChecksTo("UnityEngine.XR.LegacyInputHelpers")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("FirstPersonView")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("Lets players see their own body.")] [assembly: AssemblyFileVersion("1.4.1.0")] [assembly: AssemblyInformationalVersion("1.4.1+8ac111ffd6c74d21a9b2d8a3473f4c5fe6b4ba07")] [assembly: AssemblyProduct("FirstPersonView")] [assembly: AssemblyTitle("FirstPersonView")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.4.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.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [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 FirstPersonView { internal static class CameraRig { public static void ApplyOffset(LocalBodyState state, PlayerControllerB player) { //IL_003f: 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_0044: 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_004b: 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_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: 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_0084: 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_0094: 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_00a3: 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_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_01fc: Unknown result type (might be due to invalid IL or missing references) //IL_0201: Unknown result type (might be due to invalid IL or missing references) //IL_0202: Unknown result type (might be due to invalid IL or missing references) //IL_02ba: Unknown result type (might be due to invalid IL or missing references) //IL_02bf: Unknown result type (might be due to invalid IL or missing references) //IL_02b1: Unknown result type (might be due to invalid IL or missing references) //IL_02c4: Unknown result type (might be due to invalid IL or missing references) //IL_02c8: Unknown result type (might be due to invalid IL or missing references) //IL_02ca: Unknown result type (might be due to invalid IL or missing references) //IL_02ce: Unknown result type (might be due to invalid IL or missing references) //IL_02d3: Unknown result type (might be due to invalid IL or missing references) //IL_02d5: Unknown result type (might be due to invalid IL or missing references) //IL_02d7: Unknown result type (might be due to invalid IL or missing references) //IL_02d9: Unknown result type (might be due to invalid IL or missing references) //IL_02de: Unknown result type (might be due to invalid IL or missing references) //IL_02e0: Unknown result type (might be due to invalid IL or missing references) //IL_02e2: Unknown result type (might be due to invalid IL or missing references) //IL_02f2: 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_02fd: Unknown result type (might be due to invalid IL or missing references) //IL_02ff: Unknown result type (might be due to invalid IL or missing references) //IL_031d: Unknown result type (might be due to invalid IL or missing references) //IL_031f: Unknown result type (might be due to invalid IL or missing references) //IL_0334: Unknown result type (might be due to invalid IL or missing references) //IL_0336: Unknown result type (might be due to invalid IL or missing references) //IL_033a: Unknown result type (might be due to invalid IL or missing references) //IL_033f: Unknown result type (might be due to invalid IL or missing references) //IL_0344: Unknown result type (might be due to invalid IL or missing references) //IL_0348: Unknown result type (might be due to invalid IL or missing references) //IL_034d: Unknown result type (might be due to invalid IL or missing references) //IL_0352: Unknown result type (might be due to invalid IL or missing references) //IL_0354: Unknown result type (might be due to invalid IL or missing references) //IL_0356: Unknown result type (might be due to invalid IL or missing references) //IL_0359: Unknown result type (might be due to invalid IL or missing references) //IL_035e: Unknown result type (might be due to invalid IL or missing references) //IL_0361: Unknown result type (might be due to invalid IL or missing references) //IL_0377: Unknown result type (might be due to invalid IL or missing references) //IL_0379: Unknown result type (might be due to invalid IL or missing references) //IL_0372: Unknown result type (might be due to invalid IL or missing references) //IL_037e: Unknown result type (might be due to invalid IL or missing references) Camera gameplayCamera = state.GameplayCamera; if (!((Object)(object)gameplayCamera == (Object)null) && state.CameraBaseCaptured) { state.VehiclePushApplied = false; Transform transform = ((Component)gameplayCamera).transform; Transform parent = transform.parent; Vector3 val = (((Object)(object)parent != (Object)null) ? parent.up : Vector3.up); Vector3 val2 = Vector3.ProjectOnPlane(transform.forward, val); if (((Vector3)(ref val2)).sqrMagnitude < 1E-05f) { val2 = Vector3.ProjectOnPlane(((Component)player).transform.forward, val); } val2 = ((!(((Vector3)(ref val2)).sqrMagnitude < 1E-05f)) ? ((Vector3)(ref val2)).normalized : (((Object)(object)parent != (Object)null) ? parent.forward : Vector3.forward)); Vector3 val3 = Vector3.Cross(val, val2); Quaternion yawRotation = Quaternion.LookRotation(val2, val); CameraBlends blends = state.Blends; blends.Crouch = Mathf.MoveTowards(blends.Crouch, player.isCrouching ? 1f : 0f, Time.deltaTime / 0.15f); blends.ShovelSwing = Mathf.MoveTowards(blends.ShovelSwing, Players.IsSwingingShovelLike(player) ? 1f : 0f, Time.deltaTime / 0.18f); blends.Run = Mathf.MoveTowards(blends.Run, player.isSprinting ? 1f : 0f, Time.deltaTime / 0.18f); blends.Walk = Mathf.MoveTowards(blends.Walk, (player.isWalking && !player.isSprinting) ? 1f : 0f, Time.deltaTime / 0.18f); blends.Jump = Mathf.MoveTowards(blends.Jump, (player.isJumping || player.isFallingFromJump) ? 1f : 0f, Time.deltaTime / 0.18f); blends.Ladder = Mathf.MoveTowards(blends.Ladder, player.isClimbingLadder ? 1f : 0f, Time.deltaTime / 0.08f); float num = Vector3.Dot(transform.forward, -val); float num2 = Mathf.SmoothStep(0f, 1f, Mathf.InverseLerp(0.08f, 0.95f, num)); float num3 = (player.inVehicleAnimation ? 0.13f : 0.13f); float num4 = Mathf.Max(blends.Ladder * 0.12f, Mathf.Max(blends.ShovelSwing * 0.12f, Mathf.Max(blends.Run * 0.12f, Mathf.Max(blends.Walk * 0.02f, blends.Jump * 0.12f)))); float num5 = num2 * (num3 + num4); Vector3 val4 = (((Object)(object)parent != (Object)null) ? parent.TransformPoint(state.CameraBaseLocalPosition) : state.CameraBaseLocalPosition); Vector3 val5 = FollowBodyAnchor(state, player, val4, yawRotation, num); Vector3 val6 = val5 - val4; float num6 = Vector3.Dot(val6, val2); float num7 = num6 + num5; float num8 = Vector3.Dot(val6, val3); float totalUp = Vector3.Dot(val6, val); if (!player.inSpecialInteractAnimation) { num7 = Mathf.Max(num7, 0f); } num7 = ClampTravelToWall(val4, val2, num7, 0.05f, 0f); Vector3 horizontalPoint = val4 + val2 * num7 + val3 * num8; Vector3 val7 = (transform.position = ResolveVerticalClearance(horizontalPoint, val, totalUp)); state.LastCameraTargetLocal = (((Object)(object)parent != (Object)null) ? parent.InverseTransformPoint(val7) : val7); state.HasCameraTarget = true; state.CameraOffsetApplied = true; } } public static void PrepareVehicleDetach(LocalBodyState state) { state.CameraOffsetApplied = false; state.HasCameraTarget = false; state.NeckGuard.Initialized = false; } public static void ApplyVehiclePush(LocalBodyState state) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0035: 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_003c: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0097: 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_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) Camera gameplayCamera = state.GameplayCamera; if ((Object)(object)gameplayCamera == (Object)null) { return; } Transform transform = ((Component)gameplayCamera).transform; Transform parent = transform.parent; Vector3 val = (((Object)(object)parent != (Object)null) ? parent.up : Vector3.up); float num = Vector3.Dot(transform.forward, -val); float num2 = Mathf.SmoothStep(0f, 1f, Mathf.InverseLerp(0.08f, 0.95f, num)); Vector3 val2 = default(Vector3); ((Vector3)(ref val2))..ctor(0f, 0f, num2 * 0.26f); Vector3 localPosition = transform.localPosition; Vector3 val4; if (state.VehiclePushApplied) { Vector3 val3 = localPosition - state.VehiclePushResult; if (((Vector3)(ref val3)).sqrMagnitude < 1E-08f) { val4 = localPosition - state.VehiclePush; goto IL_00cb; } } val4 = localPosition; goto IL_00cb; IL_00cb: Vector3 val5 = val4; Vector3 vehiclePushResult = (transform.localPosition = val5 + val2); state.VehiclePush = val2; state.VehiclePushResult = vehiclePushResult; state.VehiclePushApplied = true; } public static void RelaxSeatedLookClamp(PlayerControllerB player) { if (player.isPlayerControlled && !player.isPlayerDead) { if (player.clampLooking && !player.inSpecialInteractAnimation) { player.clampLooking = false; player.inVehicleAnimation = false; } else if (player.clampLooking && player.minVerticalClamp < 75f) { player.minVerticalClamp = 75f; } } } public static void AlignForInteractionRay(LocalBodyState state) { //IL_003e: 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_0035: Unknown result type (might be due to invalid IL or missing references) if (state.HasCameraTarget && !((Object)(object)state.GameplayCamera == (Object)null)) { Transform transform = ((Component)state.GameplayCamera).transform; Transform parent = transform.parent; transform.position = (((Object)(object)parent != (Object)null) ? parent.TransformPoint(state.LastCameraTargetLocal) : state.LastCameraTargetLocal); } } public static void ApplyArmAnchor(PlayerControllerB player, bool useVanillaArms) { //IL_0046: 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_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_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) if (!useVanillaArms || player.inSpecialInteractAnimation) { return; } Transform localArmsTransform = player.localArmsTransform; Camera gameplayCamera = player.gameplayCamera; Transform cameraContainerTransform = player.cameraContainerTransform; if (!((Object)(object)localArmsTransform == (Object)null) && !((Object)(object)gameplayCamera == (Object)null) && !((Object)(object)cameraContainerTransform == (Object)null)) { Transform transform = ((Component)gameplayCamera).transform; localArmsTransform.position += transform.position - cameraContainerTransform.position; float value = ConfigManager.HandOffsetZ.Value; if (value != 0f) { localArmsTransform.position += transform.forward * value; } } } private static Vector3 FollowBodyAnchor(LocalBodyState state, PlayerControllerB player, Vector3 baseWorld, Quaternion yawRotation, float lookDown) { //IL_0010: 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_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: 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_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_0048: 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_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: 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_0138: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_011f: 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) //IL_0128: 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) //IL_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_01c4: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: 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_01b2: 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_01e3: 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_01ec: 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_01e0: Unknown result type (might be due to invalid IL or missing references) Transform headBone = state.HeadBone; if ((Object)(object)headBone == (Object)null) { return baseWorld; } EyeAnchorState eyeAnchor = state.EyeAnchor; if (!eyeAnchor.Captured && !player.isCrouching) { eyeAnchor.Local = Quaternion.Inverse(yawRotation) * (baseWorld - headBone.position); eyeAnchor.BoneLocal = headBone.InverseTransformPoint(baseWorld); eyeAnchor.Drift = Vector3.zero; eyeAnchor.Captured = true; } if (!eyeAnchor.Captured) { return baseWorld; } if (TooManyEmotesCompat.IsFirstPersonEmoteActive()) { return headBone.TransformPoint(eyeAnchor.BoneLocal); } CameraBlends blends = state.Blends; bool flag = ConfigManager.StickCameraToHeadInAnimations.Value && IsInteractTriggerAnimation(player); blends.StickToHead = Mathf.MoveTowards(blends.StickToHead, flag ? 1f : 0f, Time.deltaTime / 0.12f); Vector3 val = headBone.position + yawRotation * eyeAnchor.Local; Vector3 val2 = Quaternion.Inverse(yawRotation) * (val - baseWorld); if (IsEyeAnchorSettled(state, player, lookDown)) { float num = 1f - Mathf.Exp((0f - Time.deltaTime) / 2f); eyeAnchor.Drift = Vector3.Lerp(eyeAnchor.Drift, val2, num); } WarnOnPersistentDrift(eyeAnchor); Vector3 val3 = val2 - eyeAnchor.Drift; val3.x *= 1f; val3.z *= 1f; val3.y *= 1f; val3.y = DampHeadBob(state, player, val3.y); val3 = StabilizeSprintBob(state, player, val3); val3 = NeckGuardedFollow(state, player, val3); if (((Vector3)(ref val3)).sqrMagnitude > 0.25f) { val3 = ((Vector3)(ref val3)).normalized * 0.5f; } Vector3 val4 = baseWorld + yawRotation * val3; if (blends.StickToHead <= 0f) { return val4; } return Vector3.Lerp(val4, headBone.TransformPoint(eyeAnchor.BoneLocal), blends.StickToHead); } private static bool IsInteractTriggerAnimation(PlayerControllerB player) { if (player.inSpecialInteractAnimation && (Object)(object)player.currentTriggerInAnimationWith != (Object)null && !player.isClimbingLadder && !player.inVehicleAnimation) { return !player.inShockingMinigame; } return false; } private static void WarnOnPersistentDrift(EyeAnchorState anchor) { if (!anchor.DriftWarned) { float num = 0.06f; if (((Vector3)(ref anchor.Drift)).sqrMagnitude < num * num) { anchor.DriftHighSince = 0f; } else if (anchor.DriftHighSince <= 0f) { anchor.DriftHighSince = Time.unscaledTime; } else if (!(Time.unscaledTime - anchor.DriftHighSince < 5f)) { anchor.DriftWarned = true; Plugin.Log.LogWarning((object)($"Eye anchor drift held at {((Vector3)(ref anchor.Drift)).magnitude:F3}m for over {5f:F0}s. " + "The head bone rest pose does not match the captured anchor, the forward eye offset may be reduced.")); } } } private static bool IsEyeAnchorSettled(LocalBodyState state, PlayerControllerB player, float lookDown) { if (Mathf.Abs(lookDown) <= 0.05f && !player.isWalking && !player.isSprinting && !player.inSpecialInteractAnimation && !player.isCrouching && state.Blends.Crouch <= 0f && !player.isClimbingLadder && !player.isJumping && !player.isFallingFromJump) { return !state.NeckGuard.Engaged; } return false; } private static float DampHeadBob(LocalBodyState state, PlayerControllerB player, float rawY) { BobSmoothing bobSmooth = state.BobSmooth; CameraBlends blends = state.Blends; if (!bobSmooth.YInitialized) { bobSmooth.SmoothedY = rawY; bobSmooth.YInitialized = true; } else { float num = 1f - Mathf.Exp((0f - Time.deltaTime) / 1f); bobSmooth.SmoothedY = Mathf.Lerp(bobSmooth.SmoothedY, rawY, num); } bool flag = player.isWalking || player.isSprinting || player.isJumping || player.isFallingFromJump || player.isClimbingLadder; bool flag2 = !player.isCrouching && blends.Crouch <= 0f && (flag ? ConfigManager.DisableHeadBob.Value : ConfigManager.DisableIdleHeadBob.Value); blends.DisableBob = Mathf.MoveTowards(blends.DisableBob, flag2 ? 1f : 0f, Time.deltaTime / 0.15f); return Mathf.Lerp(rawY, bobSmooth.SmoothedY, blends.DisableBob); } private static Vector3 StabilizeSprintBob(LocalBodyState state, PlayerControllerB player, Vector3 deviationLocal) { //IL_0086: 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_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: 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_005d: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: 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) BobSmoothing bobSmooth = state.BobSmooth; CameraBlends blends = state.Blends; bool flag = player.isSprinting || player.isJumping || player.isFallingFromJump; blends.BobDamp = Mathf.MoveTowards(blends.BobDamp, flag ? 1f : 0f, Time.deltaTime / 0.12f); if (!bobSmooth.DeviationInitialized) { bobSmooth.SmoothedDeviationLocal = deviationLocal; bobSmooth.DeviationInitialized = true; } else { float num = 1f - Mathf.Exp((0f - Time.deltaTime) / 0.2f); bobSmooth.SmoothedDeviationLocal = Vector3.Lerp(bobSmooth.SmoothedDeviationLocal, deviationLocal, num); } float num2 = blends.BobDamp * 0.6f; return Vector3.Lerp(deviationLocal, bobSmooth.SmoothedDeviationLocal, num2); } private static Vector3 NeckGuardedFollow(LocalBodyState state, PlayerControllerB player, Vector3 live) { //IL_0010: 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_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_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0067: 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_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0129: 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_01d8: Unknown result type (might be due to invalid IL or missing references) //IL_01da: Unknown result type (might be due to invalid IL or missing references) //IL_01db: 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_01cd: 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_01e8: Unknown result type (might be due to invalid IL or missing references) //IL_0268: Unknown result type (might be due to invalid IL or missing references) //IL_0250: 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_0204: Unknown result type (might be due to invalid IL or missing references) //IL_028f: 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_0232: Unknown result type (might be due to invalid IL or missing references) //IL_0238: Unknown result type (might be due to invalid IL or missing references) //IL_020d: Unknown result type (might be due to invalid IL or missing references) //IL_0214: Unknown result type (might be due to invalid IL or missing references) //IL_021a: Unknown result type (might be due to invalid IL or missing references) //IL_02af: Unknown result type (might be due to invalid IL or missing references) //IL_029b: Unknown result type (might be due to invalid IL or missing references) //IL_035d: Unknown result type (might be due to invalid IL or missing references) //IL_0378: Unknown result type (might be due to invalid IL or missing references) //IL_0393: Unknown result type (might be due to invalid IL or missing references) //IL_03a3: Unknown result type (might be due to invalid IL or missing references) //IL_03a8: Unknown result type (might be due to invalid IL or missing references) //IL_03b4: Unknown result type (might be due to invalid IL or missing references) //IL_03b9: Unknown result type (might be due to invalid IL or missing references) //IL_03bf: Unknown result type (might be due to invalid IL or missing references) NeckGuardState neckGuard = state.NeckGuard; if (!neckGuard.Initialized) { neckGuard.SwingRest = live; neckGuard.EyeDeviation = live; neckGuard.EyeVelocity = Vector3.zero; neckGuard.Tail = 0f; neckGuard.Release = 0f; neckGuard.Latched = false; neckGuard.WasSwinging = false; neckGuard.Engaged = false; neckGuard.FloorActive = false; neckGuard.CrouchRestZ = live.z; neckGuard.CrouchRestY = live.y; neckGuard.Initialized = true; return live; } bool flag = player.isCrouching && player.activatingItem; if (flag && !neckGuard.WasSwinging) { neckGuard.Latched = state.Blends.Crouch >= 0.9f; } neckGuard.WasSwinging = flag; if (flag) { neckGuard.Tail = 0.6f; } else if (neckGuard.Tail > 0f) { neckGuard.Tail -= Time.deltaTime; } bool flag2 = flag || neckGuard.Tail > 0f; bool flag3 = neckGuard.Latched && player.isCrouching && flag2; if (player.isCrouching && !flag2) { neckGuard.CrouchRestZ = live.z; neckGuard.CrouchRestY = live.y; } bool flag4 = flag2 && player.isCrouching && !neckGuard.Latched; if (flag4 && !neckGuard.FloorActive) { neckGuard.FloorZ = Mathf.Max(neckGuard.CrouchRestZ, 0.35f); neckGuard.FloorActive = true; } else if (!flag4) { neckGuard.FloorActive = false; } if (neckGuard.Engaged && !flag3 && !flag4) { neckGuard.Release = 0.8f; } else if (neckGuard.Release > 0f) { neckGuard.Release -= Time.deltaTime; } neckGuard.Engaged = flag3 || flag4; if (!flag3) { neckGuard.SwingRest = live; } Vector3 swingRest = neckGuard.SwingRest; Vector3 val = live; if (flag3) { val.z = Mathf.Max(live.z, swingRest.z); if (flag) { val.y = ((live.y >= swingRest.y) ? (swingRest.y + (live.y - swingRest.y) * 1f) : (swingRest.y + (live.y - swingRest.y) * 0f)); } else { val.y = swingRest.y; } } else if (neckGuard.FloorActive) { val.z = Mathf.Max(live.z, neckGuard.FloorZ); float crouchRestY = neckGuard.CrouchRestY; val.y = ((!flag) ? crouchRestY : ((live.y >= crouchRestY) ? (crouchRestY + (live.y - crouchRestY) * 1f) : (crouchRestY + (live.y - crouchRestY) * 0f))); } bool flag5 = flag3 || (flag2 && player.isCrouching); float num = (flag5 ? 0.12f : ((!(neckGuard.Release > 0f)) ? 0.015f : Mathf.Lerp(0.015f, 0.12f, neckGuard.Release / 0.8f))); float num2 = (flag5 ? 0.12f : 0.015f); float x = neckGuard.EyeVelocity.x; float y = neckGuard.EyeVelocity.y; float z = neckGuard.EyeVelocity.z; neckGuard.EyeDeviation = new Vector3(Mathf.SmoothDamp(neckGuard.EyeDeviation.x, val.x, ref x, num), Mathf.SmoothDamp(neckGuard.EyeDeviation.y, val.y, ref y, num2), Mathf.SmoothDamp(neckGuard.EyeDeviation.z, val.z, ref z, num)); neckGuard.EyeVelocity = new Vector3(x, y, z); return neckGuard.EyeDeviation; } private static float ClampTravelToWall(Vector3 origin, Vector3 dir, float distance, float radius, float margin) { //IL_0019: 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) StartOfRound instance = StartOfRound.Instance; if ((Object)(object)instance == (Object)null || distance <= 0f) { return distance; } RaycastHit val = default(RaycastHit); if (Physics.SphereCast(origin, Mathf.Max(0.01f, radius), dir, ref val, distance + margin, instance.collidersAndRoomMask, (QueryTriggerInteraction)1)) { return Mathf.Max(0f, ((RaycastHit)(ref val)).distance - margin); } return distance; } private static Vector3 ResolveVerticalClearance(Vector3 horizontalPoint, Vector3 up, float totalUp) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: 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_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_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) Vector3 val = ((totalUp >= 0f) ? up : (-up)); float num = ClampTravelToWall(horizontalPoint, val, Mathf.Abs(totalUp), 0.1f, 0f); return horizontalPoint + val * num; } public static void RestoreOffset(LocalBodyState state) { //IL_0057: Unknown result type (might be due to invalid IL or missing references) state.Blends.Reset(); state.BobSmooth.Reset(); state.NeckGuard.Reset(); state.HasCameraTarget = false; state.VehiclePushApplied = false; if (state.CameraOffsetApplied) { Camera gameplayCamera = state.GameplayCamera; if ((Object)(object)gameplayCamera != (Object)null && state.CameraBaseCaptured) { ((Component)gameplayCamera).transform.localPosition = state.CameraBaseLocalPosition; } state.CameraOffsetApplied = false; } } } internal static class VisorRig { private static bool? immersiveVisorPresent; public static bool IsImmersiveVisorPresent() { bool valueOrDefault = immersiveVisorPresent == true; if (!immersiveVisorPresent.HasValue) { valueOrDefault = Chainloader.PluginInfos.ContainsKey("ImmersiveVisor"); immersiveVisorPresent = valueOrDefault; } return immersiveVisorPresent.Value; } public static void StickToCamera(LocalBodyState state) { if (!state.VisorReparented) { Transform localVisor = state.LocalVisor; Camera gameplayCamera = state.GameplayCamera; if (!((Object)(object)localVisor == (Object)null) && !((Object)(object)gameplayCamera == (Object)null)) { localVisor.SetParent(((Component)gameplayCamera).transform, true); state.VisorReparented = true; } } } public static void Restore(LocalBodyState state) { if (state.VisorReparented) { if ((Object)(object)state.LocalVisor != (Object)null && state.VisorOriginalParentCaptured) { state.LocalVisor.SetParent(state.VisorOriginalParent, true); } state.VisorReparented = false; } } public static void SuppressVanillaCrack(LocalBodyState state, bool hide) { if (hide == state.CrackHidden) { return; } if (state.CrackRenderers == null) { GameObject val = (((Object)(object)HUDManager.Instance != (Object)null) ? HUDManager.Instance.visorCracksObject : null); if ((Object)(object)val == (Object)null) { return; } state.CrackRenderers = val.GetComponentsInChildren(true); } Renderer[] crackRenderers = state.CrackRenderers; foreach (Renderer val2 in crackRenderers) { if ((Object)(object)val2 != (Object)null) { val2.enabled = !hide; } } state.CrackHidden = hide; } } public static class ConfigManager { public static ConfigEntry HeldItemFadeStyle; public static ConfigEntry Hands; public static ConfigEntry VanillaArmsWhileSprinting; public static ConfigEntry VanillaArmsWhileCrouching; public static ConfigEntry VanillaArmsWhileJumping; public static ConfigEntry VanillaArmsWhileWalking; public static ConfigEntry VanillaArmsWhileEmoting; public static ConfigEntry VanillaArmsNearWall; public static ConfigEntry ItemDither; public static ConfigEntry HandOffsetZ; public static ConfigEntry DisableHeadBob; public static ConfigEntry DisableIdleHeadBob; public static ConfigEntry StickCameraToHeadInAnimations; public static ConfigEntry EnableMoreCompanyCompatibility; public static ConfigEntry EnableTooManyEmotesCompatibility; public static ConfigEntry EnableLethalPhonesCompatibility; public static ConfigEntry EnableCruiserImprovedCompatibility; public static ConfigEntry ShowMoreCompanyHat; public static ConfigEntry ShowMoreCompanyChest; public static ConfigEntry ShowMoreCompanyHip; public static ConfigEntry ShowMoreCompanyRightLowerArm; public static ConfigEntry ShowMoreCompanyLeftShin; public static ConfigEntry ShowMoreCompanyRightShin; internal static void Initialize(ConfigFile config) { //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Expected O, but got Unknown EnableMoreCompanyCompatibility = config.Bind("1. Compatibility", "Enable MoreCompany Compatibility", true, "Show your MoreCompany cosmetics in first person when MoreCompany is installed."); EnableTooManyEmotesCompatibility = config.Bind("1. Compatibility", "Enable TooManyEmotes Compatibility", true, "Keep the camera on your head during a TooManyEmotes first-person emote."); EnableLethalPhonesCompatibility = config.Bind("1. Compatibility", "Enable LethalPhones Compatibility", true, "Show your hands holding a LethalPhones phone."); EnableCruiserImprovedCompatibility = config.Bind("1. Compatibility", "Enable CruiserImproved Compatibility", false, "Allows CruiserImproveds lean and seat boost to work. Not recommended as you will slightly start to see your bodies neck on leaning and camera is pushed more forward"); ShowMoreCompanyHat = config.Bind("1. Compatibility", "ShowHat", false, "Show hat cosmetics. False by default to prevent hats from clipping into the camera."); ShowMoreCompanyChest = config.Bind("1. Compatibility", "ShowChest", true, "Show chest cosmetics."); ShowMoreCompanyHip = config.Bind("1. Compatibility", "ShowHip", true, "Show hip cosmetics."); ShowMoreCompanyRightLowerArm = config.Bind("1. Compatibility", "ShowRightLowerArm", true, "Show right lower arm cosmetics."); ShowMoreCompanyLeftShin = config.Bind("1. Compatibility", "ShowLeftShin", true, "Show left shin cosmetics."); ShowMoreCompanyRightShin = config.Bind("1. Compatibility", "ShowRightShin", true, "Show right shin cosmetics."); HeldItemFadeStyle = config.Bind("2. Held Item", "FadeMode", HeldItemFadeMode.Dither, "Held item will start to dither when it is close to or filling the players camera. Dither: a fade that lets you see through the item. Off: nothing dithers."); ItemDither = config.Bind("2. Held Item", "ItemDither", ItemDitherMode.ThirdPerson, "Which hands mode the held item dithers in."); HandOffsetZ = config.Bind("2. Held Item", "HandOffsetZ", 0f, new ConfigDescription("First-person hand offset.", (AcceptableValueBase)(object)new AcceptableValueRange(-1f, 1f), Array.Empty())); Hands = config.Bind("3. Hands", "HandsMode", HandsMode.Vanilla, "Which arms hold an item in first person. Vanilla: real first-person arms that aim the item with the camera [ recommended ]. ThirdPerson: the body own arms hold the item, more consistent body, but with known issues."); VanillaArmsWhileSprinting = config.Bind("3. Hands", "Vanilla Arms While Sprinting", true, "Show vanilla first-person arms while sprinting."); VanillaArmsWhileCrouching = config.Bind("3. Hands", "Vanilla Arms While Crouching", true, "Show vanilla first-person arms while crouching."); VanillaArmsWhileJumping = config.Bind("3. Hands", "Vanilla Arms While Jumping", true, "Show vanilla first-person arms while jumping or falling."); VanillaArmsWhileWalking = config.Bind("3. Hands", "Vanilla Arms While Walking", true, "Show vanilla first-person arms while walking."); VanillaArmsWhileEmoting = config.Bind("3. Hands", "Vanilla Arms While Emoting", true, "Show vanilla first-person arms while performing an emote (dance, point)."); VanillaArmsNearWall = config.Bind("3. Hands", "Vanilla Arms Near Wall", true, "Show vanilla first-person arms when a wall is close and the body extends its hands."); DisableHeadBob = config.Bind("4. Camera", "DisableHeadBob", true, "Disable head bobbing from walking and running animations."); DisableIdleHeadBob = config.Bind("4. Camera", "DisableIdleHeadBob", false, "Disable up and down from the idle breathing animation while standing still."); StickCameraToHeadInAnimations = config.Bind("4. Camera", "StickCameraToHeadInAnimations", true, "Put the camera on your head during interact animations like the ship lever, item charging and chairs, the way vanilla does."); } } internal static class Constants { public const string ScavengerModelName = "ScavengerModel"; public const string MetarigName = "metarig"; public const string HeadBoneName = "spine.004"; public const string LeftArmBoneName = "arm.L_upper"; public const string RightArmBoneName = "arm.R_upper"; public const int EnemiesNotRenderedLayer = 23; public static readonly string[] HeadBoneNameHints = new string[4] { "head", "helmet", "visor", "spine.004" }; public const float HeadStrongInfluenceThreshold = 0.35f; public const float HeadAverageInfluenceThreshold = 0.3f; public const float PipeCullBehindThreshold = 0f; public const float CrouchBlendTime = 0.15f; public const float LadderBlendTime = 0.08f; public const float BobDampBlendTime = 0.12f; public const float BobStabilizeTau = 0.2f; public const float DisableHeadBobTau = 1f; public const float DisableHeadBobBlendTime = 0.15f; public const float ArmSwapEngageDelay = 0.05f; public const float ArmSwapReleaseDelay = 0.25f; public const float NeckGuardCalmTau = 0.015f; public const float NeckGuardSwingTau = 0.12f; public const float NeckGuardSwingTail = 0.6f; public const float NeckGuardReleaseRamp = 0.8f; public const float NeckGuardUpFollow = 1f; public const float NeckGuardDownFollow = 0f; public const float NeckGuardCrouchSettled = 0.9f; public const float NeckGuardCrouchFloor = 0.35f; public const float EyeAnchorDriftTau = 2f; public const float EyeAnchorSettledLookBand = 0.05f; public const float EyeAnchorDriftWarnThreshold = 0.06f; public const float EyeAnchorDriftWarnDelay = 5f; public const float StickToHeadBlendTime = 0.12f; public const float VehiclePushMatchEpsilonSqr = 1E-08f; public const float FollowStrengthVertical = 1f; public const float FollowStrengthHorizontal = 1f; public const float SprintBobReduction = 0.6f; public const float MaxFollowOffset = 0.5f; public const float EyeForwardFloor = 0f; public const float ShovelSwingBlendTime = 0.18f; public const float RunningBlendTime = 0.18f; public const float WalkingBlendTime = 0.18f; public const float JumpingBlendTime = 0.18f; public const float WallCollisionRadius = 0.1f; public const float WallCollisionForwardProbeRadius = 0.05f; public const float WallCollisionForwardMargin = 0f; public const float LookDownEyeOffsetForward = 0.13f; public const float LookDownCruiserImprovedEyeOffsetForward = 0.26f; public const float LookDownForwardStart = 0.08f; public const float LookDownForwardFull = 0.95f; public const float LookDownShovelSwingEyeOffsetForward = 0.12f; public const float LookDownRunningEyeOffsetForward = 0.12f; public const float LookDownWalkingEyeOffsetForward = 0.02f; public const float LookDownJumpingEyeOffsetForward = 0.12f; public const float LookDownLadderEyeOffsetForward = 0.12f; public const float LookDownCruiserEyeOffsetForward = 0.13f; public const float HeldItemFadeStartDistance = 0.35f; public const float HeldItemFadeEndDistance = 0.1f; public const float HeldItemCoverageFadeStart = 0.45f; public const float HeldItemCoverageFadeFull = 0.6f; public const float HeldItemMinFade = 0.11f; public const float HeldItemFadeSmoothTime = 0.08f; public const float SeatedLookDownClamp = 75f; public static readonly Vector3 CruiserKeyPositionOffset = new Vector3(0f, 0f, -0.05f); public static readonly Vector3 CruiserKeyRotationOffset = Vector3.zero; } public enum HandsMode { Vanilla, ThirdPerson } public enum HeldItemFadeMode { Dither, Off } [Flags] public enum ItemDitherMode { Vanilla = 1, ThirdPerson = 2 } internal sealed class CameraBlends { public float Crouch; public float Ladder; public float BobDamp; public float ShovelSwing; public float Run; public float Walk; public float Jump; public float DisableBob; public float StickToHead; public void Reset() { Crouch = 0f; Ladder = 0f; BobDamp = 0f; ShovelSwing = 0f; Run = 0f; Walk = 0f; Jump = 0f; DisableBob = 0f; StickToHead = 0f; } } internal sealed class BobSmoothing { public Vector3 SmoothedDeviationLocal; public bool DeviationInitialized; public float SmoothedY; public bool YInitialized; public void Reset() { //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) SmoothedDeviationLocal = Vector3.zero; DeviationInitialized = false; SmoothedY = 0f; YInitialized = false; } } internal sealed class NeckGuardState { public Vector3 SwingRest; public Vector3 EyeDeviation; public Vector3 EyeVelocity; public float Tail; public float Release; public float FloorZ; public float CrouchRestZ; public float CrouchRestY; public bool FloorActive; public bool Initialized; public bool Latched; public bool WasSwinging; public bool Engaged; public void Reset() { //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_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) SwingRest = Vector3.zero; EyeDeviation = Vector3.zero; EyeVelocity = Vector3.zero; Tail = 0f; Release = 0f; FloorZ = 0f; CrouchRestZ = 0f; CrouchRestY = 0f; FloorActive = false; Initialized = false; Latched = false; WasSwinging = false; Engaged = false; } } internal sealed class EyeAnchorState { public Vector3 Local; public Vector3 BoneLocal; public Vector3 Drift; public bool Captured; public float DriftHighSince; public bool DriftWarned; } internal sealed class LocalBodyState { public PlayerControllerB Player; public Transform ModelRoot; public Transform? HeadBone; public SkinnedMeshRenderer? BodyRenderer; public Mesh? OriginalBodyMesh; public bool OriginalBodyMeshCaptured; public bool HeadHidden; public SkinnedMeshRenderer? ShadowProxy; public LODGroup? PlayerLodGroup; public int BodyLodIndex = -1; public float BodyLodNextScan; public Transform? LeftArmBone; public Transform? RightArmBone; public Transform? LocalVisor; public Transform? VisorOriginalParent; public bool VisorOriginalParentCaptured; public bool VisorReparented; public Renderer[]? CrackRenderers; public bool CrackHidden; public Camera? GameplayCamera; public Vector3 CameraBaseLocalPosition; public bool CameraBaseCaptured; public bool CameraOffsetApplied; public Vector3 LastCameraTargetLocal; public bool HasCameraTarget; public Vector3 VehiclePush; public Vector3 VehiclePushResult; public bool VehiclePushApplied; public readonly CameraBlends Blends = new CameraBlends(); public readonly BobSmoothing BobSmooth = new BobSmoothing(); public readonly NeckGuardState NeckGuard = new NeckGuardState(); public readonly EyeAnchorState EyeAnchor = new EyeAnchorState(); public bool MovementArmsActive; public float MovementArmsTimer; public Component? LethalPhonesPlayerPhone; } internal static class LocalBodyViewController { private static readonly Dictionary States = new Dictionary(); private static bool renderCallbacksHooked; internal static bool LocalBodyShown; private static readonly HashSet _loggedStageErrors = new HashSet(); private static readonly (Action Apply, Action Restore)[] CameraPasses = new(Action, Action)[3] { (FirstPersonBody.ApplyForCamera, FirstPersonBody.RestoreAfterCamera), (HeldItemView.ApplyForCamera, HeldItemView.RestoreAfterCamera), (MoreCompanyCompat.ApplyForCamera, MoreCompanyCompat.RestoreAfterCamera) }; public static void ResetAllStates() { foreach (LocalBodyState value in States.Values) { FirstPersonBody.RestoreHead(value); VisorRig.Restore(value); CameraRig.RestoreOffset(value); if ((Object)(object)value.ShadowProxy != (Object)null) { Object.Destroy((Object)(object)((Component)value.ShadowProxy).gameObject); } } States.Clear(); LocalBodyShown = false; FirstPersonBody.Reset(); HeldItemView.Reset(); MoreCompanyCompat.Reset(); MeshSurgery.ClearCaches(); if (renderCallbacksHooked) { RenderPipelineManager.beginCameraRendering -= OnBeginCameraRendering; RenderPipelineManager.endCameraRendering -= OnEndCameraRendering; renderCallbacksHooked = false; } } public static void Tick(PlayerControllerB player) { if (!Players.IsLocal(player)) { return; } EnsureRenderCallbacksHooked(); LocalBodyState orCreateState = GetOrCreateState(player); if (NeedsRefresh(orCreateState, player)) { try { RefreshState(orCreateState, player); } catch (Exception ex) { LogStageError("State refresh", ex); return; } } bool flag = (LocalBodyShown = player.isPlayerControlled && !player.isPlayerDead); bool flag2 = false; try { bool flag3 = LethalPhonesCompat.IsLocalPhoneActive(orCreateState, player); flag2 = !player.inSpecialInteractAnimation && (flag3 || (Players.IsActivelyHolding(player) && ConfigManager.Hands.Value == HandsMode.Vanilla)); } catch (Exception ex2) { LogStageError("Holding arms", ex2); } bool flag4 = false; try { if (flag && !Players.IsActivelyHolding(player) && !player.inSpecialInteractAnimation) { flag4 = MovementArmsGate.Update(orCreateState, player, Time.deltaTime); } else { MovementArmsGate.Reset(orCreateState); } } catch (Exception ex3) { LogStageError("Movement arms", ex3); } bool flag5 = flag && (flag2 || flag4); try { FirstPersonBody.ApplyBodyRendering(orCreateState, flag, flag5); FirstPersonBody.ApplyFirstPersonCameraLayer(orCreateState, flag); } catch (Exception ex4) { LogStageError("Body rendering", ex4); } try { HeldItemView.ApplyHolder(orCreateState, player, flag, flag5); } catch (Exception ex5) { LogStageError("Held item", ex5); } try { if (flag) { FirstPersonBody.HideHead(orCreateState, flag5); } else { FirstPersonBody.RestoreHead(orCreateState); } } catch (Exception ex6) { LogStageError("Head hiding", ex6); } try { if (flag && !VisorRig.IsImmersiveVisorPresent()) { VisorRig.StickToCamera(orCreateState); } else { VisorRig.Restore(orCreateState); } VisorRig.SuppressVanillaCrack(orCreateState, VisorRig.IsImmersiveVisorPresent()); } catch (Exception ex7) { LogStageError("Visor", ex7); } try { if (IsInCruiserImprovedSeat(player)) { CameraRig.PrepareVehicleDetach(orCreateState); } else if (flag && !player.inTerminalMenu) { CameraRig.ApplyOffset(orCreateState, player); } else { CameraRig.RestoreOffset(orCreateState); } } catch (Exception ex8) { LogStageError("Camera offset", ex8); } try { CameraRig.ApplyArmAnchor(player, flag5); CameraRig.RelaxSeatedLookClamp(player); } catch (Exception ex9) { LogStageError("Arm anchor", ex9); } try { MoreCompanyCompat.ApplyLocalCosmeticVisibility(player, flag, flag5); } catch (Exception ex10) { LogStageError("MoreCompany cosmetics", ex10); } } private static void LogStageError(string stage, Exception ex) { if (_loggedStageErrors.Add($"{stage}|{ex.GetType()}: {ex.Message}")) { Plugin.Log.LogError((object)$"{stage} failed.\n{ex}"); } } public static void AlignCameraForInteractionRay(PlayerControllerB player) { if (Players.IsLocal(player) && States.TryGetValue(((Object)player).GetInstanceID(), out LocalBodyState value)) { if (IsInCruiserImprovedSeat(player)) { CameraRig.ApplyVehiclePush(value); } else { CameraRig.AlignForInteractionRay(value); } } } private static bool IsInCruiserImprovedSeat(PlayerControllerB player) { if (!ConfigManager.EnableCruiserImprovedCompatibility.Value || !player.inVehicleAnimation) { return false; } InteractTrigger currentTriggerInAnimationWith = player.currentTriggerInAnimationWith; if ((Object)(object)currentTriggerInAnimationWith == (Object)null || (Object)(object)currentTriggerInAnimationWith.overridePlayerParent == (Object)null) { return false; } VehicleController val = default(VehicleController); if (((Component)currentTriggerInAnimationWith.overridePlayerParent).TryGetComponent(ref val)) { return val.vehicleID == 0; } return false; } private static LocalBodyState GetOrCreateState(PlayerControllerB player) { int instanceID = ((Object)player).GetInstanceID(); if (!States.TryGetValue(instanceID, out LocalBodyState value)) { value = new LocalBodyState(); States[instanceID] = value; } return value; } private static bool NeedsRefresh(LocalBodyState state, PlayerControllerB player) { if (!((Object)(object)state.Player != (Object)(object)player) && !((Object)(object)state.ModelRoot == (Object)null) && !((Object)(object)state.HeadBone == (Object)null)) { return (Object)(object)state.BodyRenderer == (Object)null; } return true; } private static void RefreshState(LocalBodyState state, PlayerControllerB player) { state.Player = player; Transform val = ((Component)player).transform.Find("ScavengerModel"); state.ModelRoot = (((Object)(object)val != (Object)null) ? val : ((Component)player).transform); state.HeadBone = FindHeadBone(state.ModelRoot, player); state.LeftArmBone = FindBodyBone(player, "arm.L_upper"); state.RightArmBone = FindBodyBone(player, "arm.R_upper"); state.BodyRenderer = player.thisPlayerModel; state.PlayerLodGroup = ((Component)player).GetComponentInChildren(); state.BodyLodIndex = -1; CaptureOriginalBodyMesh(state); state.LocalVisor = player.localVisor; CaptureVisorOriginalParent(state); state.GameplayCamera = player.gameplayCamera; CaptureCameraBase(state); } private static void CaptureOriginalBodyMesh(LocalBodyState state) { if (!((Object)(object)state.BodyRenderer == (Object)null) && !state.OriginalBodyMeshCaptured && !state.HeadHidden) { Mesh sharedMesh = state.BodyRenderer.sharedMesh; if (!((Object)(object)sharedMesh == (Object)null) && !MeshSurgery.IsGenerated(((Object)sharedMesh).GetInstanceID())) { state.OriginalBodyMesh = sharedMesh; state.OriginalBodyMeshCaptured = true; } } } private static void CaptureVisorOriginalParent(LocalBodyState state) { if (!((Object)(object)state.LocalVisor == (Object)null) && !state.VisorOriginalParentCaptured && !state.VisorReparented) { state.VisorOriginalParent = state.LocalVisor.parent; state.VisorOriginalParentCaptured = true; } } private static void CaptureCameraBase(LocalBodyState state) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)state.GameplayCamera == (Object)null) && !state.CameraBaseCaptured && !state.CameraOffsetApplied) { state.CameraBaseLocalPosition = ((Component)state.GameplayCamera).transform.localPosition; state.CameraBaseCaptured = true; } } private static Transform? FindHeadBone(Transform modelRoot, PlayerControllerB player) { SkinnedMeshRenderer thisPlayerModel = player.thisPlayerModel; if ((Object)(object)thisPlayerModel != (Object)null) { Transform[] bones = thisPlayerModel.bones; foreach (Transform val in bones) { if ((Object)(object)val != (Object)null && NameContains(((Object)val).name, "spine.004")) { return val; } } } return FindFirstByNameContains(modelRoot, "spine.004") ?? FindFirstByNameContains(modelRoot, "head"); } private static Transform? FindBodyBone(PlayerControllerB player, string boneName) { SkinnedMeshRenderer thisPlayerModel = player.thisPlayerModel; if ((Object)(object)thisPlayerModel == (Object)null) { return null; } Transform[] bones = thisPlayerModel.bones; foreach (Transform val in bones) { if ((Object)(object)val != (Object)null && string.Equals(((Object)val).name, boneName, StringComparison.OrdinalIgnoreCase)) { return val; } } return null; } private static Transform? FindFirstByNameContains(Transform root, string token) { Queue queue = new Queue(); queue.Enqueue(root); while (queue.Count > 0) { Transform val = queue.Dequeue(); if (NameContains(((Object)val).name, token)) { return val; } for (int i = 0; i < val.childCount; i++) { queue.Enqueue(val.GetChild(i)); } } return null; } private static bool NameContains(string name, string token) { return name.IndexOf(token, StringComparison.OrdinalIgnoreCase) >= 0; } private static void EnsureRenderCallbacksHooked() { if (!renderCallbacksHooked) { renderCallbacksHooked = true; RenderPipelineManager.beginCameraRendering += OnBeginCameraRendering; RenderPipelineManager.endCameraRendering += OnEndCameraRendering; } } private static void OnBeginCameraRendering(ScriptableRenderContext context, Camera camera) { (Action, Action)[] cameraPasses = CameraPasses; for (int i = 0; i < cameraPasses.Length; i++) { (Action, Action) tuple = cameraPasses[i]; tuple.Item1(camera); } } private static void OnEndCameraRendering(ScriptableRenderContext context, Camera camera) { (Action, Action)[] cameraPasses = CameraPasses; for (int i = 0; i < cameraPasses.Length; i++) { (Action, Action) tuple = cameraPasses[i]; tuple.Item2(camera); } } } internal static class ModGUIDs { public const string MoreCompany = "me.swipez.melonloader.morecompany"; public const string TooManyEmotes = "FlipMods.TooManyEmotes"; public const string ImmersiveVisor = "ImmersiveVisor"; public const string LethalPhones = "LethalPhones"; } internal static class MovementArmsGate { private const float WallWeightThreshold = 0.01f; public static bool Update(LocalBodyState state, PlayerControllerB player, float deltaTime) { bool flag = (ConfigManager.VanillaArmsWhileSprinting.Value && player.isSprinting) || (ConfigManager.VanillaArmsWhileCrouching.Value && player.isCrouching) || (ConfigManager.VanillaArmsWhileJumping.Value && (player.isJumping || player.isFallingFromJump)) || (ConfigManager.VanillaArmsWhileWalking.Value && player.isWalking && !player.isSprinting) || (ConfigManager.VanillaArmsWhileEmoting.Value && player.performingEmote) || (ConfigManager.VanillaArmsNearWall.Value && player.handsOnWallWeight > 0.01f); if (flag == state.MovementArmsActive) { state.MovementArmsTimer = 0f; } else { state.MovementArmsTimer += deltaTime; float num = (flag ? 0.05f : 0.25f); if (state.MovementArmsTimer >= num) { state.MovementArmsActive = flag; state.MovementArmsTimer = 0f; } } return state.MovementArmsActive; } public static void Reset(LocalBodyState state) { state.MovementArmsActive = false; state.MovementArmsTimer = 0f; } } internal static class Players { private static readonly int ReelingUpHash = Animator.StringToHash("reelingUp"); public static bool IsLocal(PlayerControllerB player) { StartOfRound instance = StartOfRound.Instance; if ((Object)(object)instance != (Object)null) { return (Object)(object)instance.localPlayerController == (Object)(object)player; } return false; } public static bool IsActivelyHolding(PlayerControllerB player) { GrabbableObject currentlyHeldObjectServer = player.currentlyHeldObjectServer; if ((Object)(object)currentlyHeldObjectServer != (Object)null && currentlyHeldObjectServer.isHeld && !currentlyHeldObjectServer.isPocketed) { return (Object)(object)currentlyHeldObjectServer.playerHeldBy == (Object)(object)player; } return false; } public static bool IsSwingingShovelLike(PlayerControllerB player) { Animator playerBodyAnimator = player.playerBodyAnimator; if ((Object)(object)playerBodyAnimator != (Object)null && playerBodyAnimator.GetBool(ReelingUpHash)) { return true; } if (player.activatingItem) { return player.currentlyHeldObjectServer is Shovel; } return false; } } [BepInPlugin("com.seeya.firstpersonview", "First-Person View", "1.4.1")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { private readonly Harmony _harmony = new Harmony("com.seeya.firstpersonview"); public static Plugin Instance { get; private set; } public static ManualLogSource Log { get; private set; } internal static Harmony Harmony { get; private set; } private void Awake() { Instance = this; Log = ((BaseUnityPlugin)this).Logger; Harmony = _harmony; Log.LogInfo((object)"Initializing First-Person View"); ConfigManager.Initialize(((BaseUnityPlugin)this).Config); MoreCompanyCompat.Initialize(); TooManyEmotesCompat.Initialize(); LethalPhonesCompat.Initialize(); _harmony.PatchAll(); Log.LogInfo((object)"First-Person View is loaded!"); } } internal static class FirstPersonBody { private static SkinnedMeshRenderer? hideRenderer; private static Mesh? originalMesh; private static Mesh? headlessMesh; private static Mesh? headlessArmlessMesh; private static bool hideArmsInFirstPerson; private static Camera? hideCamera; private static bool hideActive; private static SkinnedMeshRenderer? fpArms; private static bool fpArmsIntended; public static void ApplyBodyRendering(LocalBodyState state, bool showBody, bool useVanillaArms) { //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Invalid comparison between Unknown and I4 //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Invalid comparison between Unknown and I4 //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Invalid comparison between Unknown and I4 PlayerControllerB player = state.Player; if ((Object)(object)player == (Object)null || !player.isPlayerControlled || player.isPlayerDead) { return; } if (showBody) { if ((Object)(object)player.thisPlayerModel != (Object)null) { if (!((Renderer)player.thisPlayerModel).enabled) { ((Renderer)player.thisPlayerModel).enabled = true; } if ((int)((Renderer)player.thisPlayerModel).shadowCastingMode != 1) { ((Renderer)player.thisPlayerModel).shadowCastingMode = (ShadowCastingMode)1; } if ((int)((Renderer)player.thisPlayerModel).motionVectorGenerationMode != 2) { ((Renderer)player.thisPlayerModel).motionVectorGenerationMode = (MotionVectorGenerationMode)2; } } if ((Object)(object)state.PlayerLodGroup != (Object)null) { if (!state.PlayerLodGroup.enabled) { state.PlayerLodGroup.enabled = true; } if ((Object)(object)player.thisPlayerModel != (Object)null && (state.BodyLodIndex < 0 || Time.unscaledTime >= state.BodyLodNextScan)) { state.BodyLodIndex = FindLodIndex(state.PlayerLodGroup, (Renderer)(object)player.thisPlayerModel); state.BodyLodNextScan = Time.unscaledTime + 0.5f; } state.PlayerLodGroup.ForceLOD((state.BodyLodIndex >= 0) ? state.BodyLodIndex : 0); } if ((Object)(object)player.thisPlayerModelLOD1 != (Object)null && ((Renderer)player.thisPlayerModelLOD1).enabled) { ((Renderer)player.thisPlayerModelLOD1).enabled = false; } if ((Object)(object)player.thisPlayerModelLOD2 != (Object)null && ((Renderer)player.thisPlayerModelLOD2).enabled) { ((Renderer)player.thisPlayerModelLOD2).enabled = false; } SetFpArmsEnabled(player, useVanillaArms); } else { if ((Object)(object)player.thisPlayerModel != (Object)null && (int)((Renderer)player.thisPlayerModel).shadowCastingMode != 3) { ((Renderer)player.thisPlayerModel).shadowCastingMode = (ShadowCastingMode)3; } SetFpArmsEnabled(player, enabled: true); } } private static void SetFpArmsEnabled(PlayerControllerB player, bool enabled) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Invalid comparison between Unknown and I4 fpArms = player.thisPlayerModelArms; fpArmsIntended = enabled; if (!((Object)(object)fpArms == (Object)null)) { if ((int)((Renderer)fpArms).motionVectorGenerationMode != 2) { ((Renderer)fpArms).motionVectorGenerationMode = (MotionVectorGenerationMode)2; } if (((Renderer)fpArms).enabled != enabled) { ((Renderer)fpArms).enabled = enabled; } } } private static int FindLodIndex(LODGroup group, Renderer target) { LOD[] lODs = group.GetLODs(); for (int i = 0; i < lODs.Length; i++) { Renderer[] renderers = lODs[i].renderers; for (int j = 0; j < renderers.Length; j++) { if ((Object)(object)renderers[j] == (Object)(object)target) { return i; } } } return 0; } public static void ApplyFirstPersonCameraLayer(LocalBodyState state, bool showBody) { Camera gameplayCamera = state.GameplayCamera; if (!((Object)(object)gameplayCamera == (Object)null)) { int num = 8388608; bool flag = (gameplayCamera.cullingMask & num) != 0; if (showBody && !flag) { gameplayCamera.cullingMask |= num; } else if (!showBody && flag) { gameplayCamera.cullingMask &= ~num; } } } public static void HideHead(LocalBodyState state, bool hideArms) { hideArmsInFirstPerson = hideArms; state.HeadHidden = true; SkinnedMeshRenderer bodyRenderer = state.BodyRenderer; Mesh originalBodyMesh = state.OriginalBodyMesh; if ((Object)(object)bodyRenderer == (Object)null || (Object)(object)originalBodyMesh == (Object)null || (Object)(object)state.HeadBone == (Object)null) { hideActive = false; UpdateShadowProxy(state, active: false); return; } Mesh orCreateHeadlessMesh = MeshSurgery.GetOrCreateHeadlessMesh(originalBodyMesh, bodyRenderer, state.HeadBone); if ((Object)(object)orCreateHeadlessMesh == (Object)null) { hideActive = false; UpdateShadowProxy(state, active: false); return; } if ((Object)(object)bodyRenderer.sharedMesh != (Object)(object)originalBodyMesh) { bodyRenderer.sharedMesh = originalBodyMesh; } headlessArmlessMesh = (hideArms ? MeshSurgery.GetOrCreateHeadlessArmlessMesh(originalBodyMesh, bodyRenderer, state.HeadBone, state.LeftArmBone, state.RightArmBone) : null); hideRenderer = bodyRenderer; originalMesh = originalBodyMesh; headlessMesh = orCreateHeadlessMesh; hideCamera = state.GameplayCamera; hideActive = true; UpdateShadowProxy(state, active: true); } public static void RestoreHead(LocalBodyState state) { hideActive = false; SkinnedMeshRenderer bodyRenderer = state.BodyRenderer; if ((Object)(object)bodyRenderer != (Object)null && (Object)(object)state.OriginalBodyMesh != (Object)null && (Object)(object)bodyRenderer.sharedMesh != (Object)(object)state.OriginalBodyMesh) { bodyRenderer.sharedMesh = state.OriginalBodyMesh; } UpdateShadowProxy(state, active: false); state.HeadHidden = false; } private static void UpdateShadowProxy(LocalBodyState state, bool active) { //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Expected O, but got Unknown //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) if (!active) { if ((Object)(object)state.ShadowProxy != (Object)null) { ((Renderer)state.ShadowProxy).enabled = false; } return; } SkinnedMeshRenderer bodyRenderer = state.BodyRenderer; Mesh originalBodyMesh = state.OriginalBodyMesh; if ((Object)(object)bodyRenderer == (Object)null || (Object)(object)originalBodyMesh == (Object)null) { return; } if ((Object)(object)state.ShadowProxy == (Object)null) { try { GameObject val = new GameObject("FPVHeadShadowProxy"); val.transform.SetParent(((Component)bodyRenderer).transform.parent, false); val.transform.localPosition = ((Component)bodyRenderer).transform.localPosition; val.transform.localRotation = ((Component)bodyRenderer).transform.localRotation; val.transform.localScale = ((Component)bodyRenderer).transform.localScale; SkinnedMeshRenderer val2 = val.AddComponent(); val2.sharedMesh = originalBodyMesh; val2.bones = bodyRenderer.bones; val2.rootBone = bodyRenderer.rootBone; ((Renderer)val2).sharedMaterials = ((Renderer)bodyRenderer).sharedMaterials; ((Renderer)val2).shadowCastingMode = (ShadowCastingMode)3; val2.updateWhenOffscreen = true; state.ShadowProxy = val2; } catch (Exception ex) { Plugin.Log.LogWarning((object)("Failed to create head shadow proxy. " + ex.Message)); return; } } ((Component)state.ShadowProxy).gameObject.layer = ((Component)bodyRenderer).gameObject.layer; if (!((Renderer)state.ShadowProxy).enabled) { ((Renderer)state.ShadowProxy).enabled = true; } } public static void ApplyForCamera(Camera camera) { SkinnedMeshRenderer val = hideRenderer; if (!hideActive || (Object)(object)val == (Object)null) { return; } if ((Object)(object)camera == (Object)(object)hideCamera) { Mesh val2 = ((hideArmsInFirstPerson && (Object)(object)headlessArmlessMesh != (Object)null) ? headlessArmlessMesh : headlessMesh); if ((Object)(object)val2 != (Object)null && (Object)(object)val.sharedMesh != (Object)(object)val2) { val.sharedMesh = val2; } } else if ((Object)(object)originalMesh != (Object)null && (Object)(object)val.sharedMesh != (Object)(object)originalMesh) { val.sharedMesh = originalMesh; } if ((Object)(object)fpArms != (Object)null) { ((Renderer)fpArms).enabled = fpArmsIntended && (Object)(object)camera == (Object)(object)hideCamera; } } public static void RestoreAfterCamera(Camera camera) { if ((Object)(object)fpArms != (Object)null && ((Renderer)fpArms).enabled != fpArmsIntended) { ((Renderer)fpArms).enabled = fpArmsIntended; } SkinnedMeshRenderer val = hideRenderer; if (!((Object)(object)val == (Object)null) && !((Object)(object)originalMesh == (Object)null) && (Object)(object)camera == (Object)(object)hideCamera && (Object)(object)val.sharedMesh != (Object)(object)originalMesh) { val.sharedMesh = originalMesh; } } public static void Reset() { hideActive = false; hideRenderer = null; originalMesh = null; headlessMesh = null; headlessArmlessMesh = null; hideArmsInFirstPerson = false; hideCamera = null; fpArms = null; fpArmsIntended = false; } } internal static class HeldItemView { private const int CoverageGridSize = 16; private static readonly int[] coverageRowMin = new int[16]; private static readonly int[] coverageRowMax = new int[16]; private static GrabbableObject? trackedItem; private static Renderer[] renderers = Array.Empty(); private static MotionVectorGenerationMode[] originalMotionModes = Array.Empty(); private static Material[] materials = Array.Empty(); private static Renderer? boundsSource; private static Vector3[] localVertices = Array.Empty(); private static Camera? camera; private static bool hideActive; private static float fadeCurrent = 1f; public static void ApplyHolder(LocalBodyState state, PlayerControllerB player, bool showBody, bool useVanillaArms) { GrabbableObject currentlyHeldObjectServer = player.currentlyHeldObjectServer; bool flag = Players.IsActivelyHolding(player); bool isInspectingItem = player.IsInspectingItem; if (flag && (Object)(object)currentlyHeldObjectServer != (Object)null) { Transform val = ((useVanillaArms || isInspectingItem || !showBody) ? player.localItemHolder : player.serverItemHolder); if ((Object)(object)val != (Object)null && (Object)(object)currentlyHeldObjectServer.parentObject != (Object)(object)val) { currentlyHeldObjectServer.parentObject = val; } } bool flag2 = DitherEnabled(); GrabbableObject val2 = (flag ? currentlyHeldObjectServer : null); if ((Object)(object)val2 != (Object)(object)trackedItem) { ResetEffect(); RestoreMotionVectors(); trackedItem = val2; renderers = (((Object)(object)val2 != (Object)null) ? ((Component)val2).GetComponentsInChildren() : Array.Empty()); SuppressMotionVectors(); materials = (Material[])(flag2 ? ((Array)MaterialDither.CollectInstancedMaterials(renderers)) : ((Array)Array.Empty())); boundsSource = ResolveBoundsSource(val2, renderers); localVertices = ResolveLocalVertices(boundsSource); } else if (flag2 && materials.Length == 0 && renderers.Length != 0) { materials = MaterialDither.CollectInstancedMaterials(renderers); } camera = state.GameplayCamera; hideActive = showBody && (Object)(object)val2 != (Object)null && !isInspectingItem; } public static void ApplyForCamera(Camera renderingCamera) { if (hideActive && renderers.Length != 0 && DitherEnabled()) { float fade = (((Object)(object)renderingCamera == (Object)(object)camera) ? ComputeFade(renderingCamera) : 1f); ApplyFade(fade); } } private static bool DitherEnabled() { if (ConfigManager.HeldItemFadeStyle.Value == HeldItemFadeMode.Off) { return false; } ItemDitherMode value = ConfigManager.ItemDither.Value; if (ConfigManager.Hands.Value != HandsMode.Vanilla) { return (value & ItemDitherMode.ThirdPerson) != 0; } return (value & ItemDitherMode.Vanilla) != 0; } public static void RestoreAfterCamera(Camera renderingCamera) { if (renderers.Length != 0 && (Object)(object)renderingCamera == (Object)(object)camera) { ApplyFade(1f); } } private static float ComputeFade(Camera renderingCamera) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_003e: 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_002c: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00af: 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_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) Renderer val = boundsSource; if ((Object)(object)val == (Object)null) { return 1f; } Vector3[] array = localVertices; Vector3 position = ((Component)renderingCamera).transform.position; float num; if (array.Length == 0) { num = MaterialDither.ProximityFade(NearestBoxDistance(val, position)); } else { Matrix4x4 localToWorldMatrix = val.localToWorldMatrix; float num2 = float.MaxValue; for (int i = 0; i < 16; i++) { coverageRowMin[i] = 16; coverageRowMax[i] = -1; } Vector3[] array2 = array; foreach (Vector3 val2 in array2) { Vector3 val3 = ((Matrix4x4)(ref localToWorldMatrix)).MultiplyPoint3x4(val2); Vector3 val4 = val3 - position; float sqrMagnitude = ((Vector3)(ref val4)).sqrMagnitude; if (sqrMagnitude < num2) { num2 = sqrMagnitude; } Vector3 val5 = renderingCamera.WorldToViewportPoint(val3); if (!(val5.z <= 0f)) { int num3 = Mathf.Clamp((int)(Mathf.Clamp01(val5.x) * 16f), 0, 15); int num4 = Mathf.Clamp((int)(Mathf.Clamp01(val5.y) * 16f), 0, 15); if (num3 < coverageRowMin[num4]) { coverageRowMin[num4] = num3; } if (num3 > coverageRowMax[num4]) { coverageRowMax[num4] = num3; } } } int num5 = 0; for (int k = 0; k < 16; k++) { if (coverageRowMax[k] >= coverageRowMin[k]) { num5 += coverageRowMax[k] - coverageRowMin[k] + 1; } } float coverage = (float)num5 / 256f; num = Mathf.Min(MaterialDither.ProximityFade(Mathf.Sqrt(num2)), CoverageFade(coverage)); } num = Mathf.Max(0.11f, num); fadeCurrent = MaterialDither.Smooth(fadeCurrent, num, 0.08f); return fadeCurrent; } private static float CoverageFade(float coverage) { return 1f - Mathf.Clamp01(Mathf.InverseLerp(0.45f, 0.6f, coverage)); } private static float NearestBoxDistance(Renderer renderer, Vector3 worldPoint) { //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_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: 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_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001a: 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) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0031: 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) Matrix4x4 val = renderer.worldToLocalMatrix; Vector3 val2 = ((Matrix4x4)(ref val)).MultiplyPoint3x4(worldPoint); Bounds localBounds = renderer.localBounds; Vector3 val3 = ((Bounds)(ref localBounds)).ClosestPoint(val2); val = renderer.localToWorldMatrix; Vector3 val4 = ((Matrix4x4)(ref val)).MultiplyPoint3x4(val3); return Vector3.Distance(worldPoint, val4); } private static Vector3[] ResolveLocalVertices(Renderer? source) { SkinnedMeshRenderer val = (SkinnedMeshRenderer)(object)((source is SkinnedMeshRenderer) ? source : null); Mesh val2; if (val == null) { if (source == null) { val2 = null; } else { MeshFilter component = ((Component)source).GetComponent(); val2 = ((component != null) ? component.sharedMesh : null); } } else { val2 = val.sharedMesh; } Mesh val3 = val2; if (!((Object)(object)val3 != (Object)null) || !val3.isReadable) { return Array.Empty(); } return val3.vertices; } private static Renderer? ResolveBoundsSource(GrabbableObject? item, Renderer[] itemRenderers) { if ((Object)(object)item == (Object)null) { return null; } if ((Object)(object)item.mainObjectRenderer != (Object)null) { return (Renderer?)(object)item.mainObjectRenderer; } foreach (Renderer val in itemRenderers) { if ((Object)(object)val != (Object)null) { return val; } } return null; } private static void ApplyFade(float fade) { MaterialDither.Set(renderers, materials, fade); } private static void ResetEffect() { MaterialDither.Set(renderers, materials, 1f); fadeCurrent = 1f; } private static void SuppressMotionVectors() { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Expected I4, but got Unknown originalMotionModes = (MotionVectorGenerationMode[])((renderers.Length != 0) ? ((Array)new MotionVectorGenerationMode[renderers.Length]) : ((Array)Array.Empty())); for (int i = 0; i < renderers.Length; i++) { Renderer val = renderers[i]; if (!((Object)(object)val == (Object)null)) { originalMotionModes[i] = (MotionVectorGenerationMode)(int)val.motionVectorGenerationMode; val.motionVectorGenerationMode = (MotionVectorGenerationMode)2; } } } private static void RestoreMotionVectors() { for (int i = 0; i < renderers.Length && i < originalMotionModes.Length; i++) { Renderer val = renderers[i]; if ((Object)(object)val != (Object)null) { val.motionVectorGenerationMode = originalMotionModes[i]; } } originalMotionModes = Array.Empty(); } public static void Reset() { ResetEffect(); RestoreMotionVectors(); trackedItem = null; renderers = Array.Empty(); materials = Array.Empty(); boundsSource = null; localVertices = Array.Empty(); camera = null; hideActive = false; } } internal static class MaterialDither { public const string CrossfadeKeyword = "LOD_FADE_CROSSFADE"; public static readonly int LodFadeId = Shader.PropertyToID("unity_LODFade"); private static MaterialPropertyBlock? scratch; public static Material[] CollectInstancedMaterials(params Renderer[] renderers) { if (renderers.Length == 0) { return Array.Empty(); } List list = new List(); foreach (Renderer val in renderers) { if ((Object)(object)val == (Object)null) { continue; } Material[] materials = val.materials; foreach (Material val2 in materials) { if ((Object)(object)val2 != (Object)null) { list.Add(val2); } } } return list.ToArray(); } public static void Set(Renderer[] renderers, Material[] materials, float fade) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) ToggleKeyword(materials, fade < 0.999f); Vector4 lodFade = default(Vector4); ((Vector4)(ref lodFade))..ctor(fade, fade, 0f, 0f); foreach (Renderer renderer in renderers) { WriteFade(renderer, lodFade); } } public static void Set(Renderer? renderer, Material[] materials, float fade) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) ToggleKeyword(materials, fade < 0.999f); WriteFade(renderer, new Vector4(fade, fade, 0f, 0f)); } private static void ToggleKeyword(Material[] materials, bool enable) { foreach (Material val in materials) { if (!((Object)(object)val == (Object)null)) { if (enable) { val.EnableKeyword("LOD_FADE_CROSSFADE"); } else { val.DisableKeyword("LOD_FADE_CROSSFADE"); } } } } private static void WriteFade(Renderer? renderer, Vector4 lodFade) { //IL_0030: 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_001b: Expected O, but got Unknown if (!((Object)(object)renderer == (Object)null)) { if (scratch == null) { scratch = new MaterialPropertyBlock(); } renderer.GetPropertyBlock(scratch); scratch.SetVector(LodFadeId, lodFade); renderer.SetPropertyBlock(scratch); } } public static float ProximityFade(float distance) { return Mathf.Clamp01(Mathf.InverseLerp(0.1f, 0.35f, distance)); } public static float Smooth(float current, float target, float smoothTime) { float num = 1f - Mathf.Exp((0f - Time.deltaTime) / smoothTime); return Mathf.Lerp(current, target, num); } } internal static class MeshSurgery { private static readonly Dictionary HeadlessMeshCache = new Dictionary(); private static readonly Dictionary HeadlessArmlessMeshCache = new Dictionary(); private static readonly Dictionary ReadableCopies = new Dictionary(); private static readonly HashSet GeneratedMeshIds = new HashSet(); private static readonly HashSet LoggedUnreadableMeshes = new HashSet(); public static bool IsGenerated(int meshInstanceId) { return GeneratedMeshIds.Contains(meshInstanceId); } private static int DominantBoneIndex(BoneWeight bw) { int result = ((BoneWeight)(ref bw)).boneIndex0; float num = ((BoneWeight)(ref bw)).weight0; if (((BoneWeight)(ref bw)).weight1 > num) { num = ((BoneWeight)(ref bw)).weight1; result = ((BoneWeight)(ref bw)).boneIndex1; } if (((BoneWeight)(ref bw)).weight2 > num) { num = ((BoneWeight)(ref bw)).weight2; result = ((BoneWeight)(ref bw)).boneIndex2; } if (((BoneWeight)(ref bw)).weight3 > num) { num = ((BoneWeight)(ref bw)).weight3; result = ((BoneWeight)(ref bw)).boneIndex3; } if (!(num > 0f)) { return -1; } return result; } private static bool[]? BuildPipeMask(Mesh mesh, SkinnedMeshRenderer skinned, Transform headBone) { //IL_0059: 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_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009d: 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) Transform parent = headBone.parent; Transform[] bones = skinned.bones; if ((Object)(object)parent == (Object)null || mesh.bindposes == null || mesh.bindposes.Length < bones.Length) { return null; } int num = Array.IndexOf(bones, parent); int num2 = Array.IndexOf(bones, headBone); if (num < 0 || num2 < 0) { return null; } if (!TryGetBodyForward(mesh, bones, num2, num, out var forward)) { return null; } Vector3 val = BoneBindPosition(mesh, num); BoneWeight[] boneWeights = mesh.boneWeights; Vector3[] vertices = mesh.vertices; bool[] array = new bool[vertices.Length]; int num3 = 0; for (int i = 0; i < vertices.Length; i++) { if (DominantBoneIndex(boneWeights[i]) == num && Vector3.Dot(vertices[i] - val, forward) < 0f) { array[i] = true; num3++; } } if (num3 <= 0) { return null; } return array; } private static bool TryGetBodyForward(Mesh mesh, Transform[] bones, int headIndex, int neckIndex, out Vector3 forward) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: 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_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_0063: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0084: 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) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: 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_00b5: Unknown result type (might be due to invalid IL or missing references) //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_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) forward = Vector3.zero; int num = FindBoneIndex(bones, "toe.L"); int num2 = FindBoneIndex(bones, "heel.02.L"); int num3 = FindBoneIndex(bones, "toe.R"); int num4 = FindBoneIndex(bones, "heel.02.R"); if (num < 0 || num2 < 0 || num3 < 0 || num4 < 0) { return false; } Vector3 val = BoneBindPosition(mesh, num) - BoneBindPosition(mesh, num2) + (BoneBindPosition(mesh, num3) - BoneBindPosition(mesh, num4)); Vector3 val2 = BoneBindPosition(mesh, headIndex) - BoneBindPosition(mesh, neckIndex); if (((Vector3)(ref val2)).sqrMagnitude > 1E-06f) { val -= ((Vector3)(ref val2)).normalized * Vector3.Dot(val, ((Vector3)(ref val2)).normalized); } if (((Vector3)(ref val)).sqrMagnitude < 1E-06f) { return false; } forward = ((Vector3)(ref val)).normalized; return true; } private static Vector3 BoneBindPosition(Mesh mesh, int boneIndex) { //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_0012: 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_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) Matrix4x4 inverse = ((Matrix4x4)(ref mesh.bindposes[boneIndex])).inverse; return new Vector3(inverse.m03, inverse.m13, inverse.m23); } private static int FindBoneIndex(Transform[] bones, string boneName) { for (int i = 0; i < bones.Length; i++) { if ((Object)(object)bones[i] != (Object)null && string.Equals(((Object)bones[i]).name, boneName, StringComparison.OrdinalIgnoreCase)) { return i; } } return -1; } public static void ClearCaches() { foreach (Mesh value in HeadlessMeshCache.Values) { if ((Object)(object)value != (Object)null) { Object.Destroy((Object)(object)value); } } foreach (Mesh value2 in HeadlessArmlessMeshCache.Values) { if ((Object)(object)value2 != (Object)null) { Object.Destroy((Object)(object)value2); } } foreach (Mesh value3 in ReadableCopies.Values) { if ((Object)(object)value3 != (Object)null) { Object.Destroy((Object)(object)value3); } } HeadlessMeshCache.Clear(); HeadlessArmlessMeshCache.Clear(); ReadableCopies.Clear(); GeneratedMeshIds.Clear(); LoggedUnreadableMeshes.Clear(); } public static Mesh? GetOrCreateHeadlessMesh(Mesh sourceMesh, SkinnedMeshRenderer skinned, Transform headBone) { int instanceID = ((Object)sourceMesh).GetInstanceID(); if (HeadlessMeshCache.TryGetValue(instanceID, out Mesh value) && (Object)(object)value != (Object)null) { return value; } Mesh val = ResolveReadable(sourceMesh, instanceID); if ((Object)(object)val == (Object)null) { return null; } bool[] pipeMask = BuildPipeMask(val, skinned, headBone); Mesh val2 = TryBuildFilteredMesh(val, GetHeadBoneIndices(skinned, headBone), pipeMask, "_FPVHeadless"); if ((Object)(object)val2 != (Object)null) { HeadlessMeshCache[instanceID] = val2; GeneratedMeshIds.Add(((Object)val2).GetInstanceID()); } return val2; } public static Mesh? GetOrCreateHeadlessArmlessMesh(Mesh sourceMesh, SkinnedMeshRenderer skinned, Transform headBone, Transform? leftArm, Transform? rightArm) { int instanceID = ((Object)sourceMesh).GetInstanceID(); if (HeadlessArmlessMeshCache.TryGetValue(instanceID, out Mesh value) && (Object)(object)value != (Object)null) { return value; } Mesh val = ResolveReadable(sourceMesh, instanceID); if ((Object)(object)val == (Object)null) { return null; } Mesh val2; try { val2 = BuildHeadlessArmlessMesh(val, skinned, headBone, leftArm, rightArm, "_FPVHeadlessArmless"); } catch (Exception) { return null; } if ((Object)(object)val2 != (Object)null) { HeadlessArmlessMeshCache[instanceID] = val2; GeneratedMeshIds.Add(((Object)val2).GetInstanceID()); } return val2; } private static Mesh? BuildHeadlessArmlessMesh(Mesh sourceMesh, SkinnedMeshRenderer skinned, Transform headBone, Transform? leftArm, Transform? rightArm, string nameSuffix) { //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006a: 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_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) BoneWeight[] boneWeights = sourceMesh.boneWeights; if (boneWeights == null || boneWeights.Length == 0) { return null; } HashSet headBoneIndices = GetHeadBoneIndices(skinned, headBone); HashSet armBoneIndices = GetArmBoneIndices(skinned, leftArm, rightArm); if (headBoneIndices.Count == 0 && armBoneIndices.Count == 0) { return null; } bool[] array = BuildPipeMask(sourceMesh, skinned, headBone); int num = boneWeights.Length; float[] array2 = new float[num]; bool[] array3 = new bool[num]; bool[] array4 = new bool[num]; for (int i = 0; i < num; i++) { BoneWeight bw = boneWeights[i]; array2[i] = InfluenceOf(bw, headBoneIndices); array3[i] = IsDominatedBy(bw, headBoneIndices) || (array != null && array[i]); array4[i] = IsDominatedBy(bw, armBoneIndices); } Vector3[] array5 = (Vector3[])sourceMesh.vertices.Clone(); BoneWeight[] array6 = (BoneWeight[])boneWeights.Clone(); FoldDominantVerticesToNearestSeam(sourceMesh, array3, array5, array6); if (!FoldDominantVerticesToNearestSeam(sourceMesh, array4, array5, array6, array3)) { return null; } Mesh val = Object.Instantiate(sourceMesh); ((Object)val).name = ((Object)sourceMesh).name + nameSuffix; val.vertices = array5; val.boneWeights = array6; for (int j = 0; j < val.subMeshCount; j++) { int[] triangles = sourceMesh.GetTriangles(j); List list = new List(triangles.Length); for (int k = 0; k < triangles.Length; k += 3) { int num2 = triangles[k]; int num3 = triangles[k + 1]; int num4 = triangles[k + 2]; if (!ShouldCullTriangle(num2, num3, num4, array2, array3) && (!array4[num2] || !array4[num3] || !array4[num4])) { list.Add(num2); list.Add(num3); list.Add(num4); } } val.SetTriangles(list, j); } val.RecalculateBounds(); return val; } private static List CollectSeamVertices(Mesh mesh, bool[] dominantCut) { HashSet hashSet = new HashSet(); for (int i = 0; i < mesh.subMeshCount; i++) { int[] triangles = mesh.GetTriangles(i); for (int j = 0; j < triangles.Length; j += 3) { int num = triangles[j]; int num2 = triangles[j + 1]; int num3 = triangles[j + 2]; if (dominantCut[num] || dominantCut[num2] || dominantCut[num3]) { if (!dominantCut[num]) { hashSet.Add(num); } if (!dominantCut[num2]) { hashSet.Add(num2); } if (!dominantCut[num3]) { hashSet.Add(num3); } } } } return new List(hashSet); } private static bool FoldDominantVerticesToNearestSeam(Mesh sourceMesh, bool[] dominantCut, Vector3[] foldedVertices, BoneWeight[] foldedWeights, bool[]? avoidTargets = null) { //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) List list = CollectSeamVertices(sourceMesh, dominantCut); if (list.Count == 0) { return false; } List candidates = list; if (avoidTargets != null) { List list2 = new List(list.Count); foreach (int item in list) { if (item >= 0 && item < avoidTargets.Length && !avoidTargets[item]) { list2.Add(item); } } if (list2.Count > 0) { candidates = list2; } } Vector3[] array = (Vector3[])foldedVertices.Clone(); BoneWeight[] array2 = (BoneWeight[])foldedWeights.Clone(); for (int i = 0; i < dominantCut.Length; i++) { if (dominantCut[i]) { int num = NearestVertex(array[i], candidates, array); foldedVertices[i] = array[num]; foldedWeights[i] = array2[num]; } } return true; } private static int NearestVertex(Vector3 point, List candidates, Vector3[] vertices) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) int result = candidates[0]; float num = float.MaxValue; foreach (int candidate in candidates) { Vector3 val = vertices[candidate] - point; float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude; if (sqrMagnitude < num) { num = sqrMagnitude; result = candidate; } } return result; } private static Mesh? TryBuildFilteredMesh(Mesh sourceMesh, HashSet removalBoneIndices, bool[]? pipeMask, string nameSuffix) { try { return BuildMeshWithoutBones(sourceMesh, removalBoneIndices, pipeMask, nameSuffix); } catch (Exception ex) { Plugin.Log.LogWarning((object)("Failed to build '" + ((Object)sourceMesh).name + nameSuffix + "'. " + ex.Message)); return null; } } private static Mesh? BuildMeshWithoutBones(Mesh sourceMesh, HashSet removalBoneIndices, bool[]? pipeMask, string nameSuffix) { //IL_0034: 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_003e: 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) BoneWeight[] boneWeights = sourceMesh.boneWeights; if (boneWeights == null || boneWeights.Length == 0) { return null; } if (removalBoneIndices.Count == 0) { return null; } float[] array = new float[boneWeights.Length]; bool[] array2 = new bool[boneWeights.Length]; for (int i = 0; i < boneWeights.Length; i++) { BoneWeight bw = boneWeights[i]; array[i] = InfluenceOf(bw, removalBoneIndices); array2[i] = IsDominatedBy(bw, removalBoneIndices) || (pipeMask != null && pipeMask[i]); } Vector3[] array3 = (Vector3[])sourceMesh.vertices.Clone(); BoneWeight[] array4 = (BoneWeight[])boneWeights.Clone(); FoldDominantVerticesToNearestSeam(sourceMesh, array2, array3, array4); Mesh val = Object.Instantiate(sourceMesh); ((Object)val).name = ((Object)sourceMesh).name + nameSuffix; val.vertices = array3; val.boneWeights = array4; for (int j = 0; j < val.subMeshCount; j++) { int[] triangles = sourceMesh.GetTriangles(j); List list = new List(triangles.Length); for (int k = 0; k < triangles.Length; k += 3) { int num = triangles[k]; int num2 = triangles[k + 1]; int num3 = triangles[k + 2]; if (!ShouldCullTriangle(num, num2, num3, array, array2)) { list.Add(num); list.Add(num2); list.Add(num3); } } val.SetTriangles(list, j); } val.RecalculateBounds(); return val; } private static float InfluenceOf(BoneWeight bw, HashSet set) { float num = 0f; if (set.Contains(((BoneWeight)(ref bw)).boneIndex0)) { num += ((BoneWeight)(ref bw)).weight0; } if (set.Contains(((BoneWeight)(ref bw)).boneIndex1)) { num += ((BoneWeight)(ref bw)).weight1; } if (set.Contains(((BoneWeight)(ref bw)).boneIndex2)) { num += ((BoneWeight)(ref bw)).weight2; } if (set.Contains(((BoneWeight)(ref bw)).boneIndex3)) { num += ((BoneWeight)(ref bw)).weight3; } return num; } private static bool ShouldCullTriangle(int a, int b, int c, float[] headInfluence, bool[] dominantHead) { float num = ((a >= 0 && a < headInfluence.Length) ? headInfluence[a] : 0f); float num2 = ((b >= 0 && b < headInfluence.Length) ? headInfluence[b] : 0f); float num3 = ((c >= 0 && c < headInfluence.Length) ? headInfluence[c] : 0f); int num4 = 0; if (num >= 0.35f) { num4++; } if (num2 >= 0.35f) { num4++; } if (num3 >= 0.35f) { num4++; } int num5 = 0; if (a >= 0 && a < dominantHead.Length && dominantHead[a]) { num5++; } if (b >= 0 && b < dominantHead.Length && dominantHead[b]) { num5++; } if (c >= 0 && c < dominantHead.Length && dominantHead[c]) { num5++; } if (num5 >= 2 || num4 >= 2) { return true; } float num6 = (num + num2 + num3) / 3f; if (num5 >= 1) { return num6 >= 0.3f; } return false; } private static bool IsDominatedBy(BoneWeight bw, HashSet set) { int item = ((BoneWeight)(ref bw)).boneIndex0; float num = ((BoneWeight)(ref bw)).weight0; if (((BoneWeight)(ref bw)).weight1 > num) { num = ((BoneWeight)(ref bw)).weight1; item = ((BoneWeight)(ref bw)).boneIndex1; } if (((BoneWeight)(ref bw)).weight2 > num) { num = ((BoneWeight)(ref bw)).weight2; item = ((BoneWeight)(ref bw)).boneIndex2; } if (((BoneWeight)(ref bw)).weight3 > num) { num = ((BoneWeight)(ref bw)).weight3; item = ((BoneWeight)(ref bw)).boneIndex3; } if (num > 0f) { return set.Contains(item); } return false; } private static HashSet GetHeadBoneIndices(SkinnedMeshRenderer skinned, Transform headBone) { HashSet hashSet = new HashSet(); Transform[] bones = skinned.bones; for (int i = 0; i < bones.Length; i++) { Transform val = bones[i]; if (!((Object)(object)val == (Object)null) && ((Object)(object)val == (Object)(object)headBone || val.IsChildOf(headBone) || ContainsHeadHint(((Object)val).name))) { hashSet.Add(i); } } return hashSet; } private static HashSet GetArmBoneIndices(SkinnedMeshRenderer skinned, Transform? leftArm, Transform? rightArm) { HashSet hashSet = new HashSet(); Transform[] bones = skinned.bones; for (int i = 0; i < bones.Length; i++) { Transform val = bones[i]; if (!((Object)(object)val == (Object)null)) { bool flag = (Object)(object)leftArm != (Object)null && ((Object)(object)val == (Object)(object)leftArm || val.IsChildOf(leftArm)); bool flag2 = (Object)(object)rightArm != (Object)null && ((Object)(object)val == (Object)(object)rightArm || val.IsChildOf(rightArm)); if (flag || flag2) { hashSet.Add(i); } } } return hashSet; } private static bool ContainsHeadHint(string? value) { if (string.IsNullOrWhiteSpace(value)) { return false; } string[] headBoneNameHints = Constants.HeadBoneNameHints; foreach (string value2 in headBoneNameHints) { if (value.IndexOf(value2, StringComparison.OrdinalIgnoreCase) >= 0) { return true; } } return false; } private static Mesh? ResolveReadable(Mesh sourceMesh, int meshId) { if (sourceMesh.isReadable) { return sourceMesh; } if (ReadableCopies.TryGetValue(meshId, out Mesh value)) { return value; } Mesh val = null; try { Mesh val2 = MakeReadableMeshCopy(sourceMesh); if (val2.boneWeights.Length != 0 && val2.bindposes.Length != 0) { val = val2; } else { Object.Destroy((Object)(object)val2); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("Mesh '" + ((Object)sourceMesh).name + "' could not be copied from the GPU. " + ex.Message)); } if ((Object)(object)val == (Object)null && LoggedUnreadableMeshes.Add(meshId)) { Plugin.Log.LogWarning((object)("Mesh '" + ((Object)sourceMesh).name + "' is not readable; the head can't be hidden on this model.")); } ReadableCopies[meshId] = val; return val; } private static Mesh MakeReadableMeshCopy(Mesh nonReadableMesh) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: 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_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown //IL_00c6: 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) Mesh val = new Mesh { name = ((Object)nonReadableMesh).name, indexFormat = nonReadableMesh.indexFormat }; nonReadableMesh.vertexBufferTarget = (Target)1; if (nonReadableMesh.vertexBufferCount > 0) { GraphicsBuffer vertexBuffer = nonReadableMesh.GetVertexBuffer(0); try { int num = vertexBuffer.stride * vertexBuffer.count; byte[] array = new byte[num]; vertexBuffer.GetData((Array)array); val.SetVertexBufferParams(nonReadableMesh.vertexCount, nonReadableMesh.GetVertexAttributes()); val.SetVertexBufferData(array, 0, 0, num, 0, (MeshUpdateFlags)0); } finally { ((IDisposable)vertexBuffer)?.Dispose(); } } nonReadableMesh.indexBufferTarget = (Target)2; val.subMeshCount = nonReadableMesh.subMeshCount; GraphicsBuffer indexBuffer = nonReadableMesh.GetIndexBuffer(); try { int num2 = indexBuffer.stride * indexBuffer.count; byte[] array2 = new byte[num2]; indexBuffer.GetData((Array)array2); val.SetIndexBufferParams(indexBuffer.count, nonReadableMesh.indexFormat); val.SetIndexBufferData(array2, 0, 0, num2, (MeshUpdateFlags)0); } finally { ((IDisposable)indexBuffer)?.Dispose(); } int num3 = 0; for (int i = 0; i < val.subMeshCount; i++) { int indexCount = (int)nonReadableMesh.GetIndexCount(i); val.SetSubMesh(i, new SubMeshDescriptor(num3, indexCount, (MeshTopology)0), (MeshUpdateFlags)0); num3 += indexCount; } val.bindposes = nonReadableMesh.bindposes; val.RecalculateBounds(); return val; } } public static class MyPluginInfo { public const string PLUGIN_GUID = "com.seeya.firstpersonview"; public const string PLUGIN_NAME = "First-Person View"; public const string PLUGIN_VERSION = "1.4.1"; } } namespace FirstPersonView.Patches { [HarmonyPatch(typeof(PlayerControllerB))] internal static class LocalBodyViewPatches { private static readonly HashSet _loggedTickErrors = new HashSet(); [HarmonyPatch("ConnectClientToPlayerObject")] [HarmonyPostfix] private static void ConnectClientToPlayerObject_Postfix(PlayerControllerB __instance) { if ((Object)(object)StartOfRound.Instance?.localPlayerController == (Object)(object)__instance) { LocalBodyViewController.ResetAllStates(); } } [HarmonyPatch("LateUpdate")] [HarmonyPostfix] [HarmonyPriority(0)] private static void LateUpdate_Postfix(PlayerControllerB __instance) { try { LocalBodyViewController.Tick(__instance); } catch (Exception ex) { if (_loggedTickErrors.Add($"{ex.GetType()}: {ex.Message}")) { Plugin.Log.LogError((object)$"Local body update failed.\n{ex}"); } } } [HarmonyPatch("SetHoverTipAndCurrentInteractTrigger")] [HarmonyPrefix] private static void SetHoverTipAndCurrentInteractTrigger_Prefix(PlayerControllerB __instance) { try { LocalBodyViewController.AlignCameraForInteractionRay(__instance); } catch (Exception ex) { if (_loggedTickErrors.Add($"ray|{ex.GetType()}: {ex.Message}")) { Plugin.Log.LogError((object)$"Interaction ray alignment failed.\n{ex}"); } } } } } namespace FirstPersonView.Compat { internal static class LethalPhonesCompat { private static bool _initialized; private static bool _isInstalled; private static Type? _playerPhoneType; private static FieldInfo? _toggledField; private const string PhoneChildName = "PhonePrefab(Clone)"; public static void Initialize() { if (!_initialized) { _initialized = true; bool flag = TryResolveTypes(); _isInstalled = flag && ConfigManager.EnableLethalPhonesCompatibility.Value; if (flag) { Plugin.Log.LogInfo((object)"LethalPhones detected."); } } } public static bool IsLocalPhoneActive(LocalBodyState state, PlayerControllerB player) { if (!_isInstalled || _playerPhoneType == null || _toggledField == null) { return false; } if ((Object)(object)state.LethalPhonesPlayerPhone == (Object)null) { Transform val = ((Component)player).transform.Find("PhonePrefab(Clone)"); if ((Object)(object)val == (Object)null) { return false; } state.LethalPhonesPlayerPhone = ((Component)val).GetComponent(_playerPhoneType); if ((Object)(object)state.LethalPhonesPlayerPhone == (Object)null) { return false; } } object value = _toggledField.GetValue(state.LethalPhonesPlayerPhone); if (value is bool) { return (bool)value; } return false; } private static bool TryResolveTypes() { Assembly assembly = Reflection.FindAssembly("LethalPhones"); if (assembly == null) { return false; } _playerPhoneType = assembly.GetType("Scoops.misc.PlayerPhone"); if (_playerPhoneType == null) { return false; } _toggledField = _playerPhoneType.GetField("toggled", BindingFlags.Instance | BindingFlags.Public); return _toggledField != null; } } internal static class MoreCompanyCompat { private sealed class TrackedCosmetic { public Transform Root; public Renderer[] Renderers = Array.Empty(); public Light[] Lights = Array.Empty(); public int[] LightCullingMasks = Array.Empty(); public int OriginalLayer; public ConfigEntry? FirstPersonToggle; public bool HiddenByFirstPersonArms; public bool ShowInFirstPerson = true; } private const int TooManyEmotesHiddenLayer = 23; private static bool _initialized; private static bool _isInstalled; private static readonly List Tracked = new List(); private static int _trackedApplicationId; private static int _trackedCount = -1; private static Camera? _firstPersonCamera; public static void Initialize() { if (!_initialized) { _initialized = true; _isInstalled = Chainloader.PluginInfos.ContainsKey("me.swipez.melonloader.morecompany"); if (_isInstalled) { Plugin.Log.LogInfo((object)"MoreCompany detected."); } } } public static void Reset() { Tracked.Clear(); _trackedApplicationId = 0; _trackedCount = -1; _firstPersonCamera = null; } public static void ApplyLocalCosmeticVisibility(PlayerControllerB player, bool localBodyVisible, bool firstPersonArmsActive) { if (!_isInstalled || !ConfigManager.EnableMoreCompanyCompatibility.Value || !localBodyVisible) { StopTracking(); return; } _firstPersonCamera = player.gameplayCamera; if (!RefreshTracked(player)) { StopTracking(); } else { UpdateRestingState(firstPersonArmsActive); } } public static void ApplyForCamera(Camera renderingCamera) { if (Tracked.Count == 0) { return; } bool flag = (Object)(object)renderingCamera == (Object)(object)_firstPersonCamera; foreach (TrackedCosmetic item in Tracked) { if (!((Object)(object)item.Root == (Object)null)) { SetRenderersEnabled(item, !flag || item.ShowInFirstPerson); } } } public static void RestoreAfterCamera(Camera renderingCamera) { if (Tracked.Count == 0) { return; } foreach (TrackedCosmetic item in Tracked) { if (!((Object)(object)item.Root == (Object)null)) { SetRenderersEnabled(item, enabled: true); } } } [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] private static bool RefreshTracked(PlayerControllerB player) { //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Invalid comparison between Unknown and I4 Transform obj = ((Component)player).transform.Find("ScavengerModel"); Transform val = ((obj != null) ? obj.Find("metarig") : null); if ((Object)(object)val == (Object)null) { return false; } CosmeticApplication component = ((Component)val).GetComponent(); if ((Object)(object)component == (Object)null) { return false; } int instanceID = ((Object)component).GetInstanceID(); int count = component.spawnedCosmetics.Count; if (instanceID == _trackedApplicationId && count == _trackedCount && AllTrackedAlive()) { return Tracked.Count > 0; } Tracked.Clear(); _trackedApplicationId = instanceID; _trackedCount = count; foreach (CosmeticInstance spawnedCosmetic in component.spawnedCosmetics) { if (!((Object)(object)spawnedCosmetic == (Object)null)) { Transform transform = ((Component)spawnedCosmetic).transform; Light[] componentsInChildren = ((Component)transform).GetComponentsInChildren(true); int[] array = new int[componentsInChildren.Length]; for (int i = 0; i < componentsInChildren.Length; i++) { array[i] = componentsInChildren[i].cullingMask; } Tracked.Add(new TrackedCosmetic { Root = transform, Renderers = ((Component)transform).GetComponentsInChildren(true), Lights = componentsInChildren, LightCullingMasks = array, OriginalLayer = ((Component)transform).gameObject.layer, FirstPersonToggle = FirstPersonToggleFor(spawnedCosmetic.cosmeticType), HiddenByFirstPersonArms = ((int)spawnedCosmetic.cosmeticType == 3) }); } } return Tracked.Count > 0; } [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] private static ConfigEntry? FirstPersonToggleFor(CosmeticType type) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected I4, but got Unknown return (ConfigEntry?)((int)type switch { 0 => ConfigManager.ShowMoreCompanyHat, 2 => ConfigManager.ShowMoreCompanyChest, 4 => ConfigManager.ShowMoreCompanyHip, 3 => ConfigManager.ShowMoreCompanyRightLowerArm, 5 => ConfigManager.ShowMoreCompanyLeftShin, 6 => ConfigManager.ShowMoreCompanyRightShin, _ => null, }); } private static bool AllTrackedAlive() { foreach (TrackedCosmetic item in Tracked) { if ((Object)(object)item.Root == (Object)null) { return false; } } return true; } private static void UpdateRestingState(bool firstPersonArmsActive) { foreach (TrackedCosmetic item in Tracked) { if (!((Object)(object)item.Root == (Object)null)) { item.ShowInFirstPerson = (item.FirstPersonToggle == null || item.FirstPersonToggle.Value) && !(item.HiddenByFirstPersonArms && firstPersonArmsActive); GameObject gameObject = ((Component)item.Root).gameObject; if (!gameObject.activeSelf) { gameObject.SetActive(true); } RestoreCosmeticLayer(item); SetRenderersEnabled(item, enabled: true); } } } private static void StopTracking() { foreach (TrackedCosmetic item in Tracked) { if (!((Object)(object)item.Root == (Object)null)) { SetRenderersEnabled(item, enabled: true); GameObject gameObject = ((Component)item.Root).gameObject; if (gameObject.activeSelf != item.ShowInFirstPerson) { gameObject.SetActive(item.ShowInFirstPerson); } } } Reset(); } private static void RestoreCosmeticLayer(TrackedCosmetic cosmetic) { if (cosmetic.OriginalLayer == 23 || ((Component)cosmetic.Root).gameObject.layer == cosmetic.OriginalLayer) { return; } SetLayerRecursively(cosmetic.Root, cosmetic.OriginalLayer); for (int i = 0; i < cosmetic.Lights.Length; i++) { Light val = cosmetic.Lights[i]; if ((Object)(object)val != (Object)null) { val.cullingMask = cosmetic.LightCullingMasks[i]; } } } private static void SetLayerRecursively(Transform root, int layer) { ((Component)root).gameObject.layer = layer; for (int i = 0; i < root.childCount; i++) { SetLayerRecursively(root.GetChild(i), layer); } } private static void SetRenderersEnabled(TrackedCosmetic cosmetic, bool enabled) { Renderer[] renderers = cosmetic.Renderers; foreach (Renderer val in renderers) { if ((Object)(object)val != (Object)null && val.enabled != enabled) { val.enabled = enabled; } } } } internal static class Reflection { public static Assembly? FindAssembly(string name) { return AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault((Assembly a) => a.GetName().Name == name); } public static IEnumerable GetLoadableTypes(this Assembly assembly) { if (assembly == null) { return Enumerable.Empty(); } try { return assembly.GetTypes(); } catch (ReflectionTypeLoadException ex) { return ex.Types.Where((Type type) => type != null); } } } internal static class TooManyEmotesCompat { private static bool _initialized; private static bool _isInstalled; public static void Initialize() { if (!_initialized) { _initialized = true; bool flag = Reflection.FindAssembly("TooManyEmotes") != null; _isInstalled = flag && ConfigManager.EnableTooManyEmotesCompatibility.Value; if (flag) { Plugin.Log.LogInfo((object)"TooManyEmotes detected."); } } } public static bool IsFirstPersonEmoteActive() { if (_isInstalled) { return IsFirstPersonEmoteActiveTyped(); } return false; } [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] private static bool IsFirstPersonEmoteActiveTyped() { if (!ThirdPersonEmoteController.firstPersonEmotesEnabled) { return false; } EmoteControllerPlayer emoteControllerLocal = EmoteControllerPlayer.emoteControllerLocal; if ((Object)(object)emoteControllerLocal != (Object)null) { return ((EmoteController)emoteControllerLocal).IsPerformingCustomEmote(); } return false; } } [HarmonyPatch(typeof(VehicleController))] public static class VehicleCompat { [HarmonyPatch("Update")] [HarmonyPostfix] public static void Update_Key_Postfix(VehicleController __instance) { //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_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0090: 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_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) if (((NetworkBehaviour)__instance).IsSpawned && __instance.vehicleID == 0 && LocalBodyViewController.LocalBodyShown && __instance.keyIsInDriverHand && __instance.localPlayerInControl && !__instance.keyIsInIgnition && !((Object)(object)__instance.keyObject == (Object)null)) { PlayerControllerB currentDriver = __instance.currentDriver; Transform val = (((Object)(object)currentDriver != (Object)null) ? currentDriver.serverItemHolder : null); if (!((Object)(object)val == (Object)null)) { Transform transform = ((Component)__instance.keyObject).transform; transform.rotation = val.rotation * Quaternion.Euler(Constants.CruiserKeyRotationOffset); transform.position = val.position + val.rotation * Constants.CruiserKeyPositionOffset; } } } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } }