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