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 VBDiving v0.0.4
VBDiving.dll
Decompiled 2 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.IO; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using Jotunn; using Jotunn.Entities; using Jotunn.Extensions; using Jotunn.Managers; using Jotunn.Utils; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.Rendering; using UnityEngine.UI; using VBDiving.Effects; using VBDiving.Mobs; using VBDiving.Patches; using YamlDotNet.Serialization; using YamlDotNet.Serialization.NamingConventions; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("SwimmingReworked")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("SwimmingReworked")] [assembly: AssemblyCopyright("Copyright © 2021")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("e3243d22-4307-4008-ba36-9f326008cde5")] [assembly: AssemblyFileVersion("1.0.3")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.3.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace VBDiving { internal class BreathHud : MonoBehaviour { private GameObject _root; private RectTransform _container; private readonly List<Image> _bubbles = new List<Image>(); private Sprite _bubbleSprite; private TextMeshProUGUI _breathText; private float _cachedOffsetX; private float _cachedOffsetY; private float _cachedScale; private bool _cachedShowLabels; private const int MaxBubbles = 12; private const float BubbleSize = 12f; private void Awake() { CreateHud(); } private void Start() { ApplyPositionAndScale(); } private void Update() { Player localPlayer = Player.m_localPlayer; if (!Object.op_Implicit((Object)(object)localPlayer) || !Object.op_Implicit((Object)(object)Camera.main)) { SetVisible(visible: false); return; } CheckConfigChanges(); float currentBreath = SwimAPI.GetCurrentBreath(localPlayer); float maxBreath = SwimAPI.GetMaxBreath(localPlayer); float percent = Mathf.Clamp01(SwimAPI.GetBreathPercent(localPlayer)); bool flag = WaterHelper.IsHeadUnderwater(localPlayer); bool flag2 = currentBreath < maxBreath - 0.01f; bool flag3 = flag || flag2; SetVisible(flag3); if (flag3) { float skillLevel = ((Character)localPlayer).GetSkillLevel((SkillType)103); UpdateBubblesHorizontal(percent, skillLevel); if (Object.op_Implicit((Object)(object)_breathText) && ((Component)_breathText).gameObject.activeSelf) { ((TMP_Text)_breathText).text = $"{Mathf.CeilToInt(currentBreath)}"; } } } private void UpdateBubblesHorizontal(float percent, float swimSkillLevel) { //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) int num = 2 + Mathf.FloorToInt(swimSkillLevel / 10f); num = Mathf.Clamp(num, 2, 12); int num2 = Mathf.CeilToInt(percent * (float)num); float num3 = 12f; float num4 = (float)num * 12f; float num5 = 0f - num4 / 2f + 6f; for (int i = 0; i < _bubbles.Count; i++) { Image val = _bubbles[i]; bool flag = i < num; ((Component)val).gameObject.SetActive(flag); if (flag) { bool flag2 = i < num2; float num6 = num5 + (float)i * num3; if (flag2) { RectTransform rectTransform = ((Graphic)val).rectTransform; float num7 = Mathf.Sin(Time.time * 5f + (float)i * 0.5f) * 2f; rectTransform.anchoredPosition = new Vector2(num6, num7); float num8 = 0.6f + 0.4f * Mathf.PingPong(Time.time * 2f + (float)i * 0.3f, 1f); ((Graphic)val).color = new Color(0.8f, 0.92f, 1f, num8); } else { RectTransform rectTransform2 = ((Graphic)val).rectTransform; float num9 = Mathf.Sin(Time.time * 5f + (float)i * 0.5f) * 2f; rectTransform2.anchoredPosition = new Vector2(num6, num9); ((Graphic)val).color = new Color(0.3f, 0.4f, 0.5f, 0.3f); } } } } private void CheckConfigChanges() { //IL_00b6: 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) if (!Object.op_Implicit((Object)(object)VBDiving.Instance)) { return; } float value = VBDiving.BreathHudOffsetX.Value; float value2 = VBDiving.BreathHudOffsetY.Value; float value3 = VBDiving.BreathHudScale.Value; bool value4 = VBDiving.BreathHudShowLabels.Value; bool flag = !Mathf.Approximately(_cachedOffsetX, value) || !Mathf.Approximately(_cachedOffsetY, value2); bool flag2 = !Mathf.Approximately(_cachedScale, value3); bool flag3 = _cachedShowLabels != value4; if (flag) { ApplyPosition(value, value2); _cachedOffsetX = value; _cachedOffsetY = value2; } if (flag2) { ((Transform)_container).localScale = Vector3.one * value3; _cachedScale = value3; } if (flag3) { if (Object.op_Implicit((Object)(object)_breathText)) { ((Component)_breathText).gameObject.SetActive(value4); } _cachedShowLabels = value4; } } private void ApplyPositionAndScale() { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)_container)) { float value = VBDiving.BreathHudOffsetX.Value; float value2 = VBDiving.BreathHudOffsetY.Value; float value3 = VBDiving.BreathHudScale.Value; ApplyPosition(value, value2); ((Transform)_container).localScale = Vector3.one * value3; _cachedOffsetX = value; _cachedOffsetY = value2; _cachedScale = value3; _cachedShowLabels = VBDiving.BreathHudShowLabels.Value; if (Object.op_Implicit((Object)(object)_breathText)) { ((Component)_breathText).gameObject.SetActive(_cachedShowLabels); } } } private void ApplyPosition(float offsetXPercent, float offsetYPercent) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)_container)) { _container.anchorMin = new Vector2(0.5f, 0.5f); _container.anchorMax = new Vector2(0.5f, 0.5f); _container.pivot = new Vector2(0.5f, 0.5f); float num = offsetXPercent / 100f * (float)Screen.width; float num2 = offsetYPercent / 100f * (float)Screen.height; _container.anchoredPosition = new Vector2(num, num2); if (VBDiving.DebugLogging.Value) { VBDiving.LogDebug($"BreathHud position applied: X={num}, Y={num2}"); } } } private void SetVisible(bool visible) { if (Object.op_Implicit((Object)(object)_root) && _root.activeSelf != visible) { _root.SetActive(visible); } } private void CreateHud() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Expected O, but got Unknown //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Expected O, but got Unknown //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_0168: 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_01dd: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: Expected O, but got Unknown //IL_0263: Unknown result type (might be due to invalid IL or missing references) //IL_0287: Unknown result type (might be due to invalid IL or missing references) //IL_029e: Unknown result type (might be due to invalid IL or missing references) //IL_02b5: Unknown result type (might be due to invalid IL or missing references) //IL_02cc: Unknown result type (might be due to invalid IL or missing references) //IL_02e3: Unknown result type (might be due to invalid IL or missing references) _root = new GameObject("BreathHud"); Object.DontDestroyOnLoad((Object)(object)_root); Canvas val = _root.AddComponent<Canvas>(); val.renderMode = (RenderMode)0; val.sortingOrder = 5000; CanvasScaler val2 = _root.AddComponent<CanvasScaler>(); val2.uiScaleMode = (ScaleMode)1; val2.referenceResolution = new Vector2(1920f, 1080f); val2.matchWidthOrHeight = 0.5f; _root.AddComponent<GraphicRaycaster>(); GameObject val3 = new GameObject("Container"); val3.transform.SetParent(_root.transform, false); _container = val3.AddComponent<RectTransform>(); float num = 144f; _container.sizeDelta = new Vector2(num, 30f); _bubbleSprite = CreateBubbleSprite(64); for (int i = 0; i < 12; i++) { GameObject val4 = new GameObject($"Bubble_{i}"); val4.transform.SetParent((Transform)(object)_container, false); RectTransform val5 = val4.AddComponent<RectTransform>(); val5.sizeDelta = new Vector2(12f, 12f); val5.anchorMin = new Vector2(0.5f, 0.5f); val5.anchorMax = new Vector2(0.5f, 0.5f); val5.pivot = new Vector2(0.5f, 0.5f); Image val6 = val4.AddComponent<Image>(); val6.sprite = _bubbleSprite; val6.preserveAspect = true; ((Graphic)val6).color = new Color(0.8f, 0.92f, 1f, 0.8f); _bubbles.Add(val6); } GameObject val7 = new GameObject("BreathText"); val7.transform.SetParent((Transform)(object)_container, false); _breathText = val7.AddComponent<TextMeshProUGUI>(); ((TMP_Text)_breathText).fontSize = 16f; ((TMP_Text)_breathText).fontSizeMin = 10f; ((TMP_Text)_breathText).fontSizeMax = 24f; ((TMP_Text)_breathText).alignment = (TextAlignmentOptions)4097; ((Graphic)_breathText).color = new Color(0.8f, 0.92f, 1f, 0.9f); RectTransform rectTransform = ((TMP_Text)_breathText).rectTransform; rectTransform.sizeDelta = new Vector2(60f, 25f); rectTransform.anchorMin = new Vector2(1f, 0.5f); rectTransform.anchorMax = new Vector2(1f, 0.5f); rectTransform.pivot = new Vector2(0f, 0.5f); rectTransform.anchoredPosition = new Vector2(8f, 0f); SetVisible(visible: false); } private Sprite CreateBubbleSprite(int size) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: 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_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(size, size, (TextureFormat)4, false); ((Texture)val).filterMode = (FilterMode)1; ((Texture)val).wrapMode = (TextureWrapMode)1; Vector2 val2 = default(Vector2); ((Vector2)(ref val2))..ctor((float)(size - 1) * 0.5f, (float)(size - 1) * 0.5f); float num = (float)size * 0.42f; float num2 = num * 0.72f; Vector2 val3 = default(Vector2); ((Vector2)(ref val3))..ctor(val2.x - (float)size * 0.12f, val2.y + (float)size * 0.12f); float num3 = (float)size * 0.12f; Vector2 val4 = default(Vector2); Color val5 = default(Color); for (int i = 0; i < size; i++) { for (int j = 0; j < size; j++) { ((Vector2)(ref val4))..ctor((float)j, (float)i); float num4 = Vector2.Distance(val4, val2); if (num4 > num) { val.SetPixel(j, i, Color.clear); continue; } float num5 = Mathf.InverseLerp(num, num2, num4); float num6 = Mathf.Lerp(0.15f, 0.95f, num5); ((Color)(ref val5))..ctor(0.82f, 0.93f, 1f, num6); float num7 = Vector2.Distance(val4, val3); if (num7 < num3) { float num8 = 1f - num7 / num3; val5 = Color.Lerp(val5, new Color(1f, 1f, 1f, num6), num8 * 0.65f); } val.SetPixel(j, i, val5); } } val.Apply(); return Sprite.Create(val, new Rect(0f, 0f, (float)size, (float)size), new Vector2(0.5f, 0.5f), 100f); } } internal static class InputHelper { public static bool GetRun() { return ZInput.GetButton("Run"); } public static bool GetJump() { return ZInput.GetButton("Jump"); } public static bool GetCrouch() { return ZInput.GetButton("Crouch"); } public static float GetHorizontal() { return Input.GetAxisRaw("Horizontal"); } public static float GetVertical() { return Input.GetAxisRaw("Vertical"); } public static float GetDiveVertical() { float num = 0f; if (GetJump()) { num += 1f; } if (GetCrouch()) { num -= 1f; } return num; } } internal sealed class PlayerDiveController : MonoBehaviour { private const float HeadUnderwaterTolerance = 0.01f; internal const float DefaultSwimDepth = 1.3f; internal const float DivingThreshold = 1.5f; internal const float MinSwimDepth = 1.3f; internal const float MaxSwimDepth = 100f; internal const float DepthChangeSpeed = 0.025f; private const float LegacyDepthChangeSpeed = 0.04f; [NonSerialized] internal bool toggleDive; [NonSerialized] internal bool is_diving; [NonSerialized] internal bool isUnderwater; [NonSerialized] internal string lastDiveCancel = "None"; private bool _underwaterMovementActive; private float _baseSwimSpeed; private int _swimmingUpdateContextDepth; private int _swimmingUpdateContextFrame = -1; private float _diveAxis; private float _legacyDiveVertical; private bool _legacyDiveActive; internal static PlayerDiveController? LocalInstance { get; private set; } internal Player Player { get; private set; } = null; private void Awake() { Player = ((Component)this).GetComponent<Player>(); if (!Object.op_Implicit((Object)(object)Player)) { Object.Destroy((Object)(object)this); return; } if ((Object)(object)Player != (Object)(object)Player.m_localPlayer) { Object.Destroy((Object)(object)this); return; } LocalInstance = this; ((Character)Player).m_swimDepth = 1.3f; _baseSwimSpeed = ((Character)Player).m_swimSpeed; } private void OnDestroy() { if ((Object)(object)LocalInstance == (Object)(object)this) { LocalInstance = null; } } internal void HandleDiveToggle() { if (!((Character)Player).InWater() || ((Character)Player).IsOnGround() || !((Character)Player).IsSwimming()) { if (toggleDive) { toggleDive = false; is_diving = false; _legacyDiveActive = false; _legacyDiveVertical = 0f; lastDiveCancel = "PlayerOnLand"; } } else if (VBDiving.UseLegacyDiveControls.Value) { HandleLegacyControls(); } else if (ZInput.GetButtonDown("Crouch") || ZInput.GetButtonDown("JoyCrouch")) { if (!toggleDive) { toggleDive = true; lastDiveCancel = "None"; } else if (toggleDive && ((Character)Player).m_swimDepth <= 1.5f) { toggleDive = false; lastDiveCancel = "PlayerCancelled"; } } } private void HandleLegacyControls() { bool flag = ZInput.GetButton("Crouch") || ZInput.GetButton("JoyCrouch"); bool flag2 = ZInput.GetButton("Jump") || ZInput.GetButton("JoyJump"); if (flag && !flag2) { toggleDive = true; _legacyDiveActive = true; _legacyDiveVertical = 1f; lastDiveCancel = "None"; } else if (flag2 && !flag) { _legacyDiveActive = true; _legacyDiveVertical = -1f; if (((Character)Player).m_swimDepth <= 1.4f) { toggleDive = false; _legacyDiveActive = false; _legacyDiveVertical = 0f; lastDiveCancel = "PlayerSurfaced"; } } else if (flag && flag2) { toggleDive = true; _legacyDiveActive = true; _legacyDiveVertical = 1f; } else { _legacyDiveVertical = 0f; if (((Character)Player).m_swimDepth <= 1.5f) { toggleDive = false; _legacyDiveActive = false; lastDiveCancel = "PlayerSurfaced"; } else { _legacyDiveActive = false; } } } internal void UpdateDiveState() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) if (ShieldGenerator.IsInsideShield(((Component)Player).transform.position)) { DisableUnderwaterMovement(); return; } if (!((Character)Player).InWater()) { ((Character)Player).m_swimDepth = 1.3f; return; } if (((Character)Player).m_swimDepth > 1.5f && Mathf.Max(0f, ((Character)Player).GetLiquidLevel() - ((Component)Player).transform.position.y) > 1.5f) { is_diving = true; isUnderwater = true; return; } if (is_diving) { is_diving = false; if (!VBDiving.UseLegacyDiveControls.Value || ((Character)Player).m_swimDepth <= 1.4f) { toggleDive = false; } lastDiveCancel = "PlayerSurfaced"; } isUnderwater = false; } internal void UpdateDiveDepth(Vector3 lookDir) { //IL_0062: 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_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_0224: 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_01f5: Unknown result type (might be due to invalid IL or missing references) //IL_01fb: Unknown result type (might be due to invalid IL or missing references) //IL_0200: Unknown result type (might be due to invalid IL or missing references) //IL_0207: Unknown result type (might be due to invalid IL or missing references) //IL_020c: Unknown result type (might be due to invalid IL or missing references) //IL_0211: Unknown result type (might be due to invalid IL or missing references) //IL_0215: Unknown result type (might be due to invalid IL or missing references) //IL_021a: Unknown result type (might be due to invalid IL or missing references) if (!((Character)Player).InWater() || ((Character)Player).IsOnGround() || !((Character)Player).IsSwimming()) { return; } if (VBDiving.UseLegacyDiveControls.Value) { UpdateLegacyDiveMovement(); } else { if (!toggleDive) { return; } if (lookDir.y < -0.15f) { _diveAxis = 1f; } else if (lookDir.y > 0.15f) { _diveAxis = 0f; } if (!ZInput.GetButton("Forward") && !ZInput.GetButton("JoyLStickUp")) { return; } float num2; if (_diveAxis == 1f) { float num = Mathf.Abs(lookDir.y); num2 = num * 0.025f; if (num2 < 0.005f && num > 0.9f) { num2 = 0.005f; } } else if (_diveAxis == 0f) { num2 = lookDir.y * 0.025f; if (num2 < 0.005f && lookDir.y > 0.9f) { num2 = 0.005f; } } else { num2 = 0f; } if (num2 > 0.025f) { num2 = 0.025f; } ApplyVerticalMovement(num2); if (!(((Character)Player).m_swimDepth > 1.5f)) { return; } Vector3 moveDir = lookDir; if (Mathf.Abs(lookDir.y) > 0.95f) { Vector3 forward = ((Component)Player).transform.forward; forward.y = 0f; if (((Vector3)(ref forward)).magnitude > 0.01f) { ((Vector3)(ref forward)).Normalize(); Vector3 val = lookDir * 0.7f + forward * 0.3f; moveDir = ((Vector3)(ref val)).normalized; } } ((Character)Player).SetMoveDir(moveDir); } } private void UpdateLegacyDiveMovement() { //IL_0184: 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_018d: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_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_00b0: 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_01f6: Unknown result type (might be due to invalid IL or missing references) //IL_01fb: 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_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_01d4: 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_01de: 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_0119: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_0226: Unknown result type (might be due to invalid IL or missing references) //IL_0230: Unknown result type (might be due to invalid IL or missing references) //IL_0235: Unknown result type (might be due to invalid IL or missing references) //IL_023f: Unknown result type (might be due to invalid IL or missing references) //IL_0244: Unknown result type (might be due to invalid IL or missing references) //IL_0249: Unknown result type (might be due to invalid IL or missing references) //IL_024d: Unknown result type (might be due to invalid IL or missing references) //IL_0252: Unknown result type (might be due to invalid IL or missing references) //IL_021d: Unknown result type (might be due to invalid IL or missing references) //IL_0222: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_0167: 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_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_025b: Unknown result type (might be due to invalid IL or missing references) float legacyDiveVertical = _legacyDiveVertical; if (Mathf.Abs(legacyDiveVertical) < 0.01f) { return; } if (legacyDiveVertical < 0f && ((Character)Player).m_swimDepth <= 1.3f) { ((Character)Player).m_swimDepth = 1.3f; return; } float num = legacyDiveVertical * 0.04f; float num2 = ((Character)Player).m_swimDepth + num; num2 = Mathf.Clamp(num2, 1.3f, 100f); ((Character)Player).m_swimDepth = num2; Vector3 val2; Vector3 normalized; if (legacyDiveVertical > 0f) { Vector3 lookDir = ((Character)Player).GetLookDir(); Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(lookDir.x, 0f, lookDir.z); if (((Vector3)(ref val)).magnitude > 0.1f) { val2 = ((Vector3)(ref val)).normalized * 0.7f + Vector3.down * 0.3f; normalized = ((Vector3)(ref val2)).normalized; } else { Vector3 forward = ((Component)Player).transform.forward; forward.y = 0f; if (((Vector3)(ref forward)).magnitude < 0.1f) { forward = Vector3.forward; } val2 = ((Vector3)(ref forward)).normalized * 0.3f + Vector3.down * 0.7f; normalized = ((Vector3)(ref val2)).normalized; } } else { Vector3 lookDir2 = ((Character)Player).GetLookDir(); Vector3 val3 = default(Vector3); ((Vector3)(ref val3))..ctor(lookDir2.x, 0f, lookDir2.z); if (((Vector3)(ref val3)).magnitude > 0.1f) { val2 = ((Vector3)(ref val3)).normalized * 0.7f + Vector3.up * 0.3f; normalized = ((Vector3)(ref val2)).normalized; } else { Vector3 forward2 = ((Component)Player).transform.forward; forward2.y = 0f; if (((Vector3)(ref forward2)).magnitude < 0.1f) { forward2 = Vector3.forward; } val2 = ((Vector3)(ref forward2)).normalized * 0.3f + Vector3.up * 0.7f; normalized = ((Vector3)(ref val2)).normalized; } } ((Character)Player).SetMoveDir(normalized); } private void ApplyVerticalMovement(float multiplier) { if (_diveAxis == 1f) { Player player = Player; ((Character)player).m_swimDepth = ((Character)player).m_swimDepth + multiplier; } else if (_diveAxis == 0f) { if (((Character)Player).m_swimDepth > 1.3f) { Player player2 = Player; ((Character)player2).m_swimDepth = ((Character)player2).m_swimDepth - multiplier; } if (((Character)Player).m_swimDepth < 1.3f) { ((Character)Player).m_swimDepth = 1.3f; } } if (((Character)Player).m_swimDepth > 100f) { ((Character)Player).m_swimDepth = 100f; } } internal void DisableUnderwaterMovement() { _underwaterMovementActive = false; toggleDive = false; is_diving = false; _legacyDiveActive = false; _legacyDiveVertical = 0f; ResetSwimDepthToDefault(); ((Character)Player).m_swimSpeed = _baseSwimSpeed; } internal void ResetSwimDepthIfNotInWater() { if (!WaterHelper.IsBodyInWater(Player)) { DisableUnderwaterMovement(); } } internal void ResetSwimDepthToDefault() { //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) ((Character)Player).m_swimDepth = 1.3f; if (WaterHelper.IsBodyInWater(Player) && !toggleDive && !is_diving && !_legacyDiveActive) { float liquidLevel = ((Character)Player).GetLiquidLevel(); Vector3 position = ((Component)Player).transform.position; position.y = liquidLevel - 1.3f; ((Component)Player).transform.position = position; } } internal bool CanDive() { if (!WaterHelper.IsBodyInWater(Player) || ((Character)Player).IsOnGround()) { return false; } return true; } internal bool IsHeadUnderwater() { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) float num = (Object.op_Implicit((Object)(object)((Character)Player).m_eye) ? ((Character)Player).m_eye.position.y : ((Component)Player).transform.position.y); return ((Character)Player).GetLiquidLevel() - num > 0.01f; } internal void RefreshUnderwaterMovementState() { if (!WaterHelper.IsBodyInWater(Player) || !IsHeadUnderwater()) { _underwaterMovementActive = false; } else if (IsUnderSurface()) { _underwaterMovementActive = true; } } internal bool ShouldForceSwimming() { return _underwaterMovementActive && WaterHelper.IsBodyInWater(Player) && IsHeadUnderwater(); } internal bool ShouldForceDive() { return ShouldForceSwimming() && !((Character)Player).IsOnGround(); } internal bool IsUnderSurface() { return ((Character)Player).m_swimDepth > 1.3f; } internal bool IsDiving() { return ((Character)Player).m_swimDepth > 1.5f; } internal bool IsSurfacing() { return !IsDiving() && IsUnderSurface(); } internal bool IsIdleInWater() { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) int result; if (WaterHelper.IsBodyInWater(Player) && (WaterHelper.IsBodyInWater(Player) || ShouldForceSwimming())) { Vector3 velocity = ((Character)Player).GetVelocity(); result = ((((Vector3)(ref velocity)).magnitude < 1f) ? 1 : 0); } else { result = 0; } return (byte)result != 0; } internal void BeginSwimmingUpdateContext() { _swimmingUpdateContextDepth++; _swimmingUpdateContextFrame = Time.frameCount; } internal void EndSwimmingUpdateContext() { if (_swimmingUpdateContextDepth > 0) { _swimmingUpdateContextDepth--; } if (_swimmingUpdateContextDepth == 0) { _swimmingUpdateContextFrame = -1; } } internal bool IsInSwimmingUpdateContext() { return _swimmingUpdateContextDepth > 0 && _swimmingUpdateContextFrame == Time.frameCount; } internal void UpdateSwimSpeed() { float num = 1f; if (InputHelper.GetRun()) { float skillFactor = Player.m_skills.GetSkillFactor((SkillType)103); float num2 = Mathf.Max(1f, VBDiving.SprintSwimMultiplier.Value); num = Mathf.Lerp(1f, num2, Mathf.Pow(skillFactor, 1.5f)); } ((Character)Player).m_swimSpeed = _baseSwimSpeed * num; } } public static class SwimAPI { public static event Action<Player> OnEnterWater; public static event Action<Player> OnExitWater; public static event Action<Player> OnHeadUnderwater; public static event Action<Player> OnHeadAboveWater; public static event Action<Player> OnOutOfBreath; public static float GetBreathPercent(Player player) { if (!Object.op_Implicit((Object)(object)player)) { return 1f; } SwimState swimState = SwimStateManager.Get(player); float maxBreath = GetMaxBreath(player); if (maxBreath <= 0f) { return 0f; } return Mathf.Clamp01(swimState.Breath / maxBreath); } public static bool IsUnderwater(Player player) { if (!Object.op_Implicit((Object)(object)player)) { return false; } return WaterHelper.IsHeadUnderwater(player); } public static bool IsSwimming(Player player) { if (!Object.op_Implicit((Object)(object)player)) { return false; } return WaterHelper.IsBodyInWater(player); } public static float GetCurrentBreath(Player player) { if (!Object.op_Implicit((Object)(object)player)) { return 0f; } return SwimStateManager.Get(player).Breath; } public static float GetBaseMaxBreath(Player player) { if (!Object.op_Implicit((Object)(object)player)) { return VBDiving.MaxBreathSeconds.Value; } float skillFactor = ((Character)player).GetSkillFactor((SkillType)103); return VBDiving.MaxBreathSeconds.Value + VBDiving.MaxBreathBonusAtSkill100.Value * skillFactor; } public static float GetMaxBreath(Player player) { if (!Object.op_Implicit((Object)(object)player)) { return VBDiving.MaxBreathSeconds.Value; } SwimState swimState = SwimStateManager.Get(player); return GetBaseMaxBreath(player) + swimState.ExtraBreathBonus; } public static bool IsOutOfBreath(Player player) { return GetCurrentBreath(player) <= 0f; } public static float GetSwimSkillFactor(Player player) { if (!Object.op_Implicit((Object)(object)player)) { return 0f; } return ((Character)player).GetSkillFactor((SkillType)103); } public static bool HasInfiniteBreath(Player player) { if (!Object.op_Implicit((Object)(object)player)) { return false; } SwimState swimState = SwimStateManager.Get(player); return Time.time < swimState.InfiniteBreathUntil; } public static float GetExternalSwimSpeedMultiplier(Player player) { if (!Object.op_Implicit((Object)(object)player)) { return 1f; } SwimState swimState = SwimStateManager.Get(player); if (Time.time >= swimState.SwimSpeedMultiplierUntil) { swimState.SwimSpeedMultiplier = 1f; return 1f; } return swimState.SwimSpeedMultiplier; } public static void RestoreBreath(Player player, float amount) { if (Object.op_Implicit((Object)(object)player) && !(amount <= 0f)) { SwimState swimState = SwimStateManager.Get(player); swimState.Breath = Mathf.Min(GetMaxBreath(player), swimState.Breath + amount); } } public static void DrainBreath(Player player, float amount) { if (Object.op_Implicit((Object)(object)player) && !(amount <= 0f)) { SwimState swimState = SwimStateManager.Get(player); swimState.Breath = Mathf.Max(0f, swimState.Breath - amount); } } public static void SetInfiniteBreath(Player player, float duration) { if (Object.op_Implicit((Object)(object)player) && !(duration <= 0f)) { SwimState swimState = SwimStateManager.Get(player); swimState.InfiniteBreathUntil = Mathf.Max(swimState.InfiniteBreathUntil, Time.time + duration); swimState.Breath = GetMaxBreath(player); } } public static void AddBreathBonus(Player player, float bonusSeconds) { if (Object.op_Implicit((Object)(object)player)) { SwimState swimState = SwimStateManager.Get(player); swimState.ExtraBreathBonus = Mathf.Max(0f, swimState.ExtraBreathBonus + bonusSeconds); swimState.Breath = Mathf.Min(swimState.Breath, GetMaxBreath(player)); } } public static void SetBreathBonus(Player player, float bonusSeconds) { if (Object.op_Implicit((Object)(object)player)) { SwimState swimState = SwimStateManager.Get(player); swimState.ExtraBreathBonus = Mathf.Max(0f, bonusSeconds); swimState.Breath = Mathf.Min(swimState.Breath, GetMaxBreath(player)); } } public static void AddSwimSpeedBonus(Player player, float multiplier, float duration) { if (Object.op_Implicit((Object)(object)player) && !(multiplier <= 0f) && !(duration <= 0f)) { SwimState swimState = SwimStateManager.Get(player); swimState.SwimSpeedMultiplier = Mathf.Max(swimState.SwimSpeedMultiplier, multiplier); swimState.SwimSpeedMultiplierUntil = Mathf.Max(swimState.SwimSpeedMultiplierUntil, Time.time + duration); } } internal static void UpdateEvents(Player player) { if (Object.op_Implicit((Object)(object)player)) { SwimState swimState = SwimStateManager.Get(player); bool flag = IsSwimming(player); bool flag2 = IsUnderwater(player); bool flag3 = IsOutOfBreath(player); if (flag && !swimState.WasSwimming) { SwimAPI.OnEnterWater?.Invoke(player); } else if (!flag && swimState.WasSwimming) { SwimAPI.OnExitWater?.Invoke(player); } if (flag2 && !swimState.WasHeadUnderwater) { SwimAPI.OnHeadUnderwater?.Invoke(player); } else if (!flag2 && swimState.WasHeadUnderwater) { SwimAPI.OnHeadAboveWater?.Invoke(player); } if (flag3 && !swimState.WasOutOfBreath) { SwimAPI.OnOutOfBreath?.Invoke(player); } swimState.WasSwimming = flag; swimState.WasHeadUnderwater = flag2; swimState.WasOutOfBreath = flag3; } } } [BepInPlugin("VitByr.VBDiving", "VBDiving", "0.0.4")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInIncompatibility("sighsorry.DiveIn")] [BepInIncompatibility("ch.easy.develope.vh.diving.mod")] [BepInIncompatibility("blacks7ar.VikingsDoSwim")] [BepInIncompatibility("projjm.improvedswimming")] [BepInIncompatibility("dzk.SwimmingReworked")] [SynchronizationMode(/*Could not decode attribute arguments.*/)] internal class VBDiving : BaseUnityPlugin { public const string PluginGUID = "VitByr.VBDiving"; public const string PluginName = "VBDiving"; public const string PluginVersion = "0.0.4"; internal static VBDiving Instance; internal static Harmony Harmony; internal static ConfigEntry<bool> EnableMod; internal static ConfigEntry<float> MaxBreathSeconds; internal static ConfigEntry<float> MaxBreathBonusAtSkill100; internal static ConfigEntry<float> BreathRecoveryPerSecond; internal static ConfigEntry<float> SprintSwimMultiplier; internal static ConfigEntry<float> BaseUnderwaterStaminaRegenPerSecond; internal static ConfigEntry<bool> DebugLogging; internal static ConfigEntry<bool> UseLegacyDiveControls; internal static float SwimStaminaDrainMinSkill = 4f; internal static float SwimStaminaDrainMaxSkill = 2f; internal static ConfigEntry<float> BreathHudOffsetX; internal static ConfigEntry<float> BreathHudOffsetY; internal static ConfigEntry<float> BreathHudScale; internal static ConfigEntry<bool> BreathHudShowLabels; internal static ConfigEntry<bool> SyncMonsterConfigs; internal static ConfigEntry<bool> UseServerMonsterConfigsOnly; private ConfigFileWatcher _configWatcher; internal static string ConfigFolderPath; private CustomRPC _monsterConfigRPC; private bool _hasRequestedConfigs; private void Awake() { //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Expected O, but got Unknown Instance = this; ConfigFolderPath = Path.Combine(Paths.ConfigPath, "VitByr", "VBDiving"); Directory.CreateDirectory(ConfigFolderPath); CreateConfig(); CreateConfigWatcher(); SynchronizationManager.OnConfigurationSynchronized += OnConfigurationSynchronized; SynchronizationManager.OnAdminStatusChanged += OnAdminStatusChanged; ((Component)this).gameObject.AddComponent<BreathHud>(); ((Component)this).gameObject.AddComponent<DiveImmersionEffect>(); ((MonoBehaviour)this).StartCoroutine(InitDiveControllerWhenReady()); Harmony = new Harmony("VitByr.VBDiving"); Harmony.PatchAll(); SetupMonsterConfigSync(); MonsterDiveSystem.Initialize(); } private IEnumerator InitDiveControllerWhenReady() { while (!Object.op_Implicit((Object)(object)Player.m_localPlayer)) { yield return null; } Player player = Player.m_localPlayer; PlayerDiveController playerDiveController = default(PlayerDiveController); if (!((Component)player).TryGetComponent<PlayerDiveController>(ref playerDiveController)) { ((Component)player).gameObject.AddComponent<PlayerDiveController>(); ((BaseUnityPlugin)this).Logger.LogDebug((object)"DiveController added to local player"); } } private void SetupMonsterConfigSync() { //IL_0013: 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_0029: Expected O, but got Unknown //IL_0029: Expected O, but got Unknown _monsterConfigRPC = NetworkManager.Instance.AddRPC("VBDiving_SyncMonsterConfigs", new CoroutineHandler(OnServerReceiveRequest), new CoroutineHandler(OnClientReceiveConfigs)); if ((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer()) { ((BaseUnityPlugin)this).Logger.LogInfo((object)"[VBDiving] Server mode: loading monster configs"); MonsterDiveSystem.LoadAllMonsterDiveConfigs(); } else if ((Object)(object)ZNet.instance != (Object)null && ZNetExtension.IsClientInstance(ZNet.instance)) { ((BaseUnityPlugin)this).Logger.LogInfo((object)"[VBDiving] Client mode: will request monster configs from server"); } } private IEnumerator OnServerReceiveRequest(long sender, ZPackage package) { int flag = package.ReadInt(); ((BaseUnityPlugin)this).Logger.LogInfo((object)$"[VBDiving] Server received request from client {sender}, flag={flag}"); if (flag == 0) { SendMonsterConfigsToClient(sender); } yield break; } private IEnumerator OnClientReceiveConfigs(long sender, ZPackage package) { int flag = package.ReadInt(); ((BaseUnityPlugin)this).Logger.LogInfo((object)$"[VBDiving] Client received configs from server, flag={flag}"); if (flag == 1) { string configData = package.ReadString(); ((BaseUnityPlugin)this).Logger.LogInfo((object)$"[VBDiving] Received monster configs from server ({configData.Length} bytes)"); if (string.IsNullOrEmpty(configData)) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"[VBDiving] Received empty config data from server"); } else if (UseServerMonsterConfigsOnly.Value) { ((BaseUnityPlugin)this).Logger.LogInfo((object)"[VBDiving] Using server configs only (ignoring local)"); MonsterDiveSystem.LoadSerializedConfigs(configData, useServerOnly: true); } else { ((BaseUnityPlugin)this).Logger.LogInfo((object)"[VBDiving] Merging server configs with local (server priority)"); MonsterDiveSystem.LoadSerializedConfigs(configData); } } yield break; } private void SendMonsterConfigsToAllClients() { //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Expected O, but got Unknown if (!SyncMonsterConfigs.Value) { ((BaseUnityPlugin)this).Logger.LogInfo((object)"[VBDiving] SyncMonsterConfigs is disabled, not sending"); return; } string serializedConfigs = MonsterDiveSystem.GetSerializedConfigs(); if (string.IsNullOrEmpty(serializedConfigs)) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"[VBDiving] No configs to send to clients"); return; } ((BaseUnityPlugin)this).Logger.LogInfo((object)$"[VBDiving] Sending monster configs to all clients ({serializedConfigs.Length} bytes)"); ZPackage val = new ZPackage(); val.Write(1); val.Write(serializedConfigs); foreach (ZNetPeer peer in ZNet.instance.m_peers) { if (peer.m_uid != ZRoutedRpc.instance.GetServerPeerID()) { _monsterConfigRPC.SendPackage(peer.m_uid, val); } } } private void SendMonsterConfigsToClient(long clientId) { //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Expected O, but got Unknown if (!SyncMonsterConfigs.Value) { ((BaseUnityPlugin)this).Logger.LogInfo((object)"[VBDiving] SyncMonsterConfigs is disabled, not sending to client"); return; } string serializedConfigs = MonsterDiveSystem.GetSerializedConfigs(); if (string.IsNullOrEmpty(serializedConfigs)) { ((BaseUnityPlugin)this).Logger.LogWarning((object)$"[VBDiving] No configs to send to client {clientId}"); return; } ((BaseUnityPlugin)this).Logger.LogInfo((object)$"[VBDiving] Sending monster configs to client {clientId} ({serializedConfigs.Length} bytes)"); ((BaseUnityPlugin)this).Logger.LogDebug((object)("[VBDiving] Configs preview: " + serializedConfigs.Substring(0, Math.Min(200, serializedConfigs.Length)) + "...")); ZPackage val = new ZPackage(); val.Write(1); val.Write(serializedConfigs); _monsterConfigRPC.SendPackage(clientId, val); } internal static void RequestMonsterConfigsFromServer() { //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Expected O, but got Unknown if (!((Object)(object)Instance == (Object)null) && !((Object)(object)ZNet.instance == (Object)null) && !ZNet.instance.IsServer() && SyncMonsterConfigs.Value && !Instance._hasRequestedConfigs) { Instance._hasRequestedConfigs = true; ((BaseUnityPlugin)Instance).Logger.LogInfo((object)"[VBDiving] Requesting monster configs from server..."); ZPackage val = new ZPackage(); val.Write(0); Instance._monsterConfigRPC.SendPackage(ZRoutedRpc.instance.GetServerPeerID(), val); } } internal static void OnServerConfigsChanged() { if ((Object)(object)Instance != (Object)null && (Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer() && SyncMonsterConfigs.Value) { ((BaseUnityPlugin)Instance).Logger.LogInfo((object)"[VBDiving] Server configs changed, sending updates to all clients"); Instance.SendMonsterConfigsToAllClients(); } } private void CreateConfig() { //IL_01e8: Unknown result type (might be due to invalid IL or missing references) //IL_01f2: Expected O, but got Unknown ((BaseUnityPlugin)this).Config.SaveOnConfigSet = false; EnableMod = ConfigFileExtensions.BindConfig<bool>(((BaseUnityPlugin)this).Config, "00 - Main", "EnableMod", true, "Включить или отключить мод.", true, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); SyncMonsterConfigs = ConfigFileExtensions.BindConfig<bool>(((BaseUnityPlugin)this).Config, "00 - Main", "SyncMonsterConfigs", true, "Синхронизировать конфиги монстров с сервера.", true, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); UseServerMonsterConfigsOnly = ConfigFileExtensions.BindConfig<bool>(((BaseUnityPlugin)this).Config, "00 - Main", "UseServerMonsterConfigsOnly", true, "Использовать ТОЛЬКО конфиги с сервера (игнорировать локальные файлы). Если false - серверные конфиги имеют приоритет над локальными.", true, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); UseLegacyDiveControls = ((BaseUnityPlugin)this).Config.Bind<bool>("01 - Control", "UseLegacyDiveControls", true, "Если true: зажать Crouch для погружения, Jump для всплытия.\nЕсли false: нажать Crouch для переключения режима ныряния, затем направление взгляда + Forward для движения вверх/вниз."); MaxBreathSeconds = ConfigFileExtensions.BindConfig<float>(((BaseUnityPlugin)this).Config, "02 - Breath", "MaxBreathSeconds", 30f, "Максимальное время под водой при навыке плавания 0.", true, (int?)null, (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 600f), (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); MaxBreathBonusAtSkill100 = ConfigFileExtensions.BindConfig<float>(((BaseUnityPlugin)this).Config, "02 - Breath", "MaxBreathBonusAtSkill100", 150f, "Дополнительное время под водой при навыке плавания 100.", true, (int?)null, (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 600f), (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); BreathRecoveryPerSecond = ConfigFileExtensions.BindConfig<float>(((BaseUnityPlugin)this).Config, "02 - Breath", "BreathRecoveryPerSecond", 30f, "Скорость восстановления дыхания.", true, (int?)null, (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 300f), (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); BreathHudOffsetX = ((BaseUnityPlugin)this).Config.Bind<float>("03 - BreathHud", "OffsetX", 0f, "Смещение индикатора по горизонтали от центра экрана (в процентах от ширины экрана).\nОтрицательное = левее, положительное = правее."); BreathHudOffsetY = ((BaseUnityPlugin)this).Config.Bind<float>("03 - BreathHud", "OffsetY", -30f, "Смещение индикатора по вертикали от центра экрана (в процентах от высоты экрана).\nОтрицательное = ниже, положительное = выше."); BreathHudScale = ((BaseUnityPlugin)this).Config.Bind<float>("03 - BreathHud", "Scale", 1f, new ConfigDescription("Масштаб индикатора дыхания.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.3f, 3f), Array.Empty<object>())); BreathHudShowLabels = ((BaseUnityPlugin)this).Config.Bind<bool>("03 - BreathHud", "ShowLabels", true, "Показывать числовое значение дыхания справа от пузырьков."); SprintSwimMultiplier = ConfigFileExtensions.BindConfig<float>(((BaseUnityPlugin)this).Config, "04 - Swimming", "SprintSwimMultiplier", 2.25f, "Множитель скорости при спринте в воде.", true, (int?)null, (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 5f), (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); BaseUnderwaterStaminaRegenPerSecond = ConfigFileExtensions.BindConfig<float>(((BaseUnityPlugin)this).Config, "04 - Swimming", "BaseUnderwaterStaminaRegenPerSecond", 1.25f, "Базовая скорость восстановления выносливости на поверхности без движения.", true, (int?)null, (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 50f), (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); PlayerEquipInWater.EquipInWaterList = ConfigFileExtensions.BindConfig<string>(((BaseUnityPlugin)this).Config, "06 - EquipInWater", "EiW_Custom", "KnifeFlint,KnifeCopper,KnifeChitin,KnifeSilver,KnifeBlackMetal,KnifeButcher,KnifeSkollAndHati,SpearFlint,SpearBronze,SpearElderbark,SpearWolfFang,SpearChitin,SpearCarapace,PickaxeAntler,PickaxeBronze,PickaxeIron,PickaxeBlackMetal,Hammer,Hoe,FistFenrirClaw", "Разрешить использовать оружие/инструмент в воде", true, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); PlayerEquipInWater.EquipInWaterList.SettingChanged += delegate { HashSet<string> hashSet2 = new HashSet<string>(); string[] array2 = PlayerEquipInWater.EquipInWaterList.Value.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries); foreach (string item2 in array2) { hashSet2.Add(item2); } PlayerEquipInWater.EquipInWaterItems = hashSet2; }; HashSet<string> hashSet = new HashSet<string>(); string[] array = PlayerEquipInWater.EquipInWaterList.Value.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries); foreach (string item in array) { hashSet.Add(item); } PlayerEquipInWater.EquipInWaterItems = hashSet; DebugLogging = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "DebugLogging", false, "Включить отладочные логи."); ((BaseUnityPlugin)this).Config.SaveOnConfigSet = true; ((BaseUnityPlugin)this).Config.Save(); } private void CreateConfigWatcher() { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown _configWatcher = new ConfigFileWatcher(((BaseUnityPlugin)this).Config, 1000L); _configWatcher.OnConfigFileReloaded += delegate { ((BaseUnityPlugin)this).Logger.LogInfo((object)"Config file reloaded from disk."); }; } internal static float GetClampedSkillFactor(Player player, SkillType skillType) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) float skillLevel = ((Character)player).GetSkillLevel(skillType); float num = Mathf.Min(skillLevel, 100f); return num / 100f; } internal static float GetClampedSwimFactor(Player player) { float skillLevel = ((Character)player).GetSkillLevel((SkillType)103); float num = Mathf.Min(skillLevel, 100f); return num / 100f; } private void OnConfigurationSynchronized(object sender, ConfigurationSynchronizationEventArgs e) { if (e.InitialSynchronization) { ((BaseUnityPlugin)this).Logger.LogInfo((object)"Initial config sync received."); if ((Object)(object)ZNet.instance != (Object)null && ZNetExtension.IsClientInstance(ZNet.instance)) { ((MonoBehaviour)this).StartCoroutine(RequestConfigsAfterSync()); } } else { ((BaseUnityPlugin)this).Logger.LogInfo((object)"Config sync update received."); } if ((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer() && SyncMonsterConfigs.Value) { SendMonsterConfigsToAllClients(); } } private IEnumerator RequestConfigsAfterSync() { yield return (object)new WaitForSeconds(2f); RequestMonsterConfigsFromServer(); } private void OnAdminStatusChanged() { ((BaseUnityPlugin)this).Logger.LogInfo((object)("Admin status changed: " + (SynchronizationManager.Instance.PlayerIsAdmin ? "admin" : "not admin"))); } private void OnDestroy() { SynchronizationManager.OnConfigurationSynchronized -= OnConfigurationSynchronized; SynchronizationManager.OnAdminStatusChanged -= OnAdminStatusChanged; if (_configWatcher != null) { _configWatcher = null; } } internal static bool IsEnabled() { return Object.op_Implicit((Object)(object)Instance) && EnableMod.Value; } internal static void LogDebug(string msg) { if (Object.op_Implicit((Object)(object)Instance) && DebugLogging.Value) { ((BaseUnityPlugin)Instance).Logger.LogInfo((object)msg); } } } internal class SwimState { public float Breath; public bool WasHeadUnderwater; public bool WasSwimming; public float LastSurfaceTime; public float SuffocationTickTimer; public float ExtraBreathBonus; public float InfiniteBreathUntil; public float SwimSpeedMultiplier = 1f; public float SwimSpeedMultiplierUntil; public bool WasOutOfBreath; } internal static class SwimStateManager { private static readonly Dictionary<long, SwimState> States = new Dictionary<long, SwimState>(); public static SwimState Get(Player player) { long playerID = player.GetPlayerID(); if (!States.TryGetValue(playerID, out var value)) { value = new SwimState { Breath = SwimAPI.GetBaseMaxBreath(player), WasHeadUnderwater = false, WasSwimming = false, LastSurfaceTime = 0f, SuffocationTickTimer = 0f, ExtraBreathBonus = 0f, InfiniteBreathUntil = 0f, SwimSpeedMultiplier = 1f, SwimSpeedMultiplierUntil = 0f, WasOutOfBreath = false }; States[playerID] = value; } return value; } public static void Remove(Player player) { if (Object.op_Implicit((Object)(object)player)) { States.Remove(player.GetPlayerID()); } } } internal static class WaterHelper { public static bool TryGetWaterLevel(Vector3 position, out float waterLevel) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) waterLevel = Floating.GetLiquidLevel(position, 1f, (LiquidType)0); return waterLevel > -10000f; } public static Vector3 GetHeadPosition(Player player) { //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_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)player)) { return Vector3.zero; } return ((Character)player).GetHeadPoint(); } public static Vector3 GetChestPosition(Player player) { //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_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)player)) { return Vector3.zero; } return ((Component)player).transform.position + Vector3.up * 1f; } public static bool IsBodyInWater(Player player) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)player)) { return false; } Vector3 chestPosition = GetChestPosition(player); float waterLevel; return TryGetWaterLevel(chestPosition, out waterLevel) && chestPosition.y < waterLevel; } public static bool IsHeadUnderwater(Player player) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)player)) { return false; } Vector3 headPosition = GetHeadPosition(player); float waterLevel; return TryGetWaterLevel(headPosition, out waterLevel) && headPosition.y < waterLevel - 0.02f; } public static bool IsNearSurface(Player player, float tolerance = 0.35f) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)player)) { return false; } Vector3 headPosition = GetHeadPosition(player); float waterLevel; return TryGetWaterLevel(headPosition, out waterLevel) && Mathf.Abs(headPosition.y - waterLevel) <= tolerance; } } } namespace VBDiving.Patches { [HarmonyPatch(typeof(Character), "CustomFixedUpdate")] internal static class CharacterSurfaceFix { [HarmonyPostfix] private static void Postfix(Character __instance) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: 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) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: 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_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) if (!VBDiving.IsEnabled() || (Object)(object)__instance != (Object)(object)Player.m_localPlayer) { return; } Player val = (Player)__instance; if (!WaterHelper.IsBodyInWater(val)) { return; } PlayerDiveController localInstance = PlayerDiveController.LocalInstance; if (!Object.op_Implicit((Object)(object)localInstance) || localInstance.toggleDive || localInstance.is_diving || localInstance.IsHeadUnderwater()) { return; } float liquidLevel = ((Character)val).GetLiquidLevel(); float num = liquidLevel - 1.3f; if (((Component)val).transform.position.y < num - 0.1f) { Vector3 position = ((Component)val).transform.position; position.y = Mathf.Lerp(position.y, num, Time.fixedDeltaTime * 8f); ((Component)val).transform.position = position; Rigidbody component = ((Component)val).GetComponent<Rigidbody>(); if (Object.op_Implicit((Object)(object)component) && component.linearVelocity.y < 0f) { Vector3 linearVelocity = component.linearVelocity; linearVelocity.y = Mathf.Max(linearVelocity.y, 0f); component.linearVelocity = linearVelocity; } } ((Character)val).m_swimDepth = 1.3f; } } [HarmonyPatch] internal static class CharacterWaterStatePatch { [HarmonyPostfix] [HarmonyPatch(typeof(Character), "IsOnGround")] private static void CharacterIsOnGroundPostfix(Character __instance, ref bool __result) { if (VBDiving.IsEnabled()) { Player val = (Player)(object)((__instance is Player) ? __instance : null); if (Object.op_Implicit((Object)(object)val) && !((Object)(object)val != (Object)(object)Player.m_localPlayer) && WaterHelper.IsBodyInWater(val)) { __result = false; } } } [HarmonyPostfix] [HarmonyPatch(typeof(Character), "InWater")] private static void CharacterInWaterPostfix(Character __instance, ref bool __result) { if (VBDiving.IsEnabled()) { Player val = (Player)(object)((__instance is Player) ? __instance : null); if (Object.op_Implicit((Object)(object)val) && !((Object)(object)val != (Object)(object)Player.m_localPlayer) && WaterHelper.IsBodyInWater(val)) { __result = true; } } } } [HarmonyPatch] internal static class DiveControllerPatches { [HarmonyPostfix] [HarmonyPatch(typeof(Player), "Awake")] private static void PlayerAwakePostfix(Player __instance) { if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer) { EnsureLocalDiver(); } } [HarmonyPrefix] [HarmonyPatch(typeof(Character), "UpdateMotion")] private static void CharacterUpdateMotionPrefix(Character __instance, ref float ___m_lastGroundTouch, ref float ___m_swimTimer) { if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer) { return; } PlayerDiveController playerDiveController = EnsureLocalDiver(); if (Object.op_Implicit((Object)(object)playerDiveController)) { playerDiveController.ResetSwimDepthIfNotInWater(); if (playerDiveController.is_diving || WaterHelper.IsBodyInWater((Player)(object)((__instance is Player) ? __instance : null))) { ___m_lastGroundTouch = 0.3f; ___m_swimTimer = 0f; } } } [HarmonyPrefix] [HarmonyPatch(typeof(Character), "UpdateSwimming")] private static void CharacterUpdateSwimmingPrefix(Character __instance) { if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer) { return; } Player val = (Player)(object)((__instance is Player) ? __instance : null); if (Object.op_Implicit((Object)(object)val)) { PlayerDiveController playerDiveController = EnsureLocalDiver(); if (Object.op_Implicit((Object)(object)playerDiveController)) { playerDiveController.UpdateSwimSpeed(); ApplySwimStaminaSettings(val); } } } private static void ApplySwimStaminaSettings(Player player) { if (WaterHelper.IsBodyInWater(player)) { float num = VBDiving.SwimStaminaDrainMinSkill; float num2 = VBDiving.SwimStaminaDrainMaxSkill; if (WaterHelper.IsHeadUnderwater(player)) { num *= 2f; num2 *= 2f; } if (InputHelper.GetRun() && player.GetStamina() > 0f) { num *= 1.5f; num2 *= 1.5f; } player.m_swimStaminaDrainMinSkill = num; player.m_swimStaminaDrainMaxSkill = num2; } } [HarmonyPrefix] [HarmonyPatch(typeof(Character), "CustomFixedUpdate")] private static void CharacterCustomFixedUpdatePrefix(Character __instance, ref Vector3 ___m_moveDir, ref Vector3 ___m_lookDir) { //IL_0094: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer || !__instance.IsPlayer()) { return; } PlayerDiveController playerDiveController = EnsureLocalDiver(); if (Object.op_Implicit((Object)(object)playerDiveController)) { playerDiveController.HandleDiveToggle(); playerDiveController.UpdateDiveState(); if (!__instance.InWater()) { __instance.m_swimDepth = 1.3f; } else if (playerDiveController.toggleDive && __instance.InWater() && !__instance.IsOnGround() && __instance.IsSwimming()) { playerDiveController.UpdateDiveDepth(___m_lookDir); } else if ((__instance.IsOnGround() || !playerDiveController.is_diving) && !playerDiveController.isUnderwater) { __instance.m_swimDepth = 1.3f; } } } [HarmonyPrefix] [HarmonyPatch(typeof(Character), "UpdateRotation")] private static void CharacterUpdateRotationPrefix(Character __instance, out Quaternion? __state) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer) { __state = null; return; } PlayerDiveController localInstance = PlayerDiveController.LocalInstance; if (Object.op_Implicit((Object)(object)localInstance) && localInstance.is_diving) { __state = ((Component)__instance).transform.rotation; } else { __state = null; } } [HarmonyPostfix] [HarmonyPatch(typeof(Character), "UpdateRotation")] private static void CharacterUpdateRotationPostfix(Character __instance, float turnSpeed, float dt, ref Quaternion? __state) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: 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_00bd: 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) if (__state.HasValue && Object.op_Implicit((Object)(object)__instance) && !((Object)(object)__instance != (Object)(object)Player.m_localPlayer) && !(((Component)__instance).transform.rotation != __state.Value)) { PlayerDiveController localInstance = PlayerDiveController.LocalInstance; if (Object.op_Implicit((Object)(object)localInstance) && localInstance.is_diving) { Player player = localInstance.Player; Quaternion val = ((((Character)player).AlwaysRotateCamera() || ((Character)player).m_moveDir == Vector3.zero) ? ((Character)player).m_lookYaw : Quaternion.LookRotation(((Character)player).m_moveDir)); float num = turnSpeed * ((Character)player).GetAttackSpeedFactorRotation(); ((Component)player).transform.rotation = Quaternion.RotateTowards(((Component)player).transform.rotation, val, num * dt); } } } [HarmonyPrefix] [HarmonyPatch(typeof(Player), "SetControls")] private static void PlayerSetControlsPrefix(Player __instance, ref bool crouch) { if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer && ((Character)__instance).InWater()) { crouch = false; } } private static PlayerDiveController? EnsureLocalDiver() { Player localPlayer = Player.m_localPlayer; if (!Object.op_Implicit((Object)(object)localPlayer)) { return null; } PlayerDiveController playerDiveController = PlayerDiveController.LocalInstance; if (Object.op_Implicit((Object)(object)playerDiveController) && (Object)(object)playerDiveController.Player == (Object)(object)localPlayer) { return playerDiveController; } if (!((Component)localPlayer).TryGetComponent<PlayerDiveController>(ref playerDiveController)) { playerDiveController = ((Component)localPlayer).gameObject.AddComponent<PlayerDiveController>(); } return playerDiveController; } } [HarmonyPatch(typeof(GameCamera), "UpdateCamera")] internal static class GameCameraPatch { private static float _originalMaxDistance; private static float _originalMinWaterDistance; private static bool _cachedOriginalValues; [HarmonyPrefix] private static void Prefix(GameCamera __instance, Camera ___m_camera) { if (!VBDiving.IsEnabled()) { return; } Player localPlayer = Player.m_localPlayer; if (Object.op_Implicit((Object)(object)localPlayer) && Object.op_Implicit((Object)(object)___m_camera)) { PlayerDiveController localInstance = PlayerDiveController.LocalInstance; if (!_cachedOriginalValues) { _originalMaxDistance = __instance.m_maxDistance; _originalMinWaterDistance = __instance.m_minWaterDistance; _cachedOriginalValues = true; } bool flag = Object.op_Implicit((Object)(object)localInstance) && localInstance.toggleDive; bool flag2 = Object.op_Implicit((Object)(object)localInstance) && localInstance.is_diving; if (flag || flag2) { __instance.m_minWaterDistance = -5000f; return; } __instance.m_minWaterDistance = _originalMinWaterDistance; __instance.m_maxDistance = _originalMaxDistance; } } [HarmonyPostfix] private static void Postfix(GameCamera __instance, Camera ___m_camera) { //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_008c: 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_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) if (!VBDiving.IsEnabled()) { return; } Player localPlayer = Player.m_localPlayer; if (!Object.op_Implicit((Object)(object)localPlayer) || !Object.op_Implicit((Object)(object)___m_camera)) { return; } PlayerDiveController localInstance = PlayerDiveController.LocalInstance; bool flag = Object.op_Implicit((Object)(object)localInstance) && localInstance.toggleDive; bool flag2 = Object.op_Implicit((Object)(object)localInstance) && localInstance.is_diving; float waterLevel2; if (flag || flag2) { if (WaterHelper.TryGetWaterLevel(((Component)___m_camera).transform.position, out var waterLevel)) { float y = ((Component)___m_camera).transform.position.y; if (y > waterLevel - 0.5f) { Vector3 position = ((Component)___m_camera).transform.position; position.y = waterLevel - 0.5f; ((Component)___m_camera).transform.position = position; } } } else if (WaterHelper.IsBodyInWater(localPlayer) && WaterHelper.TryGetWaterLevel(((Component)___m_camera).transform.position, out waterLevel2)) { float y2 = ((Component)___m_camera).transform.position.y; float num = waterLevel2 + 0.3f; if (y2 < num) { Vector3 position2 = ((Component)___m_camera).transform.position; position2.y = num; ((Component)___m_camera).transform.position = position2; } } } } [HarmonyPatch] internal static class PlayerEquipInWater { internal static ConfigEntry<string> EquipInWaterList; internal static HashSet<string> EquipInWaterItems = new HashSet<string>(); private static readonly CodeMatch[] Matches = (CodeMatch[])(object)new CodeMatch[5] { new CodeMatch((OpCode?)OpCodes.Ldarg_0, (object)null, (string)null), new CodeMatch((OpCode?)OpCodes.Call, (object)AccessTools.Method(typeof(Character), "IsSwimming", (Type[])null, (Type[])null), (string)null), new CodeMatch((OpCode?)OpCodes.Brfalse, (object)null, (string)null), new CodeMatch((OpCode?)OpCodes.Ldarg_0, (object)null, (string)null), new CodeMatch((OpCode?)OpCodes.Call, (object)AccessTools.Method(typeof(Character), "IsOnGround", (Type[])null, (Type[])null), (string)null) }; public static bool VB_CheckWaterItem(ItemData item) { if (item == null) { HandleNullItemCase(); return false; } return IsItemAllowed(item.m_shared.m_name); } private static void HandleNullItemCase() { Player localPlayer = Player.m_localPlayer; if (Object.op_Implicit((Object)(object)localPlayer)) { CheckAndUnequipItem(((Humanoid)localPlayer).m_leftItem); CheckAndUnequipItem(((Humanoid)localPlayer).m_rightItem); } } private static void CheckAndUnequipItem(ItemData item) { if (item != null && !IsItemAllowed(((Object)item.m_dropPrefab).name)) { Player localPlayer = Player.m_localPlayer; if (localPlayer != null) { ((Humanoid)localPlayer).UnequipItem(item, true); } } } private static bool IsItemAllowed(string itemName) { return EquipInWaterItems.Contains(itemName); } private static IEnumerable<MethodBase> TargetMethods() { return new <>z__ReadOnlyArray<MethodBase>(new MethodBase[3] { AccessTools.Method(typeof(Player), "Update", (Type[])null, (Type[])null), AccessTools.Method(typeof(Humanoid), "EquipItem", (Type[])null, (Type[])null), AccessTools.Method(typeof(Humanoid), "UpdateEquipment", (Type[])null, (Type[])null) }); } public static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions, MethodBase original) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) CodeMatcher val = new CodeMatcher(instructions, (ILGenerator)null).MatchStartForward(Matches); try { switch (original.Name) { case "Update": val.Advance(1).RemoveInstructions(6); break; case "EquipItem": val.Advance(6).Insert((IEnumerable<CodeInstruction>)GenerateInjectionCode(val, OpCodes.Ldarg_1)); break; case "UpdateEquipment": val.Advance(6).Insert((IEnumerable<CodeInstruction>)GenerateInjectionCode(val, OpCodes.Ldnull)); break; } } catch (ArgumentException ex) { Debug.LogError((object)("IL Transpiler Error in VB_EquipInWater: " + ex.Message)); Debug.LogError((object)"Plugin initialization failed. Valheim will shutdown."); Environment.Exit(1); } return val.InstructionEnumeration(); } private static List<CodeInstruction> GenerateInjectionCode(CodeMatcher matcher, OpCode loadOpCode) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Expected O, but got Unknown //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Expected O, but got Unknown //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Expected O, but got Unknown List<CodeInstruction> list = new List<CodeInstruction>(); list.Add(new CodeInstruction(loadOpCode, (object)null)); list.Add(new CodeInstruction(OpCodes.Call, (object)typeof(PlayerEquipInWater).GetMethod("VB_CheckWaterItem"))); list.Add(new CodeInstruction(OpCodes.Brfalse, matcher.InstructionAt(-1).operand)); return list; } } [HarmonyPatch(typeof(Player), "FixedUpdate")] internal static class PlayerFixedUpdatePatch { private static void Postfix(Player __instance) { //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) if (!VBDiving.IsEnabled() || !Object.op_Implicit((Object)(object)__instance) || (Object)(object)__instance != (Object)(object)Player.m_localPlayer || ((Character)__instance).IsDebugFlying()) { return; } bool flag = WaterHelper.IsBodyInWater(__instance); bool flag2 = WaterHelper.IsHeadUnderwater(__instance); Rigidbody component = ((Component)__instance).GetComponent<Rigidbody>(); if (!Object.op_Implicit((Object)(object)component)) { return; } if (!flag) { Traverse.Create((object)__instance).Field("m_staminaRegenTimer").SetValue((object)0f); component.useGravity = true; HandleBreath(__instance, headUnderwater: false); return; } component.useGravity = true; HandleBreath(__instance, flag2); Vector2 val = new Vector2(component.linearVelocity.x, component.linearVelocity.z); float magnitude = ((Vector2)(ref val)).magnitude; bool flag3 = magnitude > 0.5f; if (!flag2 && !IsDivingDeep(__instance) && !flag3) { Traverse.Create((object)__instance).Field("m_staminaRegenTimer").SetValue((object)0f); HandleWaterStaminaRegen(__instance); } else { Traverse.Create((object)__instance).Field("m_staminaRegenTimer").SetValue((object)10f); } PlayerDiveController localInstance = PlayerDiveController.LocalInstance; if (Object.op_Implicit((Object)(object)localInstance)) { localInstance.UpdateSwimSpeed(); } } private static bool IsDivingDeep(Player player) { PlayerDiveController localInstance = PlayerDiveController.LocalInstance; if (Object.op_Implicit((Object)(object)localInstance)) { return localInstance.toggleDive || localInstance.is_diving || localInstance.IsUnderSurface(); } return ((Character)player).m_swimDepth > 1.4f; } private static void HandleBreath(Player player, bool headUnderwater) { SwimState swimState = SwimStateManager.Get(player); float fixedDeltaTime = Time.fixedDeltaTime; float maxBreath = SwimAPI.GetMaxBreath(player); if (headUnderwater) { swimState.Breath -= fixedDeltaTime; if (swimState.Breath < 0f) { swimState.Breath = 0f; } if (swimState.Breath <= 0f && ((Character)player).HaveStamina(0f)) { ((Character)player).UseStamina(5f * fixedDeltaTime); } } else { swimState.Breath += VBDiving.BreathRecoveryPerSecond.Value * fixedDeltaTime; if (swimState.Breath > maxBreath) { swimState.Breath = maxBreath; } } SwimAPI.UpdateEvents(player); swimState.WasHeadUnderwater = headUnderwater; } private static void HandleWaterStaminaRegen(Player player) { float value = VBDiving.BaseUnderwaterStaminaRegenPerSecond.Value; float value2 = Traverse.Create((object)player).Field("m_stamina").GetValue<float>(); float maxStamina = ((Character)player).GetMaxStamina(); if (value2 < maxStamina) { value2 += value * Time.fixedDeltaTime; if (value2 > maxStamina) { value2 = maxStamina; } Traverse.Create((object)player).Field("m_stamina").SetValue((object)value2); } } } [HarmonyPatch(typeof(Player), "UpdateStats", new Type[] { typeof(float) })] internal static class PlayerUpdateStatsPatch { private static void Postfix(Player __instance, float dt) { if (VBDiving.IsEnabled() && Object.op_Implicit((Object)(object)__instance) && !((Object)(object)__instance != (Object)(object)Player.m_localPlayer) && WaterHelper.IsBodyInWater(__instance)) { bool flag = WaterHelper.IsHeadUnderwater(__instance); PlayerDiveController localInstance = PlayerDiveController.LocalInstance; bool flag2 = Object.op_Implicit((Object)(object)localInstance) && (localInstance.toggleDive || localInstance.is_diving || localInstance.IsUnderSurface()); if (flag || flag2) { Traverse.Create((object)__instance).Field("m_staminaRegenTimer").SetValue((object)float.MaxValue); } if (Object.op_Implicit((Object)(object)localInstance)) { localInstance.UpdateSwimSpeed(); } } } } [HarmonyPatch(typeof(WaterVolume), "UpdateMaterials")] internal static class SurfacePatch { private static readonly Dictionary<MeshRenderer, GameObject> UnderwaterCopies = new Dictionary<MeshRenderer, GameObject>(); private const float SurfaceOffset = -0.05f; private const float OverlapScale = 1.02f; private static void Postfix(WaterVolume __instance) { if (!VBDiving.IsEnabled() || !Object.op_Implicit((Object)(object)__instance) || !Object.op_Implicit((Object)(object)__instance.m_waterSurface)) { return; } MeshRenderer component = ((Component)__instance.m_waterSurface).GetComponent<MeshRenderer>(); MeshFilter component2 = ((Component)__instance.m_waterSurface).GetComponent<MeshFilter>(); if (!Object.op_Implicit((Object)(object)component) || !Object.op_Implicit((Object)(object)component2)) { return; } bool flag = IsCameraUnderwater(); if (!UnderwaterCopies.TryGetValue(component, out var value) || (Object)(object)value == (Object)null) { value = CreateUnderwaterSurfaceCopy(((Component)component).gameObject, component, component2); if (Object.op_Implicit((Object)(object)value)) { UnderwaterCopies[component] = value; } } if (Object.op_Implicit((Object)(object)value)) { ((Renderer)component).enabled = !flag; value.SetActive(flag); } } private static GameObject CreateUnderwaterSurfaceCopy(GameObject original, MeshRenderer originalRenderer, MeshFilter originalFilter) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown //IL_0034: 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_0074: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("VBDiving_UnderwaterSurface"); val.transform.SetParent(original.transform, false); val.transform.localPosition = new Vector3(0f, -0.05f, 0f); val.transform.localRotation = Quaternion.Euler(180f, 0f, 0f); val.transform.localScale = new Vector3(1.02f, 1f, -1.02f); MeshFilter val2 = val.AddComponent<MeshFilter>(); val2.sharedMesh = originalFilter.sharedMesh; MeshRenderer val3 = val.AddComponent<MeshRenderer>(); ((Renderer)val3).sharedMaterial = ((Renderer)originalRenderer).sharedMaterial; ((Renderer)val3).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)val3).receiveShadows = false; ((Renderer)val3).lightProbeUsage = (LightProbeUsage)0; ((Renderer)val3).reflectionProbeUsage = (ReflectionProbeUsage)0; ((Renderer)val3).allowOcclusionWhenDynamic = false; ((Renderer)val3).forceRenderingOff = false; ((Renderer)val3).enabled = true; val.SetActive(false); return val; } private static bool IsCameraUnderwater() { //IL_003a: 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) if (!Object.op_Implicit((Object)(object)GameCamera.instance)) { return false; } Camera component = ((Component)GameCamera.instance).GetComponent<Camera>(); if (!Object.op_Implicit((Object)(object)component)) { return false; } if (!WaterHelper.TryGetWaterLevel(((Component)component).transform.position, out var waterLevel)) { return false; } return ((Component)component).transform.position.y < waterLevel - 0.15f; } } [HarmonyPatch(typeof(Player), "UseStamina")] internal static class UseStaminaPatch { private static bool AllowStaminaUseFromSwimSprint; private static bool Prefix(Player __instance, ref float v) { if (!VBDiving.IsEnabled()) { return true; } if (AllowStaminaUseFromSwimSprint) { return true; } if (!Object.op_Implicit((Object)(object)__instance) || (Object)(object)__instance != (Object)(object)Player.m_localPlayer) { return true; } if (!WaterHelper.IsBodyInWater(__instance)) { return true; } return true; } } [HarmonyPatch(typeof(WaterVolume), "UpdateMaterials")] internal static class WaterShaderPatch { private static readonly int ColorTopId = Shader.PropertyToID("_ColorTop"); private static readonly int ColorBottomId = Shader.PropertyToID("_ColorBottom"); private static readonly int ColorBottomShallowId = Shader.PropertyToID("_ColorBottomShallow"); private static readonly int SurfaceColorId = Shader.PropertyToID("_SurfaceColor"); private static readonly int DepthFadeId = Shader.PropertyToID("_DepthFade"); private static readonly int CullId = Shader.PropertyToID("_Cull"); private static Color _originalColorTop; private static Color _originalColorBottom; private static Color _originalColorBottomShallow; private static Color _originalSurfaceColor; private static float _originalDepthFade; private static bool _originalValuesSaved; private static Material _instanceMaterial; private static MeshRenderer _lastRenderer; private static void Postfix(WaterVolume __instance) { if (VBDiving.IsEnabled() && Object.op_Implicit((Object)(object)__instance.m_waterSurface)) { MeshRenderer waterSurface = __instance.m_waterSurface; if (!Object.op_Implicit((Object)(object)_instanceMaterial) || (Object)(object)_lastRenderer != (Object)(object)waterSurface) { _instanceMaterial = ((Renderer)waterSurface).material; _lastRenderer = waterSurface; SaveOriginalValues(_instanceMaterial); } if (_instanceMaterial.HasProperty(CullId)) { _instanceMaterial.SetInt(CullId, 0); } if (Object.op_Implicit((Object)(object)PlayerDiveController.LocalInstance) && PlayerDiveController.LocalInstance.isUnderwater) { ApplyUnderwaterSettings(_instanceMaterial); } else { ApplyWaterSettings(_instanceMaterial); } } } private static void SaveOriginalValues(Material mat) { //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_0035: 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_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_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 (mat.HasProperty(ColorTopId)) { _originalColorTop = mat.GetColor(ColorTopId); } if (mat.HasProperty(ColorBottomId)) { _originalColorBottom = mat.GetColor(ColorBottomId); } if (mat.HasProperty(ColorBottomShallowId)) { _originalColorBottomShallow = mat.GetColor(ColorBottomShallowId); } if (mat.HasProperty(SurfaceColorId)) { _originalSurfaceColor = mat.GetColor(SurfaceColorId); } if (mat.HasProperty(DepthFadeId)) { _originalDepthFade = mat.GetFloat(DepthFadeId); } _originalValuesSaved = true; } private static void ApplyWaterSettings(Material mat) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) if (mat.HasProperty(ColorTopId)) { mat.SetColor(ColorTopId, new Color(0.2f, 0.25f, 0.2f, 0.95f)); } if (mat.HasProperty(ColorBottomId)) { mat.SetColor(ColorBottomId, new Color(0.15f, 0.2f, 0.2f, 0.95f)); } if (mat.HasProperty(ColorBottomShallowId)) { mat.SetColor(ColorBottomShallowId, new Color(0.2f, 0.25f, 0.2f, 0.95f)); } if (mat.HasProperty(SurfaceColorId)) { mat.SetColor(SurfaceColorId, new Color(0.3f, 0.35f, 0.35f, 0.95f)); } if (mat.HasProperty(DepthFadeId)) { mat.SetFloat(DepthFadeId, _originalDepthFade * 1f); } } private static void ApplyUnderwaterSettings(Material mat) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) if (mat.HasProperty(ColorTopId)) { mat.SetColor(ColorTopId, new Color(0.2f, 0.25f, 0.2f, 0.95f)); } if (mat.HasProperty(ColorBottomId)) { mat.SetColor(ColorBottomId, new Color(0.15f, 0.2f, 0.2f, 0.95f)); } if (mat.HasProperty(ColorBottomShallowId)) { mat.SetColor(ColorBottomShallowId, new Color(0.2f, 0.25f, 0.2f, 0.95f)); } if (mat.HasProperty(SurfaceColorId)) { mat.SetColor(SurfaceColorId, new Color(0.3f, 0.35f, 0.35f, 0.95f)); } if (mat.HasProperty(DepthFadeId)) { mat.SetFloat(DepthFadeId, _originalDepthFade * 1.25f); } } } } namespace VBDiving.Mobs { [HarmonyPatch] internal static class MonsterDivePatches { [HarmonyPostfix] [HarmonyPatch(typeof(MonsterAI), "Awake")] private static void MonsterAIAwakePostfix(MonsterAI __instance) { if (VBDiving.IsEnabled() && MonsterDiveSystem.IsConfiguredMonster(__instance)) { MonsterDiveSystem.EnsureDiveFlags(__instance); } } [HarmonyPrefix] [HarmonyPatch(typeof(MonsterAI), "UpdateAI")] private static void MonsterAIUpdateAIPrefix(MonsterAI __instance) { if (VBDiving.IsEnabled() && MonsterDiveSystem.IsConfiguredMonster(__instance)) { MonsterDiveSystem.EnsureDiveFlags(__instance); } } [HarmonyPrefix] [HarmonyPatch(typeof(BaseAI), "HavePath")] private static bool BaseAIHavePathPrefix(BaseAI __instance, Vector3 target, ref bool __result) { //IL_0064: Unknown result type (might be due to invalid IL or missing references) if (!VBDiving.IsEnabled()) { return true; } MonsterAI val = (MonsterAI)(object)((__instance is MonsterAI) ? __instance : null); if (val == null) { return true; } if (!MonsterDiveSystem.IsConfiguredMonster(val) || !MonsterDiveSystem.ShouldUseWaterDiveMode(val)) { return true; } Character character = ((BaseAI)val).m_character; if (!Object.op_Implicit((Object)(object)character)) { return true; } __result = MonsterDiveSystem.HasReasonableUnderwaterRoute(__instance, character, target); return false; } [HarmonyPrefix] [HarmonyPatch(typeof(BaseAI), "MoveTo")] private static bool BaseAIMoveToPrefix(BaseAI __instance, float dt, Vector3 point, float dist, bool run, ref bool __result) { //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_009b: 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_00b3: 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_0119: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Unknown result type (might be due to invalid IL or missing references) if (!VBDiving.IsEnabled()) { return true; } MonsterAI val = (MonsterAI)(object)((__instance is MonsterAI) ? __instance : null); if (val == null) { return true; } if (!MonsterDiveSystem.IsConfiguredMonster(val) || !MonsterDiveSystem.ShouldUseWaterDiveMode(val)) { return true; } Character character = ((BaseAI)val).m_character; if (!Object.op_Implicit((Object)(object)character)) { return true; } float num = MonsterDiveSystem.UpdateSwimDepthTowardsTarget(val, character, point, dt); float num2 = Mathf.Max(dist, run ? 1f : 0.5f); float num3 = Utils.DistanceXZ(point, ((Component)__instance).transform.position); float num4 = Mathf.Abs(point.y - ((Component)__instance).transform.position.y); float num5 = Mathf.Abs(num - ((Component)__instance).transform.position.y); if (num3 < num2 && (num4 < 0.75f || num5 < 0.35f)) { __instance.StopMoving(); __result = true; return false; } Vector3 val2 = point - ((Component)__instance).transform.position; if (((Vector3)(ref val2)).sqrMagnitude <= 0.0001f) { __instance.StopMoving(); __result = true; return false; } Vector3 val3 = MonsterDiveSystem.BuildSteerDirectionWithAvoidance(__instance, character, point); if (((Vector3)(ref val3)).sqrMagnitude <= 0.0001f) { __instance.StopMoving(); __result = true; return false; } __instance.MoveTowards(val3, run); __result = false; return false; } [HarmonyPrefix] [HarmonyPatch(typeof(Character), "IsOnGround")] private static bool CharacterIsOnGroundPrefix(Character __instance, ref bool __result) { if (!VBDiving.IsEnabled()) { return true; } if (__instance is Player) { return true; } MonsterAI component = ((Component)__instance).GetComponent<MonsterAI>(); if (!Object.op_Implicit((Object)(object)component)) { return true; } if (!MonsterDiveSystem.IsConfiguredMonster(component)) { return true; } if (MonsterDiveSystem.ShouldUseWaterDiveMode(component)) { __result = false; return false; } return true; } [HarmonyPostfix] [HarmonyPatch(typeof(MonsterAI), "UpdateAI")] private static void MonsterAIUpdateAIPostfix(MonsterAI __instance, float dt) { //IL_008c: 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_00b2: 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_00de: 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) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) if (!VBDiving.IsEnabled() || !MonsterDiveSystem.IsConfiguredMonster(__instance)) { return; } Character character = ((BaseAI)__instance).m_character; if (!Object.op_Implicit((Object)(object)character) || !MonsterDiveSystem.ShouldUseWaterDiveMode(__instance)) { return; } character.m_lastGroundTouch = 1f; if (character.IsOnGround() && character.InWater()) { float liquidLevel = character.GetLiquidLevel(); float num = liquidLevel - character.m_swimDepth; if (((Component)character).transform.position.y < num + 0.5f) { Vector3 position = ((Component)character).transform.position; position.y = num; ((Component)character).transform.position = position; Rigidbody component = ((Component)character).GetComponent<Rigidbody>(); if (Object.op_Implicit((Object)(object)component) && component.linearVelocity.y < 0f) { Vector3 linearVelocity = component.linearVelocity; linearVelocity.y = 0f; component.linearVelocity = linearVelocity; } } } character.m_swimTimer = 0f; } } internal static class MonsterDiveSystem { private readonly struct RouteCacheEntry { public readonly float Time; public readonly Vector3Int PositionBucket; public readonly Vector3Int TargetBucket; public readonly bool Result; public RouteCacheEntry(float time, Vector3Int positionBucket, Vector3Int targetBucket, bool result) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000a