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 POV v1.0.3
BepInEx/plugins/FirstPersonPOV.dll
Decompiled 4 days 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.Globalization; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using TMPro; using UnityEngine; using UnityEngine.Rendering; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyFileVersion("1.0.5.0")] [assembly: AssemblyInformationalVersion("1.0.5")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = "")] [assembly: AssemblyVersion("1.0.5.0")] namespace JPValheim.FirstPersonPOV; internal static class BodyFade { private sealed class GroupState { internal LODGroup Group; internal LOD[] Lods; internal Vector3 Reference; internal float Size; internal LODFadeMode FadeMode; internal bool Animate; } private static readonly List<GroupState> Groups = new List<GroupState>(); private static readonly Dictionary<Renderer, bool> HiddenStates = new Dictionary<Renderer, bool>(); internal static void Apply(Camera camera, LODGroup group, Transform leftItem, Transform rightItem, float opacity, float leftOpacity, float rightOpacity, bool leftShield, bool rightShield) { Restore(); if (!(opacity >= 0.999f) || !(leftOpacity >= 0.999f) || !(rightOpacity >= 0.999f)) { if (leftShield && leftOpacity < 0.999f) { FadeHeldItem(camera, leftItem, leftOpacity, shield: true); } if (rightShield && rightOpacity < 0.999f) { FadeHeldItem(camera, rightItem, rightOpacity, shield: true); } if (opacity < 0.999f) { FadeGroup(camera, group, opacity); } if (!leftShield && leftOpacity < 0.999f) { FadeHeldItem(camera, leftItem, leftOpacity, shield: false); } if (!rightShield && rightOpacity < 0.999f) { FadeHeldItem(camera, rightItem, rightOpacity, shield: false); } } } private static void FadeHeldItem(Camera camera, Transform item, float opacity, bool shield) { if ((Object)(object)item == (Object)null) { return; } if (!shield) { LODGroup[] componentsInChildren = ((Component)item).GetComponentsInChildren<LODGroup>(true); foreach (LODGroup val in componentsInChildren) { FadeGroup(camera, val, opacity); } } Renderer[] componentsInChildren2 = ((Component)item).GetComponentsInChildren<Renderer>(true); foreach (Renderer renderer in componentsInChildren2) { if (opacity <= 0f) { HideRenderer(renderer); } else if (shield) { BodyShaderFade.ApplyShield(renderer, opacity); } else { BodyShaderFade.Apply(renderer, opacity); } } } private static void FadeGroup(Camera camera, LODGroup group, float opacity) { //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_01cb: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: Unknown result type (might be due to invalid IL or missing references) //IL_01e7: Unknown result type (might be due to invalid IL or missing references) //IL_01f5: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)group == (Object)null) { return; } foreach (GroupState group2 in Groups) { if ((Object)(object)group2.Group == (Object)(object)group) { return; } } LOD[] lODs = group.GetLODs(); if (lODs.Length == 0) { return; } Groups.Add(new GroupState { Group = group, Lods = lODs, Reference = group.localReferencePoint, Size = group.size, FadeMode = group.fadeMode, Animate = group.animateCrossFading }); HashSet<Renderer> hashSet = new HashSet<Renderer>(lODs[0].renderers); foreach (Renderer item in hashSet) { if (opacity <= 0f) { HideRenderer(item); } else { BodyShaderFade.Apply(item, opacity); } } for (int i = 1; i < lODs.Length; i++) { Renderer[] renderers = lODs[i].renderers; foreach (Renderer val in renderers) { if (!hashSet.Contains(val)) { HideRenderer(val); } } } LOD val2 = default(LOD); ((LOD)(ref val2))..ctor(0.01f, lODs[0].renderers); val2.fadeTransitionWidth = 1f; LOD val3 = val2; group.SetLODs((LOD[])(object)new LOD[1] { val3 }); group.fadeMode = (LODFadeMode)1; group.animateCrossFading = false; group.localReferencePoint = ((Component)group).transform.InverseTransformPoint(((Component)camera).transform.position + ((Component)camera).transform.forward * 10f); Vector3 lossyScale = ((Component)group).transform.lossyScale; float num = Mathf.Max(new float[4] { Mathf.Abs(lossyScale.x), Mathf.Abs(lossyScale.y), Mathf.Abs(lossyScale.z), 0.0001f }); group.size = 20f * Mathf.Tan(camera.fieldOfView * ((float)Math.PI / 180f) * 0.5f) * LookMath.FadeScreenHeight(opacity) / (Mathf.Max(QualitySettings.lodBias, 0.0001f) * num); } private static void HideRenderer(Renderer renderer) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Invalid comparison between Unknown and I4 if (!((Object)(object)renderer == (Object)null) && (int)renderer.shadowCastingMode != 3) { if (!HiddenStates.ContainsKey(renderer)) { HiddenStates.Add(renderer, renderer.forceRenderingOff); } renderer.forceRenderingOff = true; } } internal static void Restore() { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) BodyShaderFade.Restore(); foreach (GroupState group in Groups) { if ((Object)(object)group.Group != (Object)null) { group.Group.SetLODs(group.Lods); group.Group.localReferencePoint = group.Reference; group.Group.size = group.Size; group.Group.fadeMode = group.FadeMode; group.Group.animateCrossFading = group.Animate; } } Groups.Clear(); foreach (KeyValuePair<Renderer, bool> hiddenState in HiddenStates) { if ((Object)(object)hiddenState.Key != (Object)null) { hiddenState.Key.forceRenderingOff = hiddenState.Value; } } HiddenStates.Clear(); } internal static void Cleanup() { Restore(); BodyShaderFade.Cleanup(); } } internal static class BodyShaderFade { private sealed class Slot { internal readonly MaterialPropertyBlock Original = new MaterialPropertyBlock(); internal readonly MaterialPropertyBlock Working = new MaterialPropertyBlock(); internal bool Applied; } private sealed class RendererState { internal Renderer Renderer; internal Material[] Original; internal Material[] Assigned; internal readonly List<Slot> Slots = new List<Slot>(); internal bool Active; } private const string Keyword = "LOD_FADE_CROSSFADE"; private const string ShieldAlphaKeyword = "_SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A"; private static readonly int FadeId = Shader.PropertyToID("unity_LODFade"); private static readonly int ColorId = Shader.PropertyToID("_Color"); private static readonly Dictionary<Material, Material> Materials = new Dictionary<Material, Material>(); private static readonly Dictionary<Material, Material> ShieldMaterials = new Dictionary<Material, Material>(); private static readonly Dictionary<Renderer, RendererState> States = new Dictionary<Renderer, RendererState>(); private static readonly List<RendererState> Active = new List<RendererState>(); private static Shader _shieldShader; private static bool _missingShieldShader; internal static void Apply(Renderer renderer, float opacity) { ApplyMaterial(renderer, opacity, shield: false); } internal static void ApplyShield(Renderer renderer, float opacity) { ApplyMaterial(renderer, opacity, shield: true); } private static void ApplyMaterial(Renderer renderer, float opacity, bool shield) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Invalid comparison between Unknown and I4 //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0118: 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_0189: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Expected O, but got Unknown //IL_0290: Unknown result type (might be due to invalid IL or missing references) //IL_0254: Unknown result type (might be due to invalid IL or missing references) //IL_0259: Unknown result type (might be due to invalid IL or missing references) //IL_026f: Unknown result type (might be due to invalid IL or missing references) //IL_0241: Unknown result type (might be due to invalid IL or missing references) //IL_0233: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)renderer == (Object)null || (int)renderer.shadowCastingMode == 3 || renderer.forceRenderingOff || opacity <= 0f || opacity >= 0.999f || (shield && !EnsureShieldShader())) { return; } if (!States.TryGetValue(renderer, out var value)) { value = new RendererState { Renderer = renderer }; States.Add(renderer, value); } if (value.Active) { return; } Material[] sharedMaterials = renderer.sharedMaterials; if (value.Assigned == null || value.Assigned.Length != sharedMaterials.Length) { value.Assigned = (Material[])(object)new Material[sharedMaterials.Length]; } while (value.Slots.Count < sharedMaterials.Length) { value.Slots.Add(new Slot()); } bool flag = false; for (int i = 0; i < sharedMaterials.Length; i++) { Material val = sharedMaterials[i]; Slot slot = value.Slots[i]; slot.Applied = false; value.Assigned[i] = val; if ((Object)(object)val == (Object)null || (Object)(object)val.shader == (Object)null) { continue; } if (!shield) { LocalKeywordSpace keywordSpace = val.shader.keywordSpace; LocalKeyword val2 = ((LocalKeywordSpace)(ref keywordSpace)).FindKeyword("LOD_FADE_CROSSFADE"); if (!((LocalKeyword)(ref val2)).isValid) { continue; } } Shader val3 = (shield ? _shieldShader : val.shader); Dictionary<Material, Material> dictionary = (shield ? ShieldMaterials : Materials); if (!dictionary.TryGetValue(val, out var value2) || (Object)(object)value2 == (Object)null || (Object)(object)value2.shader != (Object)(object)val3) { if ((Object)(object)value2 != (Object)null) { Object.Destroy((Object)(object)value2); } value2 = (dictionary[val] = new Material(val) { shader = val3, hideFlags = (HideFlags)61 }); } value2.CopyPropertiesFromMaterial(val); if (shield) { ConfigureShieldMaterial(value2); } else { value2.EnableKeyword("LOD_FADE_CROSSFADE"); } value.Assigned[i] = value2; renderer.GetPropertyBlock(slot.Original, i); if (slot.Original.isEmpty) { renderer.GetPropertyBlock(slot.Working); } else { renderer.GetPropertyBlock(slot.Working, i); } if (shield) { Color val5 = (slot.Working.HasProperty(ColorId) ? slot.Working.GetColor(ColorId) : (val.HasProperty(ColorId) ? val.GetColor(ColorId) : Color.white)); val5.a = opacity; slot.Working.SetColor(ColorId, val5); } else { slot.Working.SetVector(FadeId, new Vector4(opacity, opacity, 0f, 0f)); } renderer.SetPropertyBlock(slot.Working, i); slot.Applied = true; flag = true; } if (flag) { value.Original = sharedMaterials; renderer.sharedMaterials = value.Assigned; value.Active = true; Active.Add(value); } } private static bool EnsureShieldShader() { //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_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_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_0073: 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) if ((Object)(object)_shieldShader != (Object)null) { return true; } if (_missingShieldShader) { return false; } _shieldShader = Shader.Find("Standard"); if ((Object)(object)_shieldShader != (Object)null && _shieldShader.isSupported) { LocalKeywordSpace keywordSpace = _shieldShader.keywordSpace; LocalKeyword val = ((LocalKeywordSpace)(ref keywordSpace)).FindKeyword("_ALPHABLEND_ON"); if (((LocalKeyword)(ref val)).isValid) { keywordSpace = _shieldShader.keywordSpace; val = ((LocalKeywordSpace)(ref keywordSpace)).FindKeyword("_SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A"); if (((LocalKeyword)(ref val)).isValid) { return true; } } } _shieldShader = null; _missingShieldShader = true; Debug.LogWarning((object)"First Person POV: Standard shield-fade shader is unavailable; shield keeps its normal appearance."); return false; } private static void ConfigureShieldMaterial(Material material) { material.DisableKeyword("LOD_FADE_CROSSFADE"); material.DisableKeyword("_ALPHATEST_ON"); material.DisableKeyword("_ALPHAPREMULTIPLY_ON"); material.EnableKeyword("_ALPHABLEND_ON"); material.EnableKeyword("_SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A"); material.SetFloat("_SmoothnessTextureChannel", 1f); material.SetFloat("_GlossMapScale", 0f); material.SetFloat("_Mode", 2f); material.SetFloat("_SrcBlend", 5f); material.SetFloat("_DstBlend", 10f); material.SetFloat("_ZWrite", 0f); material.SetOverrideTag("RenderType", "Transparent"); material.renderQueue = 3000; } internal static void Restore() { foreach (RendererState item in Active) { Renderer renderer = item.Renderer; if ((Object)(object)renderer != (Object)null) { Material[] sharedMaterials = renderer.sharedMaterials; bool flag = sharedMaterials.Length == item.Assigned.Length; int num = 0; while (flag && num < sharedMaterials.Length) { flag = (Object)(object)sharedMaterials[num] == (Object)(object)item.Assigned[num]; num++; } if (flag) { renderer.sharedMaterials = item.Original; } for (int i = 0; i < item.Original.Length && i < sharedMaterials.Length; i++) { Slot slot = item.Slots[i]; if (slot.Applied) { renderer.SetPropertyBlock(slot.Original.isEmpty ? null : slot.Original, i); } } } item.Active = false; } Active.Clear(); } internal static void Cleanup() { Restore(); foreach (Material value in Materials.Values) { if ((Object)(object)value != (Object)null) { Object.Destroy((Object)(object)value); } } foreach (Material value2 in ShieldMaterials.Values) { if ((Object)(object)value2 != (Object)null) { Object.Destroy((Object)(object)value2); } } Materials.Clear(); ShieldMaterials.Clear(); States.Clear(); _shieldShader = null; _missingShieldShader = false; } } internal sealed class BowPose { private Transform _leftShoulder; private Transform _rightShoulder; private Transform _leftHand; private Transform _rightHand; private Transform _leftForearm; private Transform _rightForearm; private Transform _skinRoot; private Vector3 _leftPosition; private Vector3 _rightPosition; private Quaternion _leftRotation; private Quaternion _rightRotation; private Quaternion _leftHandRotation; private Quaternion _rightHandRotation; private Quaternion _leftForearmRotation; private Quaternion _rightForearmRotation; private bool _leftBow; private bool _applied; private readonly List<SkinnedMeshRenderer> _renderers = new List<SkinnedMeshRenderer>(); private readonly List<bool> _originalSkinning = new List<bool>(); internal static Transform FindHandBone(Transform attachment, SkinnedMeshRenderer body) { if ((Object)(object)body == (Object)null) { return null; } Transform[] bones = body.bones; Transform val = attachment; while ((Object)(object)val != (Object)null) { Transform[] array = bones; foreach (Transform val2 in array) { if ((Object)(object)val2 != (Object)null && (Object)(object)val2 == (Object)(object)val) { return val2; } } val = val.parent; } return null; } internal void Configure(Transform leftShoulder, Transform rightShoulder, Transform leftHand, Transform rightHand, bool leftBow, Transform skinRoot = null) { Reset(); if (!((Object)(object)leftShoulder == (Object)null) && !((Object)(object)rightShoulder == (Object)null) && !((Object)(object)leftHand == (Object)null) && !((Object)(object)rightHand == (Object)null) && !leftShoulder.IsChildOf(rightShoulder) && !rightShoulder.IsChildOf(leftShoulder) && !((Object)(object)leftHand == (Object)(object)leftShoulder) && !((Object)(object)rightHand == (Object)(object)rightShoulder) && leftHand.IsChildOf(leftShoulder) && rightHand.IsChildOf(rightShoulder)) { _leftShoulder = leftShoulder; _rightShoulder = rightShoulder; _leftHand = leftHand; _rightHand = rightHand; _leftForearm = (((Object)(object)leftHand.parent != (Object)(object)leftShoulder) ? leftHand.parent : null); _rightForearm = (((Object)(object)rightHand.parent != (Object)(object)rightShoulder) ? rightHand.parent : null); _skinRoot = skinRoot; _leftBow = leftBow; } } internal bool Apply(Vector3 aimDirection, float weight, float rollDegrees = 0f) { //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_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_0096: 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_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: 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_00d5: 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_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: Unknown result type (might be due to invalid IL or missing references) //IL_01be: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: Unknown result type (might be due to invalid IL or missing references) //IL_01da: Unknown result type (might be due to invalid IL or missing references) //IL_01db: Unknown result type (might be due to invalid IL or missing references) //IL_01e2: Unknown result type (might be due to invalid IL or missing references) //IL_01e7: Unknown result type (might be due to invalid IL or missing references) //IL_01e8: 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_01f2: Unknown result type (might be due to invalid IL or missing references) //IL_0202: Unknown result type (might be due to invalid IL or missing references) //IL_0209: Unknown result type (might be due to invalid IL or missing references) //IL_020e: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_0184: 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_0228: Unknown result type (might be due to invalid IL or missing references) //IL_022d: Unknown result type (might be due to invalid IL or missing references) //IL_023a: 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) Restore(); if ((Object)(object)_leftShoulder == (Object)null || (Object)(object)_rightShoulder == (Object)null || (Object)(object)_leftHand == (Object)null || (Object)(object)_rightHand == (Object)null || weight <= 0f || ((Vector3)(ref aimDirection)).sqrMagnitude < 0.0001f) { return false; } Vector3 val = (_leftBow ? (_leftHand.position - _rightHand.position) : (_rightHand.position - _leftHand.position)); if (((Vector3)(ref val)).sqrMagnitude < 0.0001f) { return false; } Quaternion val2 = Quaternion.Slerp(Quaternion.identity, Quaternion.FromToRotation(val, aimDirection), Mathf.Clamp01(weight)); Vector3 val3 = (_leftShoulder.position + _rightShoulder.position) * 0.5f; _leftPosition = _leftShoulder.localPosition; _rightPosition = _rightShoulder.localPosition; _leftRotation = _leftShoulder.localRotation; _rightRotation = _rightShoulder.localRotation; _leftHandRotation = _leftHand.localRotation; _rightHandRotation = _rightHand.localRotation; if ((Object)(object)_leftForearm != (Object)null) { _leftForearmRotation = _leftForearm.localRotation; } if ((Object)(object)_rightForearm != (Object)null) { _rightForearmRotation = _rightForearm.localRotation; } _applied = true; _leftShoulder.position = val3 + val2 * (_leftShoulder.position - val3); _leftShoulder.rotation = val2 * _leftShoulder.rotation; _rightShoulder.position = val3 + val2 * (_rightShoulder.position - val3); _rightShoulder.rotation = val2 * _rightShoulder.rotation; if (Mathf.Abs(rollDegrees) >= 0.05f) { Quaternion roll = Quaternion.AngleAxis(0f - rollDegrees, aimDirection); TwistHand(_leftHand, _leftForearm, roll, rollDegrees); TwistHand(_rightHand, _rightForearm, roll, rollDegrees); } if ((Object)(object)_skinRoot != (Object)null) { ((Component)_skinRoot).GetComponentsInChildren<SkinnedMeshRenderer>(true, _renderers); foreach (SkinnedMeshRenderer renderer in _renderers) { _originalSkinning.Add(renderer.forceMatrixRecalculationPerRender); renderer.forceMatrixRecalculationPerRender = true; } } return true; } private static void TwistHand(Transform hand, Transform forearm, Quaternion roll, float degrees) { //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_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_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_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0034: 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) Quaternion rotation = hand.rotation; if ((Object)(object)forearm != (Object)null) { Vector3 val = hand.position - forearm.position; if (((Vector3)(ref val)).sqrMagnitude > 0.0001f) { forearm.rotation = Quaternion.AngleAxis(0f - degrees, val) * forearm.rotation; } } hand.rotation = roll * rotation; } internal void Restore() { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_002f: 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_005f: 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_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) if (!_applied) { return; } if ((Object)(object)_leftShoulder != (Object)null) { _leftShoulder.localPosition = _leftPosition; _leftShoulder.localRotation = _leftRotation; } if ((Object)(object)_rightShoulder != (Object)null) { _rightShoulder.localPosition = _rightPosition; _rightShoulder.localRotation = _rightRotation; } if ((Object)(object)_leftForearm != (Object)null) { _leftForearm.localRotation = _leftForearmRotation; } if ((Object)(object)_rightForearm != (Object)null) { _rightForearm.localRotation = _rightForearmRotation; } if ((Object)(object)_leftHand != (Object)null) { _leftHand.localRotation = _leftHandRotation; } if ((Object)(object)_rightHand != (Object)null) { _rightHand.localRotation = _rightHandRotation; } for (int i = 0; i < _renderers.Count; i++) { if ((Object)(object)_renderers[i] != (Object)null) { _renderers[i].forceMatrixRecalculationPerRender = _originalSkinning[i]; } } _renderers.Clear(); _originalSkinning.Clear(); _applied = false; } internal void Reset() { Restore(); _leftShoulder = (_rightShoulder = (_leftHand = (_rightHand = null))); _leftForearm = (_rightForearm = (_skinRoot = null)); } } internal sealed class RollVisibility { private bool _rolling; private float _until; internal bool Update(bool rolling, float time) { if (rolling && !_rolling) { _until = time + 2f; } _rolling = rolling; if (!rolling) { return time < _until; } return true; } internal void Reset() { _rolling = false; _until = 0f; } } internal static class CameraFeatures { internal static Vector3 EyeForward(Quaternion viewYaw, float distance) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) return viewYaw * new Vector3(0f, 0f, distance); } internal static float Fov(float firstPerson, float native, float nativeBase, bool effect) { float num = ((effect && nativeBase > 0f) ? (native - nativeBase) : 0f); return Math.Max(1f, Math.Min(179f, firstPerson + num)); } internal static float ShieldOpacity(float bodyOpacity, float transparency, bool blocking) { float val = (blocking ? (1f - Math.Max(0f, Math.Min(100f, transparency)) / 100f) : 1f); return Math.Min(bodyOpacity, val); } internal static float RollOpacity(float bodyOpacity, bool rolling) { if (!rolling) { return bodyOpacity; } return Math.Min(bodyOpacity, 0.1f); } internal static float HelmLimit(float normal, float multiplier) { return normal * Math.Max(1f, Math.Min(8f, multiplier)); } } internal static class ConfigMigration { internal const string LegacyGuid = "jpvalheim.naturalfirstperson"; internal static string CurrentName(string name) { return name.ToLowerInvariant() switch { "softyawdegrees" => "BodyTurnStartAngle", "yawresistancestart" => "SidewaysSlowdownStart", "yawresistancewidth" => "SidewaysSlowdownRange", "maxyawdegrees" => "MaxSidewaysLook", "poseresidualsmoothing" => "AnimationSmoothing", _ => name, }; } internal static HashSet<ConfigDefinition> ReadDefinitions(string path) { //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Expected O, but got Unknown HashSet<ConfigDefinition> hashSet = new HashSet<ConfigDefinition>(); if (!File.Exists(path)) { return hashSet; } string text = ""; string[] array = File.ReadAllLines(path); for (int i = 0; i < array.Length; i++) { string text2 = array[i].Trim(); if (text2.Length == 0 || text2.StartsWith("#")) { continue; } if (text2.StartsWith("[") && text2.EndsWith("]")) { text = text2.Substring(1, text2.Length - 2).Trim(); continue; } int num = text2.IndexOf('='); if (num > 0) { hashSet.Add(new ConfigDefinition(text, text2.Substring(0, num).Trim())); } } return hashSet; } internal static ConfigEntry<T> Bind<T>(ConfigFile config, HashSet<ConfigDefinition> saved, string oldSection, string section, string oldName, T defaultValue, ConfigDescription description) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Expected O, but got Unknown //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown ConfigDefinition val = new ConfigDefinition(oldSection, oldName); ConfigDefinition val2 = new ConfigDefinition(section, CurrentName(oldName)); ConfigEntry<T> val3 = config.Bind<T>(val2, defaultValue, description); if (saved.Contains(val) && !val.Equals(val2)) { ConfigEntry<T> val4 = config.Bind<T>(val, defaultValue, (ConfigDescription)null); if (!saved.Contains(val2)) { val3.Value = val4.Value; } config.Remove(val); } return val3; } internal static float? Import(ConfigFile config, string legacyPath) { //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_002d: Unknown result type (might be due to invalid IL or missing references) if (File.Exists(config.ConfigFilePath) || !File.Exists(legacyPath)) { return null; } ConfigFile val = new ConfigFile(legacyPath, false) { SaveOnConfigSet = false }; float value = val.Bind<float>("Body Awareness", "HardYawDegrees", 75f, (ConfigDescription)null).Value; float value2 = val.Bind<float>("Body Awareness", "SoftYawDegrees", 40f, (ConfigDescription)null).Value; float num = Math.Min(90f, Math.Max(value, value2) + 10f); if (float.IsNaN(num) || float.IsInfinity(num)) { num = 85f; } File.Copy(legacyPath, config.ConfigFilePath); config.Reload(); config.Remove(((ConfigEntryBase)config.Bind<float>("Body Awareness", "HardYawDegrees", 75f, (ConfigDescription)null)).Definition); config.Remove(((ConfigEntryBase)config.Bind<int>("Internal", "LookDefaultsRevision", 0, (ConfigDescription)null)).Definition); return num; } } internal sealed class EyeAnchor { private Vector3 _neutralEyeLocal; private Vector3 _neutralEyeRelativeToVisual; private Vector3 _headToEye; private Vector3 _filtered; private bool _needsNeutralCalibration; private bool _snap; internal static bool TryGetReferenceHead(Transform root, Transform head, SkinnedMeshRenderer body, out Vector3 position) { //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_0061: 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_0069: 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_0073: 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) position = Vector3.zero; if ((Object)(object)head == (Object)null || (Object)(object)body == (Object)null || (Object)(object)body.sharedMesh == (Object)null) { return false; } int num = Array.IndexOf(body.bones, head); Matrix4x4[] bindposes = body.sharedMesh.bindposes; if (num < 0 || num >= bindposes.Length) { return false; } Transform transform = ((Component)body).transform; Matrix4x4 inverse = ((Matrix4x4)(ref bindposes[num])).inverse; position = root.InverseTransformPoint(transform.TransformPoint(((Matrix4x4)(ref inverse)).MultiplyPoint3x4(Vector3.zero))); return true; } internal void Initialize(Vector3 eyeLocal, Vector3 visualLocal, Vector3 headLocal, bool hasHead, bool neutralPose, bool moving) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_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_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0034: 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_0039: Unknown result type (might be due to invalid IL or missing references) _neutralEyeLocal = eyeLocal; _neutralEyeRelativeToVisual = eyeLocal - visualLocal; _headToEye = (Vector3)((hasHead && neutralPose) ? (eyeLocal - headLocal) : new Vector3(0f, 0.1f, 0f)); _needsNeutralCalibration = !neutralPose || moving; ResetMotion(); } internal Vector3 Evaluate(Vector3 eyeLocal, Vector3 visualLocal, Vector3 headLocal, bool hasHead, bool neutralPose, bool atRest, float dt, float smoothing) { //IL_000f: 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_002c: 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_002e: Unknown result type (might be due to invalid IL or missing references) //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_004b: 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_008d: Unknown result type (might be due to invalid IL or missing references) //IL_001f: 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_0026: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: 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_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_010c: 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) if (_needsNeutralCalibration && neutralPose && atRest) { Initialize(eyeLocal, visualLocal, headLocal, hasHead, neutralPose: true, moving: false); } if (hasHead) { return headLocal + _headToEye; } Vector3 val = eyeLocal - visualLocal - _neutralEyeRelativeToVisual; val.x = Math.Max(-0.015f, Math.Min(0.015f, val.x)); val.z = Math.Max(-0.02f, Math.Min(0.02f, val.z)); val.y = Math.Max(-0.3f, Math.Min(0.1f, val.y)); float num = ((smoothing <= 0f) ? 1f : (1f - (float)Math.Exp((0f - Math.Max(0f, dt)) / smoothing))); _filtered = (_snap ? val : (_filtered + (val - _filtered) * num)); _snap = false; return _neutralEyeLocal + _filtered; } internal void ResetMotion() { //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) _filtered = Vector3.zero; _snap = true; } } internal sealed class FirstPersonBody { private sealed class Entry { internal Renderer Source; internal Renderer Shadow; internal Mesh Original; internal ShadowCastingMode Mode; internal bool Hidden; internal bool Applied; internal bool SkinRefresh; internal readonly MaterialPropertyBlock Block = new MaterialPropertyBlock(); } private readonly Dictionary<Renderer, Entry> _entries = new Dictionary<Renderer, Entry>(); private readonly List<Renderer> _renderers = new List<Renderer>(); private readonly List<Renderer> _removed = new List<Renderer>(); private Transform _root; private Transform _head; private ShadowHeadPose _shadowPose; private Vector3 _headScale; private bool _active; internal void Apply(Transform root, Transform head, Transform helmet, Transform hair, Transform beard, bool showShadow) { //IL_0380: Unknown result type (might be due to invalid IL or missing references) //IL_0385: Unknown result type (might be due to invalid IL or missing references) //IL_038c: Unknown result type (might be due to invalid IL or missing references) //IL_0396: Unknown result type (might be due to invalid IL or missing references) //IL_0214: Unknown result type (might be due to invalid IL or missing references) //IL_0219: Unknown result type (might be due to invalid IL or missing references) //IL_030f: Unknown result type (might be due to invalid IL or missing references) //IL_0315: Invalid comparison between Unknown and I4 if ((Object)(object)_root != (Object)(object)root || (Object)(object)_head != (Object)(object)head) { Cleanup(); _root = root; _head = head; _shadowPose = new ShadowHeadPose(head, CreatePoseTransform, DestroyPoseTransform); } if (_active || (Object)(object)root == (Object)null) { return; } ((Component)root).GetComponentsInChildren<Renderer>(true, _renderers); _removed.Clear(); foreach (KeyValuePair<Renderer, Entry> entry in _entries) { if ((Object)(object)entry.Key == (Object)null || !_renderers.Contains(entry.Key)) { _removed.Add(entry.Key); } } foreach (Renderer item in _removed) { Release(_entries[item]); _entries.Remove(item); } foreach (Renderer renderer in _renderers) { if ((Object)(object)renderer == (Object)null || (Object)(object)((Component)renderer).GetComponent<FirstPersonShadow>() != (Object)null) { continue; } bool flag = Under(((Component)renderer).transform, helmet) || Under(((Component)renderer).transform, hair) || Under(((Component)renderer).transform, beard); Mesh val = MeshOf(renderer); if (_entries.TryGetValue(renderer, out var value) && (Object)(object)val != (Object)(object)value.Original) { Release(value); _entries.Remove(renderer); value = null; } if (value == null) { value = new Entry { Source = renderer, Original = val }; CreateShadow(value); _entries.Add(renderer, value); } value.Mode = renderer.shadowCastingMode; value.Hidden = renderer.forceRenderingOff; value.Applied = true; SkinnedMeshRenderer val2 = (SkinnedMeshRenderer)(object)((renderer is SkinnedMeshRenderer) ? renderer : null); if ((Object)(object)val2 != (Object)null) { value.SkinRefresh = val2.forceMatrixRecalculationPerRender; val2.forceMatrixRecalculationPerRender = true; } if ((Object)(object)value.Shadow != (Object)null) { Material[] sharedMaterials = renderer.sharedMaterials; value.Shadow.sharedMaterials = sharedMaterials; renderer.GetPropertyBlock(value.Block); value.Shadow.SetPropertyBlock(value.Block); for (int i = 0; i < sharedMaterials.Length; i++) { renderer.GetPropertyBlock(value.Block, i); value.Shadow.SetPropertyBlock(value.Block.isEmpty ? null : value.Block, i); } value.Shadow.enabled = showShadow && renderer.enabled && !value.Hidden && (int)value.Mode > 0; Renderer shadow = value.Shadow; CopyBlendShapes(val2, (SkinnedMeshRenderer)(object)((shadow is SkinnedMeshRenderer) ? shadow : null)); } renderer.shadowCastingMode = (ShadowCastingMode)0; if (flag) { renderer.forceRenderingOff = true; } } if (_shadowPose != null) { _shadowPose.Capture(); } if ((Object)(object)head != (Object)null) { _headScale = head.localScale; head.localScale = _headScale * 0.0001f; } _active = true; } private static bool Under(Transform child, Transform parent) { if ((Object)(object)parent != (Object)null) { return child.IsChildOf(parent); } return false; } private static Mesh MeshOf(Renderer renderer) { SkinnedMeshRenderer val = (SkinnedMeshRenderer)(object)((renderer is SkinnedMeshRenderer) ? renderer : null); if ((Object)(object)val != (Object)null) { return val.sharedMesh; } MeshFilter component = ((Component)renderer).GetComponent<MeshFilter>(); if (!((Object)(object)component != (Object)null)) { return null; } return component.sharedMesh; } private static Transform CreatePoseTransform() { //IL_0005: 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) return new GameObject("FirstPersonPOV shadow pose") { hideFlags = (HideFlags)61 }.transform; } private static void DestroyPoseTransform(Transform transform) { if ((Object)(object)transform != (Object)null) { Object.Destroy((Object)(object)((Component)transform).gameObject); } } private void CreateShadow(Entry entry) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Expected O, but got Unknown //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)entry.Original == (Object)null) { return; } Renderer source = entry.Source; SkinnedMeshRenderer val = (SkinnedMeshRenderer)(object)((source is SkinnedMeshRenderer) ? source : null); if ((Object)(object)val == (Object)null && !(entry.Source is MeshRenderer)) { return; } GameObject val2 = new GameObject("FirstPersonPOV shadow") { hideFlags = (HideFlags)61 }; val2.AddComponent<FirstPersonShadow>(); val2.layer = ((Component)entry.Source).gameObject.layer; val2.transform.SetParent(_shadowPose.Resolve(((Component)entry.Source).transform), false); if ((Object)(object)val != (Object)null) { SkinnedMeshRenderer val3 = val2.AddComponent<SkinnedMeshRenderer>(); val3.sharedMesh = entry.Original; Transform[] bones = val.bones; for (int i = 0; i < bones.Length; i++) { bones[i] = _shadowPose.Resolve(bones[i]); } val3.bones = bones; val3.rootBone = _shadowPose.Resolve(val.rootBone); ((Renderer)val3).localBounds = ((Renderer)val).localBounds; val3.quality = val.quality; val3.updateWhenOffscreen = true; val3.forceMatrixRecalculationPerRender = true; entry.Shadow = (Renderer)(object)val3; } else { val2.AddComponent<MeshFilter>().sharedMesh = entry.Original; entry.Shadow = (Renderer)(object)val2.AddComponent<MeshRenderer>(); } entry.Shadow.shadowCastingMode = (ShadowCastingMode)3; entry.Shadow.receiveShadows = false; entry.Shadow.enabled = false; } private static void CopyBlendShapes(SkinnedMeshRenderer source, SkinnedMeshRenderer target) { if (!((Object)(object)source == (Object)null) && !((Object)(object)target == (Object)null) && !((Object)(object)source.sharedMesh == (Object)null) && !((Object)(object)target.sharedMesh == (Object)null)) { int num = Mathf.Min(source.sharedMesh.blendShapeCount, target.sharedMesh.blendShapeCount); for (int i = 0; i < num; i++) { target.SetBlendShapeWeight(i, source.GetBlendShapeWeight(i)); } } } internal void Restore() { //IL_001e: 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) if (!_active) { return; } if ((Object)(object)_head != (Object)null) { _head.localScale = _headScale; } foreach (Entry value in _entries.Values) { if ((Object)(object)value.Shadow != (Object)null) { value.Shadow.enabled = false; } if (!value.Applied) { continue; } if ((Object)(object)value.Source != (Object)null) { Renderer source = value.Source; SkinnedMeshRenderer val = (SkinnedMeshRenderer)(object)((source is SkinnedMeshRenderer) ? source : null); if ((Object)(object)val != (Object)null) { val.forceMatrixRecalculationPerRender = value.SkinRefresh; } value.Source.shadowCastingMode = value.Mode; value.Source.forceRenderingOff = value.Hidden; } value.Applied = false; } _active = false; } private void Release(Entry entry) { if ((Object)(object)entry.Shadow != (Object)null) { entry.Shadow.enabled = false; Object.Destroy((Object)(object)((Component)entry.Shadow).gameObject); } } internal void Cleanup() { Restore(); foreach (Entry value in _entries.Values) { Release(value); } _entries.Clear(); if (_shadowPose != null && (Object)(object)_shadowPose.Root != (Object)null) { Object.Destroy((Object)(object)((Component)_shadowPose.Root).gameObject); } _shadowPose = null; _root = (_head = null); } } internal sealed class FirstPersonShadow : MonoBehaviour { } [BepInPlugin("jpvalheim.firstpersonpov", "First Person POV", "1.0.5")] [BepInIncompatibility("jpvalheim.naturalfirstperson")] public sealed class FirstPersonPOVPlugin : BaseUnityPlugin { [HarmonyPatch(typeof(Player), "UpdateDodge")] private static class RollVisibilityPatch { private static void Postfix(Player __instance) { if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer && IsFirstPersonRequested(__instance)) { _rollFaded = RollFade.Update(((Character)__instance).InDodge(), Time.time); } } } [HarmonyPatch(typeof(Pickable), "Awake")] private static class PickableVisibilityPatch { private static void Postfix(Pickable __instance) { PickableVisibility.Track(__instance); } } private struct CameraOverrideState { public bool Active; public float Distance; public Vector3 FpsOffset; public bool BaseOffsetOverridden; public Vector3 BaseOffset; public Vector3 EyeWorld; } [HarmonyPatch(typeof(Character), "SetVisible")] private static class CharacterSetVisiblePatch { private static bool Prefix(Character __instance) { Player val = (Player)(object)((__instance is Player) ? __instance : null); if ((Object)(object)val == (Object)null || (Object)(object)val != (Object)(object)Player.m_localPlayer) { return true; } if (IsFirstPersonRequested(val)) { ApplyFirstPersonVisibility(val); return false; } if (_lodSettingsOverridden) { RestoreFirstPersonVisibility(); } return true; } } [HarmonyPatch(typeof(Player), "SetMouseLook")] private static class SetMouseLookPatch { private struct LookState { public bool Active; public float Pitch; } private static void Prefix(Player __instance, ref Vector2 mouseLook, out LookState __state) { //IL_00a3: 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_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) __state = default(LookState); if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer) && IsFirstPersonRequested(__instance) && !(LookYawField == null) && !(LookPitchField == null)) { __state.Active = true; float pitch = (float)LookPitchField.GetValue(__instance); mouseLook.y = 0f - LookMath.ApplyDownwardInput(pitch, 0f - mouseLook.y, BodyFadeStart.Value, LookDownResistanceWidth.Value, LookDownSensitivity.Value); __state.Pitch = LookMath.ApplyPitch(pitch, mouseLook.y, MaxLookUp.Value); float y = ((Component)__instance).transform.eulerAngles.y; Quaternion val = (Quaternion)LookYawField.GetValue(__instance); float relativeYaw = Mathf.DeltaAngle(y, ((Quaternion)(ref val)).eulerAngles.y); if (!ShouldLockBodyToView(__instance) && LimitSidewaysLook.Value) { mouseLook.x = YawResistance.Apply(relativeYaw, mouseLook.x, YawResistanceStart.Value, YawResistanceWidth.Value, MaxYawDegrees.Value); } } } private static void Postfix(Player __instance, LookState __state) { if (__state.Active && (Object)(object)__instance == (Object)(object)Player.m_localPlayer && IsFirstPersonRequested(__instance)) { LookPitchField.SetValue(__instance, __state.Pitch); ApplyFirstPersonLookConstraints(__instance); } } } [HarmonyPatch(typeof(Character), "UpdateRotation")] private static class BodyAwareRotationPatch { private struct RotationState { public bool Active; public Quaternion CameraYaw; } private static void Prefix(Character __instance, ref float turnSpeed, out RotationState __state) { //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: 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_010c: 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_009a: 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_009f: Unknown result type (might be due to invalid IL or missing references) __state = default(RotationState); Player val = (Player)(object)((__instance is Player) ? __instance : null); if (!((Object)(object)val == (Object)null) && !((Object)(object)val != (Object)(object)Player.m_localPlayer) && ShouldApplyBodyYawController(val) && !(LookYawField == null)) { ApplyFirstPersonLookConstraints(val); Quaternion cameraYaw = (Quaternion)LookYawField.GetValue(val); float num = ((Quaternion)(ref cameraYaw)).eulerAngles.y; if (!LockBodyToView.Value) { float y = ((Component)val).transform.eulerAngles.y; Vector3 val2 = (Vector3)((MoveDirField != null) ? ((Vector3)MoveDirField.GetValue(val)) : Vector3.zero); bool flag = ((Vector3)(ref val2)).sqrMagnitude > 0.01f; bool flag2 = ((Character)val).IsSwimming(); num = LookMath.BodyYawTarget(y, num, Mathf.DeltaAngle(y, num), SoftYawDegrees.Value, !flag && !flag2 && VagonTowing.IsTowing(val), flag2, flag); } __state.Active = true; __state.CameraYaw = cameraYaw; _forceBodyRotationCameraTarget = true; LookYawField.SetValue(val, Quaternion.Euler(0f, num, 0f)); turnSpeed = BodyTurnSpeed.Value; } } private static void Postfix(Character __instance, RotationState __state) { //IL_0041: Unknown result type (might be due to invalid IL or missing references) if (__state.Active) { _forceBodyRotationCameraTarget = false; Player val = (Player)(object)((__instance is Player) ? __instance : null); if (!((Object)(object)val == (Object)null) && !((Object)(object)val != (Object)(object)Player.m_localPlayer) && !(LookYawField == null)) { LookYawField.SetValue(val, __state.CameraYaw); ApplyFirstPersonLookConstraints(val); } } } } [HarmonyPatch(typeof(Player), "AlwaysRotateCamera")] private static class AlwaysRotateCameraPatch { private static void Postfix(Player __instance, ref bool __result) { if (_forceBodyRotationCameraTarget && (Object)(object)__instance == (Object)(object)Player.m_localPlayer) { __result = true; } } } [HarmonyPatch(typeof(GameCamera), "UpdateCamera")] private static class UpdateCameraPatch { private static void Prefix(GameCamera __instance, out BoatZoomState __state) { if ((Object)(object)_cameraPlayer != (Object)(object)Player.m_localPlayer) { _cameraPlayer = Player.m_localPlayer; _grapple = null; _grappleFovTracked = false; RollFade.Reset(); PlayerDamageHud.Restore(); } __state = BeginBoatZoom(__instance); RestoreBodyFade(); RestoreBowVisual(); RestoreHead(); _forceBodyRotationCameraTarget = false; _firstPersonFrame = false; if (GameCamera.InFreeFly()) { RestoreVanillaPitch(Player.m_localPlayer); RestoreFirstPersonVisibility(); ResetPoseResidual(); _wasFirstPerson = false; if (_fovOverridden) { RestoreVanillaFov(__instance); _fovOverridden = false; } } } private static void Postfix(GameCamera __instance, BoatZoomState __state) { RestoreBoatZoom(__instance, __state); Player localPlayer = Player.m_localPlayer; bool num = _firstPersonFrame && (Object)(object)localPlayer != (Object)null && !GameCamera.InFreeFly(); PickableVisibility.SetFirstPerson(num); if (!num) { ResetBowVisual(); if (_wasFirstPerson) { RestoreFirstPersonVisibility(); ResetPoseResidual(); _wasFirstPerson = false; } if (!GameCamera.InFreeFly()) { _fovOverridden = false; } } else { ApplyFirstPersonVisibility(localPlayer); UpdateBodyOpacity(localPlayer); UpdateBowVisual(localPlayer); _wasFirstPerson = true; ApplyFirstPersonFov(__instance); ApplyFirstPersonNearClip(__instance); ApplyHeadHide(localPlayer); } } private static Exception Finalizer(GameCamera __instance, BoatZoomState __state, Exception __exception) { RestoreBoatZoom(__instance, __state); return __exception; } } private struct BoatZoomState { internal bool Active; internal float Original; internal float Applied; } [HarmonyPatch(typeof(GrapplingPoint), "Activate")] private static class GrappleStartPatch { private static void Postfix(GrapplingPoint __instance, Character character) { if (!((Object)(object)Player.m_localPlayer == (Object)null) && !((Object)(object)character != (Object)(object)Player.m_localPlayer) && __instance.m_FOVTarget != 0f) { _grapple = __instance; _grappleFovTracked = true; } } } [HarmonyPatch(typeof(GrapplingPoint), "Deactivate")] private static class GrappleEndPatch { private static void Prefix(GrapplingPoint __instance) { if ((Object)(object)_grapple == (Object)(object)__instance) { _grapple = null; } } } [HarmonyPatch(typeof(DamageText), "AddInworldText")] private static class PlayerDamageTextPatch { private static void Prefix(DamageText __instance, bool mySelf, object[] __args, out int __state) { int num = Convert.ToInt32(__args[0], CultureInfo.InvariantCulture); __state = ((mySelf && DamageHudAllowed && (num <= 3 || num == 6 || num == 7)) ? PlayerDamageHud.Count(__instance) : (-1)); } private static void Postfix(DamageText __instance, int __state) { if (__state >= 0) { PlayerDamageHud.Track(__instance, __state); } } } [HarmonyPatch(typeof(DamageText), "UpdateWorldTexts")] private static class PlayerDamagePositionPatch { private static void Postfix() { PlayerDamageHud.Update(DamageHudAllowed); } } [HarmonyPatch(typeof(GameCamera), "GetCameraPosition")] private static class GetCameraPositionPatch { private static void Prefix(GameCamera __instance, float dt, ref float ___m_distance, ref Vector3 ___m_fpsOffset, out CameraOverrideState __state) { //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //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_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0083: 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_0093: 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_009b: 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_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00de: 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) __state = default(CameraOverrideState); Player localPlayer = Player.m_localPlayer; if (_firstPersonLocked && CanUseFirstPerson(localPlayer)) { ___m_distance = __instance.m_minDistance; } if (!ShouldUseFirstPerson(localPlayer, ___m_distance, __instance.m_minDistance)) { RestoreVanillaPitch(localPlayer); return; } __state.Active = true; __state.Distance = ___m_distance; __state.FpsOffset = ___m_fpsOffset; ApplyFirstPersonLookConstraints(localPlayer); if (CameraBaseOffsetField != null) { Vector3 baseOffset = (Vector3)CameraBaseOffsetField.GetValue(__instance); __state.BaseOffset = baseOffset; __state.BaseOffsetOverridden = true; Vector3 val = (__state.EyeWorld = EvaluateStableEye(localPlayer, dt)); Vector3 val2 = ((Component)localPlayer).transform.position; if (!((Character)localPlayer).IsAttached() && !((Object)(object)((Character)localPlayer).GetStandingOnShip() != (Object)null) && CameraPlayerPosField != null) { val2 = (Vector3)CameraPlayerPosField.GetValue(__instance); } CameraBaseOffsetField.SetValue(__instance, val - val2); } ___m_distance = 0f; ___m_fpsOffset = Vector3.zero; _firstPersonFrame = true; } private static void Postfix(GameCamera __instance, ref float ___m_distance, ref Vector3 ___m_fpsOffset, ref Vector3 pos, ref Quaternion rot, CameraOverrideState __state) { //IL_0016: 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_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_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_0092: Unknown result type (might be due to invalid IL or missing references) if (__state.Active) { if (__state.BaseOffsetOverridden) { pos = __state.EyeWorld; } if ((Object)(object)Player.m_localPlayer != (Object)null && (float)LookPitchField.GetValue(Player.m_localPlayer) < -89f) { rot = ((Character)Player.m_localPlayer).m_eye.rotation; } ___m_distance = __state.Distance; ___m_fpsOffset = __state.FpsOffset; if (__state.BaseOffsetOverridden && CameraBaseOffsetField != null) { CameraBaseOffsetField.SetValue(__instance, __state.BaseOffset); } } } } [HarmonyPatch(typeof(GameCamera), "ToggleFreeFly")] private static class ToggleFreeFlyPatch { private static void Prefix(GameCamera __instance) { ResetBowVisual(); RestoreVanillaPitch(Player.m_localPlayer); RestoreHead(); ResetPoseResidual(); RestoreFirstPersonVisibility(); RestoreFreeFlyNearClip(__instance); _wasFirstPerson = false; if (_fovOverridden) { RestoreVanillaFov(__instance); _fovOverridden = false; } _firstPersonFrame = false; } } [HarmonyPatch(typeof(Hud), "Update")] private static class HudUpdatePatch { private static void Prefix(Hud __instance) { //IL_0012: 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) if ((Object)(object)Player.m_localPlayer != (Object)null) { KeyboardShortcut value = ToggleHudKey.Value; if (((KeyboardShortcut)(ref value)).IsDown()) { __instance.m_userHidden = !__instance.m_userHidden; } } } } [HarmonyPatch(typeof(Hud), "UpdateCrosshair")] private static class CrosshairPatch { private static void Prefix() { RestoreCrosshairGraphics(); } private static void Postfix(Hud __instance, Player player) { if (!((Object)(object)player != (Object)(object)Player.m_localPlayer) && IsFirstPersonRequested(player)) { if (!ShouldShowCrosshair(player)) { HideCrosshairGraphic((Graphic)(object)__instance.m_crosshair); } if (!ShowBowDrawCircle.Value) { HideCrosshairGraphic((Graphic)(object)__instance.m_crosshairBow); } } } } [HarmonyPatch(typeof(Hud), "UpdateShipHud")] private static class ShipHudPatch { private static void Postfix(Hud __instance) { //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if ((Object)(object)__instance.m_shipHudRoot == (Object)null || !__instance.m_shipHudRoot.activeSelf || (Object)(object)__instance.m_shipControlsRoot == (Object)null) { return; } if (!IsFirstPersonRequested(localPlayer)) { __instance.m_shipControlsRoot.SetActive(true); return; } Ship controlledShip = localPlayer.GetControlledShip(); if ((Object)(object)controlledShip == (Object)null || (Object)(object)controlledShip.m_rudderObject == (Object)null) { return; } Renderer componentInChildren = controlledShip.m_rudderObject.GetComponentInChildren<Renderer>(); Camera mainCamera = Utils.GetMainCamera(); if (!((Object)(object)componentInChildren == (Object)null) && !((Object)(object)mainCamera == (Object)null)) { Bounds bounds = componentInChildren.bounds; Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(((Bounds)(ref bounds)).center.x, ((Bounds)(ref bounds)).max.y + 0.1f, ((Bounds)(ref bounds)).center.z); Vector3 val2 = mainCamera.WorldToViewportPoint(val); bool flag = val2.z > mainCamera.nearClipPlane && val2.x >= 0f && val2.x <= 1f && val2.y >= 0f && val2.y <= 1f; __instance.m_shipControlsRoot.SetActive(flag); if (flag) { __instance.m_shipControlsRoot.transform.position = Utils.WorldToScreenPointScaled(mainCamera, val); } } } } [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static ConsoleEvent <>9__99_0; public static ConsoleEvent <>9__99_1; public static Comparison<ConfigEntryBase> <>9__108_0; internal void <Awake>b__99_0(ConsoleEventArgs args) { _firstPersonLocked = false; args.Context.AddString("First Person POV: first-person lock disabled."); } internal void <Awake>b__99_1(ConsoleEventArgs args) { _firstPersonLocked = true; GameCamera instance = GameCamera.instance; if ((Object)(object)instance != (Object)null && CameraDistanceField != null) { CameraDistanceField.SetValue(instance, instance.m_minDistance); } args.Context.AddString("First Person POV: first-person lock enabled."); } internal int <PrintSettingHelp>b__108_0(ConfigEntryBase a, ConfigEntryBase b) { return string.Compare(a.Definition.Section + a.Definition.Key, b.Definition.Section + b.Definition.Key, StringComparison.Ordinal); } } public const string PluginGuid = "jpvalheim.firstpersonpov"; public const string PluginName = "First Person POV"; public const string PluginVersion = "1.0.5"; private const float DistanceEpsilon = 0.001f; internal static ConfigEntry<float> FirstPersonFov; internal static ConfigEntry<bool> ForceFirstPerson; internal static ConfigEntry<float> ForwardOffset; internal static ConfigEntry<float> VerticalOffset; internal static ConfigEntry<float> SoftYawDegrees; internal static ConfigEntry<float> YawResistanceStart; internal static ConfigEntry<float> YawResistanceWidth; internal static ConfigEntry<float> MaxYawDegrees; internal static ConfigEntry<float> BodyTurnSpeed; internal static ConfigEntry<float> PoseResidualSmoothing; internal static ConfigEntry<float> MovementSwayAmount; internal static ConfigEntry<float> BodyFadeStart; internal static ConfigEntry<float> LookDownResistanceWidth; internal static ConfigEntry<float> LookDownSensitivity; internal static ConfigEntry<float> MaxLookUp; internal static ConfigEntry<float> FirstPersonNearClip; internal static ConfigEntry<float> WaterContactMargin; internal static ConfigEntry<KeyboardShortcut> ToggleHudKey; internal static ConfigEntry<bool> ShowCrosshairWithBow; internal static ConfigEntry<bool> ShowCrosshairWithHammer; internal static ConfigEntry<bool> ShowCrosshairWithCultivator; internal static ConfigEntry<bool> ShowCrosshairWithHoe; internal static ConfigEntry<bool> ShowCrosshairWhileSneaking; internal static ConfigEntry<bool> ShowCrosshairOtherwise; internal static ConfigEntry<bool> ShowBowDrawCircle; internal static ConfigEntry<float> DrawnBowRoll; internal static ConfigEntry<bool> ShowPlayerShadow; internal static ConfigEntry<bool> LimitSidewaysLook; internal static ConfigEntry<bool> LockBodyToView; internal static ConfigEntry<bool> UnderwaterBlur; internal static ConfigEntry<bool> GrapplingFovEffect; internal static ConfigEntry<float> BoatHelmZoomMultiplier; internal static ConfigEntry<float> BlockingShieldTransparency; internal static ConfigEntry<PlayerDamageTextLocation> PlayerDamageText; private static readonly FieldInfo HeadField = AccessTools.Field(typeof(Character), "m_head"); private static readonly FieldInfo LodVisibleField = AccessTools.Field(typeof(Character), "m_lodVisible"); private static readonly FieldInfo LodGroupField = AccessTools.Field(typeof(Character), "m_lodGroup"); private static readonly FieldInfo OriginalLocalRefField = AccessTools.Field(typeof(Character), "m_originalLocalRef"); private static readonly FieldInfo CameraDistanceField = AccessTools.Field(typeof(GameCamera), "m_distance"); private static readonly FieldInfo CameraFovBaseField = AccessTools.Field(typeof(GameCamera), "m_fovBase"); private static readonly FieldInfo CameraBaseOffsetField = AccessTools.Field(typeof(GameCamera), "m_currentBaseOffset"); private static readonly FieldInfo CameraPlayerPosField = AccessTools.Field(typeof(GameCamera), "m_playerPos"); private static readonly FieldInfo LookYawField = AccessTools.Field(typeof(Character), "m_lookYaw"); private static readonly FieldInfo LookDirField = AccessTools.Field(typeof(Character), "m_lookDir"); private static readonly FieldInfo MoveDirField = AccessTools.Field(typeof(Character), "m_moveDir"); private static readonly FieldInfo LookPitchField = AccessTools.Field(typeof(Player), "m_lookPitch"); private static readonly FieldInfo VisualField = AccessTools.Field(typeof(Character), "m_visual"); private static readonly FieldInfo HelmetItemInstanceField = AccessTools.Field(typeof(VisEquipment), "m_helmetItemInstance"); private static readonly FieldInfo HairItemInstanceField = AccessTools.Field(typeof(VisEquipment), "m_hairItemInstance"); private static readonly FieldInfo BeardItemInstanceField = AccessTools.Field(typeof(VisEquipment), "m_beardItemInstance"); private static readonly FieldInfo LeftItemInstanceField = AccessTools.Field(typeof(VisEquipment), "m_leftItemInstance"); private static readonly FieldInfo RightItemInstanceField = AccessTools.Field(typeof(VisEquipment), "m_rightItemInstance"); private static readonly FieldInfo LeftEquippedItemField = AccessTools.Field(typeof(Humanoid), "m_leftItem"); private static readonly FieldInfo RightEquippedItemField = AccessTools.Field(typeof(Humanoid), "m_rightItem"); private static readonly FieldInfo LeftHandField = AccessTools.Field(typeof(VisEquipment), "m_leftHand"); private static readonly FieldInfo RightHandField = AccessTools.Field(typeof(VisEquipment), "m_rightHand"); private static readonly FieldInfo BodyModelField = AccessTools.Field(typeof(VisEquipment), "m_bodyModel"); private static readonly FieldInfo LeftShoulderField = AccessTools.Field(typeof(CharacterAnimEvent), "m_leftShoulder"); private static readonly FieldInfo RightShoulderField = AccessTools.Field(typeof(CharacterAnimEvent), "m_rightShoulder"); private static bool _firstPersonFrame; private static bool _firstPersonLocked; private static bool _wasFirstPerson; private static bool _fovOverridden; private static bool _forceBodyRotationCameraTarget; private static LODGroup _firstPersonLodGroup; private static bool _lodSettingsOverridden; private static bool _originalAnimateCrossFading; private static LODFadeMode _originalFadeMode; private static readonly Dictionary<Graphic, bool> CrosshairGraphicStates = new Dictionary<Graphic, bool>(); private static Transform _bowVisual; private static float _bowRollAngle; private static float _bowPoseWeight; private static readonly BowPose DrawnBowPose = new BowPose(); private static Player _anchorPlayer; private static Transform _anchorVisualRoot; private static Transform _anchorEye; private static Transform _anchorHead; private static readonly EyeAnchor StableEye = new EyeAnchor(); private static readonly MovementSway LocomotionSway = new MovementSway(); private static bool _anchorInitialized; private static Player _fadePlayer; private static float _bodyOpacity = 1f; private static bool _rollFaded; private static readonly RollVisibility RollFade = new RollVisibility(); private static readonly FirstPersonBody BodyView = new FirstPersonBody(); private static GrapplingPoint _grapple; private static bool _grappleFovTracked; private static Player _helmPlayer; private static GameCamera _helmCamera; private static bool _wasHelming; private static Player _cameraPlayer; private static WaterScreen _waterScreen; private static readonly Func<Vector3, float> SampleWaterLevel = GetWaterLevel; private Harmony _harmony; private HashSet<ConfigDefinition> _savedDefinitions; internal static bool DamageHudAllowed { get { if (_firstPersonFrame && CanUseFirstPerson(Player.m_localPlayer)) { return PlayerDamageText.Value == PlayerDamageTextLocation.NearHealth; } return false; } } private void Awake() { //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Expected O, but got Unknown //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Expected O, but got Unknown //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Expected O, but got Unknown //IL_01fa: Unknown result type (might be due to invalid IL or missing references) //IL_0204: Expected O, but got Unknown //IL_0237: Unknown result type (might be due to invalid IL or missing references) //IL_0241: Expected O, but got Unknown //IL_0274: Unknown result type (might be due to invalid IL or missing references) //IL_027e: Expected O, but got Unknown //IL_02b1: Unknown result type (might be due to invalid IL or missing references) //IL_02bb: Expected O, but got Unknown //IL_02ee: Unknown result type (might be due to invalid IL or missing references) //IL_02f8: Expected O, but got Unknown //IL_0345: Unknown result type (might be due to invalid IL or missing references) //IL_034f: Expected O, but got Unknown //IL_0382: Unknown result type (might be due to invalid IL or missing references) //IL_038c: Expected O, but got Unknown //IL_03ff: Unknown result type (might be due to invalid IL or missing references) //IL_0409: Expected O, but got Unknown //IL_043c: Unknown result type (might be due to invalid IL or missing references) //IL_0446: Expected O, but got Unknown //IL_0479: Unknown result type (might be due to invalid IL or missing references) //IL_0483: Expected O, but got Unknown //IL_04b6: Unknown result type (might be due to invalid IL or missing references) //IL_04c0: Expected O, but got Unknown //IL_04f3: Unknown result type (might be due to invalid IL or missing references) //IL_04fd: Expected O, but got Unknown //IL_0530: Unknown result type (might be due to invalid IL or missing references) //IL_053a: Expected O, but got Unknown //IL_0559: Unknown result type (might be due to invalid IL or missing references) //IL_067b: Unknown result type (might be due to invalid IL or missing references) //IL_0685: Expected O, but got Unknown //IL_0768: Unknown result type (might be due to invalid IL or missing references) //IL_0772: Expected O, but got Unknown //IL_07a5: Unknown result type (might be due to invalid IL or missing references) //IL_07af: Expected O, but got Unknown //IL_07fc: Unknown result type (might be due to invalid IL or missing references) //IL_080e: Unknown result type (might be due to invalid IL or missing references) //IL_081b: Expected O, but got Unknown //IL_081b: Expected O, but got Unknown //IL_0816: Unknown result type (might be due to invalid IL or missing references) //IL_084f: Unknown result type (might be due to invalid IL or missing references) //IL_083a: Unknown result type (might be due to invalid IL or missing references) //IL_083f: Unknown result type (might be due to invalid IL or missing references) //IL_0845: Expected O, but got Unknown //IL_0888: Unknown result type (might be due to invalid IL or missing references) //IL_0894: Unknown result type (might be due to invalid IL or missing references) //IL_089e: Expected O, but got Unknown //IL_08b5: Unknown result type (might be due to invalid IL or missing references) //IL_08bf: Expected O, but got Unknown //IL_08bf: Unknown result type (might be due to invalid IL or missing references) //IL_08c9: Expected O, but got Unknown //IL_08d5: Unknown result type (might be due to invalid IL or missing references) //IL_08df: Expected O, but got Unknown //IL_08df: Unknown result type (might be due to invalid IL or missing references) //IL_08e9: Expected O, but got Unknown //IL_0873: Unknown result type (might be due to invalid IL or missing references) //IL_0878: Unknown result type (might be due to invalid IL or missing references) //IL_087e: Expected O, but got Unknown _savedDefinitions = new HashSet<ConfigDefinition>(); ((BaseUnityPlugin)this).Config.SaveOnConfigSet = false; float? num = null; try { num = ConfigMigration.Import(((BaseUnityPlugin)this).Config, Path.Combine(Paths.ConfigPath, "jpvalheim.naturalfirstperson.cfg")); _savedDefinitions = ConfigMigration.ReadDefinitions(((BaseUnityPlugin)this).Config.ConfigFilePath); } catch (IOException ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Could not import previous settings: " + ex.Message)); } catch (UnauthorizedAccessException ex2) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Could not import previous settings: " + ex2.Message)); } FirstPersonFov = BindSetting("Camera", "01 Camera and controls", "FirstPersonFOV", 85f, new ConfigDescription("Vertical field of view, in degrees. Higher values widen your view.\nAt 16:9, 85 vertical is about 117 degrees horizontally.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(30f, 120f), Array.Empty<object>())); ForceFirstPerson = BindSetting("Mode", "01 Camera and controls", "ForceFirstPerson", defaultValue: false, "Prevent scrolling out of first person. Off allows normal zoom.\nThe lockfirstperson and unlockfirstperson commands override this for the current session."); _firstPersonLocked = ForceFirstPerson.Value; ForceFirstPerson.SettingChanged += OnForceFirstPersonChanged; ForwardOffset = BindSetting("Camera", "01 Camera and controls", "EyeForwardOffset", 0.08f, new ConfigDescription("Move your viewpoint along your horizontal look direction, in meters. Positive moves\nforward; negative moves backward. 0.01 = 1 cm.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-0.05f, 0.2f), Array.Empty<object>())); VerticalOffset = BindSetting("Camera", "01 Camera and controls", "EyeVerticalOffset", -0.06f, new ConfigDescription("Raise or lower your viewpoint, in meters. Positive raises it; negative lowers it.\n0.01 = 1 cm.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-0.1f, 0.2f), Array.Empty<object>())); LockBodyToView = BindSetting("Camera", "04 Look limits", "LockBodyToView", defaultValue: true, "Turn your body immediately with your view in first person, even while standing still.\nOverrides BodyTurnStartAngle, BodyTurnSpeed and sideways look limits. Does not activate\nblocking or tilt your body vertically. Rolls, attached positions and vehicle controls keep normal facing."); LimitSidewaysLook = BindSetting("Camera", "04 Look limits", "LimitSidewaysLook", defaultValue: false, "Limit sideways free look relative to your body's facing. Off removes that limit.\nOn uses SidewaysSlowdownStart, SidewaysSlowdownRange and MaxSidewaysLook.\nIgnored while LockBodyToView is active."); SoftYawDegrees = BindSetting("Body Awareness", "04 Look limits", "SoftYawDegrees", 40f, new ConfigDescription("Sideways view angle before your body follows while standing still, in degrees.\n0 starts following immediately. Moving and swimming face the view.\nIgnored while LockBodyToView is active.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 60f), Array.Empty<object>())); BodyTurnSpeed = BindSetting("Body Awareness", "04 Look limits", "BodyTurnSpeed", 480f, new ConfigDescription("How quickly your body follows your view, in degrees per second. Higher values turn faster.\nIgnored while LockBodyToView is active.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(120f, 900f), Array.Empty<object>())); YawResistanceStart = BindSetting("Body Awareness", "04 Look limits", "YawResistanceStart", 85f, new ConfigDescription("Sideways angle from your body where looking farther starts slowing, in degrees.\nLower values start sooner; turning back stays at normal speed.\nRequires LimitSidewaysLook on; ignored while LockBodyToView is active.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(30f, 120f), Array.Empty<object>())); YawResistanceWidth = BindSetting("Body Awareness", "04 Look limits", "YawResistanceWidth", 15f, new ConfigDescription("Degrees over which sideways look slows to 25% speed after SidewaysSlowdownStart.\nHigher values make the slowdown gentler. Turning back stays at normal speed.\nRequires LimitSidewaysLook on; ignored while LockBodyToView is active.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(5f, 60f), Array.Empty<object>())); MaxYawDegrees = BindSetting("Body Awareness", "04 Look limits", "MaxYawDegrees", 160f, new ConfigDescription("Farthest sideways view angle from your body, in degrees. Higher values allow more turning.\nRequires LimitSidewaysLook on; ignored while LockBodyToView is active.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(90f, 175f), Array.Empty<object>())); if (num.HasValue) { YawResistanceStart.Value = num.Value; } PoseResidualSmoothing = BindSetting("Body Awareness", "06 Advanced", "PoseResidualSmoothing", 0.04f, new ConfigDescription("Smooth camera movement when your character's animated head cannot be found, in seconds.\n0 disables this fallback smoothing. Normal head tracking is unaffected.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 0.15f), Array.Empty<object>())); MovementSwayAmount = BindSetting("Body Awareness", "03 Movement", "MovementSway", 1f, new ConfigDescription("Side-to-side and vertical walking sway: 0 off, 0.5 gentle, 1 normal, 2 strong.\nSettles when idle, drawing a bow, attacking, swimming, rolling or attached.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 2f), Array.Empty<object>())); ConfigEntry<float> val = ((BaseUnityPlugin)this).Config.Bind<float>("Camera", "MaxLookDown", 20f, (ConfigDescription)null); float defaultValue = Mathf.Clamp(val.Value, 20f, 69f); ((BaseUnityPlugin)this).Config.Remove(((ConfigEntryBase)val).Definition); BodyFadeStart = BindSetting("Camera", "04 Look limits", "BodyFadeStart", defaultValue, new ConfigDescription("Angle below the horizon where your body and equipment start fading, in degrees.\nLower values fade sooner, over up to 30 degrees. Downward look also starts slowing here;\nlooking up stays at normal speed.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(20f, 69f), Array.Empty<object>())); LookDownResistanceWidth = BindSetting("Camera", "04 Look limits", "LookDownResistanceWidth", 5f, new ConfigDescription("Degrees over which downward look slows after BodyFadeStart. Higher values make the\nslowdown gentler. Final speed is set by LookDownSensitivity; looking up is unaffected.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 20f), Array.Empty<object>())); LookDownSensitivity = BindSetting("Camera", "04 Look limits", "LookDownSensitivity", 0.7f, new ConfigDescription("Downward look speed after the slowdown: 0.7 = 70% of normal speed; 1 removes the slowdown.\nLooking up keeps its normal speed.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 1f), Array.Empty<object>())); MaxLookUp = BindSetting("Camera", "04 Look limits", "MaxLookUp", 100f, new ConfigDescription("How far you can look upward from the horizon, in degrees. 90 looks straight up; higher\nvalues let you look slightly beyond vertical.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(89f, 120f), Array.Empty<object>())); FirstPersonNearClip = BindSetting("Camera", "06 Advanced", "NearClip", 0.03f, new ConfigDescription("How close geometry can be before it is clipped, in meters. Lower values reveal more nearby\nhands and objects. 0.01 = 1 cm. This does not control plants' close-camera hiding effect.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.005f, 0.2f), Array.Empty<object>())); WaterContactMargin = BindSetting("Water", "05 Water", "WaterContactMargin", 0.07f, new ConfigDescription("Extra distance added to the water-blur trigger, in meters. 0.07 adds 7 cm.\nLarger values start the blur sooner. Used when UnderwaterBlur is on.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 0.08f), Array.Empty<object>())); ToggleHudKey = BindSetting<KeyboardShortcut>("HUD", "01 Camera and controls", "ToggleHudKey", new KeyboardShortcut((KeyCode)282, Array.Empty<KeyCode>()), "Key for showing or hiding the HUD. Use None to disable, or a combination such as F1 + LeftShift.\nCtrl+F1 keeps its normal mouse-capture function."); ShowCrosshairWithBow = BindSetting("HUD", "02 Crosshair", "ShowCrosshairWithBow", defaultValue: true, "Show the center crosshair while holding a bow. ShowBowDrawCircle controls the draw circle\nseparately. An enabled sneaking rule can also show the crosshair."); ShowCrosshairWithHammer = BindSetting("HUD", "02 Crosshair", "ShowCrosshairWithHammer", defaultValue: true, "Show the center crosshair while holding a hammer."); ShowCrosshairWithCultivator = BindSetting("HUD", "02 Crosshair", "ShowCrosshairWithCultivator", defaultValue: true, "Show the center crosshair while holding a cultivator."); ShowCrosshairWithHoe = BindSetting("HUD", "02 Crosshair", "ShowCrosshairWithHoe", defaultValue: true, "Show the center crosshair while holding a hoe."); ShowCrosshairWhileSneaking = BindSetting("HUD", "02 Crosshair", "ShowCrosshairWhileSneaking", defaultValue: true, "Show the center crosshair while sneaking. A matching equipment rule can also show it.\nThe game's sneak indicator remains available when this is off."); ShowCrosshairOtherwise = BindSetting("HUD", "02 Crosshair", "ShowCrosshairOtherwise", defaultValue: false, "Show the center crosshair when you're not sneaking and no listed equipment is in your hands.\nAny enabled matching equipment or sneaking rule can show it. The bow draw circle is separate."); ShowBowDrawCircle = BindSetting("HUD", "02 Crosshair", "ShowBowDrawCircle", defaultValue: true, "Show the circle that tightens while drawing a bow. Independent of the center crosshair."); DrawnBowRoll = BindSetting("Bow", "01 Camera and controls", "DrawnBowRollDegrees", 75f, new ConfigDescription("Tilt the visible bow while drawing, in degrees. Positive values tilt clockwise; negative\nvalues tilt the other way; 0 removes the tilt. Aiming and arrow direction stay unchanged.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-180f, 180f), Array.Empty<object>())); ShowPlayerShadow = BindSetting("Body", "03 Movement", "ShowPlayerShadow", defaultValue: true, "Show your complete first-person shadow, including your head and equipped helmet.\nOff hides your own character and equipment shadows."); ((BaseUnityPlugin)this).Config.Remove(((ConfigEntryBase)((BaseUnityPlugin)this).Config.Bind<bool>("03 Movement", "HideHeadlessShadow", true, (ConfigDescription)null)).Definition); ((BaseUnityPlugin)this).Config.Remove(((ConfigEntryBase)((BaseUnityPlugin)this).Config.Bind<bool>("Body Awareness", "HideHeadlessShadow", true, (ConfigDescription)null)).Definition); UnderwaterBlur = BindSetting("Water", "05 Water", "UnderwaterBlur", defaultValue: true, "Blur and tint your view at the water surface and underwater. Off removes the entire effect,\nincluding the fade after leaving water."); GrapplingFovEffect = BindSetting("Camera", "01 Camera and controls", "GrapplingFovEffect", defaultValue: true, "Keep the game's temporary grappling-hook field-of-view effect in first person.\nYour configured field of view returns when the effect ends."); BoatHelmZoomMultiplier = BindSetting("Camera", "01 Camera and controls", "BoatHelmZoomMultiplier", 4f, new ConfigDescription("Maximum third-person camera distance while steering a boat, as a multiplier.\n1 keeps the normal limit; 4 allows four times the distance. Normal zoom returns when you stop steering.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 8f), Array.Empty<object>())); BlockingShieldTransparency = BindSetting("Body", "03 Movement", "BlockingShieldTransparency", 90f, new ConfigDescription("Equipped shield transparency while blocking, in percent. 0 keeps it solid; 90 leaves it\nfaintly visible; 100 hides it. Looking-down fade still applies.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), Array.Empty<object>())); PlayerDamageText = BindSetting("HUD", "02 HUD", "PlayerDamageText", PlayerDamageTextLocation.NearHealth, "Where your incoming damage numbers appear in first person: NearHealth places them above\nthe health bar; World keeps their normal position. Numbers keep their normal style and fade."); ((BaseUnityPlugin)this).Config.SaveOnConfigSet = true; ((BaseUnityPlugin)this).Config.Save(); new ConsoleCommand("ffpov", "List settings; ffpov <setting> explains it; ffpov <setting> <value> changes and saves it.", new ConsoleEvent(HandleSettingCommand), false, false, false, false, false, false, new ConsoleOptionsFetcher(GetSettingOptions), false, false, false); object obj = <>c.<>9__99_0; if (obj == null) { ConsoleEvent val2 = delegate(ConsoleEventArgs args) { _firstPersonLocked = false; args.Context.AddString("First Person POV: first-person lock disabled."); }; <>c.<>9__99_0 = val2; obj = (object)val2; } new ConsoleCommand("unlockfirstperson", "Unlock forced first-person mode for the current game session.", (ConsoleEvent)obj, false, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); object obj2 = <>c.<>9__99_1; if (obj2 == null) { ConsoleEvent val3 = delegate(ConsoleEventArgs args) { _firstPersonLocked = true; GameCamera instance = GameCamera.instance; if ((Object)(object)instance != (Object)null && CameraDistanceField != null) { CameraDistanceField.SetValue(instance, instance.m_minDistance); } args.Context.AddString("First Person POV: first-person lock enabled."); }; <>c.<>9__99_1 = val3; obj2 = (object)val3; } new ConsoleCommand("lockfirstperson", "Force first-person mode for the current game session.", (ConsoleEvent)obj2, false, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); _harmony = new Harmony("jpvalheim.firstpersonpov"); _harmony.PatchAll(); Camera.onPreCull = (CameraCallback)Delegate.Combine((Delegate?)(object)Camera.onPreCull, (Delegate?)new CameraCallback(OnCameraPreCull)); Camera.onPostRender = (CameraCallback)Delegate.Combine((Delegate?)(object)Camera.onPostRender, (Delegate?)new CameraCallback(OnCameraPostRender)); ((BaseUnityPlugin)this).Logger.LogInfo((object)"First Person POV 1.0.5 loaded."); } private ConfigEntry<T> BindSetting<T>(string oldSection, string section, string name, T defaultValue, ConfigDescription description) { return ConfigMigration.Bind(((BaseUnityPlugin)this).Config, _savedDefinitions, oldSection, section, name, defaultValue, description); } private ConfigEntry<T> BindSetting<T>(string oldSection, string section, string name, T defaultValue, string description) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown return BindSetting(oldSection, section, name, defaultValue, new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty<object>())); } private IEnumerable<ConfigEntryBase> PlayerSettings() { foreach (KeyValuePair<ConfigDefinition, ConfigEntryBase> item in ((BaseUnityPlugin)this).Config) { yield return item.Value; } } private ConfigEntryBase FindSetting(string name) { name = ConfigMigration.CurrentName(name); foreach (ConfigEntryBase item in PlayerSettings()) { if (item.Definition.Key.Equals(name, StringComparison.OrdinalIgnoreCase)) { return item; } } return null; } private List<string> GetSettingOptions() { List<string> list = new List<string> { "camera", "help", "list" }; foreach (ConfigEntryBase item in PlayerSettings()) { list.Add(item.Definition.Key); } list.Sort(StringComparer.OrdinalIgnoreCase); return list; } private static string SectionTitle(string section) { if (section.Length <= 3 || !char.IsDigit(section[0]) || !char.IsDigit(section[1]) || section[2] != ' ') { return section; } return section.Substring(3); } private static string ValueHint(ConfigEntryBase setting) { if (setting.SettingType.IsEnum) { return string.Join(" or ", Enum.GetNames(setting.SettingType)); } if (setting.SettingType == typeof(bool)) { return "true or false (on/off also work)"; } if (setting.SettingType == typeof(KeyboardShortcut)) { return "a key such as F1, a combination such as F1 + LeftShift, or None"; } if (setting.Description.AcceptableValues is AcceptableValueRange<float> val) { return "a number from " + val.MinValue.ToString(CultureInfo.InvariantCulture) + " to " + val.MaxValue.ToString(CultureInfo.InvariantCulture); } return "a number"; } private static void PrintSettingDetails(Terminal terminal, ConfigEntryBase setting) { terminal.AddString(setting.Definition.Key + " = " + setting.GetSerializedValue()); terminal.AddString("Default: " + TomlTypeConverter.ConvertToString(setting.DefaultValue, setting.SettingType) + "; use " + ValueHint(setting) + "."); string[] array = setting.Description.Description.Split('\n'); foreach (string text in array) { terminal.AddString(text); } string text2 = ((!(setting.SettingType == typeof(bool))) ? TomlTypeConverter.ConvertToString(setting.DefaultValue, setting.SettingType) : (((bool)setting.BoxedValue) ? "false" : "true")); if (setting.Definition.Key == "MovementSway") { text2 = "1.5"; } terminal.AddString("Change and save: ffpov " + setting.Definition.Key + " " + text2); } private void PrintSettingHelp(Terminal terminal) { terminal.AddString("ffpov <setting> explains a setting; ffpov <setting> <value> changes and saves it."); terminal.AddString("Examples: ffpov MovementSway 1.5 | ffpov ShowCrosshairWithBow off"); terminal.AddString("Apply FOV and eye-position defaults only: ffpov camera reset"); terminal.AddString("Type 'ffpov ' for setting suggestions; Tab completes a suggestion."); List<ConfigEntryBase> list = new List<ConfigEntryBase>(PlayerSettings()); list.Sort((ConfigEntryBase a, ConfigEntryBase b) => string.Compare(a.Definition.Section + a.Definition.Key, b.Definition.Section + b.Definition.Key, StringComparison.Ordinal)); string text = null; foreach (ConfigEntryBase item in list) { if (text != item.Definition.Section) { text = item.Definition.Section; terminal.AddString("[" + SectionTitle(text) + "]"); } terminal.AddString(" " + item.Definition.Key + " = " + item.GetSerializedValue()); } } private void HandleSettingCommand(ConsoleEventArgs args) { if (args.Length < 2 || string.IsNullOrWhiteSpace(args[1]) || args[1].Equals("help", StringComparison.OrdinalIgnoreCase) || args[1].Equals("list", StringComparison.OrdinalIgnoreCase)) { PrintSettingHelp(args.Context); return; } if (args[1].Equals("camera", StringComparison.OrdinalIgnoreCase)) { HandleCameraCommand(args); return; } ConfigEntryBase val = FindSetting(args[1]); if (val == null) { args.Context.AddString("Unknown setting '" + args[1] + "'. Type 'ffpov ' for suggestions, or run ffpov to list settings."); return; } string text = ((args.Length > 2) ? string.Join(" ", args.Args, 2, args.Args.Length - 2).Trim() : ""); string error; if (text.Length == 0) { PrintSettingDetails(args.Context, val); } else if (!TrySetSetting(val, text, out error)) { args.Context.AddString(error); } else { args.Context.AddString(val.Definition.Key + " = " + val.GetSerializedValue() + " (saved)"); } } private void HandleCameraCommand(ConsoleEventArgs args) { bool flag = args.Length == 3 && args[2].Equals("reset", StringComparison.OrdinalIgnoreCase); if (args.Length != 2 && !flag) { args.Context.AddString("Use ffpov camera to view settings, or ffpov camera reset to apply FOV and eye-position defaults."); return; } if (flag) { FirstPersonFov.Value = (float)((ConfigEntryBase)FirstPersonFov).DefaultValue; ForwardOffset.Value = (float)((ConfigEntryBase)ForwardOffset).DefaultValue; VerticalOffset.Value = (float)((ConfigEntryBase)VerticalOffset).DefaultValue; if (!((BaseUnityPlugin)this).Config.SaveOnConfigSet) { ((BaseUnityPlugin)this).Config.Save(); } } args.Context.AddString("Camera: FOV " + ((ConfigEntryBase)FirstPersonFov).GetSerializedValue() + " vertical; forward " + ((ConfigEntryBase)ForwardOffset).GetSerializedValue() + " m; height " + ((ConfigEntryBase)VerticalOffset).GetSerializedValue() + " m" + (flag ? " (saved)" : "")); if (!flag) { args.Context.AddString("Apply FOV and eye-position defaults only: ffpov camera reset"); } } private bool TrySetSetting(ConfigEntryBase setting, string input, out string error) { //IL_0111: Unknown result type (might be due to invalid IL or mis