Decompiled source of HardheimDiving v1.0.1

plugins/HardheimDiving.dll

Decompiled a week ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
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.1")]
[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__24 : 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__24(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.1";

	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> 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;

	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.1 loaded.");
	}

	[IteratorStateMachine(typeof(<InitHudDelayed>d__24))]
	private IEnumerator InitHudDelayed()
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <InitHudDelayed>d__24(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.", 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.", 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.", 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.", 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.", 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.", 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.08298756f, "Milyen gyorsan sötétedjen a látvány, ahogy a játékos mélyebbre merül.", 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", 0f, "Milyen gyorsan sűrűsödjön a köd, ahogy a játékos mélyebbre merül.", 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.06452283f, "A víz alatti köd minimum sűrűsége.", 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", 1.518672f, "A víz alatti köd maximum sűrűsége.", 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.", 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.", 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.", 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.", 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.", 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.", 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_0190: Unknown result type (might be due to invalid IL or missing references)
		//IL_0197: Expected O, but got Unknown
		//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d3: 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 && (flag3 || flag4 || diver.IsUnderSurface() || diver.IsInsideLiquid()))
		{
			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 GuiBar oxygenBar;

	private float retryTimer;

	private float displayedOxygen01 = 1f;

	private void Update()
	{
		if ((Object)(object)Player.m_localPlayer == (Object)null || (Object)(object)HardheimDivingPlugin.Instance == (Object)null)
		{
			SetVisible(visible: false);
			return;
		}
		if ((Object)(object)oxygenRoot == (Object)null || (Object)(object)oxygenBar == (Object)null)
		{
			retryTimer -= Time.deltaTime;
			if (retryTimer <= 0f)
			{
				retryTimer = 1f;
				TryCreateFromStaminaBar();
			}
			return;
		}
		bool flag = HardheimDivingPlugin.ShouldShowOxygenHud();
		SetVisible(flag);
		if (flag)
		{
			float value = HardheimDivingPlugin.Instance.MaxOxygen.Value;
			float oxygen = HardheimDivingPlugin.GetOxygen01();
			displayedOxygen01 = Mathf.MoveTowards(displayedOxygen01, oxygen, Time.deltaTime * 0.75f);
			float value2 = Mathf.Clamp(displayedOxygen01 * value, 0f, value);
			oxygenBar.SetMaxValue(value);
			oxygenBar.SetValue(value2);
		}
	}

	private void TryCreateFromStaminaBar()
	{
		//IL_00b8: 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_00d2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00df: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ee: 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_00ff: Unknown result type (might be due to invalid IL or missing references)
		//IL_011c: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)Hud.instance == (Object)null)
		{
			return;
		}
		GuiBar val = FindStaminaBar();
		if ((Object)(object)val == (Object)null)
		{
			HardheimDivingPlugin.LogInfo("Oxygen HUD: nem találtam stamina GuiBar-t.");
			return;
		}
		oxygenRoot = Object.Instantiate<GameObject>(((Component)val).gameObject, ((Component)val).transform.parent);
		((Object)oxygenRoot).name = "Hardheim_OxygenBar";
		oxygenRoot.SetActive(true);
		oxygenBar = oxygenRoot.GetComponent<GuiBar>();
		RectTransform component = oxygenRoot.GetComponent<RectTransform>();
		RectTransform component2 = ((Component)val).GetComponent<RectTransform>();
		if ((Object)(object)component != (Object)null && (Object)(object)component2 != (Object)null)
		{
			component.anchorMin = component2.anchorMin;
			component.anchorMax = component2.anchorMax;
			component.pivot = component2.pivot;
			component.anchoredPosition = component2.anchoredPosition + new Vector2(45f, 38f);
			((Transform)component).localScale = Vector3.one;
			((Transform)component).SetAsLastSibling();
			component.sizeDelta = new Vector2(158f, 16f);
			RectTransform[] componentsInChildren = oxygenRoot.GetComponentsInChildren<RectTransform>(true);
			foreach (RectTransform val2 in componentsInChildren)
			{
				val2.SetSizeWithCurrentAnchors((Axis)0, 158f);
			}
		}
		Image[] componentsInChildren2 = oxygenRoot.GetComponentsInChildren<Image>(true);
		foreach (Image val3 in componentsInChildren2)
		{
			if (!((Object)(object)val3 == (Object)null))
			{
				string text = ((Object)val3).name.ToLowerInvariant();
				if (!text.Contains("background") && !text.Contains("bg") && !text.Contains("border"))
				{
					((Graphic)val3).color = new Color(0.05f, 0.55f, 1f, ((Graphic)val3).color.a);
				}
			}
		}
		if ((Object)(object)oxygenBar != (Object)null)
		{
			oxygenBar.SetMaxValue(HardheimDivingPlugin.Instance.MaxOxygen.Value);
			oxygenBar.SetValue(HardheimDivingPlugin.Instance.MaxOxygen.Value);
		}
		SetVisible(visible: false);
		HardheimDivingPlugin.LogInfo("Hardheim oxigén HUD létrehozva teljes stamina panel klónból.");
	}

	private GuiBar FindStaminaBar()
	{
		//IL_0103: Unknown result type (might be due to invalid IL or missing references)
		//IL_0108: Unknown result type (might be due to invalid IL or missing references)
		//IL_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)
		GuiBar[] componentsInChildren = ((Component)Hud.instance).GetComponentsInChildren<GuiBar>(true);
		GuiBar val = null;
		GuiBar[] array = componentsInChildren;
		foreach (GuiBar val2 in array)
		{
			if ((Object)(object)val2 == (Object)null)
			{
				continue;
			}
			string text = GetPath(((Component)val2).transform).ToLowerInvariant();
			if (!text.Contains("hardheim_oxygenbar") && !text.Contains("mounthud") && !text.Contains("mountpanel") && !text.Contains("eitr") && !text.Contains("adrenaline") && text.Contains("hudroot/staminapanel/stamina") && text.EndsWith("stamina_fast"))
			{
				RectTransform component = ((Component)val2).GetComponent<RectTransform>();
				float num;
				Rect rect;
				if (!((Object)(object)component != (Object)null))
				{
					num = 0f;
				}
				else
				{
					rect = component.rect;
					num = ((Rect)(ref rect)).width;
				}
				float num2 = num;
				float num3;
				if (!((Object)(object)component != (Object)null))
				{
					num3 = 0f;
				}
				else
				{
					rect = component.rect;
					num3 = ((Rect)(ref rect)).height;
				}
				float num4 = num3;
				HardheimDivingPlugin.LogInfo("Player stamina GuiBar candidate: " + text + " activeInHierarchy=" + ((Component)val2).gameObject.activeInHierarchy + " width=" + num2 + " height=" + num4);
				val = val2;
				break;
			}
		}
		if ((Object)(object)val != (Object)null)
		{
			HardheimDivingPlugin.LogInfo("Oxygen HUD PLAYER stamina source: " + GetPath(((Component)val).transform));
		}
		return val;
	}

	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;
	}
}
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 = 2.5f;

	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() > 2.5f;
	}

	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))
		{
			float num = ((ZInput.GetButton("Run") || ZInput.GetButton("JoyRun")) ? dt : (0f - dt));
			float num2 = ReflectionFields.Get(ReflectionFields.SwimAcceleration, player, 1f);
			float num3 = GetSwimSpeed() + num2 * num;
			num3 = Mathf.Clamp(num3, BaseSwimSpeed, HardheimDivingPlugin.Instance.MaxSwimSpeed.Value);
			SetSwimSpeed(num3);
		}
	}

	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_002f: 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 = GetSwimDepth() - val.y * dt;
		SetSwimDepth(Mathf.Max(num, 1.4f));
	}

	public Vector3 GetDiveDirection(bool ascend)
	{
		//IL_000b: 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_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		//IL_004e: Unknown result type (might be due to invalid IL or missing references)
		//IL_004f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0050: Unknown result type (might be due to invalid IL or missing references)
		//IL_0055: Unknown result type (might be due to invalid IL or missing references)
		//IL_005e: Unknown result type (might be due to invalid IL or missing references)
		//IL_005f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0063: Unknown result type (might be due to invalid IL or missing references)
		//IL_0047: Unknown result type (might be due to invalid IL or missing references)
		//IL_004c: Unknown result type (might be due to invalid IL or missing references)
		Vector3 val = (ascend ? Vector3.up : Vector3.down);
		Vector3 val2 = GetMoveDir();
		if (((Vector3)(ref val2)).magnitude < 0.1f)
		{
			float scale = ((ascend && IsSurfacing()) ? 0.6f : 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))
		{
			return;
		}
		if (!diver.HasRequiredSwimmingSkill())
		{
			diver.ResetSwimDepthToDefault();
			return;
		}
		diver.UpdateSwimSpeed(dt);
		if ((ZInput.GetButton("Jump") || ZInput.GetButton("JoyJump")) && diver.IsUnderSurface())
		{
			diver.Dive(dt, ascend: true, out __state);
		}
		else if ((ZInput.GetButton("Crouch") || ZInput.GetButton("JoyCrouch")) && diver.CanDive())
		{
			diver.Dive(dt, ascend: false, out __state);
		}
		else if ((__instance.IsOnGround() || !diver.IsDiving()) && !diver.IsRestingInWater())
		{
			diver.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;
		}
	}

	[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, Vector3 targetVel, float dt)
	{
		if (!(((Vector3)(ref targetVel)).magnitude >= 0.1f) && DivingUtils.TryGetDiver(__instance, out var diver) && diver.HasRequiredSwimmingSkill())
		{
			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 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_01e5: 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_0140: Unknown result type (might be due to invalid IL or missing references)
		//IL_014e: 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_0175: 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_017c: 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)
			{
				EnvSetup currentEnvironment = EnvMan.instance.GetCurrentEnvironment();
				if (currentEnvironment != null)
				{
					Color color = ((!EnvMan.IsNight()) ? currentEnvironment.m_fogColorDay : currentEnvironment.m_fogColorNight);
					color.a = 1f;
					color = ChangeColorBrightness(color, diver.GetSwimDepth() * (0f - HardheimDivingPlugin.Instance.ColorDarknessFactor.Value));
					RenderSettings.fogColor = color;
					RenderSettings.fogDensity = Mathf.Clamp(RenderSettings.fogDensity + diver.GetSwimDepth() * HardheimDivingPlugin.Instance.FogDensityFactor.Value, 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);
			}
			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();
	}
}