Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of First Person View v1.0.1
BepInEx/plugins/FirstPersonView/FirstPersonView.dll
Decompiled 4 hours ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; 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 UnityEngine; using UnityEngine.Rendering; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("FirstPersonView")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("Lets players see their own body.")] [assembly: AssemblyFileVersion("1.0.1.0")] [assembly: AssemblyInformationalVersion("1.0.1+058a0c624f188a4e010b55984f0e2cc89f58d0f4")] [assembly: AssemblyProduct("FirstPersonView")] [assembly: AssemblyTitle("FirstPersonView")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.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_0038: 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_003d: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_009a: 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_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) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_0234: Unknown result type (might be due to invalid IL or missing references) //IL_0239: 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_023e: Unknown result type (might be due to invalid IL or missing references) //IL_0242: Unknown result type (might be due to invalid IL or missing references) //IL_0244: Unknown result type (might be due to invalid IL or missing references) //IL_0246: Unknown result type (might be due to invalid IL or missing references) //IL_024b: Unknown result type (might be due to invalid IL or missing references) //IL_024d: Unknown result type (might be due to invalid IL or missing references) //IL_024f: Unknown result type (might be due to invalid IL or missing references) //IL_0253: Unknown result type (might be due to invalid IL or missing references) //IL_0258: Unknown result type (might be due to invalid IL or missing references) //IL_025d: Unknown result type (might be due to invalid IL or missing references) //IL_0264: Unknown result type (might be due to invalid IL or missing references) //IL_0269: Unknown result type (might be due to invalid IL or missing references) //IL_026e: Unknown result type (might be due to invalid IL or missing references) //IL_0271: Unknown result type (might be due to invalid IL or missing references) //IL_0276: Unknown result type (might be due to invalid IL or missing references) //IL_027b: Unknown result type (might be due to invalid IL or missing references) //IL_027d: Unknown result type (might be due to invalid IL or missing references) //IL_027f: Unknown result type (might be due to invalid IL or missing references) //IL_0281: Unknown result type (might be due to invalid IL or missing references) //IL_0286: Unknown result type (might be due to invalid IL or missing references) //IL_0289: Unknown result type (might be due to invalid IL or missing references) //IL_029f: Unknown result type (might be due to invalid IL or missing references) //IL_02a1: Unknown result type (might be due to invalid IL or missing references) //IL_029a: Unknown result type (might be due to invalid IL or missing references) //IL_02a6: Unknown result type (might be due to invalid IL or missing references) Camera gameplayCamera = state.GameplayCamera; if (!((Object)(object)gameplayCamera == (Object)null) && state.CameraBaseCaptured) { 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); state.CrouchBlend = Mathf.MoveTowards(state.CrouchBlend, player.isCrouching ? 1f : 0f, Time.deltaTime / 0.15f); state.HoldBlend = Mathf.MoveTowards(state.HoldBlend, Players.IsHoldingTwoHanded(player) ? 1f : 0f, Time.deltaTime / 0.18f); state.RunBlend = Mathf.MoveTowards(state.RunBlend, player.isSprinting ? 1f : 0f, Time.deltaTime / 0.18f); state.JumpBlend = Mathf.MoveTowards(state.JumpBlend, (player.isJumping || player.isFallingFromJump) ? 1f : 0f, Time.deltaTime / 0.18f); float num = 0f + state.CrouchBlend * 0.12f + state.HoldBlend * 0.07f + state.RunBlend * 0.05f + state.JumpBlend * 0f; state.LadderBlend = Mathf.MoveTowards(state.LadderBlend, player.isClimbingLadder ? 1f : 0f, Time.deltaTime / 0.08f); float num2 = Mathf.Lerp(0.13f, 0f, state.LadderBlend) + state.HoldBlend * 0.15f + state.RunBlend * 0.1f + state.JumpBlend * 0.13f; Vector3 val4 = (((Object)(object)parent != (Object)null) ? parent.TransformPoint(state.CameraBaseLocalPosition) : state.CameraBaseLocalPosition); Vector3 val5 = FollowBodyAnchor(state, player, val4, yawRotation); Vector3 desired = val5 + val2 * num2 + val3 * 0f + val * num; desired = (transform.position = ResolveWallCollision(val4, desired)); state.LastCameraTargetLocal = (((Object)(object)parent != (Object)null) ? parent.InverseTransformPoint(desired) : desired); state.HasCameraTarget = true; state.CameraOffsetApplied = true; } } public static void RelaxSeatedLookClamp(PlayerControllerB player) { if (player.inVehicleAnimation && 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) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0023: 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_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_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_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0077: 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_007e: 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_0089: 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_00d0: 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_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00df: 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_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) Transform headBone = state.HeadBone; if ((Object)(object)headBone == (Object)null) { return baseWorld; } if (!state.EyeAnchorCaptured) { state.EyeAnchorLocal = Quaternion.Inverse(yawRotation) * (baseWorld - headBone.position); state.EyeAnchorBoneLocal = headBone.InverseTransformPoint(baseWorld); state.EyeAnchorCaptured = true; } if (TooManyEmotesCompat.IsFirstPersonEmoteActive()) { return headBone.TransformPoint(state.EyeAnchorBoneLocal); } Vector3 val = headBone.position + yawRotation * state.EyeAnchorLocal; Vector3 val2 = Quaternion.Inverse(yawRotation) * (val - baseWorld); val2.x *= 1f; val2.z *= 1f; val2.y *= 1f; val2.y = DampHeadBob(state, player, val2.y); val2 = StabilizeSprintBob(state, player, val2); val2 = NeckGuardedFollow(state, player, val2); if (((Vector3)(ref val2)).sqrMagnitude > 0.25f) { val2 = ((Vector3)(ref val2)).normalized * 0.5f; } return baseWorld + yawRotation * val2; } private static float DampHeadBob(LocalBodyState state, PlayerControllerB player, float rawY) { if (!state.DisableBobSmoothInitialized) { state.DisableBobSmoothedY = rawY; state.DisableBobSmoothInitialized = true; } else { float num = 1f - Mathf.Exp((0f - Time.deltaTime) / 1f); state.DisableBobSmoothedY = Mathf.Lerp(state.DisableBobSmoothedY, rawY, num); } bool flag = ConfigManager.DisableHeadBob.Value && !player.isCrouching && state.CrouchBlend <= 0f && (player.isWalking || player.isSprinting || player.isJumping || player.isFallingFromJump); state.DisableBobBlend = Mathf.MoveTowards(state.DisableBobBlend, flag ? 1f : 0f, Time.deltaTime / 0.15f); return Mathf.Lerp(rawY, state.DisableBobSmoothedY, state.DisableBobBlend); } private static Vector3 StabilizeSprintBob(LocalBodyState state, PlayerControllerB player, Vector3 deviationLocal) { //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_007e: 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_004e: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_0097: 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) bool flag = player.isSprinting || player.isJumping || player.isFallingFromJump; state.BobDampBlend = Mathf.MoveTowards(state.BobDampBlend, flag ? 1f : 0f, Time.deltaTime / 0.12f); if (!state.DeviationSmoothInitialized) { state.SmoothedDeviationLocal = deviationLocal; state.DeviationSmoothInitialized = true; } else { float num = 1f - Mathf.Exp((0f - Time.deltaTime) / 0.2f); state.SmoothedDeviationLocal = Vector3.Lerp(state.SmoothedDeviationLocal, deviationLocal, num); } float num2 = state.BobDampBlend * 0.6f; return Vector3.Lerp(deviationLocal, state.SmoothedDeviationLocal, num2); } private static Vector3 NeckGuardedFollow(LocalBodyState state, PlayerControllerB player, Vector3 live) { //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_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_001c: 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_0060: 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_0111: 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_01c2: 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_01c9: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: 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_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_01d7: Unknown result type (might be due to invalid IL or missing references) //IL_0257: Unknown result type (might be due to invalid IL or missing references) //IL_023f: Unknown result type (might be due to invalid IL or missing references) //IL_01ed: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_027e: 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_0221: Unknown result type (might be due to invalid IL or missing references) //IL_0227: 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_0203: Unknown result type (might be due to invalid IL or missing references) //IL_0209: Unknown result type (might be due to invalid IL or missing references) //IL_029e: Unknown result type (might be due to invalid IL or missing references) //IL_028a: Unknown result type (might be due to invalid IL or missing references) //IL_034c: Unknown result type (might be due to invalid IL or missing references) //IL_0367: Unknown result type (might be due to invalid IL or missing references) //IL_0382: Unknown result type (might be due to invalid IL or missing references) //IL_0392: Unknown result type (might be due to invalid IL or missing references) //IL_0397: 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_03ae: Unknown result type (might be due to invalid IL or missing references) if (!state.NeckGuardInitialized) { state.SwingRest = live; state.GuardedEyeDeviation = live; state.GuardedEyeVelocity = Vector3.zero; state.NeckGuardTail = 0f; state.NeckGuardRelease = 0f; state.NeckGuardLatched = false; state.NeckGuardWasSwinging = false; state.NeckGuardEngaged = false; state.NeckGuardFloorActive = false; state.NeckGuardCrouchRestZ = live.z; state.NeckGuardCrouchRestY = live.y; state.NeckGuardInitialized = true; return live; } bool flag = player.isCrouching && player.activatingItem; if (flag && !state.NeckGuardWasSwinging) { state.NeckGuardLatched = state.CrouchBlend >= 0.9f; } state.NeckGuardWasSwinging = flag; if (flag) { state.NeckGuardTail = 0.6f; } else if (state.NeckGuardTail > 0f) { state.NeckGuardTail -= Time.deltaTime; } bool flag2 = flag || state.NeckGuardTail > 0f; bool flag3 = state.NeckGuardLatched && player.isCrouching && flag2; if (player.isCrouching && !flag2) { state.NeckGuardCrouchRestZ = live.z; state.NeckGuardCrouchRestY = live.y; } bool flag4 = flag2 && player.isCrouching && !state.NeckGuardLatched; if (flag4 && !state.NeckGuardFloorActive) { state.NeckGuardFloorZ = Mathf.Max(state.NeckGuardCrouchRestZ, 0.35f); state.NeckGuardFloorActive = true; } else if (!flag4) { state.NeckGuardFloorActive = false; } if (state.NeckGuardEngaged && !flag3 && !flag4) { state.NeckGuardRelease = 0.8f; } else if (state.NeckGuardRelease > 0f) { state.NeckGuardRelease -= Time.deltaTime; } state.NeckGuardEngaged = flag3 || flag4; if (!flag3) { state.SwingRest = live; } Vector3 swingRest = state.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 (state.NeckGuardFloorActive) { val.z = Mathf.Max(live.z, state.NeckGuardFloorZ); float neckGuardCrouchRestY = state.NeckGuardCrouchRestY; val.y = ((!flag) ? neckGuardCrouchRestY : ((live.y >= neckGuardCrouchRestY) ? (neckGuardCrouchRestY + (live.y - neckGuardCrouchRestY) * 1f) : (neckGuardCrouchRestY + (live.y - neckGuardCrouchRestY) * 0f))); } bool flag5 = flag3 || (flag2 && player.isCrouching); float num = (flag5 ? 0.12f : ((!(state.NeckGuardRelease > 0f)) ? 0.015f : Mathf.Lerp(0.015f, 0.12f, state.NeckGuardRelease / 0.8f))); float num2 = (flag5 ? 0.12f : 0.015f); float x = state.GuardedEyeVelocity.x; float y = state.GuardedEyeVelocity.y; float z = state.GuardedEyeVelocity.z; state.GuardedEyeDeviation = new Vector3(Mathf.SmoothDamp(state.GuardedEyeDeviation.x, val.x, ref x, num), Mathf.SmoothDamp(state.GuardedEyeDeviation.y, val.y, ref y, num2), Mathf.SmoothDamp(state.GuardedEyeDeviation.z, val.z, ref z, num)); state.GuardedEyeVelocity = new Vector3(x, y, z); return state.GuardedEyeDeviation; } private static Vector3 ResolveWallCollision(Vector3 origin, Vector3 desired) { //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_0018: 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_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) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) StartOfRound instance = StartOfRound.Instance; if ((Object)(object)instance == (Object)null) { return desired; } Vector3 val = desired - origin; float magnitude = ((Vector3)(ref val)).magnitude; if (magnitude < 0.0001f) { return desired; } Vector3 val2 = val / magnitude; float num = Mathf.Max(0.01f, 0.11f); RaycastHit val3 = default(RaycastHit); if (Physics.SphereCast(origin, num, val2, ref val3, magnitude, instance.collidersAndRoomMask, (QueryTriggerInteraction)1)) { float num2 = Mathf.Clamp(((RaycastHit)(ref val3)).distance, 0f, magnitude); return origin + val2 * num2; } return desired; } public static void RestoreOffset(LocalBodyState state) { //IL_00ae: Unknown result type (might be due to invalid IL or missing references) state.CrouchBlend = 0f; state.LadderBlend = 0f; state.BobDampBlend = 0f; state.HoldBlend = 0f; state.RunBlend = 0f; state.JumpBlend = 0f; state.NeckGuardInitialized = false; state.NeckGuardTail = 0f; state.NeckGuardRelease = 0f; state.NeckGuardFloorActive = false; state.DeviationSmoothInitialized = false; state.DisableBobSmoothInitialized = false; state.DisableBobBlend = 0f; state.HasCameraTarget = 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<Renderer>(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<HeldItemFadeMode> HeldItemFadeStyle; public static ConfigEntry<HandsMode> Hands; public static ConfigEntry<ItemDitherMode> ItemDither; public static ConfigEntry<float> HandOffsetZ; public static ConfigEntry<bool> DisableHeadBob; public static ConfigEntry<bool> EnableMoreCompanyCompatibility; public static ConfigEntry<bool> EnableTooManyEmotesCompatibility; public static ConfigEntry<bool> ShowMoreCompanyHat; public static ConfigEntry<bool> ShowMoreCompanyChest; public static ConfigEntry<bool> ShowMoreCompanyHip; public static ConfigEntry<bool> ShowMoreCompanyRightLowerArm; public static ConfigEntry<bool> ShowMoreCompanyLeftShin; public static ConfigEntry<bool> ShowMoreCompanyRightShin; internal static void Initialize(ConfigFile config) { //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Expected O, but got Unknown EnableMoreCompanyCompatibility = config.Bind<bool>("1. Compatibility", "Enable MoreCompany Compatibility", true, "Show your MoreCompany cosmetics in first person when MoreCompany is installed."); EnableTooManyEmotesCompatibility = config.Bind<bool>("1. Compatibility", "Enable TooManyEmotes Compatibility", true, "Keep the camera on your head during a TooManyEmotes first-person emote. Takes effect on restart."); ShowMoreCompanyHat = config.Bind<bool>("1. Compatibility", "ShowHat", false, "Show hat cosmetics. False by default to prevent hats from clipping into the camera."); ShowMoreCompanyChest = config.Bind<bool>("1. Compatibility", "ShowChest", true, "Show chest cosmetics."); ShowMoreCompanyHip = config.Bind<bool>("1. Compatibility", "ShowHip", true, "Show hip cosmetics."); ShowMoreCompanyRightLowerArm = config.Bind<bool>("1. Compatibility", "ShowRightLowerArm", true, "Show right lower arm cosmetics."); ShowMoreCompanyLeftShin = config.Bind<bool>("1. Compatibility", "ShowLeftShin", true, "Show left shin cosmetics."); ShowMoreCompanyRightShin = config.Bind<bool>("1. Compatibility", "ShowRightShin", true, "Show right shin cosmetics."); HeldItemFadeStyle = config.Bind<HeldItemFadeMode>("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<ItemDitherMode>("2. Held Item", "ItemDither", ItemDitherMode.ThirdPerson, "Which hands mode the held item dithers in."); HandOffsetZ = config.Bind<float>("2. Held Item", "HandOffsetZ", 0f, new ConfigDescription("First-person hand offset.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-1f, 1f), Array.Empty<object>())); Hands = config.Bind<HandsMode>("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."); DisableHeadBob = config.Bind<bool>("4. Camera", "DisableHeadBob", false, "Disable head bobbing from walking and running animations."); } } internal static class Constants { public const string ScavengerModelName = "ScavengerModel"; public const string MetarigName = "metarig"; public const string HeadBoneName = "spine.004"; public const string LeftArmBoneName = "shoulder.L"; public const string RightArmBoneName = "shoulder.R"; 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 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 FollowStrengthVertical = 1f; public const float FollowStrengthHorizontal = 1f; public const float SprintBobReduction = 0.6f; public const float MaxFollowOffset = 0.5f; public const float EyeOffsetForward = 0.13f; public const float EyeOffsetForwardOnLadder = 0f; public const float EyeOffsetUp = 0f; public const float EyeOffsetRight = 0f; public const float CrouchEyeOffsetUp = 0.12f; public const float HoldingEyeOffsetForward = 0.15f; public const float HoldingEyeOffsetUp = 0.07f; public const float HoldingBlendTime = 0.18f; public const float RunningEyeOffsetForward = 0.1f; public const float RunningEyeOffsetUp = 0.05f; public const float RunningBlendTime = 0.18f; public const float JumpingEyeOffsetForward = 0.13f; public const float JumpingEyeOffsetUp = 0f; public const float JumpingBlendTime = 0.18f; public const bool EnableWallCollision = true; public const float WallCollisionRadius = 0.11f; 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 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 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 float CrouchBlend; public float LadderBlend; public float BobDampBlend; public float HoldBlend; public float RunBlend; public float JumpBlend; public Vector3 SmoothedDeviationLocal; public bool DeviationSmoothInitialized; public float DisableBobSmoothedY; public bool DisableBobSmoothInitialized; public float DisableBobBlend; public Vector3 SwingRest; public Vector3 GuardedEyeDeviation; public Vector3 GuardedEyeVelocity; public float NeckGuardTail; public float NeckGuardRelease; public float NeckGuardFloorZ; public float NeckGuardCrouchRestZ; public float NeckGuardCrouchRestY; public bool NeckGuardFloorActive; public bool NeckGuardInitialized; public bool NeckGuardLatched; public bool NeckGuardWasSwinging; public bool NeckGuardEngaged; public Vector3 EyeAnchorLocal; public Vector3 EyeAnchorBoneLocal; public bool EyeAnchorCaptured; } internal static class LocalBodyViewController { private static readonly Dictionary<int, LocalBodyState> States = new Dictionary<int, LocalBodyState>(); private static bool renderCallbacksHooked; internal static bool LocalBodyShown; private static readonly (Action<Camera> Apply, Action<Camera> Restore)[] CameraPasses = new(Action<Camera>, Action<Camera>)[2] { (FirstPersonBody.ApplyForCamera, FirstPersonBody.RestoreAfterCamera), (HeldItemView.ApplyForCamera, HeldItemView.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(); MeshSurgery.ClearCaches(); if (renderCallbacksHooked) { RenderPipelineManager.beginCameraRendering -= OnBeginCameraRendering; RenderPipelineManager.endCameraRendering -= OnEndCameraRendering; renderCallbacksHooked = false; } } public static void Tick(PlayerControllerB player) { if (Players.IsLocal(player)) { EnsureRenderCallbacksHooked(); LocalBodyState orCreateState = GetOrCreateState(player); if (NeedsRefresh(orCreateState, player)) { RefreshState(orCreateState, player); } bool flag = (LocalBodyShown = player.isPlayerControlled && !player.isPlayerDead); bool flag2 = flag && Players.IsActivelyHolding(player) && !player.inSpecialInteractAnimation && ConfigManager.Hands.Value == HandsMode.Vanilla; FirstPersonBody.ApplyBodyRendering(orCreateState, flag, flag2); FirstPersonBody.ApplyFirstPersonCameraLayer(orCreateState, flag); HeldItemView.ApplyHolder(orCreateState, player, flag, flag2); if (flag) { FirstPersonBody.HideHead(orCreateState, flag2); } else { FirstPersonBody.RestoreHead(orCreateState); } if (flag && !VisorRig.IsImmersiveVisorPresent()) { VisorRig.StickToCamera(orCreateState); } else { VisorRig.Restore(orCreateState); } VisorRig.SuppressVanillaCrack(orCreateState, VisorRig.IsImmersiveVisorPresent()); if (flag && !player.inTerminalMenu) { CameraRig.ApplyOffset(orCreateState, player); } else { CameraRig.RestoreOffset(orCreateState); } CameraRig.ApplyArmAnchor(player, flag2); CameraRig.RelaxSeatedLookClamp(player); MoreCompanyCompat.ApplyLocalCosmeticVisibility(player, flag, flag2); } } public static void AlignCameraForInteractionRay(PlayerControllerB player) { if (Players.IsLocal(player) && States.TryGetValue(((Object)player).GetInstanceID(), out LocalBodyState value)) { CameraRig.AlignForInteractionRay(value); } } 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, "shoulder.L"); state.RightArmBone = FindBodyBone(player, "shoulder.R"); state.BodyRenderer = player.thisPlayerModel; 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<Transform> queue = new Queue<Transform>(); 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<Camera>, Action<Camera>)[] cameraPasses = CameraPasses; for (int i = 0; i < cameraPasses.Length; i++) { (Action<Camera>, Action<Camera>) tuple = cameraPasses[i]; tuple.Item1(camera); } } private static void OnEndCameraRendering(ScriptableRenderContext context, Camera camera) { (Action<Camera>, Action<Camera>)[] cameraPasses = CameraPasses; for (int i = 0; i < cameraPasses.Length; i++) { (Action<Camera>, Action<Camera>) 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"; } internal static class Players { 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 IsHoldingTwoHanded(PlayerControllerB player) { return player.twoHanded; } } [BepInPlugin("com.seeya.firstpersonview", "First-Person View", "1.0.1")] [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(); _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_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: 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 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 ((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) { fpArms = player.thisPlayerModelArms; fpArmsIntended = enabled; if ((Object)(object)fpArms != (Object)null && ((Renderer)fpArms).enabled != enabled) { ((Renderer)fpArms).enabled = enabled; } } 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<SkinnedMeshRenderer>(); 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<Renderer>(); private static MotionVectorGenerationMode[] originalMotionModes = Array.Empty<MotionVectorGenerationMode>(); private static Material[] materials = Array.Empty<Material>(); private static Renderer? boundsSource; private static Vector3[] localVertices = Array.Empty<Vector3>(); private static Camera? camera; private static bool hideActive; private static float fadeCurrent = 1f; private static bool fpItemActive; private static Transform? localHolder; private static Transform? serverHolder; private static Transform? itemTransform; private static bool itemRepositioned; private static Vector3 cachedItemPos; private static Quaternion cachedItemRot; 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<Renderer>() : Array.Empty<Renderer>()); SuppressMotionVectors(); materials = (Material[])(flag2 ? ((Array)MaterialDither.CollectInstancedMaterials(renderers)) : ((Array)Array.Empty<Material>())); 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; bool flag3 = (fpItemActive = useVanillaArms && showBody && flag && !isInspectingItem && (Object)(object)currentlyHeldObjectServer != (Object)null); localHolder = player.localItemHolder; serverHolder = player.serverItemHolder; itemTransform = (flag3 ? ((Component)currentlyHeldObjectServer).transform : null); } public static void ApplyForCamera(Camera renderingCamera) { RepositionForCamera(renderingCamera); if (hideActive && renderers.Length != 0 && DitherEnabled()) { float fade = (((Object)(object)renderingCamera == (Object)(object)camera) ? ComputeFade(renderingCamera) : 1f); ApplyFade(fade); } } private static void RepositionForCamera(Camera renderingCamera) { //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_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //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_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //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_0096: 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_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) if (fpItemActive && !itemRepositioned && !((Object)(object)itemTransform == (Object)null) && !((Object)(object)localHolder == (Object)null) && !((Object)(object)serverHolder == (Object)null) && !((Object)(object)renderingCamera == (Object)(object)camera)) { cachedItemPos = itemTransform.position; cachedItemRot = itemTransform.rotation; Vector3 val = localHolder.InverseTransformPoint(cachedItemPos); Quaternion val2 = Quaternion.Inverse(localHolder.rotation) * cachedItemRot; itemTransform.position = serverHolder.TransformPoint(val); itemTransform.rotation = serverHolder.rotation * val2; itemRepositioned = true; } } 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) { //IL_0019: 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) if (itemRepositioned && (Object)(object)itemTransform != (Object)null) { itemTransform.position = cachedItemPos; itemTransform.rotation = cachedItemRot; } itemRepositioned = false; 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<MeshFilter>(); val2 = ((component != null) ? component.sharedMesh : null); } } else { val2 = val.sharedMesh; } Mesh val3 = val2; if (!((Object)(object)val3 != (Object)null) || !val3.isReadable) { return Array.Empty<Vector3>(); } 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<MotionVectorGenerationMode>())); 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<MotionVectorGenerationMode>(); } public static void Reset() { ResetEffect(); RestoreMotionVectors(); trackedItem = null; renderers = Array.Empty<Renderer>(); materials = Array.Empty<Material>(); boundsSource = null; localVertices = Array.Empty<Vector3>(); camera = null; hideActive = false; fpItemActive = false; localHolder = null; serverHolder = null; itemTransform = null; itemRepositioned = 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<Material>(); } List<Material> list = new List<Material>(); 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<int, Mesh> HeadlessMeshCache = new Dictionary<int, Mesh>(); private static readonly Dictionary<int, Mesh> HeadlessArmlessMeshCache = new Dictionary<int, Mesh>(); private static readonly Dictionary<int, Mesh?> ReadableCopies = new Dictionary<int, Mesh>(); private static readonly HashSet<int> GeneratedMeshIds = new HashSet<int>(); private static readonly HashSet<int> LoggedUnreadableMeshes = new HashSet<int>(); 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) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0128: 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<int> headBoneIndices = GetHeadBoneIndices(skinned, headBone); HashSet<int> 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); } List<int> list = CollectSeamVertices(sourceMesh, array2, array3, array4); if (list.Count == 0) { return null; } Vector3[] vertices = sourceMesh.vertices; Vector3[] array5 = (Vector3[])vertices.Clone(); BoneWeight[] array6 = (BoneWeight[])boneWeights.Clone(); for (int j = 0; j < num; j++) { if (array4[j]) { int num2 = NearestVertex(vertices[j], list, vertices); array5[j] = vertices[num2]; array6[j] = boneWeights[num2]; } } Mesh val = Object.Instantiate<Mesh>(sourceMesh); ((Object)val).name = ((Object)sourceMesh).name + nameSuffix; val.vertices = array5; val.boneWeights = array6; for (int k = 0; k < val.subMeshCount; k++) { int[] triangles = sourceMesh.GetTriangles(k); List<int> list2 = new List<int>(triangles.Length); for (int l = 0; l < triangles.Length; l += 3) { int num3 = triangles[l]; int num4 = triangles[l + 1]; int num5 = triangles[l + 2]; if (!ShouldCullTriangle(num3, num4, num5, array2, array3) && (!array4[num3] || !array4[num4] || !array4[num5])) { list2.Add(num3); list2.Add(num4); list2.Add(num5); } } val.SetTriangles(list2, k); } val.RecalculateBounds(); return val; } private static List<int> CollectSeamVertices(Mesh mesh, float[] headInfluence, bool[] headDominant, bool[] armDominant) { HashSet<int> hashSet = new HashSet<int>(); 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 (!ShouldCullTriangle(num, num2, num3, headInfluence, headDominant) && (armDominant[num] || armDominant[num2] || armDominant[num3])) { if (!armDominant[num]) { hashSet.Add(num); } if (!armDominant[num2]) { hashSet.Add(num2); } if (!armDominant[num3]) { hashSet.Add(num3); } } } } return new List<int>(hashSet); } private static int NearestVertex(Vector3 point, List<int> 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<int> 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<int> 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]); } Mesh val = Object.Instantiate<Mesh>(sourceMesh); ((Object)val).name = ((Object)sourceMesh).name + nameSuffix; for (int j = 0; j < val.subMeshCount; j++) { int[] triangles = sourceMesh.GetTriangles(j); List<int> list = new List<int>(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<int> 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 IsDominatedBy(BoneWeight bw, HashSet<int> 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<int> GetHeadBoneIndices(SkinnedMeshRenderer skinned, Transform headBone) { HashSet<int> hashSet = new HashSet<int>(); 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<int> GetArmBoneIndices(SkinnedMeshRenderer skinned, Transform? leftArm, Transform? rightArm) { HashSet<int> hashSet = new HashSet<int>(); 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 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 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<byte>(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<byte>(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.0.1"; } } namespace FirstPersonView.Patches { [HarmonyPatch(typeof(PlayerControllerB))] internal static class LocalBodyViewPatches { private static readonly HashSet<string> _loggedTickErrors = new HashSet<string>(); [HarmonyPatch("ConnectClientToPlayerObject")] [HarmonyPostfix] private static void ConnectClientToPlayerObject_Postfix(PlayerControllerB __instance) { if ((Object)(object)StartOfRound.Instance?.localPlayerController == (Object)(object)__instance) { VehicleCompat.EnsurePatched(); 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) { LocalBodyViewController.AlignCameraForInteractionRay(__instance); } } } namespace FirstPersonView.Compat { internal static class MoreCompanyCompat { private static bool _initialized; private static bool _isInstalled; private static Type? _cosmeticApplicationType; private static Type? _cosmeticInstanceType; private static FieldInfo? _spawnedCosmeticsField; private static FieldInfo? _cosmeticTypeField; 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 ApplyLocalCosmeticVisibility(PlayerControllerB player, bool localBodyVisible, bool firstPersonArmsActive) { if (!_isInstalled || !ConfigManager.EnableMoreCompanyCompatibility.Value || !localBodyVisible || !TryResolveSpawnedCosmetics(player, out IEnumerable cosmetics)) { return; } foreach (object item in cosmetics) { Component val = (Component)((item is Component) ? item : null); if (val != null) { bool flag = ShouldShowCosmetic(item, firstPersonArmsActive); if (val.gameObject.activeSelf != flag) { val.gameObject.SetActive(flag); } } } } private static bool TryResolveSpawnedCosmetics(PlayerControllerB player, out IEnumerable cosmetics) { cosmetics = Array.Empty<object>(); if (!TryResolveTypes()) { return false; } if (_cosmeticApplicationType == null || _spawnedCosmeticsField == null) { return false; } Transform obj = ((Component)player).transform.Find("ScavengerModel"); Transform val = ((obj != null) ? obj.Find("metarig") : null); if ((Object)(object)val == (Object)null) { return false; } Component component = ((Component)val).GetComponent(_cosmeticApplicationType); if ((Object)(object)component == (Object)null) { return false; } object value = _spawnedCosmeticsField.GetValue(component); if (!(value is IEnumerable enumerable)) { return false; } cosmetics = enumerable; return true; } private static bool ShouldShowCosmetic(object cosmetic, bool firstPersonArmsActive) { if (_cosmeticTypeField == null) { return true; } string text = _cosmeticTypeField.GetValue(cosmetic)?.ToString() ?? string.Empty; if (firstPersonArmsActive && text.IndexOf("ARM", StringComparison.OrdinalIgnoreCase) >= 0) { return false; } return text switch { "HAT" => ConfigManager.ShowMoreCompanyHat.Value, "CHEST" => ConfigManager.ShowMoreCompanyChest.Value, "HIP" => ConfigManager.ShowMoreCompanyHip.Value, "R_LOWER_ARM" => ConfigManager.ShowMoreCompanyRightLowerArm.Value, "L_SHIN" => ConfigManager.ShowMoreCompanyLeftShin.Value, "R_SHIN" => ConfigManager.ShowMoreCompanyRightShin.Value, _ => true, }; } private static bool TryResolveTypes() { if (_cosmeticApplicationType != null && _spawnedCosmeticsField != null && _cosmeticInstanceType != null) { return true; } Assembly assembly = Reflection.FindAssembly("MoreCompany"); if (assembly == null) { return false; } _cosmeticApplicationType = assembly.GetType("MoreCompany.Cosmetics.CosmeticApplication"); _cosmeticInstanceType = assembly.GetType("MoreCompany.Cosmetics.CosmeticInstance"); if (_cosmeticApplicationType == null || _cosmeticInstanceType == null) { return false; } _spawnedCosmeticsField = _cosmeticApplicationType.GetField("spawnedCosmetics", BindingFlags.Instance | BindingFlags.Public); _cosmeticTypeField = _cosmeticInstanceType.GetField("cosmeticType", BindingFlags.Instance | BindingFlags.P