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 ValynDiving v0.2.7
plugins/ValynDiving.dll
Decompiled 5 days agousing System; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("ValynDiving")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.2.7.0")] [assembly: AssemblyInformationalVersion("0.2.7")] [assembly: AssemblyProduct("ValynDiving")] [assembly: AssemblyTitle("ValynDiving")] [assembly: AssemblyVersion("0.2.7.0")] namespace ValynMods.Diving; internal sealed class BreathHud { private static readonly FieldInfo StaminaRoot = AccessTools.Field(typeof(Hud), "m_staminaBar2Root"); private static readonly FieldInfo StaminaText = AccessTools.Field(typeof(Hud), "m_staminaText"); private static readonly Type ImageType = Type.GetType("UnityEngine.UI.Image, UnityEngine.UI"); private GameObject container; private GameObject label; private RectTransform panel; private RectTransform staminaRoot; private RectTransform background; private RectTransform fill; private Component labelComponent; private PropertyInfo labelText; private Hud owner; internal bool Visible { get; private set; } internal void Show(float remaining, float maximum) { //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) Hud instance = Hud.instance; if ((Object)(object)instance == (Object)null) { Hide(); return; } if ((Object)(object)container == (Object)null || (Object)(object)owner != (Object)(object)instance) { Create(instance); } if ((Object)(object)container == (Object)null) { Visible = false; return; } AlignToStamina(); float x = panel.sizeDelta.x; fill.sizeDelta = new Vector2(x * Mathf.Clamp01(remaining / Mathf.Max(1f, maximum)), 15f); if ((Object)(object)label != (Object)null && labelText != null) { labelText.SetValue(labelComponent, "BREATH " + Mathf.CeilToInt(remaining) + " / " + Mathf.CeilToInt(maximum) + " s"); } container.SetActive(true); Visible = container.activeInHierarchy; } private void Create(Hud hud) { //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Expected O, but got Unknown //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Expected O, but got Unknown //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_01b8: Unknown result type (might be due to invalid IL or missing references) //IL_01be: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_01da: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: Unknown result type (might be due to invalid IL or missing references) //IL_021e: Unknown result type (might be due to invalid IL or missing references) Destroy(); owner = hud; ref RectTransform reference = ref staminaRoot; object? obj = StaminaRoot?.GetValue(hud); reference = (RectTransform)((obj is RectTransform) ? obj : null); if ((Object)(object)staminaRoot == (Object)null || (Object)(object)((Transform)staminaRoot).parent == (Object)null || ImageType == null) { return; } container = new GameObject("Valyn Breath HUD", new Type[1] { typeof(RectTransform) }); panel = (RectTransform)container.transform; ((Transform)panel).SetParent(((Transform)staminaRoot).parent, false); background = MakeImage("Breath background", new Color(0.02f, 0.08f, 0.16f, 0.9f)); fill = MakeImage("Breath fill", new Color(0.05f, 0.55f, 1f, 1f)); object? obj2 = StaminaText?.GetValue(hud); Component val = (Component)((obj2 is Component) ? obj2 : null); if ((Object)(object)val != (Object)null) { label = Object.Instantiate<GameObject>(val.gameObject, (Transform)(object)panel, false); ((Object)label).name = "Breath seconds"; labelComponent = label.GetComponent(((object)val).GetType()); labelText = ((object)labelComponent)?.GetType().GetProperty("text"); Transform transform = label.transform; RectTransform val2 = (RectTransform)(object)((transform is RectTransform) ? transform : null); if ((Object)(object)val2 != (Object)null) { Vector2 val3 = default(Vector2); ((Vector2)(ref val3))..ctor(0.5f, 0.5f); val2.pivot = val3; Vector2 anchorMin = (val2.anchorMax = val3); val2.anchorMin = anchorMin; val2.anchoredPosition = Vector2.zero; val2.sizeDelta = new Vector2(300f, 24f); ((Transform)val2).localScale = Vector3.one; } Type obj3 = ((object)labelComponent)?.GetType(); obj3?.GetProperty("color")?.SetValue(labelComponent, Color.white); obj3?.GetProperty("fontSize")?.SetValue(labelComponent, 14f); obj3?.GetProperty("raycastTarget")?.SetValue(labelComponent, false); label.SetActive(true); } AlignToStamina(); container.SetActive(false); } private RectTransform MakeImage(string name, Color color) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Expected O, but got Unknown //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Expected O, but got Unknown //IL_00b1: Expected O, but got Unknown GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) }); RectTransform val2 = (RectTransform)val.transform; ((Transform)val2).SetParent((Transform)(object)panel, false); Vector2 val3 = default(Vector2); ((Vector2)(ref val3))..ctor(0f, 0.5f); val2.pivot = val3; Vector2 anchorMin = (val2.anchorMax = val3); val2.anchorMin = anchorMin; val2.anchoredPosition = Vector2.zero; ((Transform)val2).localScale = Vector3.one; Component obj = val.AddComponent(ImageType); ImageType.GetProperty("color")?.SetValue(obj, color); PropertyInfo? property = ImageType.GetProperty("raycastTarget"); if ((object)property != null) { property.SetValue(obj, false); return val2; } return val2; } private void AlignToStamina() { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_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_0095: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)panel == (Object)null) && !((Object)(object)staminaRoot == (Object)null)) { panel.anchorMin = staminaRoot.anchorMin; panel.anchorMax = staminaRoot.anchorMax; panel.pivot = staminaRoot.pivot; panel.anchoredPosition = staminaRoot.anchoredPosition + new Vector2(0f, -32f); ((Transform)panel).localScale = ((Transform)staminaRoot).localScale; Rect rect = staminaRoot.rect; float num = Mathf.Clamp(((Rect)(ref rect)).width, 160f, 320f); panel.sizeDelta = new Vector2(num, 15f); background.sizeDelta = new Vector2(num, 15f); } } internal void Hide() { if ((Object)(object)container != (Object)null) { container.SetActive(false); } Visible = false; } internal void Destroy() { if ((Object)(object)container != (Object)null) { Object.Destroy((Object)(object)container); } container = (label = null); panel = (staminaRoot = (background = (fill = null))); labelComponent = null; labelText = null; owner = null; Visible = false; } } [BepInPlugin("valyn.mods.diving", "Valyn Diving", "0.2.7")] public sealed class DivingPlugin : BaseUnityPlugin { internal static ConfigEntry<float> StaminaMultiplier; internal static ConfigEntry<float> BreathSeconds; internal static ConfigEntry<float> DescentSpeed; internal static ConfigEntry<float> AscentSpeed; internal static ConfigEntry<float> DrowningDamage; internal static ConfigEntry<bool> BlockWaterRegen; internal static ConfigEntry<bool> AllowWadingRegen; internal static ConfigEntry<float> BreathSkillBonus; internal static ConfigEntry<float> FastSwimMultiplier; internal static ConfigEntry<bool> AllowUnderwaterCamera; internal static ConfigEntry<bool> EnableSeabedMovement; internal static ConfigEntry<float> SeabedSpeedMultiplier; internal static ConfigEntry<bool> SteepSeabedAssist; private readonly BreathHud breathHud = new BreathHud(); private bool hudConfirmed; private bool hudWarning; private float hudMissingTime; internal static ManualLogSource ModLog; private Harmony harmony; private void LateUpdate() { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || !DiveState.SwimmingOrSubmerged(localPlayer)) { breathHud.Hide(); return; } breathHud.Show(DiveState.Breath, DiveState.Cap(localPlayer)); if (breathHud.Visible && !hudConfirmed) { hudConfirmed = true; ((BaseUnityPlugin)this).Logger.LogInfo((object)"Breath HUD elements active"); } if (!breathHud.Visible && !hudWarning) { hudMissingTime += Time.deltaTime; if (hudMissingTime > 2f) { hudWarning = true; ((BaseUnityPlugin)this).Logger.LogWarning((object)"Breath HUD could not attach to the game's stamina HUD elements"); } } } private void Awake() { //IL_01b5: Unknown result type (might be due to invalid IL or missing references) //IL_01bf: Expected O, but got Unknown //IL_01ea: Unknown result type (might be due to invalid IL or missing references) //IL_01f4: Expected O, but got Unknown ModLog = ((BaseUnityPlugin)this).Logger; StaminaMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Stamina", "Swim drain multiplier", 0.85f, "0.85 uses 15% less stamina while swimming."); BreathSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Breath", "Underwater seconds", 30f, "Time below the waterline before drowning damage begins."); DescentSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Movement", "Descent speed", 2.5f, "Vertical speed while holding the game's Crouch action underwater, including its controller binding."); AscentSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Movement", "Ascent speed", 3f, "Vertical speed while holding the game's Jump action underwater, including its controller binding."); DrowningDamage = ((BaseUnityPlugin)this).Config.Bind<float>("Breath", "Drowning damage per second", 5f, "Damage while breath is depleted."); BlockWaterRegen = ((BaseUnityPlugin)this).Config.Bind<bool>("Stamina", "No regeneration while in water", true, "Prevents stamina regeneration while swimming or submerged. See Allow regeneration while wading."); AllowWadingRegen = ((BaseUnityPlugin)this).Config.Bind<bool>("Stamina", "Allow regeneration while wading", true, "Allows stamina recovery when walking in shallow water with your head above the surface."); BreathSkillBonus = ((BaseUnityPlugin)this).Config.Bind<float>("Breath", "Swim skill breath bonus", 1f, "At 100 Swim skill, 1.0 doubles the base breath duration."); FastSwimMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Movement", "Shift swim speed multiplier", 1.25f, "Hold the game's Run action to swim faster; stamina drain scales with speed."); AllowUnderwaterCamera = ((BaseUnityPlugin)this).Config.Bind<bool>("Camera", "Allow underwater camera", true, "Allows the third-person camera below the water surface while swimming or diving. Set false for the game's normal surface clamp."); EnableSeabedMovement = ((BaseUnityPlugin)this).Config.Bind<bool>("Movement", "Allow movement on seabed", true, "Allow slower horizontal movement when your head is underwater and you touch the ground."); SeabedSpeedMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Movement", "Seabed speed multiplier", 0.55f, new ConfigDescription("Fraction of normal swim speed while moving on the seabed. 0.2-0.95.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.2f, 0.95f), Array.Empty<object>())); SteepSeabedAssist = ((BaseUnityPlugin)this).Config.Bind<bool>("Movement", "Steep seabed swim assist", true, "When movement stalls against a steep underwater slope, rise into swimming. Does not climb vertical walls or lift you out of the water."); harmony = new Harmony("valyn.mods.diving"); harmony.PatchAll(typeof(DivingPlugin).Assembly); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Valyn Diving loaded"); } private void OnDestroy() { Harmony obj = harmony; if (obj != null) { obj.UnpatchSelf(); } breathHud.Destroy(); } } [HarmonyPatch(typeof(GameCamera), "UpdateCamera")] internal static class UnderwaterCameraPatch { private static readonly FieldInfo MinWaterDistance = AccessTools.Field(typeof(GameCamera), "m_minWaterDistance"); private static void Prefix(GameCamera __instance, out float __state) { __state = float.NaN; Player localPlayer = Player.m_localPlayer; if (!((Object)(object)localPlayer == (Object)null) && !(MinWaterDistance == null) && DivingPlugin.AllowUnderwaterCamera.Value && DiveState.SwimmingOrSubmerged(localPlayer) && DiveState.Wet(localPlayer)) { __state = (float)MinWaterDistance.GetValue(__instance); MinWaterDistance.SetValue(__instance, -10000f); } } private static void Postfix(GameCamera __instance, float __state) { if (!float.IsNaN(__state)) { MinWaterDistance.SetValue(__instance, __state); } } } internal static class DiveState { internal static float Breath; internal static float DamageClock; internal static float SkillClock; internal static bool Diving; internal static Player Current; private static bool seabedLogged; private static bool slopeAssistLogged; private static bool hasSeabedPosition; private static Vector3 lastSeabedPosition; private static float stalledSlopeTime; internal static readonly FieldInfo Body = AccessTools.Field(typeof(Character), "m_body"); internal static readonly FieldInfo Velocity = AccessTools.Field(typeof(Character), "m_currentVel"); internal static readonly FieldInfo DrainMin = AccessTools.Field(typeof(Player), "m_swimStaminaDrainMinSkill"); internal static readonly FieldInfo SwimSpeed = AccessTools.Field(typeof(Character), "m_swimSpeed"); internal static readonly FieldInfo DrainMax = AccessTools.Field(typeof(Player), "m_swimStaminaDrainMaxSkill"); private static readonly Func<string, bool> GameButton = ResolveGameButton(); private static readonly Type InputType = Type.GetType("UnityEngine.Input, UnityEngine.InputLegacyModule"); private static readonly MethodInfo GetKey = InputType?.GetMethod("GetKey", new Type[1] { typeof(KeyCode) }); internal static readonly PropertyInfo BodyVelocity = Body.FieldType.GetProperty("velocity"); internal static bool Fast => Action("Run", "JoyRun", (KeyCode)304); private static Func<string, bool> ResolveGameButton() { try { MethodInfo methodInfo = Type.GetType("ZInput, assembly_utils")?.GetMethod("GetButton", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[1] { typeof(string) }, null); if (methodInfo != null) { return (Func<string, bool>)Delegate.CreateDelegate(typeof(Func<string, bool>), methodInfo); } } catch (Exception ex) { Debug.LogWarning((object)("Valyn Diving input binding: " + ex)); } Debug.LogWarning((object)"Valyn Diving could not find Valheim's mapped input; keyboard fallback active."); return null; } internal static bool Action(string keyboard, string gamepad, KeyCode fallback) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) if (GameButton == null) { if (GetKey != null) { return (bool)GetKey.Invoke(null, new object[1] { fallback }); } return false; } if (!GameButton(keyboard)) { return GameButton(gamepad); } return true; } internal static bool Local(Player player) { if ((Object)(object)player != (Object)null && ((Character)player).IsOwner()) { return (Object)(object)player == (Object)(object)Player.m_localPlayer; } return false; } internal static float Cap(Player player) { return Mathf.Max(1f, DivingPlugin.BreathSeconds.Value * (1f + Mathf.Max(0f, DivingPlugin.BreathSkillBonus.Value) * ((Character)player).GetSkillFactor((SkillType)103))); } internal static bool Wet(Player player) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) if (!((Character)player).InWater()) { return ((Character)player).GetLiquidLevel() > ((Component)player).transform.position.y + 0.3f; } return true; } internal static bool Underwater(Player player) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return ((Character)player).GetHeadPoint().y < ((Character)player).GetLiquidLevel() - 0.12f; } internal static bool SwimmingOrSubmerged(Player player) { if (!((Character)player).IsSwimming() && !Underwater(player)) { return Diving; } return true; } internal static bool BlockRegen(Player player) { if (Wet(player)) { if (DivingPlugin.AllowWadingRegen.Value) { return SwimmingOrSubmerged(player); } return true; } return false; } internal static void Reset(Player player) { Current = player; Breath = Cap(player); DamageClock = 0f; SkillClock = 0f; Diving = false; hasSeabedPosition = false; stalledSlopeTime = 0f; } internal static void MoveOnSeabed(Player player, float dt) { //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_0135: 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_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_0153: 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_017a: Unknown result type (might be due to invalid IL or missing references) //IL_020e: Unknown result type (might be due to invalid IL or missing references) //IL_0210: Unknown result type (might be due to invalid IL or missing references) //IL_022b: Unknown result type (might be due to invalid IL or missing references) //IL_0231: Unknown result type (might be due to invalid IL or missing references) //IL_0247: Unknown result type (might be due to invalid IL or missing references) //IL_024d: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_0274: Unknown result type (might be due to invalid IL or missing references) //IL_01be: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: 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_030f: Unknown result type (might be due to invalid IL or missing references) //IL_0320: Unknown result type (might be due to invalid IL or missing references) //IL_0288: Unknown result type (might be due to invalid IL or missing references) //IL_02e5: Unknown result type (might be due to invalid IL or missing references) if (!DivingPlugin.EnableSeabedMovement.Value || !Local(player) || !((Character)player).InWater() || !Underwater(player) || !((Character)player).IsOnGround() || !((Character)player).CanMove() || ((Character)player).IsDead() || ((Character)player).IsAttached() || ((Character)player).IsTeleporting()) { hasSeabedPosition = false; stalledSlopeTime = 0f; return; } Vector3 moveDir = ((Character)player).GetMoveDir(); moveDir.y = 0f; if (((Vector3)(ref moveDir)).sqrMagnitude < 0.001f) { hasSeabedPosition = false; stalledSlopeTime = 0f; return; } if (((Vector3)(ref moveDir)).sqrMagnitude > 1f) { ((Vector3)(ref moveDir)).Normalize(); } if (!seabedLogged) { seabedLogged = true; Debug.Log((object)("VALYN DIVING: seabed movement engaged, swimming=" + ((Character)player).IsSwimming())); } object value = Body.GetValue(player); if (value == null) { return; } Vector3 val = (Vector3)BodyVelocity.GetValue(value); float num = (float)SwimSpeed.GetValue(player) * DivingPlugin.SeabedSpeedMultiplier.Value * (Fast ? Mathf.Max(1f, DivingPlugin.FastSwimMultiplier.Value) : 1f); Vector3 position = ((Component)player).transform.position; Vector3 lastGroundNormal = ((Character)player).GetLastGroundNormal(); Vector3 val2 = default(Vector3); ((Vector3)(ref val2))..ctor(0f - lastGroundNormal.x, 0f, 0f - lastGroundNormal.z); if (DivingPlugin.SteepSeabedAssist.Value && lastGroundNormal.y > 0.15f && lastGroundNormal.y < 0.79f && ((Vector3)(ref val2)).sqrMagnitude > 0.01f && Vector3.Dot(moveDir, ((Vector3)(ref val2)).normalized) > 0.45f && hasSeabedPosition && dt > 0f) { Vector3 val3 = position - lastSeabedPosition; val3.y = 0f; if (((Vector3)(ref val3)).magnitude < num * dt * 0.3f) { stalledSlopeTime += dt; } else { stalledSlopeTime = 0f; } } else { stalledSlopeTime = 0f; } lastSeabedPosition = position; hasSeabedPosition = true; float num2 = Mathf.Clamp01(dt * 10f); val.x = Mathf.Lerp(val.x, moveDir.x * num, num2); val.z = Mathf.Lerp(val.z, moveDir.z * num, num2); if (stalledSlopeTime > 0.22f && ((Character)player).GetLiquidLevel() - ((Character)player).GetHeadPoint().y > 0.5f) { val.y = Mathf.Max(val.y, Mathf.Max(0f, DivingPlugin.AscentSpeed.Value) * 0.7f); if (!slopeAssistLogged) { slopeAssistLogged = true; Debug.Log((object)"VALYN DIVING: steep seabed swim assist engaged"); } } if (Diving && Action("Jump", "JoyJump", (KeyCode)32)) { val.y = Mathf.Max(val.y, Mathf.Max(0f, DivingPlugin.AscentSpeed.Value)); } BodyVelocity.SetValue(value, val); Velocity.SetValue(player, val); } } [HarmonyPatch(typeof(Character), "UpdateSwimming")] internal static class SwimmingMovementPatch { private static void Prefix(Character __instance, out float __state) { __state = 0f; Player val = (Player)(object)((__instance is Player) ? __instance : null); if (DiveState.Local(val) && DiveState.Fast) { __state = (float)DiveState.SwimSpeed.GetValue(val); DiveState.SwimSpeed.SetValue(val, __state * Mathf.Max(1f, DivingPlugin.FastSwimMultiplier.Value)); } } private static void Postfix(Character __instance, float dt, float __state) { if (__state > 0f) { DiveState.SwimSpeed.SetValue(__instance, __state); } ApplyDiving(__instance, dt); DiveState.MoveOnSeabed((Player)(object)((__instance is Player) ? __instance : null), dt); } private static void ApplyDiving(Character __instance, float dt) { //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) Player val = (Player)(object)((__instance is Player) ? __instance : null); if (!DiveState.Local(val) || ((Character)val).IsDead() || ((Character)val).IsAttached() || ((Character)val).IsTeleporting()) { return; } if (!((Character)val).InWater()) { DiveState.Diving = false; return; } bool flag = DiveState.Action("Crouch", "JoyCrouch", (KeyCode)306); bool flag2 = DiveState.Action("Jump", "JoyJump", (KeyCode)32); float num = ((Character)val).GetLiquidLevel() - ((Component)val).transform.position.y; if (!DiveState.Diving && flag && (((Character)val).IsSwimming() || DiveState.Underwater(val))) { DiveState.Diving = true; } if (!DiveState.Diving) { return; } if (num < 0.35f && !flag && !DiveState.Underwater(val)) { DiveState.Diving = false; return; } float num2 = ((!((Character)val).IsOnGround() || !DiveState.Underwater(val)) ? (flag ? (0f - Mathf.Max(0f, DivingPlugin.DescentSpeed.Value)) : (flag2 ? Mathf.Max(0f, DivingPlugin.AscentSpeed.Value) : 0f)) : (flag2 ? Mathf.Max(0f, DivingPlugin.AscentSpeed.Value) : 0f)); if (num < 0.5f && num2 > 0f) { DiveState.Diving = false; return; } object value = DiveState.Body.GetValue(val); if (value != null) { Vector3 val2 = (Vector3)DiveState.BodyVelocity.GetValue(value); val2.y = num2; DiveState.BodyVelocity.SetValue(value, val2); DiveState.Velocity.SetValue(val, val2); } } } [HarmonyPatch(typeof(Character), "UpdateWalking")] internal static class SeabedWalkingPatch { private static void Postfix(Character __instance, float __0) { DiveState.MoveOnSeabed((Player)(object)((__instance is Player) ? __instance : null), __0); } } [HarmonyPatch(typeof(Player), "OnSwimming")] internal static class SwimStaminaPatch { private static bool Prefix(Player __instance, Vector3 targetVel, float dt, out float[] __state) { __state = null; if (!DiveState.Local(__instance)) { return true; } if ((Object)(object)DiveState.Current != (Object)(object)__instance) { DiveState.Reset(__instance); } float num = (float)DiveState.DrainMin.GetValue(__instance); float num2 = (float)DiveState.DrainMax.GetValue(__instance); float num3 = Mathf.Clamp(DivingPlugin.StaminaMultiplier.Value, 0f, 1f) * (DiveState.Fast ? Mathf.Max(1f, DivingPlugin.FastSwimMultiplier.Value) : 1f); if (((Character)__instance).InWater() && DiveState.Underwater(__instance)) { float skillFactor = ((Character)__instance).GetSkills().GetSkillFactor((SkillType)103); float num4 = Mathf.Lerp(num, num2, skillFactor); if (((Vector3)(ref targetVel)).sqrMagnitude > 0.01f) { ((Character)__instance).UseStamina(dt * Mathf.Max(0f, num4) * num3); DiveState.SkillClock += dt; if (DiveState.SkillClock >= 1f) { DiveState.SkillClock -= 1f; ((Character)__instance).RaiseSkill((SkillType)103, 1f); } } return false; } __state = new float[2] { num, num2 }; DiveState.DrainMin.SetValue(__instance, num * num3); DiveState.DrainMax.SetValue(__instance, num2 * num3); return true; } private static void Postfix(Player __instance, float dt, float[] __state) { if (DiveState.Local(__instance) && __state != null) { DiveState.DrainMin.SetValue(__instance, __state[0]); DiveState.DrainMax.SetValue(__instance, __state[1]); } } } [HarmonyPatch(typeof(Player), "Update")] internal static class BreathRecoveryPatch { private static void Postfix(Player __instance) { //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Expected O, but got Unknown if (!DiveState.Local(__instance)) { return; } if ((Object)(object)DiveState.Current != (Object)(object)__instance) { DiveState.Reset(__instance); } if (((Character)__instance).IsDead()) { return; } if (!DiveState.Underwater(__instance)) { DiveState.Breath = DiveState.Cap(__instance); DiveState.DamageClock = 0f; if (!((Character)__instance).InWater()) { DiveState.Diving = false; } return; } float deltaTime = Time.deltaTime; float num = DiveState.Cap(__instance); DiveState.Breath = Mathf.Max(0f, Mathf.Min(num, DiveState.Breath) - deltaTime); if (!(DiveState.Breath > 0f)) { DiveState.DamageClock += deltaTime; if (!(DiveState.DamageClock < 1f)) { DiveState.DamageClock -= 1f; HitData val = new HitData(); val.m_damage.m_damage = Mathf.Max(0f, DivingPlugin.DrowningDamage.Value); ((Character)__instance).Damage(val); } } } } [HarmonyPatch(typeof(Player), "UpdateStats", new Type[] { typeof(float) })] internal static class WaterStaminaRegenPatch { private static readonly FieldInfo Stamina = AccessTools.Field(typeof(Player), "m_stamina"); private static bool loggedBlock; private static void Prefix(Player __instance, out float __state) { __state = ((DiveState.Local(__instance) && DivingPlugin.BlockWaterRegen.Value && DiveState.BlockRegen(__instance)) ? __instance.GetStamina() : (-1f)); } private static void Postfix(Player __instance, float __state) { if (__state < 0f || !DiveState.BlockRegen(__instance) || !(__instance.GetStamina() > __state)) { return; } Stamina.SetValue(__instance, __state); if (!loggedBlock) { loggedBlock = true; ManualLogSource modLog = DivingPlugin.ModLog; if (modLog != null) { modLog.LogInfo((object)"Blocked stamina regeneration while in water"); } } } }