Decompiled source of Water Walking Boots v0.3.11

BepInEx/plugins/WaterWalkingBoots/WaterWalkingBoots.dll

Decompiled 4 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using FishNet.Object;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("WaterWalkingBoots")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.3.11.0")]
[assembly: AssemblyInformationalVersion("0.3.11")]
[assembly: AssemblyProduct("WaterWalkingBoots")]
[assembly: AssemblyTitle("WaterWalkingBoots")]
[assembly: AssemblyVersion("0.3.11.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace WaterWalkingBoots
{
	[BepInPlugin("ponyfisher.howtofish.waterwalkingboots", "Water Walking Boots", "0.3.11")]
	[BepInProcess("How to Fish.exe")]
	public sealed class Plugin : BaseUnityPlugin
	{
		public const string Guid = "ponyfisher.howtofish.waterwalkingboots";

		public const string Name = "Water Walking Boots";

		public const string Version = "0.3.11";

		internal static ManualLogSource Log;

		internal static ConfigEntry<KeyCode> PurchaseKey;

		internal static ConfigEntry<int> PurchasePrice;

		internal static ConfigEntry<KeyCode> ToggleKey;

		internal static ConfigEntry<float> SurfacePadding;

		private void Awake()
		{
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Expected O, but got Unknown
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			PurchaseKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Vendor", "PurchaseKey", (KeyCode)57, "Buy Water Walking Boots while at a vendor.");
			PurchasePrice = ((BaseUnityPlugin)this).Config.Bind<int>("Vendor", "PurchasePrice", 15000, "Price of Water Walking Boots at vendors.");
			ToggleKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Controls", "ToggleKey", (KeyCode)101, "Toggle Water Walking Boots ON/OFF while the boots are held.");
			SurfacePadding = ((BaseUnityPlugin)this).Config.Bind<float>("WaterWalking", "SurfacePadding", 0.12f, new ConfigDescription("How far above the water surface the player's feet are held.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 0.25f), Array.Empty<object>()));
			GameObject val = new GameObject("WaterWalkingBootsRuntime");
			Object.DontDestroyOnLoad((Object)val);
			val.AddComponent<BootsItemRuntime>();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Water Walking Boots 0.3.11 loaded. Purchase the boots from the Island 4 StoreClerc.");
		}
	}
	public sealed class BootsItemRuntime : MonoBehaviour
	{
		internal static byte BootsId;

		private const string InternalSpawnName = "waterwalkingboots";

		private static Harmony? _harmony;

		private GameObject? _holder;

		private GameObject? _template;

		private Texture2D? _bootsTexture;

		private bool _forgeFailed;

		private float _retryTimer;

		private float _vendorScanTimer;

		private bool _nearVendor;

		private string _purchaseStatus = "";

		private float _purchaseStatusUntil;

		private Component? _hoveredInteractable;

		internal static bool BootsActive;

		internal static bool WaterSurfaceSupportActive;

		private bool _lastHeldState;

		private GameObject? _waterPlatform;

		private BoxCollider? _waterPlatformCollider;

		private GameObject? _heldBootVisual;

		private Item? _lastHeldBootItem;

		private readonly List<Renderer> _hiddenHeldRenderers = new List<Renderer>();

		private void Start()
		{
			LoadBootTexture();
		}

		private void Update()
		{
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_template == (Object)null && !_forgeFailed)
			{
				_retryTimer -= Time.unscaledDeltaTime;
				if (_retryTimer <= 0f)
				{
					_retryTimer = 1f;
					TryForgeItem();
				}
			}
			bool flag = (Object)(object)GetHeldBoots() != (Object)null;
			if (flag && Input.GetKeyDown(Plugin.ToggleKey.Value))
			{
				BootsActive = !BootsActive;
				RefreshBootIndicators();
				Plugin.Log.LogInfo((object)("Water Walking Boots " + (BootsActive ? "ON" : "OFF")));
			}
			if (_lastHeldState != flag)
			{
				_lastHeldState = flag;
				RefreshBootIndicators();
			}
			_vendorScanTimer -= Time.unscaledDeltaTime;
			if (_vendorScanTimer <= 0f)
			{
				_vendorScanTimer = 0.2f;
				_nearVendor = DetectVendorInteraction();
			}
			if ((Object)(object)_template != (Object)null && _nearVendor && Input.GetKeyDown(Plugin.PurchaseKey.Value))
			{
				TryPurchaseBoots();
			}
		}

		private void FixedUpdate()
		{
			UpdateWaterWalkingSurface();
		}

		private void LateUpdate()
		{
			UpdateHeldBootVisual();
		}

		private void OnGUI()
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: 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_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Expected O, but got Unknown
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Expected O, but got Unknown
			//IL_005c: 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_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d1: Expected O, but got Unknown
			//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)GetHeldBoots() != (Object)null)
			{
				GUIStyle val = new GUIStyle(GUI.skin.box)
				{
					alignment = (TextAnchor)4,
					fontSize = 17,
					fontStyle = (FontStyle)1
				};
				val.normal.textColor = (Color)(BootsActive ? new Color(0.35f, 1f, 0.55f) : Color.white);
				string text = (BootsActive ? "E: Deactivate Boots" : "E: Activate Boots");
				string text2 = (BootsActive ? "ON" : "OFF");
				float num = 330f;
				float num2 = ((float)Screen.width - num) * 0.5f;
				float num3 = (float)Screen.height - 195f;
				GUI.Box(new Rect(num2, num3, num, 34f), text + "   [" + text2 + "]", val);
			}
			if (_nearVendor)
			{
				GUIStyle val2 = new GUIStyle(GUI.skin.box)
				{
					alignment = (TextAnchor)4,
					fontSize = 18,
					fontStyle = (FontStyle)1
				};
				val2.normal.textColor = (Color)((MoneyManager.Money >= Plugin.PurchasePrice.Value) ? Color.white : new Color(1f, 0.45f, 0.35f));
				float num4 = 470f;
				float num5 = ((float)Screen.width - num4) * 0.5f;
				float num6 = (float)Screen.height * 0.67f;
				GUI.Box(new Rect(num5, num6, num4, 38f), $"[9] Buy Water Walking Boots - ${Plugin.PurchasePrice.Value:N0}", val2);
				if (!string.IsNullOrEmpty(_purchaseStatus) && Time.unscaledTime < _purchaseStatusUntil)
				{
					GUIStyle val3 = new GUIStyle(GUI.skin.box)
					{
						alignment = (TextAnchor)4,
						fontSize = 15,
						fontStyle = (FontStyle)1
					};
					val3.normal.textColor = Color.white;
					GUI.Box(new Rect(num5 + 45f, num6 + 44f, num4 - 90f, 30f), _purchaseStatus, val3);
				}
			}
		}

		private void UpdateHeldBootVisual()
		{
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			Item heldBoots = GetHeldBoots();
			if ((Object)(object)heldBoots == (Object)null)
			{
				RestoreHiddenHeldRenderers();
				if ((Object)(object)_heldBootVisual != (Object)null)
				{
					_heldBootVisual.SetActive(false);
				}
				_lastHeldBootItem = null;
				return;
			}
			Player localPlayer = Player.LocalPlayer;
			if ((Object)(object)localPlayer == (Object)null || (Object)(object)localPlayer.CamObject == (Object)null)
			{
				return;
			}
			if ((Object)(object)_lastHeldBootItem != (Object)(object)heldBoots)
			{
				RestoreHiddenHeldRenderers();
				_lastHeldBootItem = heldBoots;
				Renderer[] componentsInChildren = ((Component)heldBoots).GetComponentsInChildren<Renderer>(true);
				foreach (Renderer val in componentsInChildren)
				{
					if (!((Object)(object)val == (Object)null))
					{
						val.enabled = false;
						_hiddenHeldRenderers.Add(val);
					}
				}
			}
			else
			{
				foreach (Renderer hiddenHeldRenderer in _hiddenHeldRenderers)
				{
					if ((Object)(object)hiddenHeldRenderer != (Object)null)
					{
						hiddenHeldRenderer.enabled = false;
					}
				}
			}
			EnsureHeldBootVisual(localPlayer.CamObject);
			if ((Object)(object)_heldBootVisual != (Object)null)
			{
				_heldBootVisual.SetActive(true);
				Transform transform = _heldBootVisual.transform;
				transform.localPosition = new Vector3(0.3f, -0.28f, 0.72f);
				transform.localRotation = Quaternion.Euler(8f, -22f, 4f);
				transform.localScale = Vector3.one * 0.72f;
			}
		}

		private void EnsureHeldBootVisual(Transform cameraTransform)
		{
			if ((Object)(object)_heldBootVisual != (Object)null)
			{
				if ((Object)(object)_heldBootVisual.transform.parent != (Object)(object)cameraTransform)
				{
					_heldBootVisual.transform.SetParent(cameraTransform, false);
				}
				return;
			}
			_heldBootVisual = BuildBootsModel(cameraTransform, ((Component)cameraTransform).gameObject.layer);
			((Object)_heldBootVisual).name = "WWBoots_FirstPersonVisual";
			Collider[] componentsInChildren = _heldBootVisual.GetComponentsInChildren<Collider>(true);
			foreach (Collider val in componentsInChildren)
			{
				if ((Object)(object)val != (Object)null)
				{
					Object.Destroy((Object)(object)val);
				}
			}
			_heldBootVisual.SetActive(false);
		}

		private void RestoreHiddenHeldRenderers()
		{
			foreach (Renderer hiddenHeldRenderer in _hiddenHeldRenderers)
			{
				if ((Object)(object)hiddenHeldRenderer != (Object)null)
				{
					hiddenHeldRenderer.enabled = true;
				}
			}
			_hiddenHeldRenderers.Clear();
		}

		private void UpdateWaterWalkingSurface()
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: 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_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: 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_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01db: Unknown result type (might be due to invalid IL or missing references)
			//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_019b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: 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_0173: 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_0191: Unknown result type (might be due to invalid IL or missing references)
			if (!BootsActive)
			{
				DisableWaterPlatform();
				return;
			}
			Player localPlayer = Player.LocalPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				DisableWaterPlatform();
				return;
			}
			Transform transform = localPlayer.Transform;
			Vector3 position = transform.position;
			if (!TryGetWaterHeight(position, out var waterY))
			{
				DisableWaterPlatform();
				return;
			}
			if (Mathf.Abs(position.y - waterY) > 3f)
			{
				DisableWaterPlatform();
				return;
			}
			EnsureWaterPlatform();
			if ((Object)(object)_waterPlatform == (Object)null)
			{
				return;
			}
			float num = Mathf.Max(Plugin.SurfacePadding.Value, 0.12f);
			float num2 = 0.06f;
			float num3 = waterY + num - num2;
			Vector3 position2 = default(Vector3);
			((Vector3)(ref position2))..ctor(position.x, num3, position.z);
			PrepareWaterPlatformCollisions(localPlayer, position2);
			_waterPlatform.transform.position = position2;
			if (!_waterPlatform.activeSelf)
			{
				_waterPlatform.SetActive(true);
			}
			WaterSurfaceSupportActive = true;
			Collider val = FindBestPlayerCollider(localPlayer);
			Rigidbody rigidbody = localPlayer.Rigidbody;
			if ((Object)(object)val != (Object)null)
			{
				Bounds bounds = val.bounds;
				float y = ((Bounds)(ref bounds)).min.y;
				float num4 = waterY + num;
				if (y < num4 - 0.01f && y > waterY - 2.5f)
				{
					float num5 = num4 - y;
					Vector3 position3 = transform.position + Vector3.up * num5;
					if ((Object)(object)rigidbody != (Object)null)
					{
						rigidbody.position = position3;
						Vector3 linearVelocity = rigidbody.linearVelocity;
						if (linearVelocity.y < 0f)
						{
							linearVelocity.y = 0f;
						}
						rigidbody.linearVelocity = linearVelocity;
					}
					else
					{
						transform.position = position3;
					}
				}
			}
			if ((Object)(object)rigidbody != (Object)null && rigidbody.position.y <= waterY + 1.5f && rigidbody.linearVelocity.y < -0.5f)
			{
				Vector3 linearVelocity2 = rigidbody.linearVelocity;
				linearVelocity2.y = 0f;
				rigidbody.linearVelocity = linearVelocity2;
			}
		}

		private static Collider? FindBestPlayerCollider(Player player)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: 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)
			Collider[] componentsInChildren = ((Component)player).GetComponentsInChildren<Collider>(true);
			Collider result = null;
			float num = 0f;
			Collider[] array = componentsInChildren;
			foreach (Collider val in array)
			{
				if (!((Object)(object)val == (Object)null) && !val.isTrigger)
				{
					Bounds bounds = val.bounds;
					float num2 = ((Bounds)(ref bounds)).size.x * ((Bounds)(ref bounds)).size.y * ((Bounds)(ref bounds)).size.z;
					if (num2 > num)
					{
						num = num2;
						result = val;
					}
				}
			}
			return result;
		}

		private static bool TryGetWaterHeight(Vector3 position, out float waterY)
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			waterY = 0f;
			try
			{
				MethodInfo methodInfo = AccessTools.Method(typeof(WaterManager), "GetWaterHeight", new Type[1] { typeof(Vector3) }, (Type[])null);
				if (methodInfo != null)
				{
					object obj = methodInfo.Invoke(null, new object[1] { position });
					if (obj is float num)
					{
						waterY = num;
						return true;
					}
					if (obj is double num2)
					{
						waterY = (float)num2;
						return true;
					}
				}
				PropertyInfo propertyInfo = AccessTools.Property(typeof(WaterManager), "WaterHeight");
				if (propertyInfo != null)
				{
					object value = propertyInfo.GetValue(null);
					if (value is float num3)
					{
						waterY = num3;
						return true;
					}
					if (value is double num4)
					{
						waterY = (float)num4;
						return true;
					}
				}
				FieldInfo fieldInfo = AccessTools.Field(typeof(WaterManager), "WaterHeight");
				if (fieldInfo != null)
				{
					object value2 = fieldInfo.GetValue(null);
					if (value2 is float num5)
					{
						waterY = num5;
						return true;
					}
					if (value2 is double num6)
					{
						waterY = (float)num6;
						return true;
					}
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogDebug((object)("Water height lookup failed: " + ex.Message));
			}
			return false;
		}

		private void EnsureWaterPlatform()
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Expected O, but got Unknown
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_waterPlatform != (Object)null))
			{
				_waterPlatform = new GameObject("WaterWalkingBoots_Surface");
				Object.DontDestroyOnLoad((Object)(object)_waterPlatform);
				_waterPlatformCollider = _waterPlatform.AddComponent<BoxCollider>();
				_waterPlatform.layer = FindWaterPlatformLayer();
				((Collider)_waterPlatformCollider).isTrigger = false;
				_waterPlatformCollider.size = new Vector3(1.15f, 0.12f, 1.15f);
				_waterPlatform.SetActive(false);
				Plugin.Log.LogInfo((object)"Created Water Walking Boots surface collider.");
			}
		}

		private void PrepareWaterPlatformCollisions(Player player, Vector3 position)
		{
			//IL_001c: 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_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_waterPlatformCollider == (Object)null)
			{
				return;
			}
			Collider val = FindBestPlayerCollider(player);
			Vector3 val2 = _waterPlatformCollider.size * 0.55f;
			if ((Object)(object)val != (Object)null)
			{
				Physics.IgnoreCollision((Collider)(object)_waterPlatformCollider, val, false);
			}
			Collider[] array = Physics.OverlapBox(position, val2, Quaternion.identity, -1, (QueryTriggerInteraction)2);
			foreach (Collider val3 in array)
			{
				if (!((Object)(object)val3 == (Object)null) && !((Object)(object)val3 == (Object)(object)_waterPlatformCollider) && !((Object)(object)val3 == (Object)(object)val))
				{
					Physics.IgnoreCollision((Collider)(object)_waterPlatformCollider, val3, true);
				}
			}
		}

		private void DisableWaterPlatform()
		{
			WaterSurfaceSupportActive = false;
			if ((Object)(object)_waterPlatform != (Object)null && _waterPlatform.activeSelf)
			{
				_waterPlatform.SetActive(false);
			}
		}

		private static int FindWaterPlatformLayer()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: 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_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			LayerMask val = GameInfo.LevelLayer;
			int value = ((LayerMask)(ref val)).value;
			val = GameInfo.CanJumpOnLayers;
			int num = value & ((LayerMask)(ref val)).value;
			if (num == 0)
			{
				val = GameInfo.CanJumpOnLayers;
				num = ((LayerMask)(ref val)).value;
			}
			for (int i = 0; i < 32; i++)
			{
				if ((num & (1 << i)) != 0)
				{
					return i;
				}
			}
			return 0;
		}

		private bool DetectVendorInteraction()
		{
			//IL_0081: 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)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.LocalPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				return false;
			}
			if ((Object)(object)_hoveredInteractable != (Object)null && IsExactIsland4StoreClerk(_hoveredInteractable.transform))
			{
				return true;
			}
			if ((Object)(object)localPlayer.CamObject != (Object)null)
			{
				Vector3 position = localPlayer.CamObject.position;
				Vector3 forward = localPlayer.CamObject.forward;
				RaycastHit val = default(RaycastHit);
				if (Physics.Raycast(position, forward, ref val, 6f, -1, (QueryTriggerInteraction)2) && IsExactIsland4StoreClerk(((RaycastHit)(ref val)).transform))
				{
					return true;
				}
			}
			return IsNearExactIsland4StoreClerk(localPlayer.Transform.position, 4f);
		}

		private static bool IsExactIsland4StoreClerk(Transform start)
		{
			//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)
			if ((Object)(object)start == (Object)null)
			{
				return false;
			}
			Scene scene = ((Component)start).gameObject.scene;
			if (!string.Equals(((Scene)(ref scene)).name, "Island4", StringComparison.OrdinalIgnoreCase))
			{
				return false;
			}
			Transform val = start;
			while ((Object)(object)val != (Object)null)
			{
				if (string.Equals(((Object)((Component)val).gameObject).name, "StoreClerc NPC", StringComparison.Ordinal))
				{
					return string.Equals(BuildTransformPath(val), "IslandHolder/NPCs/StoreClerc NPC", StringComparison.Ordinal);
				}
				val = val.parent;
			}
			return false;
		}

		private static bool IsNearExactIsland4StoreClerk(Vector3 playerPosition, float radius)
		{
			//IL_0017: 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_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = GameObject.Find("IslandHolder/NPCs/StoreClerc NPC");
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			Scene scene = val.scene;
			if (!string.Equals(((Scene)(ref scene)).name, "Island4", StringComparison.OrdinalIgnoreCase))
			{
				return false;
			}
			float num = radius * radius;
			Vector3 val2 = val.transform.position - playerPosition;
			return ((Vector3)(ref val2)).sqrMagnitude <= num;
		}

		private static string BuildTransformPath(Transform target)
		{
			List<string> list = new List<string>();
			Transform val = target;
			while ((Object)(object)val != (Object)null)
			{
				list.Add(((Object)((Component)val).gameObject).name);
				val = val.parent;
			}
			list.Reverse();
			return string.Join("/", list);
		}

		private Item? GetHeldBoots()
		{
			try
			{
				Player localPlayer = Player.LocalPlayer;
				if ((Object)(object)localPlayer == (Object)null || (Object)(object)localPlayer.Holding == (Object)null)
				{
					return null;
				}
				Item heldItem = localPlayer.Holding.HeldItem;
				if ((Object)(object)heldItem != (Object)null && BootsId != 0 && heldItem.ID == BootsId)
				{
					return heldItem;
				}
			}
			catch
			{
			}
			return null;
		}

		private static void RefreshBootIndicators()
		{
			WaterBootsSlotIndicator[] array = Object.FindObjectsByType<WaterBootsSlotIndicator>((FindObjectsInactive)1, (FindObjectsSortMode)0);
			for (int i = 0; i < array.Length; i++)
			{
				array[i].Refresh();
			}
		}

		private void TryPurchaseBoots()
		{
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: 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_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: 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_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.LocalPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				SetPurchaseStatus("Player not ready.");
				return;
			}
			if ((Object)(object)_template == (Object)null)
			{
				SetPurchaseStatus("Boots item is not ready.");
				return;
			}
			int num = Mathf.Max(0, Plugin.PurchasePrice.Value);
			if (MoneyManager.Money < num)
			{
				SetPurchaseStatus($"Not enough money! Need ${num:N0}.");
				return;
			}
			if ((Object)(object)ItemManager.Instance == (Object)null)
			{
				SetPurchaseStatus("Item manager not ready.");
				return;
			}
			Item component = _template.GetComponent<Item>();
			if ((Object)(object)component == (Object)null)
			{
				SetPurchaseStatus("Boots prefab missing.");
				return;
			}
			try
			{
				Vector3 val = (((Object)(object)localPlayer.CamObject != (Object)null) ? localPlayer.CamObject.forward : localPlayer.Transform.forward);
				Vector3 val2 = localPlayer.Transform.position + val * 1.2f + Vector3.up * 0.8f;
				Item val3 = ItemManager.Instance.SpawnNewItem(component, val2, Quaternion.identity);
				if ((Object)(object)val3 == (Object)null)
				{
					SetPurchaseStatus("Could not spawn boots.");
					return;
				}
				MoneyManager.AddMoney(-num, localPlayer);
				val3.SetSyncedHolder(localPlayer, true);
				SetPurchaseStatus($"Purchased Water Walking Boots for ${num:N0}!");
				Plugin.Log.LogInfo((object)($"Water Walking Boots purchased from Island 4 clerk for ${num:N0}. " + $"Money remaining: {MoneyManager.Money:N0}"));
			}
			catch (Exception arg)
			{
				SetPurchaseStatus("Purchase failed - check log.");
				Plugin.Log.LogError((object)$"Water Walking Boots Island 4 vendor purchase failed: {arg}");
			}
		}

		private void SetPurchaseStatus(string message)
		{
			_purchaseStatus = message;
			_purchaseStatusUntil = Time.unscaledTime + 2.5f;
		}

		private static void InstallVendorHoverPatch()
		{
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Expected O, but got Unknown
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Expected O, but got Unknown
			if (_harmony == null)
			{
				return;
			}
			Type type = AccessTools.TypeByName("Interactable");
			if (!(type == null))
			{
				MethodInfo methodInfo = AccessTools.Method(type, "OnStartHover", (Type[])null, (Type[])null);
				MethodInfo methodInfo2 = AccessTools.Method(type, "OnStopHover", (Type[])null, (Type[])null);
				if (methodInfo != null)
				{
					_harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(BootsItemRuntime), "OnInteractableStartHover", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				}
				if (methodInfo2 != null)
				{
					_harmony.Patch((MethodBase)methodInfo2, (HarmonyMethod)null, new HarmonyMethod(typeof(BootsItemRuntime), "OnInteractableStopHover", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				}
			}
		}

		private static void OnInteractableStartHover(Component __instance)
		{
			BootsItemRuntime bootsItemRuntime = Object.FindFirstObjectByType<BootsItemRuntime>();
			if ((Object)(object)bootsItemRuntime != (Object)null)
			{
				bootsItemRuntime._hoveredInteractable = __instance;
			}
		}

		private static void OnInteractableStopHover(Component __instance)
		{
			BootsItemRuntime bootsItemRuntime = Object.FindFirstObjectByType<BootsItemRuntime>();
			if ((Object)(object)bootsItemRuntime != (Object)null && (Object)(object)bootsItemRuntime._hoveredInteractable == (Object)(object)__instance)
			{
				bootsItemRuntime._hoveredInteractable = null;
			}
		}

		private void LoadBootTexture()
		{
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Expected O, but got Unknown
			try
			{
				string text = Path.Combine(Path.GetDirectoryName(typeof(Plugin).Assembly.Location), "boots_icon.png");
				if (!File.Exists(text))
				{
					Plugin.Log.LogWarning((object)("Boot icon not found: " + text));
					return;
				}
				Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false);
				if (!ImageConversion.LoadImage(val, File.ReadAllBytes(text)))
				{
					Plugin.Log.LogWarning((object)"Could not decode boots_icon.png");
					return;
				}
				((Object)val).name = "WWBootsIconTexture";
				((Texture)val).wrapMode = (TextureWrapMode)1;
				_bootsTexture = val;
				Plugin.Log.LogInfo((object)"Loaded Water Walking Boots texture.");
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("Could not load Water Walking Boots texture: " + ex.Message));
			}
		}

		private void TryForgeItem()
		{
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Expected O, but got Unknown
			//IL_018c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: Expected O, but got Unknown
			//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_020a: Unknown result type (might be due to invalid IL or missing references)
			//IL_024b: 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_0267: Unknown result type (might be due to invalid IL or missing references)
			//IL_0287: Unknown result type (might be due to invalid IL or missing references)
			//IL_0296: Unknown result type (might be due to invalid IL or missing references)
			//IL_029b: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0502: Unknown result type (might be due to invalid IL or missing references)
			//IL_0526: Unknown result type (might be due to invalid IL or missing references)
			//IL_0530: Expected O, but got Unknown
			//IL_0538: Unknown result type (might be due to invalid IL or missing references)
			//IL_0542: Expected O, but got Unknown
			try
			{
				IDictionary dictionary = AccessTools.Field(typeof(GameInfo), "_allItems")?.GetValue(null) as IDictionary;
				IDictionary dictionary2 = AccessTools.Field(typeof(GameInfo), "_idToSpawnable")?.GetValue(null) as IDictionary;
				IDictionary dictionary3 = AccessTools.Field(typeof(GameInfo), "_nameToSpawnable")?.GetValue(null) as IDictionary;
				if (dictionary == null || dictionary.Count == 0)
				{
					return;
				}
				Item val = FindReferenceItem(dictionary);
				if ((Object)(object)val == (Object)null)
				{
					Plugin.Log.LogWarning((object)"No suitable vanilla item reference found yet. Retrying...");
					return;
				}
				byte b = FindFreeItemId(dictionary, 231);
				if (b == 0)
				{
					Plugin.Log.LogError((object)"No free custom Item ID was available.");
					_forgeFailed = true;
					return;
				}
				BootsId = b;
				int layer = ((Component)val).gameObject.layer;
				int visualLayer = layer;
				int layer2 = layer;
				Renderer componentInChildren = ((Component)val).GetComponentInChildren<Renderer>(true);
				if ((Object)(object)componentInChildren != (Object)null)
				{
					visualLayer = ((Component)componentInChildren).gameObject.layer;
				}
				if (AccessTools.Field(typeof(Item), "_worldColliders")?.GetValue(val) is Collider[] array && array.Length != 0 && (Object)(object)array[0] != (Object)null)
				{
					layer2 = ((Component)array[0]).gameObject.layer;
				}
				_holder = new GameObject("WWBootsTemplateHolder");
				_holder.SetActive(false);
				Object.DontDestroyOnLoad((Object)(object)_holder);
				_template = new GameObject("WW Boots Item");
				_template.transform.SetParent(_holder.transform, false);
				_template.layer = layer;
				_template.AddComponent<NetworkObject>();
				Rigidbody val2 = _template.AddComponent<Rigidbody>();
				Rigidbody component = ((Component)val).GetComponent<Rigidbody>();
				if ((Object)(object)component != (Object)null)
				{
					val2.mass = component.mass;
					val2.interpolation = component.interpolation;
					val2.collisionDetectionMode = component.collisionDetectionMode;
					val2.linearDamping = component.linearDamping;
					val2.angularDamping = component.angularDamping;
				}
				else
				{
					val2.mass = 1.5f;
					val2.collisionDetectionMode = (CollisionDetectionMode)1;
				}
				GameObject val3 = new GameObject("WorldCollider");
				val3.transform.SetParent(_template.transform, false);
				val3.layer = layer2;
				BoxCollider val4 = val3.AddComponent<BoxCollider>();
				val4.size = new Vector3(0.52f, 0.42f, 0.52f);
				GameObject val5 = new GameObject("PickupTrigger");
				val5.transform.SetParent(_template.transform, false);
				val5.layer = layer;
				val5.tag = "Item";
				BoxCollider val6 = val5.AddComponent<BoxCollider>();
				((Collider)val6).isTrigger = true;
				val6.size = new Vector3(0.8f, 0.8f, 0.8f);
				GameObject val7 = BuildBootsModel(_template.transform, visualLayer);
				BootsWorldVisualKeeper bootsWorldVisualKeeper = _template.AddComponent<BootsWorldVisualKeeper>();
				bootsWorldVisualKeeper.VisualRoot = val7;
				bootsWorldVisualKeeper.SourceTexture = _bootsTexture;
				BootsPickupKeeper bootsPickupKeeper = _template.AddComponent<BootsPickupKeeper>();
				bootsPickupKeeper.PickupCollider = (Collider?)(object)val6;
				bootsPickupKeeper.WorldColliders = (Collider[]?)(object)new Collider[1] { (Collider)val4 };
				bootsPickupKeeper.Body = val2;
				List<Renderer> value = new List<Renderer>(val7.GetComponentsInChildren<Renderer>(true));
				Item val8 = _template.AddComponent<Item>();
				SetField(val8, "_id", b);
				SetField(val8, "_canPickUp", true);
				SetField(val8, "_cost", 15000);
				SetField(val8, "_worth", 7500);
				SetField(val8, "_ignoredBySeagulls", true);
				SetField(val8, "_ignoredByMoneyNPC", false);
				SetField(val8, "_worldColliders", new Collider[1] { (Collider)val4 });
				SetField(val8, "_pickUpCollider", val6);
				SetField(val8, "_hoverTextTarget", val7.transform);
				SetField(val8, "_extraRigs", new ItemExtraRigidbody[0]);
				SetField(val8, "_renderers", value);
				SetField(val8, "_skinRenderers", new List<Renderer>());
				SetField(val8, "_trailEffects", new List<GameObject>());
				SetField(val8, "_modelForwardLength", 0.4f);
				SetField(val8, "_modelHeight", 0.42f);
				MeshFilter componentInChildren2 = val7.GetComponentInChildren<MeshFilter>(true);
				if ((Object)(object)componentInChildren2 != (Object)null)
				{
					SetField(val8, "_mesh", componentInChildren2.sharedMesh);
				}
				SetField(val8, "_inventoryMeshRot", (object)new Vector3(18f, -32f, -8f));
				SetField(val8, "_inventoryMeshScale", 0.95f);
				SetField(val8, "_inventoryMeshPos", (object)new Vector3(0f, -0.02f, 0f));
				CopyOptionalField(val, val8, "_impactSoundType");
				SetField(val8, "_handTransformsRight", (object)new HandTransforms(false));
				SetField(val8, "_handTransformsLeft", (object)new HandTransforms(false));
				CopyOptionalField(val, val8, "_floatInfos");
				SetField(_template.AddComponent<RigidbodySync>(), "_extraHinges", new Rigidbody[0]);
				dictionary.Add(b, val8);
				if (dictionary2 != null && !dictionary2.Contains(b))
				{
					dictionary2.Add(b, val8);
				}
				if (dictionary3 != null && !dictionary3.Contains("waterwalkingboots"))
				{
					dictionary3.Add("waterwalkingboots", val8);
				}
				RegisterWithFishNet(_template);
				InstallPatches();
				Plugin.Log.LogInfo((object)$"WATER WALKING BOOTS READY: Item ID {b}. Purchase from the Island 4 StoreClerc.");
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"Water Walking Boots item creation failed: {arg}");
				_forgeFailed = true;
			}
		}

		private GameObject BuildBootsModel(Transform parent, int visualLayer)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: 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_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Expected O, but got Unknown
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Expected O, but got Unknown
			//IL_008b: 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_009c: Expected O, but got Unknown
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Expected O, but got Unknown
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: 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_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Expected O, but got Unknown
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("WWBootsModel");
			val.transform.SetParent(parent, false);
			val.layer = visualLayer;
			Shader val2 = Shader.Find("Universal Render Pipeline/Lit");
			if ((Object)(object)val2 == (Object)null)
			{
				val2 = Shader.Find("Standard");
			}
			Material val3 = new Material(val2);
			((Object)val3).name = "WWBootsUpper";
			val3.color = new Color(0.035f, 0.2f, 0.46f);
			Material val4 = new Material(val2);
			((Object)val4).name = "WWBootsSole";
			val4.color = new Color(0.025f, 0.045f, 0.065f);
			Material val5 = new Material(val2);
			((Object)val5).name = "WWBootsTrim";
			val5.color = new Color(0.05f, 0.72f, 0.92f);
			if (val5.HasProperty("_EmissionColor"))
			{
				val5.EnableKeyword("_EMISSION");
				val5.SetColor("_EmissionColor", new Color(0.01f, 0.28f, 0.46f));
			}
			Material val6 = new Material(val2);
			((Object)val6).name = "WWBootsBuckles";
			val6.color = new Color(0.9f, 0.64f, 0.16f);
			BuildSingleBoot(val.transform, -0.135f, -4f, val3, val4, val5, val6, visualLayer);
			BuildSingleBoot(val.transform, 0.135f, 4f, val3, val4, val5, val6, visualLayer);
			val.transform.localPosition = new Vector3(0f, -0.02f, 0f);
			val.transform.localRotation = Quaternion.Euler(0f, 180f, 0f);
			return val;
		}

		private static void BuildSingleBoot(Transform parent, float x, float yaw, Material upper, Material sole, Material trim, Material buckle, int layer)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Expected O, but got Unknown
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: 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_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01db: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_0203: Unknown result type (might be due to invalid IL or missing references)
			//IL_022c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0240: Unknown result type (might be due to invalid IL or missing references)
			//IL_0254: Unknown result type (might be due to invalid IL or missing references)
			//IL_027e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0292: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02df: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f8: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject((x < 0f) ? "LeftBoot" : "RightBoot");
			val.transform.SetParent(parent, false);
			val.transform.localPosition = new Vector3(x, 0f, 0f);
			val.transform.localRotation = Quaternion.Euler(0f, yaw, 0f);
			val.layer = layer;
			AddBootPart("Sole", val.transform, (PrimitiveType)3, new Vector3(0f, -0.145f, 0.045f), new Vector3(0.215f, 0.06f, 0.47f), Vector3.zero, sole, layer);
			AddBootPart("WaterTread", val.transform, (PrimitiveType)3, new Vector3(0f, -0.181f, 0.055f), new Vector3(0.18f, 0.018f, 0.39f), Vector3.zero, trim, layer);
			AddBootPart("Foot", val.transform, (PrimitiveType)3, new Vector3(0f, -0.055f, 0.055f), new Vector3(0.19f, 0.145f, 0.35f), new Vector3(5f, 0f, 0f), upper, layer);
			AddBootPart("RoundedToe", val.transform, (PrimitiveType)0, new Vector3(0f, -0.055f, 0.235f), new Vector3(0.195f, 0.14f, 0.2f), Vector3.zero, upper, layer);
			AddBootPart("Heel", val.transform, (PrimitiveType)3, new Vector3(0f, -0.045f, -0.17f), new Vector3(0.19f, 0.18f, 0.14f), Vector3.zero, upper, layer);
			AddBootPart("Shaft", val.transform, (PrimitiveType)3, new Vector3(0f, 0.155f, -0.125f), new Vector3(0.205f, 0.34f, 0.185f), new Vector3(-5f, 0f, 0f), upper, layer);
			AddBootPart("Cuff", val.transform, (PrimitiveType)3, new Vector3(0f, 0.335f, -0.14f), new Vector3(0.23f, 0.055f, 0.205f), new Vector3(-5f, 0f, 0f), trim, layer);
			AddBootPart("AnkleStrap", val.transform, (PrimitiveType)3, new Vector3(0f, 0.055f, -0.015f), new Vector3(0.225f, 0.045f, 0.05f), new Vector3(-12f, 0f, 0f), trim, layer);
			AddBootPart("Buckle", val.transform, (PrimitiveType)3, new Vector3((x < 0f) ? (-0.116f) : 0.116f, 0.065f, -0.008f), new Vector3(0.025f, 0.075f, 0.065f), Vector3.zero, buckle, layer);
		}

		private static GameObject AddBootPart(string name, Transform parent, PrimitiveType primitive, Vector3 position, Vector3 scale, Vector3 rotation, Material material, int layer)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: 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)
			GameObject obj = GameObject.CreatePrimitive(primitive);
			((Object)obj).name = name;
			obj.transform.SetParent(parent, false);
			obj.transform.localPosition = position;
			obj.transform.localRotation = Quaternion.Euler(rotation);
			obj.transform.localScale = scale;
			obj.layer = layer;
			Collider component = obj.GetComponent<Collider>();
			if ((Object)(object)component != (Object)null)
			{
				Object.DestroyImmediate((Object)(object)component);
			}
			Renderer component2 = obj.GetComponent<Renderer>();
			if ((Object)(object)component2 != (Object)null)
			{
				component2.sharedMaterial = material;
			}
			return obj;
		}

		private static Item? FindReferenceItem(IDictionary allItems)
		{
			foreach (DictionaryEntry allItem in allItems)
			{
				object? value = allItem.Value;
				Item val = (Item)((value is Item) ? value : null);
				if (val != null && (Object)(object)((Component)val).GetComponent<Rigidbody>() != (Object)null && (Object)(object)((Component)val).GetComponentInChildren<Renderer>(true) != (Object)null)
				{
					return val;
				}
			}
			return null;
		}

		private static byte FindFreeItemId(IDictionary allItems, byte start)
		{
			for (int i = start; i <= 255; i++)
			{
				byte b = (byte)i;
				if (!allItems.Contains(b))
				{
					return b;
				}
			}
			return 0;
		}

		private static void InstallPatches()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Expected O, but got Unknown
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Expected O, but got Unknown
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Expected O, but got Unknown
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Expected O, but got Unknown
			if (_harmony == null)
			{
				_harmony = new Harmony("ponyfisher.howtofish.waterwalkingboots.itemtest");
				MethodInfo methodInfo = AccessTools.Method(typeof(Item), "GetName", (Type[])null, (Type[])null);
				if (methodInfo != null)
				{
					_harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(BootsItemRuntime), "GetNamePrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				}
				MethodInfo methodInfo2 = AccessTools.Method(typeof(Item), "SetSyncedHolder", (Type[])null, (Type[])null);
				if (methodInfo2 != null)
				{
					_harmony.Patch((MethodBase)methodInfo2, (HarmonyMethod)null, new HarmonyMethod(typeof(BootsItemRuntime), "SetSyncedHolderPostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				}
				MethodInfo methodInfo3 = AccessTools.Method(typeof(InventorySlot), "SetItem", (Type[])null, (Type[])null);
				if (methodInfo3 != null)
				{
					_harmony.Patch((MethodBase)methodInfo3, (HarmonyMethod)null, new HarmonyMethod(typeof(BootsItemRuntime), "InventorySlotPostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				}
				MethodInfo methodInfo4 = AccessTools.Method(typeof(PlayerMovement), "UnderWaterCheck", (Type[])null, (Type[])null);
				if (methodInfo4 != null)
				{
					_harmony.Patch((MethodBase)methodInfo4, (HarmonyMethod)null, new HarmonyMethod(typeof(BootsItemRuntime), "UnderWaterCheckPostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				}
				InstallVendorHoverPatch();
			}
		}

		private static void UnderWaterCheckPostfix(PlayerMovement __instance)
		{
			if (BootsActive && WaterSurfaceSupportActive && !((Object)(object)Player.LocalPlayer == (Object)null) && !((Object)(object)Player.LocalPlayer.Movement != (Object)(object)__instance))
			{
				AccessTools.Field(typeof(PlayerMovement), "_isSwimming")?.SetValue(__instance, false);
			}
		}

		private static bool GetNamePrefix(Item __instance, ref string __result)
		{
			if ((Object)(object)__instance != (Object)null && BootsId != 0 && __instance.ID == BootsId)
			{
				__result = "Water Walking Boots";
				return false;
			}
			return true;
		}

		private static void SetSyncedHolderPostfix(Item __instance)
		{
			if (!((Object)(object)__instance == (Object)null) && BootsId != 0 && __instance.ID == BootsId)
			{
				BootsPickupKeeper component = ((Component)__instance).GetComponent<BootsPickupKeeper>();
				if ((Object)(object)component != (Object)null)
				{
					component.RefreshNow();
				}
			}
		}

		private static void InventorySlotPostfix(InventorySlot __instance, Item item)
		{
			//IL_015f: 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)
			try
			{
				object? obj = AccessTools.Field(typeof(InventorySlot), "_itemImage")?.GetValue(__instance);
				RawImage val = (RawImage)((obj is RawImage) ? obj : null);
				object? obj2 = AccessTools.Field(typeof(InventorySlot), "_filter")?.GetValue(__instance);
				MeshFilter val2 = (MeshFilter)((obj2 is MeshFilter) ? obj2 : null);
				WaterBootsSlotState waterBootsSlotState = ((Component)__instance).GetComponent<WaterBootsSlotState>();
				if ((Object)(object)waterBootsSlotState == (Object)null)
				{
					waterBootsSlotState = ((Component)__instance).gameObject.AddComponent<WaterBootsSlotState>();
					waterBootsSlotState.Capture(val);
				}
				WaterBootsSlotIcon[] componentsInChildren = ((Component)__instance).GetComponentsInChildren<WaterBootsSlotIcon>(true);
				foreach (WaterBootsSlotIcon waterBootsSlotIcon in componentsInChildren)
				{
					if ((Object)(object)waterBootsSlotIcon != (Object)null)
					{
						Object.DestroyImmediate((Object)(object)((Component)waterBootsSlotIcon).gameObject);
					}
				}
				WaterBootsSlotIndicator[] componentsInChildren2 = ((Component)__instance).GetComponentsInChildren<WaterBootsSlotIndicator>(true);
				foreach (WaterBootsSlotIndicator waterBootsSlotIndicator in componentsInChildren2)
				{
					if ((Object)(object)waterBootsSlotIndicator != (Object)null)
					{
						Object.DestroyImmediate((Object)(object)((Component)waterBootsSlotIndicator).gameObject);
					}
				}
				if (!((Object)(object)item != (Object)null) || BootsId == 0 || item.ID != BootsId)
				{
					waterBootsSlotState.Restore(val);
					return;
				}
				BootsItemRuntime bootsItemRuntime = Object.FindFirstObjectByType<BootsItemRuntime>();
				if ((Object)(object)val != (Object)null && (Object)(object)bootsItemRuntime != (Object)null && (Object)(object)bootsItemRuntime._bootsTexture != (Object)null)
				{
					val.texture = (Texture)(object)bootsItemRuntime._bootsTexture;
					((Graphic)val).material = null;
					val.uvRect = new Rect(0f, 0f, 1f, 1f);
					((Graphic)val).color = Color.white;
					((Behaviour)val).enabled = true;
					((Graphic)val).raycastTarget = false;
				}
				if ((Object)(object)val2 != (Object)null)
				{
					val2.sharedMesh = null;
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogDebug((object)("Could not update Water Walking Boots hotbar UI: " + ex.Message));
			}
		}

		private static void CopyOptionalField(object source, object destination, string fieldName)
		{
			FieldInfo fieldInfo = AccessTools.Field(source.GetType(), fieldName);
			if (!(fieldInfo == null))
			{
				object value = fieldInfo.GetValue(source);
				if (value != null)
				{
					fieldInfo.SetValue(destination, value);
				}
			}
		}

		private static void SetField(object target, string fieldName, object value)
		{
			FieldInfo fieldInfo = AccessTools.Field(target.GetType(), fieldName);
			if (fieldInfo != null)
			{
				fieldInfo.SetValue(target, value);
			}
			else
			{
				Plugin.Log.LogDebug((object)("Optional field not found: " + target.GetType().Name + "." + fieldName));
			}
		}

		private static bool RegisterWithFishNet(GameObject template)
		{
			try
			{
				Type type = Type.GetType("FishNet.Object.NetworkObject, FishNet.Runtime");
				Type type2 = Type.GetType("FishNet.InstanceFinder, FishNet.Runtime");
				if (type == null || type2 == null)
				{
					Plugin.Log.LogWarning((object)"Could not resolve FishNet runtime types.");
					return false;
				}
				Component component = template.GetComponent(type);
				if ((Object)(object)component == (Object)null)
				{
					return false;
				}
				object obj = type2.GetProperty("NetworkManager", BindingFlags.Static | BindingFlags.Public)?.GetValue(null);
				if (obj == null)
				{
					Plugin.Log.LogWarning((object)"FishNet NetworkManager is not ready.");
					return false;
				}
				object obj2 = obj.GetType().GetProperty("SpawnablePrefabs")?.GetValue(obj);
				if (obj2 == null)
				{
					return false;
				}
				MethodInfo methodInfo = null;
				MethodInfo[] methods = obj2.GetType().GetMethods(BindingFlags.Instance | BindingFlags.Public);
				foreach (MethodInfo methodInfo2 in methods)
				{
					if (!(methodInfo2.Name != "AddObject"))
					{
						ParameterInfo[] parameters = methodInfo2.GetParameters();
						if (parameters.Length >= 1 && parameters[0].ParameterType == type)
						{
							methodInfo = methodInfo2;
							break;
						}
					}
				}
				if (methodInfo == null)
				{
					return false;
				}
				ParameterInfo[] parameters2 = methodInfo.GetParameters();
				object[] array = new object[parameters2.Length];
				array[0] = component;
				for (int j = 1; j < array.Length; j++)
				{
					if (parameters2[j].HasDefaultValue)
					{
						array[j] = parameters2[j].DefaultValue;
					}
					else if (parameters2[j].ParameterType == typeof(bool))
					{
						array[j] = false;
					}
					else
					{
						array[j] = null;
					}
				}
				methodInfo.Invoke(obj2, array);
				Plugin.Log.LogInfo((object)"Registered Water Walking Boots with FishNet spawnables.");
				return true;
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("FishNet registration failed: " + ex.Message));
				return false;
			}
		}
	}
	public sealed class BootsPickupKeeper : MonoBehaviour
	{
		public Collider? PickupCollider;

		public Collider[]? WorldColliders;

		public Rigidbody? Body;

		private Item? _item;

		private float _timer;

		private void Awake()
		{
			_item = ((Component)this).GetComponent<Item>();
		}

		private void OnEnable()
		{
			RefreshNow();
		}

		private void Update()
		{
			_timer -= Time.unscaledDeltaTime;
			if (_timer <= 0f)
			{
				_timer = 0.15f;
				RefreshNow();
			}
		}

		public void RefreshNow()
		{
			if ((Object)(object)_item == (Object)null)
			{
				_item = ((Component)this).GetComponent<Item>();
			}
			if ((Object)(object)_item == (Object)null)
			{
				return;
			}
			bool flag = false;
			try
			{
				Player localPlayer = Player.LocalPlayer;
				flag = (Object)(object)localPlayer != (Object)null && (Object)(object)localPlayer.Holding != (Object)null && (Object)(object)localPlayer.Holding.HeldItem == (Object)(object)_item;
			}
			catch
			{
			}
			if (flag)
			{
				return;
			}
			try
			{
				if ((Object)(object)PickupCollider == (Object)null)
				{
					ref Collider? pickupCollider = ref PickupCollider;
					object? obj2 = AccessTools.Field(typeof(Item), "_pickUpCollider")?.GetValue(_item);
					pickupCollider = (Collider?)((obj2 is Collider) ? obj2 : null);
				}
				if (WorldColliders == null || WorldColliders.Length == 0)
				{
					WorldColliders = AccessTools.Field(typeof(Item), "_worldColliders")?.GetValue(_item) as Collider[];
				}
				if ((Object)(object)Body == (Object)null)
				{
					Body = ((Component)this).GetComponent<Rigidbody>();
				}
				if ((Object)(object)PickupCollider != (Object)null)
				{
					PickupCollider.enabled = true;
					PickupCollider.isTrigger = true;
					if (!((Component)PickupCollider).gameObject.activeSelf)
					{
						((Component)PickupCollider).gameObject.SetActive(true);
					}
				}
				if (WorldColliders != null)
				{
					Collider[] worldColliders = WorldColliders;
					foreach (Collider val in worldColliders)
					{
						if (!((Object)(object)val == (Object)null))
						{
							val.enabled = true;
							val.isTrigger = false;
							if (!((Component)val).gameObject.activeSelf)
							{
								((Component)val).gameObject.SetActive(true);
							}
						}
					}
				}
				if ((Object)(object)Body != (Object)null)
				{
					Body.isKinematic = false;
					Body.detectCollisions = true;
					Body.useGravity = true;
					Body.WakeUp();
				}
				if (!((Component)this).gameObject.activeSelf)
				{
					((Component)this).gameObject.SetActive(true);
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogDebug((object)("Boots dropped-item state restore failed: " + ex.Message));
			}
		}
	}
	public sealed class WaterBootsSlotState : MonoBehaviour
	{
		private Texture? _texture;

		private Material? _material;

		private Rect _uvRect;

		private Color _color;

		private bool _raycastTarget;

		private bool _captured;

		public void Capture(RawImage? image)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			if (!_captured && !((Object)(object)image == (Object)null))
			{
				_texture = image.texture;
				_material = ((Graphic)image).material;
				_uvRect = image.uvRect;
				_color = ((Graphic)image).color;
				_raycastTarget = ((Graphic)image).raycastTarget;
				_captured = true;
			}
		}

		public void Restore(RawImage? image)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			if (_captured && !((Object)(object)image == (Object)null))
			{
				image.texture = _texture;
				((Graphic)image).material = _material;
				image.uvRect = _uvRect;
				((Graphic)image).color = _color;
				((Graphic)image).raycastTarget = _raycastTarget;
				((Behaviour)image).enabled = true;
			}
		}
	}
	public sealed class WaterBootsSlotIcon : MonoBehaviour
	{
	}
	public sealed class WaterBootsSlotIndicator : MonoBehaviour
	{
		public RawImage? Light;

		private static Texture2D? _greenPixel;

		public void Refresh()
		{
			//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_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Expected O, but got Unknown
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)Light == (Object)null))
			{
				if ((Object)(object)_greenPixel == (Object)null)
				{
					_greenPixel = new Texture2D(1, 1, (TextureFormat)4, false);
					((Object)_greenPixel).name = "WWBootsGreenIndicator";
					_greenPixel.SetPixel(0, 0, new Color(0.16f, 1f, 0.32f, 1f));
					_greenPixel.Apply();
				}
				Light.texture = (Texture)(object)_greenPixel;
				Light.uvRect = new Rect(0f, 0f, 1f, 1f);
				((Graphic)Light).color = Color.white;
				((Behaviour)Light).enabled = BootsItemRuntime.BootsActive;
			}
		}
	}
	public sealed class BootsWorldVisualKeeper : MonoBehaviour
	{
		public GameObject? VisualRoot;

		public Texture2D? SourceTexture;

		private Renderer[]? _renderers;

		private Material[][]? _defaultMaterials;

		private float _refreshTimer;

		private void Awake()
		{
			EnsureVisual();
		}

		private void OnEnable()
		{
			EnsureVisual();
		}

		private void LateUpdate()
		{
			_refreshTimer -= Time.unscaledDeltaTime;
			if (_refreshTimer <= 0f)
			{
				_refreshTimer = 0.5f;
				EnsureVisual();
			}
		}

		private void EnsureVisual()
		{
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)VisualRoot == (Object)null)
			{
				Transform val = ((Component)this).transform.Find("WWBootsModel");
				if ((Object)(object)val != (Object)null)
				{
					VisualRoot = ((Component)val).gameObject;
				}
			}
			if ((Object)(object)VisualRoot == (Object)null)
			{
				return;
			}
			VisualRoot.SetActive(true);
			if (_renderers == null)
			{
				_renderers = VisualRoot.GetComponentsInChildren<Renderer>(true);
			}
			if (_defaultMaterials == null || _defaultMaterials.Length != _renderers.Length)
			{
				_defaultMaterials = new Material[_renderers.Length][];
				for (int i = 0; i < _renderers.Length; i++)
				{
					Material[] sharedMaterials = _renderers[i].sharedMaterials;
					_defaultMaterials[i] = (Material[])(object)new Material[sharedMaterials.Length];
					for (int j = 0; j < sharedMaterials.Length; j++)
					{
						_defaultMaterials[i][j] = (((Object)(object)sharedMaterials[j] == (Object)null) ? ((Material)null) : new Material(sharedMaterials[j]));
					}
				}
			}
			Item component = ((Component)this).GetComponent<Item>();
			bool flag = (Object)(object)component != (Object)null && (Object)(object)Player.LocalPlayer != (Object)null && (Object)(object)Player.LocalPlayer.Holding != (Object)null && (Object)(object)Player.LocalPlayer.Holding.HeldItem == (Object)(object)component;
			for (int k = 0; k < _renderers.Length; k++)
			{
				Renderer val2 = _renderers[k];
				if ((Object)(object)val2 != (Object)null)
				{
					val2.sharedMaterials = _defaultMaterials[k];
					val2.enabled = !flag;
				}
			}
		}
	}
}