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 HardheimDiving v1.0.2
plugins/HardheimDiving.dll
Decompiled a month agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using Jotunn.Extensions; using Jotunn.Utils; using UnityEngine; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("HardheimDiving")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("HardheimDiving")] [assembly: AssemblyCopyright("Copyright © 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("24fb0f19-a1c4-450f-90e2-e32044a5031d")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyVersion("1.0.0.0")] namespace Hardheim.Diving; [BepInPlugin("hardheim.diving", "Hardheim Diving", "1.0.2")] [BepInDependency(/*Could not decode attribute arguments.*/)] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] [SynchronizationMode(/*Could not decode attribute arguments.*/)] public class HardheimDivingPlugin : BaseUnityPlugin { [CompilerGenerated] private sealed class <InitHudDelayed>d__26 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public HardheimDivingPlugin <>4__this; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <InitHudDelayed>d__26(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitForSeconds(2f); <>1__state = 1; return true; case 1: <>1__state = -1; ((Component)<>4__this).gameObject.AddComponent<OxygenHud>(); LogInfo("Oxygen HUD initialized."); return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } public const string PluginGuid = "hardheim.diving"; public const string PluginName = "Hardheim Diving"; public const string PluginVersion = "1.0.2"; internal static HardheimDivingPlugin Instance; internal ConfigEntry<float> RequiredSwimmingSkill; internal ConfigEntry<bool> UseEquipInWater; internal ConfigEntry<float> RestingStaminaRegenDelay; internal ConfigEntry<float> RestingStaminaRegenRate; internal ConfigEntry<float> UnderwaterRestingStaminaDrainRate; internal ConfigEntry<float> MaxSwimSpeed; internal ConfigEntry<float> FastSwimSpeedMultiplier; internal ConfigEntry<float> ColorDarknessFactor; internal ConfigEntry<float> FogDensityFactor; internal ConfigEntry<float> MinFogDensity; internal ConfigEntry<float> MaxFogDensity; internal ConfigEntry<bool> DebugLogging; internal ConfigEntry<float> MaxOxygen; internal ConfigEntry<float> OxygenDrainPerSecond; internal ConfigEntry<float> OxygenRegenPerSecond; internal ConfigEntry<float> OxygenDamageInterval; internal ConfigEntry<float> OxygenDamageAmount; internal ConfigEntry<float> UnderwaterOverlayOpacity; private static float currentOxygen; private static float oxygenDamageTimer; private Harmony harmony; private void Awake() { //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Expected O, but got Unknown Instance = this; ((BaseUnityPlugin)this).Config.SaveOnConfigSet = false; BindConfigs(); currentOxygen = MaxOxygen.Value; ((BaseUnityPlugin)this).Config.Save(); ((BaseUnityPlugin)this).Config.SaveOnConfigSet = true; harmony = new Harmony("hardheim.diving"); harmony.PatchAll(); ((MonoBehaviour)this).StartCoroutine(InitHudDelayed()); Game.isModded = true; LogInfo("Hardheim Diving 1.0.2 loaded."); } [IteratorStateMachine(typeof(<InitHudDelayed>d__26))] private IEnumerator InitHudDelayed() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <InitHudDelayed>d__26(0) { <>4__this = this }; } private void OnDestroy() { Harmony obj = harmony; if (obj != null) { obj.UnpatchSelf(); } ((BaseUnityPlugin)this).Config.Save(); } private void BindConfigs() { RequiredSwimmingSkill = ConfigFileExtensions.BindConfig<float>(((BaseUnityPlugin)this).Config, "Hardheim", "Szükséges úszás szint", 20f, "Minimum úszás skill, ami szükséges a merülés használatához. Ez alatt a játékos csak vanilla módon úszik.\n\nMinimum swimming skill required for diving. Below this, the player swims using vanilla behavior.", true, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); UseEquipInWater = ConfigFileExtensions.BindConfig<bool>(((BaseUnityPlugin)this).Config, "Általános", "Eszközhasználat vízben", true, "Engedélyezi, hogy a játékos vízben is használhasson eszközöket és fegyvereket.\n\nAllows the player to use tools and weapons while in water.", true, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); RestingStaminaRegenDelay = ConfigFileExtensions.BindConfig<float>(((BaseUnityPlugin)this).Config, "Stamina", "Pihenő stamina visszatöltés késleltetése", 2f, "Mennyi idő után kezdjen visszatöltődni a stamina vízben lebegés közben. A vanilla késleltetés szorzója.\n\nHow long it takes before stamina starts regenerating while floating in water. Multiplier of vanilla stamina delay.", true, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); RestingStaminaRegenRate = ConfigFileExtensions.BindConfig<float>(((BaseUnityPlugin)this).Config, "Stamina", "Pihenő stamina visszatöltés mértéke", 0.5f, "Milyen gyorsan töltődjön vissza a stamina vízben lebegés közben. A vanilla visszatöltés szorzója.\n\nControls stamina regeneration speed while floating in water. Multiplier of vanilla regeneration.", true, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); UnderwaterRestingStaminaDrainRate = ConfigFileExtensions.BindConfig<float>(((BaseUnityPlugin)this).Config, "Stamina", "Víz alatti stamina fogyás", 0.5f, "Milyen gyorsan fogyjon a stamina víz alatt lebegés közben. A vanilla úszás stamina fogyás szorzója.\n\nControls stamina drain while staying underwater. Multiplier of vanilla swimming stamina drain.", true, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); MaxSwimSpeed = ConfigFileExtensions.BindConfig<float>(((BaseUnityPlugin)this).Config, "Mozgás", "Maximális úszási sebesség", 3f, "Maximális úszási sebesség sprintelés közben.\n\nMaximum swimming speed while sprinting.", true, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); FastSwimSpeedMultiplier = ConfigFileExtensions.BindConfig<float>(((BaseUnityPlugin)this).Config, "Mozgás", "Gyorsúszás sebesség szorzó", 0.5f, "Run/Sprint gomb nyomva tartásakor ennyi extra úszási sebességet ad hozzá.\n\nAdditional swimming speed while holding the Run/Sprint key.", true, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); ColorDarknessFactor = ConfigFileExtensions.BindConfig<float>(((BaseUnityPlugin)this).Config, "Vizuális", "Sötétedés mértéke", 0.13f, "Milyen gyorsan sötétedjen a látvány, ahogy a játékos mélyebbre merül.\n\nControls how quickly the view darkens while diving deeper.", true, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); FogDensityFactor = ConfigFileExtensions.BindConfig<float>(((BaseUnityPlugin)this).Config, "Vizuális", "Köd sűrűsödés mértéke", 0.012f, "Milyen gyorsan sűrűsödjön a köd, ahogy a játékos mélyebbre merül.\n\nControls how quickly underwater fog becomes denser while diving deeper.", true, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); MinFogDensity = ConfigFileExtensions.BindConfig<float>(((BaseUnityPlugin)this).Config, "Vizuális", "Minimum köd sűrűség", 0.06f, "A víz alatti köd minimum sűrűsége.\n\nMinimum underwater fog density.", true, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); MaxFogDensity = ConfigFileExtensions.BindConfig<float>(((BaseUnityPlugin)this).Config, "Vizuális", "Maximum köd sűrűség", 0.9f, "A víz alatti köd maximum sűrűsége.\n\nMaximum underwater fog density.", true, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); DebugLogging = ConfigFileExtensions.BindConfig<bool>(((BaseUnityPlugin)this).Config, "Debug", "Részletes logolás", false, "Részletes debug logok bekapcsolása hibakereséshez. Normál használat mellett maradjon kikapcsolva.\n\nEnables verbose debug logging for troubleshooting. Recommended to keep disabled during normal gameplay.", true, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); MaxOxygen = ConfigFileExtensions.BindConfig<float>(((BaseUnityPlugin)this).Config, "Oxigén", "Maximális oxigén", 100f, "A játékos maximális oxigén mennyisége víz alatt.\n\nMaximum underwater oxygen amount.", true, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); OxygenDrainPerSecond = ConfigFileExtensions.BindConfig<float>(((BaseUnityPlugin)this).Config, "Oxigén", "Oxigén fogyás másodpercenként", 1f, "Ennyi oxigén fogy másodpercenként, amikor a játékos víz alatt van.\n\nAmount of oxygen drained per second underwater.", true, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); OxygenRegenPerSecond = ConfigFileExtensions.BindConfig<float>(((BaseUnityPlugin)this).Config, "Oxigén", "Oxigén visszatöltés másodpercenként", 10f, "Ennyi oxigén töltődik vissza másodpercenként, amikor a játékos nincs víz alatt.\n\nAmount of oxygen regenerated per second when not underwater.", true, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); OxygenDamageInterval = ConfigFileExtensions.BindConfig<float>(((BaseUnityPlugin)this).Config, "Oxigén", "Fulladás sebzés időköze", 1f, "Másodpercben megadva, milyen gyakran kap sebzést a játékos, ha elfogyott az oxigénje.\n\nHow often drowning damage is applied after oxygen runs out.", true, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); OxygenDamageAmount = ConfigFileExtensions.BindConfig<float>(((BaseUnityPlugin)this).Config, "Oxigén", "Fulladás sebzés mértéke", 5f, "Ennyi sebzést kap a játékos minden fulladás sebzésnél.\n\nDamage dealt each time drowning damage is applied.", true, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); UnderwaterOverlayOpacity = ConfigFileExtensions.BindConfig<float>(((BaseUnityPlugin)this).Config, "Vizuális", "Víz alatti overlay erősség", 0.22f, "Mennyire legyen erős a víz alatti overlay effekt.\n\nControls the strength of the underwater overlay effect.", true, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); } internal bool IsEnvAllowed() { if ((Object)(object)EnvMan.instance == (Object)null) { return true; } EnvSetup currentEnvironment = EnvMan.instance.GetCurrentEnvironment(); return currentEnvironment == null || currentEnvironment.m_name != "SunkenCrypt"; } internal static bool HasRequiredSwimmingSkill(Player player) { if ((Object)(object)player == (Object)null || (Object)(object)Instance == (Object)null) { return false; } return ((Character)player).GetSkillLevel((SkillType)103) >= Instance.RequiredSwimmingSkill.Value; } internal static float GetOxygen01() { if ((Object)(object)Instance == (Object)null || Instance.MaxOxygen.Value <= 0f) { return 1f; } return Mathf.Clamp01(currentOxygen / Instance.MaxOxygen.Value); } internal static bool ShouldShowOxygenHud() { if ((Object)(object)Player.m_localPlayer == (Object)null) { return false; } if (!DivingUtils.TryGetDiver(Player.m_localPlayer, out var diver)) { return false; } return ((Character)Player.m_localPlayer).InWater() && diver.HasRequiredSwimmingSkill(); } internal static void HandleOxygen(Player player, Diver diver, float dt) { //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Expected O, but got Unknown //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01af: 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) if ((Object)(object)Instance == (Object)null || (Object)(object)player == (Object)null || (Object)(object)diver == (Object)null) { return; } float num = Mathf.Max(1f, Instance.MaxOxygen.Value); if (currentOxygen > num) { currentOxygen = num; } if (currentOxygen < 0f) { currentOxygen = 0f; } bool flag = diver.HasRequiredSwimmingSkill(); bool flag2 = ((Character)player).InWater(); bool flag3 = ZInput.GetButton("Crouch") || ZInput.GetButton("JoyCrouch"); bool flag4 = ZInput.GetButton("Jump") || ZInput.GetButton("JoyJump"); float liquidLevel = ((Character)player).GetLiquidLevel(); float num2 = ((Component)player).transform.position.y + 1.55f; bool flag5 = num2 < liquidLevel - 0.05f; if (flag2 && flag && flag5) { currentOxygen = Mathf.MoveTowards(currentOxygen, 0f, Instance.OxygenDrainPerSecond.Value * dt); if (currentOxygen <= 0f) { oxygenDamageTimer += dt; if (oxygenDamageTimer >= Instance.OxygenDamageInterval.Value) { oxygenDamageTimer = 0f; HitData val = new HitData(); val.m_damage.m_damage = Instance.OxygenDamageAmount.Value; val.m_point = ((Component)player).transform.position; val.m_dir = Vector3.up; val.m_hitType = (HitType)4; ((Character)player).Damage(val); } } else { oxygenDamageTimer = 0f; } } else { currentOxygen = Mathf.MoveTowards(currentOxygen, num, Instance.OxygenRegenPerSecond.Value * dt); oxygenDamageTimer = 0f; } } internal static void LogInfo(string msg) { HardheimDivingPlugin instance = Instance; if (instance != null) { ((BaseUnityPlugin)instance).Logger.LogInfo((object)msg); } } internal static void LogDebug(string msg) { if ((Object)(object)Instance != (Object)null && Instance.DebugLogging.Value) { ((BaseUnityPlugin)Instance).Logger.LogInfo((object)("[DEBUG] " + msg)); } } internal static void LogWarning(string msg) { HardheimDivingPlugin instance = Instance; if (instance != null) { ((BaseUnityPlugin)instance).Logger.LogWarning((object)msg); } } } internal class OxygenHud : MonoBehaviour { private GameObject oxygenRoot; private Image underwaterOverlay; private Image oxygenFrameImage; private Image oxygenFillImage; private Image oxygenGlowImage; private Image oxygenIconImage; private float retryTimer; private RectTransform oxygenFillRect; private const float OxygenBarWidth = 290f; private const float OxygenBarHeight = 16f; private void Update() { //IL_0196: 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_016a: 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) if ((Object)(object)Player.m_localPlayer == (Object)null || (Object)(object)HardheimDivingPlugin.Instance == (Object)null) { SetVisible(visible: false); UpdateUnderwaterOverlay(); return; } if ((Object)(object)oxygenRoot == (Object)null || (Object)(object)oxygenFillRect == (Object)null) { retryTimer -= Time.deltaTime; if (retryTimer <= 0f) { retryTimer = 1f; TryCreateFromStaminaBar(); } UpdateUnderwaterOverlay(); return; } UpdateUnderwaterOverlay(); bool flag = HardheimDivingPlugin.ShouldShowOxygenHud(); SetVisible(flag); if (!flag) { return; } float value = HardheimDivingPlugin.Instance.MaxOxygen.Value; float num = Mathf.Clamp(HardheimDivingPlugin.GetOxygen01() * value, 0f, value); float num2 = num / value; bool flag2 = num2 <= 0.4f; Image component = ((Component)oxygenFillRect).GetComponent<Image>(); if ((Object)(object)component != (Object)null) { if (flag2) { float num3 = Mathf.Abs(Mathf.Sin(Time.time * 14f)); ((Graphic)component).color = Color.Lerp(new Color(0.8f, 0f, 0f, 0.75f), new Color(1f, 0f, 0f, 1f), num3); } else { ((Graphic)component).color = new Color(0.05f, 0.55f, 1f, 0.9f); } } oxygenFillRect.SetSizeWithCurrentAnchors((Axis)0, 290f * Mathf.Clamp01(num2)); } private Image CreateHudImage(string name, Transform parent, Sprite sprite, Vector2 size, Vector2 position) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Expected O, but got Unknown //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name); val.transform.SetParent(parent, false); RectTransform val2 = val.AddComponent<RectTransform>(); val2.anchorMin = new Vector2(0.5f, 0.5f); val2.anchorMax = new Vector2(0.5f, 0.5f); val2.pivot = new Vector2(0.5f, 0.5f); val2.anchoredPosition = position; val2.sizeDelta = size; Image val3 = val.AddComponent<Image>(); val3.sprite = sprite; ((Graphic)val3).raycastTarget = false; return val3; } private Sprite LoadSprite(string path) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown //IL_0085: 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) if (!File.Exists(path)) { HardheimDivingPlugin.LogWarning("HUD asset missing: " + path); return null; } byte[] data = File.ReadAllBytes(path); Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false); if (!TryLoadPngTexture(val, data)) { HardheimDivingPlugin.LogWarning("Failed to load HUD asset: " + path); return null; } ((Texture)val).wrapMode = (TextureWrapMode)1; ((Texture)val).filterMode = (FilterMode)1; return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f)); } private bool TryLoadPngTexture(Texture2D tex, byte[] data) { Type type = Type.GetType("UnityEngine.ImageConversion, UnityEngine.ImageConversionModule"); if (type == null) { return false; } MethodInfo method = type.GetMethod("LoadImage", BindingFlags.Static | BindingFlags.Public, null, new Type[2] { typeof(Texture2D), typeof(byte[]) }, null); if (method == null) { return false; } object obj = method.Invoke(null, new object[2] { tex, data }); bool flag = default(bool); int num; if (obj is bool) { flag = (bool)obj; num = 1; } else { num = 0; } return (byte)((uint)num & (flag ? 1u : 0u)) != 0; } private void UpdateUnderwaterOverlay() { //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: 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_0090: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)underwaterOverlay == (Object)null) && !((Object)(object)HardheimDivingPlugin.Instance == (Object)null) && !((Object)(object)Player.m_localPlayer == (Object)null)) { Player localPlayer = Player.m_localPlayer; Camera main = Camera.main; bool flag = (Object)(object)main != (Object)null && ((Character)localPlayer).InWater() && ((Component)main).transform.position.y < ((Character)localPlayer).GetLiquidLevel() - 0.05f; float num = 0f; float num2 = 0f; if (flag) { num2 = Mathf.Clamp01(((Component)main).transform.forward.y); float num3 = num2 * 0.35f; num = HardheimDivingPlugin.Instance.UnderwaterOverlayOpacity.Value + num3; } Color color = ((Graphic)underwaterOverlay).color; color.a = Mathf.MoveTowards(color.a, Mathf.Clamp01(num), Time.deltaTime * 8f); ((Graphic)underwaterOverlay).color = color; } } private void TryCreateFromStaminaBar() { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Expected O, but got Unknown //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Expected O, but got Unknown //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: 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_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_01fd: Unknown result type (might be due to invalid IL or missing references) //IL_0204: Expected O, but got Unknown //IL_0235: Unknown result type (might be due to invalid IL or missing references) //IL_0250: Unknown result type (might be due to invalid IL or missing references) //IL_026b: Unknown result type (might be due to invalid IL or missing references) //IL_027c: Unknown result type (might be due to invalid IL or missing references) //IL_0297: Unknown result type (might be due to invalid IL or missing references) //IL_0313: Unknown result type (might be due to invalid IL or missing references) //IL_0322: Unknown result type (might be due to invalid IL or missing references) //IL_035d: Unknown result type (might be due to invalid IL or missing references) //IL_0395: Unknown result type (might be due to invalid IL or missing references) //IL_03a4: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)Hud.instance == (Object)null)) { oxygenRoot = new GameObject("Hardheim_OxygenBar"); oxygenRoot.transform.SetParent(((Component)Hud.instance).transform, false); RectTransform val = oxygenRoot.AddComponent<RectTransform>(); val.anchorMin = new Vector2(0.5f, 0f); val.anchorMax = new Vector2(0.5f, 0f); val.pivot = new Vector2(0.5f, 0.5f); val.anchoredPosition = new Vector2(0f, 110f); val.sizeDelta = new Vector2(520f, 72f); ((Transform)val).localScale = Vector3.one * 0.6f; string text = Path.Combine(Paths.ConfigPath, "HardheimDiving", "assets"); Directory.CreateDirectory(text); oxygenFrameImage = CreateHudImage("Frame", oxygenRoot.transform, LoadSprite(Path.Combine(text, "oxygen_frame.png")), new Vector2(360f, 54f), Vector2.zero); GameObject val2 = new GameObject("FillMask"); val2.transform.SetParent(oxygenRoot.transform, false); RectTransform val3 = val2.AddComponent<RectTransform>(); val3.anchorMin = new Vector2(0f, 0.5f); val3.anchorMax = new Vector2(0f, 0.5f); val3.pivot = new Vector2(0f, 0.5f); val3.anchoredPosition = new Vector2(143f, -0.5f); val3.sizeDelta = new Vector2(290f, 30f); Image val4 = val2.AddComponent<Image>(); ((Graphic)val4).color = Color.white; ((Graphic)val4).raycastTarget = false; Mask val5 = val2.AddComponent<Mask>(); val5.showMaskGraphic = false; GameObject val6 = new GameObject("Fill"); val6.transform.SetParent(val2.transform, false); oxygenFillRect = val6.AddComponent<RectTransform>(); oxygenFillRect.anchorMin = new Vector2(0f, 0.5f); oxygenFillRect.anchorMax = new Vector2(0f, 0.5f); oxygenFillRect.pivot = new Vector2(0f, 0.5f); oxygenFillRect.anchoredPosition = Vector2.zero; oxygenFillRect.sizeDelta = new Vector2(290f, 30f); oxygenFillImage = val6.AddComponent<Image>(); oxygenFillImage.sprite = LoadSprite(Path.Combine(text, "oxygen_fill.png")); oxygenFillImage.type = (Type)0; ((Graphic)oxygenFillImage).raycastTarget = false; oxygenGlowImage = CreateHudImage("Glow", oxygenRoot.transform, LoadSprite(Path.Combine(text, "oxygen_glow.png")), new Vector2(340f, 54f), new Vector2(-4f, 0f)); ((Component)oxygenGlowImage).gameObject.SetActive(false); ((Graphic)oxygenGlowImage).color = new Color(1f, 1f, 1f, 0.75f); oxygenIconImage = CreateHudImage("Icon", oxygenRoot.transform, LoadSprite(Path.Combine(text, "oxygen_icon.png")), new Vector2(40f, 40f), new Vector2(-148f, 0f)); CreateUnderwaterOverlay(); SetVisible(visible: false); HardheimDivingPlugin.LogInfo("Hardheim assetes oxigén HUD létrehozva."); } } private void SetVisible(bool visible) { if (!((Object)(object)oxygenRoot == (Object)null)) { oxygenRoot.SetActive(visible); } } private string GetPath(Transform t) { if ((Object)(object)t == (Object)null) { return ""; } string text = ((Object)t).name; while ((Object)(object)t.parent != (Object)null) { t = t.parent; text = ((Object)t).name + "/" + text; } return text; } private void CreateUnderwaterOverlay() { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)Hud.instance == (Object)null)) { GameObject val = new GameObject("Hardheim_UnderwaterOverlay"); val.transform.SetParent(((Component)Hud.instance).transform, false); underwaterOverlay = val.AddComponent<Image>(); ((Graphic)underwaterOverlay).raycastTarget = false; ((Graphic)underwaterOverlay).color = new Color(0.05f, 0.22f, 0.18f, 0f); RectTransform component = val.GetComponent<RectTransform>(); component.anchorMin = Vector2.zero; component.anchorMax = Vector2.one; component.offsetMin = Vector2.zero; component.offsetMax = Vector2.zero; val.transform.SetAsFirstSibling(); HardheimDivingPlugin.LogInfo("Underwater overlay created."); } } } internal static class ReflectionFields { internal static readonly FieldInfo MoveDir = AccessTools.Field(typeof(Character), "m_moveDir"); internal static readonly FieldInfo CurrentVel = AccessTools.Field(typeof(Character), "m_currentVel"); internal static readonly FieldInfo LastGroundTouch = AccessTools.Field(typeof(Character), "m_lastGroundTouch"); internal static readonly FieldInfo SwimTimer = AccessTools.Field(typeof(Character), "m_swimTimer"); internal static readonly FieldInfo SwimDepth = AccessTools.Field(typeof(Player), "m_swimDepth"); internal static readonly FieldInfo SwimSpeed = AccessTools.Field(typeof(Player), "m_swimSpeed"); internal static readonly FieldInfo SwimAcceleration = AccessTools.Field(typeof(Player), "m_swimAcceleration"); internal static readonly FieldInfo SwimSkillImproveTimer = AccessTools.Field(typeof(Player), "m_swimSkillImproveTimer"); internal static readonly FieldInfo Stamina = AccessTools.Field(typeof(Player), "m_stamina"); internal static readonly FieldInfo StaminaRegenTimer = AccessTools.Field(typeof(Player), "m_staminaRegenTimer"); internal static readonly FieldInfo StaminaRegen = AccessTools.Field(typeof(Player), "m_staminaRegen"); internal static readonly FieldInfo StaminaRegenDelay = AccessTools.Field(typeof(Player), "m_staminaRegenDelay"); internal static readonly FieldInfo SwimStaminaDrainMinSkill = AccessTools.Field(typeof(Player), "m_swimStaminaDrainMinSkill"); internal static readonly FieldInfo SwimStaminaDrainMaxSkill = AccessTools.Field(typeof(Player), "m_swimStaminaDrainMaxSkill"); internal static readonly FieldInfo GameCameraMinWaterDistance = AccessTools.Field(typeof(GameCamera), "m_minWaterDistance"); internal static T Get<T>(FieldInfo field, object instance, T fallback = default(T)) { if (field == null || instance == null) { return fallback; } try { object value = field.GetValue(instance); if (value is T) { T result = (T)value; if (true) { return result; } } } catch { } return fallback; } internal static void Set<T>(FieldInfo field, object instance, T value) { if (field == null || instance == null) { return; } try { field.SetValue(instance, value); } catch { } } } internal class Diver : MonoBehaviour { private const float DefaultSwimDepth = 1.4f; private const float DivingSwimDepth = 2f; private static readonly Dictionary<Player, Diver> Divers = new Dictionary<Player, Diver>(); public Player player; public float BaseSwimSpeed { get; private set; } public float RestingStaminaRegenDelay { get { float num = ReflectionFields.Get(ReflectionFields.StaminaRegenDelay, player, 1f); return (0f - HardheimDivingPlugin.Instance.RestingStaminaRegenDelay.Value) * num; } } public float RestingStaminaRegenRate { get { float num = ReflectionFields.Get(ReflectionFields.StaminaRegen, player, 1f); return HardheimDivingPlugin.Instance.RestingStaminaRegenRate.Value * num; } } private void Awake() { player = ((Component)this).GetComponent<Player>(); if (!((Object)(object)player == (Object)null)) { SetSwimDepth(1.4f); BaseSwimSpeed = GetSwimSpeed(); if (!Divers.ContainsKey(player)) { Divers.Add(player, this); } } } private void OnDestroy() { if ((Object)(object)player != (Object)null && Divers.ContainsKey(player)) { Divers.Remove(player); } } public bool HasRequiredSwimmingSkill() { return HardheimDivingPlugin.HasRequiredSwimmingSkill(player); } public void ResetSwimDepthIfNotInWater() { if ((Object)(object)player == (Object)null || !((Character)player).InWater()) { ResetSwimDepthToDefault(); } } public void ResetSwimDepthToDefault() { SetSwimDepth(1.4f); } public bool CanDive() { if ((Object)(object)player == (Object)null) { return false; } if (!HasRequiredSwimmingSkill()) { return false; } return ((Character)player).InWater() && !((Character)player).IsOnGround() && ((Character)player).IsSwimming(); } public bool IsInsideLiquid() { //IL_0031: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null) { return false; } return Mathf.Max(0f, ((Character)player).GetLiquidLevel() - ((Component)player).transform.position.y) > 1.4f; } public bool IsUnderSurface() { return GetSwimDepth() > 1.4f; } public bool IsDiving() { return GetSwimDepth() > 2f; } public bool IsSurfacing() { return !IsDiving() && IsUnderSurface(); } public bool IsRestingInWater() { //IL_002a: 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) int result; if ((Object)(object)player != (Object)null && !IsDiving() && ((Character)player).IsSwimming()) { Vector3 velocity = ((Character)player).GetVelocity(); result = ((((Vector3)(ref velocity)).magnitude < 1f) ? 1 : 0); } else { result = 0; } return (byte)result != 0; } public void RegenRestingStamina(float dt) { if (!((Object)(object)player == (Object)null)) { float num = ReflectionFields.Get(ReflectionFields.StaminaRegenTimer, player, 0f); num -= dt; ReflectionFields.Set(ReflectionFields.StaminaRegenTimer, player, num); if (player.GetStamina() < ((Character)player).GetMaxStamina() && num <= RestingStaminaRegenDelay) { float skillFactor = ((Character)player).GetSkillFactor((SkillType)103); float num2 = (1f + skillFactor) * RestingStaminaRegenRate; float num3 = ReflectionFields.Get(ReflectionFields.Stamina, player, player.GetStamina()); num3 = Mathf.Min(((Character)player).GetMaxStamina(), num3 + num2 * dt * Game.m_staminaRegenRate); ReflectionFields.Set(ReflectionFields.Stamina, player, num3); } } } public void DrainDivingStamina(float dt) { } public void UpdateSwimSkill(float dt) { if (!((Object)(object)player == (Object)null)) { float num = ReflectionFields.Get(ReflectionFields.SwimSkillImproveTimer, player, 0f); num += dt; if (num > 1f) { num = 0f; ((Character)player).RaiseSkill((SkillType)103, 1f); } ReflectionFields.Set(ReflectionFields.SwimSkillImproveTimer, player, num); } } public void UpdateSwimSpeed(float dt) { if (!((Object)(object)player == (Object)null) && !((Object)(object)HardheimDivingPlugin.Instance == (Object)null)) { bool flag = ZInput.GetButton("Run") || ZInput.GetButton("JoyRun"); float num = ReflectionFields.Get(ReflectionFields.SwimAcceleration, player, 1f); float value = HardheimDivingPlugin.Instance.MaxSwimSpeed.Value; float num2 = value * Mathf.Max(1f, HardheimDivingPlugin.Instance.FastSwimSpeedMultiplier.Value); float num3 = (flag ? num2 : BaseSwimSpeed); float num4 = Mathf.MoveTowards(GetSwimSpeed(), num3, num * dt); num4 = Mathf.Clamp(num4, BaseSwimSpeed, num2); SetSwimSpeed(num4); } } public void ApplyFastSwimVelocity() { //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0122: 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_0126: Unknown result type (might be due to invalid IL or missing references) //IL_012b: 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_0146: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)player == (Object)null) && !((Object)(object)HardheimDivingPlugin.Instance == (Object)null) && ((Character)player).InWater() && ((Character)player).IsSwimming() && (ZInput.GetButton("Run") || ZInput.GetButton("JoyRun"))) { Vector3 val = GetMoveDir(); val.y = 0f; if (((Vector3)(ref val)).sqrMagnitude < 0.01f) { val = ((Component)player).transform.forward; val.y = 0f; } if (!(((Vector3)(ref val)).sqrMagnitude < 0.01f)) { ((Vector3)(ref val)).Normalize(); float value = HardheimDivingPlugin.Instance.FastSwimSpeedMultiplier.Value; float num = HardheimDivingPlugin.Instance.MaxSwimSpeed.Value + value; Vector3 val2 = ReflectionFields.Get<Vector3>(ReflectionFields.CurrentVel, player, ((Character)player).GetVelocity()); Vector3 value2 = val * num; value2.y = val2.y; ReflectionFields.Set<Vector3>(ReflectionFields.CurrentVel, player, value2); HardheimDivingPlugin.LogDebug("Gyorsúszás fizikai sebesség alkalmazva. speed=" + num + " currentVel=" + ((Vector3)(ref value2)).magnitude); } } } public void Dive(float dt, bool ascend, out Vector3? defaultMoveDir) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: 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_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) defaultMoveDir = GetMoveDir(); Vector3 diveDirection = GetDiveDirection(ascend); SetMoveDir(diveDirection); Vector3 val = CalculateSwimVelocity(); float num = (ascend ? 3f : 1f); float num2 = GetSwimDepth() - val.y * dt * num; SetSwimDepth(Mathf.Max(num2, 1.4f)); } public Vector3 GetDiveDirection(bool ascend) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_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_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) Vector3 val = (ascend ? (Vector3.up * 2.2f) : Vector3.down); Vector3 val2 = GetMoveDir(); if (((Vector3)(ref val2)).magnitude < 0.1f) { float scale = (ascend ? 0.05f : 0.05f); val2 = GetHorizontalLookDir(scale); } Vector3 result = val2 + val; ((Vector3)(ref result)).Normalize(); return result; } private Vector3 GetHorizontalLookDir(float scale) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) Vector3 forward = ((Component)player).transform.forward; forward.y = 0f; ((Vector3)(ref forward)).Normalize(); return forward * scale; } public Vector3 CalculateSwimVelocity() { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0028: 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_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) float num = GetSwimSpeed(); if (((Character)player).InMinorActionSlowdown()) { num = 0f; } Vector3 moveDir = GetMoveDir(); Vector3 val = moveDir * num; Vector3 val2 = ReflectionFields.Get<Vector3>(ReflectionFields.CurrentVel, player, ((Character)player).GetVelocity()); float num2 = ReflectionFields.Get(ReflectionFields.SwimAcceleration, player, 1f); Vector3 result = Vector3.Lerp(val2, val, num2); try { } catch { } return result; } public float GetSwimDepth() { return ReflectionFields.Get(ReflectionFields.SwimDepth, player, 1.4f); } private void SetSwimDepth(float value) { ReflectionFields.Set(ReflectionFields.SwimDepth, player, value); } private float GetSwimSpeed() { return ReflectionFields.Get(ReflectionFields.SwimSpeed, player, 2f); } private void SetSwimSpeed(float value) { ReflectionFields.Set(ReflectionFields.SwimSpeed, player, value); } public Vector3 GetMoveDir() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) return ReflectionFields.Get<Vector3>(ReflectionFields.MoveDir, player, Vector3.zero); } public void SetMoveDir(Vector3 value) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) ReflectionFields.Set<Vector3>(ReflectionFields.MoveDir, player, value); } } internal static class DivingUtils { public static bool TryGetDiver(Character character, out Diver diver) { if (!IsValidLocalPlayer(character, out var player)) { diver = null; return false; } return ((Component)player).TryGetComponent<Diver>(ref diver); } public static bool TryGetDiver(Player player, out Diver diver) { if (!IsValidLocalPlayer(player)) { diver = null; return false; } return ((Component)player).TryGetComponent<Diver>(ref diver); } public static bool IsValidLocalPlayer(Character character, out Player player) { if ((Object)(object)character != (Object)null && character.IsPlayer() && (Object)(object)character == (Object)(object)Player.m_localPlayer) { player = Player.m_localPlayer; return true; } player = null; return false; } public static bool IsValidLocalPlayer(Player player) { return (Object)(object)player != (Object)null && (Object)(object)player == (Object)(object)Player.m_localPlayer; } } [HarmonyPatch] internal static class DivingPatches { private static bool InUpdateSwimming; [HarmonyPostfix] [HarmonyPatch(typeof(Player), "Awake")] private static void Player_Awake_Postfix(Player __instance) { Diver diver = default(Diver); if (!((Object)(object)__instance == (Object)null) && !((Component)__instance).TryGetComponent<Diver>(ref diver)) { ((Component)__instance).gameObject.AddComponent<Diver>(); } } [HarmonyPrefix] [HarmonyPatch(typeof(Character), "UpdateMotion")] private static void Character_UpdateMotion_Prefix(Character __instance) { if (!DivingUtils.TryGetDiver(__instance, out var diver) || (Object)(object)HardheimDivingPlugin.Instance == (Object)null || !HardheimDivingPlugin.Instance.IsEnvAllowed()) { return; } if (!diver.HasRequiredSwimmingSkill()) { diver.ResetSwimDepthToDefault(); return; } diver.ResetSwimDepthIfNotInWater(); if (diver.IsUnderSurface() && diver.IsInsideLiquid()) { ReflectionFields.Set(ReflectionFields.LastGroundTouch, diver.player, 0.3f); ReflectionFields.Set(ReflectionFields.SwimTimer, diver.player, 0f); } } [HarmonyPrefix] [HarmonyPatch(typeof(Character), "UpdateSwimming")] public static void UpdateSwimming_Prefix(Character __instance, float dt, out Vector3? __state) { InUpdateSwimming = true; __state = null; if (DivingUtils.TryGetDiver(__instance, out var diver)) { bool flag = ZInput.GetButton("Crouch") || ZInput.GetButton("JoyCrouch"); bool flag2 = ZInput.GetButton("Run") || ZInput.GetButton("JoyRun"); bool flag3 = ZInput.GetButton("Jump") || ZInput.GetButton("JoyJump"); HardheimDivingPlugin.LogDebug("[INPUT] crouch=" + flag + " run=" + flag2 + " jump=" + flag3 + " swimming=" + __instance.IsSwimming() + " onGround=" + __instance.IsOnGround() + " inWater=" + __instance.InWater() + " underSurface=" + diver.IsUnderSurface() + " insideLiquid=" + diver.IsInsideLiquid()); } if (!DivingUtils.TryGetDiver(__instance, out var diver2)) { return; } if (!diver2.HasRequiredSwimmingSkill()) { diver2.ResetSwimDepthToDefault(); return; } diver2.UpdateSwimSpeed(dt); if ((ZInput.GetButton("Jump") || ZInput.GetButton("JoyJump")) && diver2.IsUnderSurface()) { diver2.Dive(dt, ascend: true, out __state); } else if ((ZInput.GetButton("Crouch") || ZInput.GetButton("JoyCrouch")) && diver2.CanDive()) { diver2.Dive(dt, ascend: false, out __state); } else if ((__instance.IsOnGround() || !diver2.IsDiving()) && !diver2.IsRestingInWater()) { diver2.ResetSwimDepthToDefault(); } } [HarmonyPostfix] [HarmonyPatch(typeof(Character), "UpdateSwimming")] public static void UpdateSwimming_Postfix(Character __instance, float dt, ref Vector3? __state) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) InUpdateSwimming = false; if (__state.HasValue) { ReflectionFields.Set<Vector3>(ReflectionFields.MoveDir, __instance, __state.Value); __state = null; } if (DivingUtils.TryGetDiver(__instance, out var diver) && diver.HasRequiredSwimmingSkill()) { diver.ApplyFastSwimVelocity(); } } [HarmonyPrefix] [HarmonyPatch(typeof(Character), "UpdateRotation")] public static void UpdateRotation_Prefix(Character __instance, out Quaternion? __state) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) if (InUpdateSwimming) { __state = ((Component)__instance).transform.rotation; } else { __state = null; } } [HarmonyPostfix] [HarmonyPatch(typeof(Character), "UpdateRotation")] public static void UpdateRotation_Postfix(Character __instance, float turnSpeed, float dt, ref Quaternion? __state) { //IL_002c: 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_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0072: 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_008d: 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_0080: 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_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) if (InUpdateSwimming && __state.HasValue && !((Object)(object)__instance == (Object)null) && !(((Component)__instance).transform.rotation != __state.Value) && DivingUtils.TryGetDiver(__instance, out var diver) && diver.IsUnderSurface()) { Player player = diver.player; Vector3 moveDir = diver.GetMoveDir(); Quaternion val = ((moveDir == Vector3.zero) ? ((Component)player).transform.rotation : Quaternion.LookRotation(moveDir)); ((Component)player).transform.rotation = Quaternion.RotateTowards(((Component)player).transform.rotation, val, turnSpeed * dt); } } [HarmonyPrefix] [HarmonyPatch(typeof(Player), "OnSwimming")] public static void Player_OnSwimming_Prefix(Player __instance, ref Vector3 targetVel, float dt) { if (DivingUtils.TryGetDiver(__instance, out var diver) && diver.HasRequiredSwimmingSkill() && !(((Vector3)(ref targetVel)).magnitude >= 0.1f)) { if (diver.IsDiving()) { diver.DrainDivingStamina(dt); diver.UpdateSwimSkill(dt); } else if (diver.IsRestingInWater()) { diver.RegenRestingStamina(dt); } } } [HarmonyPostfix] [HarmonyPatch(typeof(Player), "Update")] private static void Player_Update_Postfix(Player __instance) { if (DivingUtils.TryGetDiver(__instance, out var diver)) { HardheimDivingPlugin.HandleOxygen(__instance, diver, Time.deltaTime); } } [HarmonyPrefix] [HarmonyPatch(typeof(Player), "UseStamina")] private static bool Player_UseStamina_Prefix(Player __instance) { if (!DivingUtils.TryGetDiver(__instance, out var diver)) { return true; } if (!diver.HasRequiredSwimmingSkill()) { return true; } if (((Character)__instance).InWater() && diver.IsUnderSurface()) { HardheimDivingPlugin.LogDebug("Stamina használat blokkolva víz alatt. Oxigén fogy helyette."); return false; } return true; } } [HarmonyPatch] internal static class WaterCameraPatches { private static float WaterLevelCamera; private static bool ShouldResetCamera; private static float? CachedMinWaterDistance; private static float OriginalFogDensity; private static bool CachedFogDensity; private const float UnderWaterCameraMinWaterDistance = -1000f; [HarmonyPrefix] [HarmonyPatch(typeof(GameCamera), "UpdateCamera")] private static void GameCamera_UpdateCamera_Prefix(GameCamera __instance) { //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_023e: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_017c: 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) //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance == (Object)null || !Object.op_Implicit((Object)(object)Player.m_localPlayer) || !DivingUtils.TryGetDiver(Player.m_localPlayer, out var diver)) { ResetMinWaterDistance(__instance); return; } if (!diver.HasRequiredSwimmingSkill() || (Object)(object)HardheimDivingPlugin.Instance == (Object)null || !HardheimDivingPlugin.Instance.IsEnvAllowed()) { ResetMinWaterDistance(__instance); return; } bool flag = diver.IsUnderSurface() && ((Character)Player.m_localPlayer).IsSwimming(); if (flag && !diver.IsRestingInWater()) { SetMinWaterDistanceUnderWater(__instance); } else { ResetMinWaterDistance(__instance); } Camera main = Camera.main; if ((Object)(object)main == (Object)null) { return; } if (((Component)main).gameObject.transform.position.y < WaterLevelCamera && flag && HardheimDivingPlugin.Instance.IsEnvAllowed()) { SetMinWaterDistanceUnderWater(__instance); if (!((Object)(object)EnvMan.instance != (Object)null)) { return; } EnvSetup currentEnvironment = EnvMan.instance.GetCurrentEnvironment(); if (currentEnvironment != null) { if (!CachedFogDensity) { OriginalFogDensity = RenderSettings.fogDensity; CachedFogDensity = true; } Color val = ((!EnvMan.IsNight()) ? currentEnvironment.m_fogColorDay : currentEnvironment.m_fogColorNight); val.a = 1f; val *= 0.45f; val = ChangeColorBrightness(val, diver.GetSwimDepth() * (0f - HardheimDivingPlugin.Instance.ColorDarknessFactor.Value)); RenderSettings.fogColor = val; float num = Mathf.Max(0f, diver.GetSwimDepth() - 1.4f); float num2 = OriginalFogDensity + HardheimDivingPlugin.Instance.MinFogDensity.Value + num * HardheimDivingPlugin.Instance.FogDensityFactor.Value; RenderSettings.fogDensity = Mathf.Clamp(num2, HardheimDivingPlugin.Instance.MinFogDensity.Value, HardheimDivingPlugin.Instance.MaxFogDensity.Value); ShouldResetCamera = true; } } else if (ShouldResetCamera && ((Component)main).gameObject.transform.position.y > WaterLevelCamera && (Object)(object)EnvMan.instance != (Object)null) { EnvSetup currentEnvironment2 = EnvMan.instance.GetCurrentEnvironment(); if (currentEnvironment2 != null) { EnvMan.instance.SetForceEnvironment(currentEnvironment2.m_name); EnvMan.instance.SetForceEnvironment(string.Empty); } CachedFogDensity = false; ShouldResetCamera = false; } } [HarmonyPrefix] [HarmonyPatch(typeof(WaterVolume), "UpdateMaterials")] private static void WaterVolume_UpdateMaterials_Prefix(WaterVolume __instance) { //IL_0059: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)__instance == (Object)null) && Object.op_Implicit((Object)(object)GameCamera.instance) && Object.op_Implicit((Object)(object)Player.m_localPlayer) && DivingUtils.TryGetDiver(Player.m_localPlayer, out var diver) && diver.HasRequiredSwimmingSkill()) { WaterLevelCamera = __instance.GetWaterSurface(((Component)GameCamera.instance).transform.position, 1f); } } private static void SetMinWaterDistanceUnderWater(GameCamera camera) { if (!((Object)(object)camera == (Object)null) && !(ReflectionFields.GameCameraMinWaterDistance == null)) { if (!CachedMinWaterDistance.HasValue) { CachedMinWaterDistance = ReflectionFields.Get(ReflectionFields.GameCameraMinWaterDistance, camera, 0.4f); } ReflectionFields.Set(ReflectionFields.GameCameraMinWaterDistance, camera, -1000f); } } private static void ResetMinWaterDistance(GameCamera camera) { if (!((Object)(object)camera == (Object)null) && !(ReflectionFields.GameCameraMinWaterDistance == null) && CachedMinWaterDistance.HasValue) { ReflectionFields.Set(ReflectionFields.GameCameraMinWaterDistance, camera, CachedMinWaterDistance.Value); } } private static Color ChangeColorBrightness(Color color, float correctionFactor) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002f: 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_00a1: 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_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) float r = color.r; float g = color.g; float b = color.b; if (correctionFactor >= 0f) { return new Color(r, g, b, color.a); } correctionFactor *= -1f; r -= r * correctionFactor; g -= g * correctionFactor; b -= b * correctionFactor; if (r < 0f) { r = 0f; } if (g < 0f) { g = 0f; } if (b < 0f) { b = 0f; } return new Color(r, g, b, color.a); } } [HarmonyPatch] internal static class UseEquipPatches { private static readonly CodeMatch[] CodeMatches = (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) }; private static readonly int InstructionMatchCount = CodeMatches.Length + 1; private static bool ShouldHideItem() { return (Object)(object)HardheimDivingPlugin.Instance != (Object)null && !HardheimDivingPlugin.Instance.UseEquipInWater.Value; } [HarmonyTranspiler] [HarmonyPatch(typeof(Humanoid), "UpdateEquipment")] private static IEnumerable<CodeInstruction> UpdateEquipment_Transpiler(IEnumerable<CodeInstruction> instructions) { return PatchSwimmingEquipmentCheck(instructions, "Humanoid.UpdateEquipment"); } [HarmonyTranspiler] [HarmonyPatch(typeof(Humanoid), "EquipItem")] private static IEnumerable<CodeInstruction> EquipItem_Transpiler(IEnumerable<CodeInstruction> instructions) { return PatchSwimmingEquipmentCheck(instructions, "Humanoid.EquipItem"); } [HarmonyTranspiler] [HarmonyPatch(typeof(Player), "Update")] private static IEnumerable<CodeInstruction> UpdatePlayer_Transpiler(IEnumerable<CodeInstruction> instructions) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Expected O, but got Unknown CodeMatcher val = new CodeMatcher(instructions, (ILGenerator)null); val.MatchStartForward(CodeMatches); if (!val.IsValid) { HardheimDivingPlugin.LogWarning("Failed to patch Player.Update equipment swimming check."); return instructions; } val.Advance(1); val.RemoveInstructions(InstructionMatchCount); return val.InstructionEnumeration(); } private static IEnumerable<CodeInstruction> PatchSwimmingEquipmentCheck(IEnumerable<CodeInstruction> instructions, string methodName) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Expected O, but got Unknown //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Expected O, but got Unknown CodeMatcher val = new CodeMatcher(instructions, (ILGenerator)null); val.MatchStartForward(CodeMatches); if (!val.IsValid) { HardheimDivingPlugin.LogWarning("Failed to patch " + methodName + " equipment swimming check."); return instructions; } val.Advance(InstructionMatchCount); val.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[2] { Transpilers.EmitDelegate<Func<bool>>((Func<bool>)ShouldHideItem), new CodeInstruction(OpCodes.Brfalse, val.InstructionAt(-1).operand) }); return val.InstructionEnumeration(); } }