Decompiled source of HardheimDiving v1.0.2

plugins/HardheimDiving.dll

Decompiled a month ago
using 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();
	}
}